All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/17] ICL PLLs, DP/HDMI and misc display
@ 2018-02-22  3:55 Paulo Zanoni
  2018-02-22  3:55 ` [PATCH 01/17] drm/i915/icl: add definitions for the ICL PLL registers Paulo Zanoni
                   ` (20 more replies)
  0 siblings, 21 replies; 41+ messages in thread
From: Paulo Zanoni @ 2018-02-22  3:55 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

Hello

Here are some more ICL patches, now with the Combo & MG PLLs, some DP/HDMI
initialization code and a few misc fixes.

Again, the R-B tags already present in some of the patches (including those form
me) were given a long time ago, so they need to be re-issued due to the
rebasing.

Thanks,
Paulo

Arkadiusz Hiler (1):
  drm/i915/icl: Calculate link clock using the new registers

Dhinakaran Pandiyan (1):
  drm/i915/icl: HPD pin for port F

James Ausmus (1):
  drm/i915/icl: Don't set pipe CSC/Gamma in PLANE_COLOR_CTL

Manasi Navare (7):
  drm/i915/icl: Add register definitions for Combo PHY vswing sequences.
  drm/i915/icl: Add Combo PHY DDI Buffer translation tables for Icelake.
  drm/i915/icl: Implement voltage swing programming sequence for Combo
    PHY DDI
  drm/i915/icl: Add register defs for voltage swing sequences for MG PHY
    DDI
  drm/i915/icl: Add Voltage swing table for MG PHY DDI Buffer
  drm/i915/icl: Implement voltage swing programming sequence for MG PHY
    DDI
  drm/i915/icl: Fix the DP Max Voltage for ICL

Nabendu Maiti (1):
  drm/i915/icl: Added 5k source scaling support for Gen11 platform

Paulo Zanoni (6):
  drm/i915/icl: add definitions for the ICL PLL registers
  drm/i915/icl: add basic support for the ICL clocks
  drm/i915/icl: compute the combo PHY (DPLL) HDMI registers
  drm/i915/icl: compute the combo PHY (DPLL) DP registers
  drm/i915/icl: compute the MG PLL registers
  drm/i915/gen11: all the DDI ports on gen 11 support 4 lanes

 drivers/gpu/drm/i915/i915_debugfs.c   |  22 ++
 drivers/gpu/drm/i915/i915_drv.h       |   1 +
 drivers/gpu/drm/i915/i915_reg.h       | 313 ++++++++++++++++-
 drivers/gpu/drm/i915/intel_ddi.c      | 529 +++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_display.c  |  33 +-
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 642 +++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_dpll_mgr.h |  41 +++
 drivers/gpu/drm/i915/intel_drv.h      |  10 +
 drivers/gpu/drm/i915/intel_hotplug.c  |   3 +
 9 files changed, 1569 insertions(+), 25 deletions(-)

-- 
2.14.3

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

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

* [PATCH 01/17] drm/i915/icl: add definitions for the ICL PLL registers
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
@ 2018-02-22  3:55 ` Paulo Zanoni
  2018-02-27 22:22   ` James Ausmus
                     ` (2 more replies)
  2018-02-22  3:55 ` Paulo Zanoni
                   ` (19 subsequent siblings)
  20 siblings, 3 replies; 41+ messages in thread
From: Paulo Zanoni @ 2018-02-22  3:55 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

There's a lot of code for the PLL enabling, so let's first only
introduce the register definitions in order to make patch reviewing a
little easier.

v2: Coding style (Jani).
v3: Preparation for upstreaming.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h | 149 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 149 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 1412abcb27d4..f62335c4a748 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -8783,6 +8783,12 @@ enum skl_power_gate {
 #define  PORT_CLK_SEL_NONE		(7<<29)
 #define  PORT_CLK_SEL_MASK		(7<<29)
 
+/* On ICL+ this is the same as PORT_CLK_SEL, but all bits change. */
+#define DDI_CLK_SEL(port)		PORT_CLK_SEL(port)
+#define  DDI_CLK_SEL_NONE		(0x0 << 28)
+#define  DDI_CLK_SEL_MG			(0x8 << 28)
+#define  DDI_CLK_SEL_MASK		(0xF << 28)
+
 /* Transcoder clock selection */
 #define _TRANS_CLK_SEL_A		0x46140
 #define _TRANS_CLK_SEL_B		0x46144
@@ -8913,6 +8919,7 @@ enum skl_power_gate {
  * CNL Clocks
  */
 #define DPCLKA_CFGCR0				_MMIO(0x6C200)
+#define DPCLKA_CFGCR0_ICL			_MMIO(0x164280)
 #define  DPCLKA_CFGCR0_DDI_CLK_OFF(port)	(1 << ((port) ==  PORT_F ? 23 : \
 						      (port)+10))
 #define  DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port)	((port) == PORT_F ? 21 : \
@@ -8929,10 +8936,141 @@ enum skl_power_gate {
 #define  PLL_POWER_STATE	(1 << 26)
 #define CNL_DPLL_ENABLE(pll)	_MMIO_PLL(pll, DPLL0_ENABLE, DPLL1_ENABLE)
 
+#define _MG_PLL1_ENABLE		0x46030
+#define _MG_PLL2_ENABLE		0x46034
+#define _MG_PLL3_ENABLE		0x46038
+#define _MG_PLL4_ENABLE		0x4603C
+/* Bits are the same as DPLL0_ENABLE */
+#define MG_PLL_ENABLE(port)	_MMIO_PORT((port) - PORT_C, _MG_PLL1_ENABLE, \
+					   _MG_PLL2_ENABLE)
+
+#define _MG_REFCLKIN_CTL_PORT1				0x16892C
+#define _MG_REFCLKIN_CTL_PORT2				0x16992C
+#define _MG_REFCLKIN_CTL_PORT3				0x16A92C
+#define _MG_REFCLKIN_CTL_PORT4				0x16B92C
+#define   MG_REFCLKIN_CTL_OD_2_MUX(x)			((x) << 8)
+#define MG_REFCLKIN_CTL(port) _MMIO_PORT((port) - PORT_C, \
+					 _MG_REFCLKIN_CTL_PORT1, \
+					 _MG_REFCLKIN_CTL_PORT2)
+
+#define _MG_CLKTOP2_CORECLKCTL1_PORT1			0x1690D8
+#define _MG_CLKTOP2_CORECLKCTL1_PORT2			0x16B0D8
+#define _MG_CLKTOP2_CORECLKCTL1_PORT3			0x16D0D8
+#define _MG_CLKTOP2_CORECLKCTL1_PORT4			0x16F0D8
+#define   MG_CLKTOP2_CORECLKCTL1_B_DIVRATIO(x)		((x) << 16)
+#define   MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO(x)		((x) << 8)
+#define MG_CLKTOP2_CORECLKCTL1(port) _MMIO_PORT((port) - PORT_C, \
+						_MG_CLKTOP2_CORECLKCTL1_PORT1, \
+						_MG_CLKTOP2_CORECLKCTL1_PORT2)
+
+#define _MG_CLKTOP2_HSCLKCTL_PORT1			0x1688D4
+#define _MG_CLKTOP2_HSCLKCTL_PORT2			0x1698D4
+#define _MG_CLKTOP2_HSCLKCTL_PORT3			0x16A8D4
+#define _MG_CLKTOP2_HSCLKCTL_PORT4			0x16B8D4
+#define   MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL(x)		((x) << 16)
+#define   MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL(x)	((x) << 14)
+#define   MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO(x)		((x) << 12)
+#define   MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO(x)		((x) << 8)
+#define MG_CLKTOP2_HSCLKCTL(port) _MMIO_PORT((port) - PORT_C, \
+					     _MG_CLKTOP2_HSCLKCTL_PORT1, \
+					     _MG_CLKTOP2_HSCLKCTL_PORT2)
+
+#define _MG_PLL_DIV0_PORT1				0x168A00
+#define _MG_PLL_DIV0_PORT2				0x169A00
+#define _MG_PLL_DIV0_PORT3				0x16AA00
+#define _MG_PLL_DIV0_PORT4				0x16BA00
+#define   MG_PLL_DIV0_FRACNEN_H				(1 << 30)
+#define   MG_PLL_DIV0_FBDIV_FRAC(x)			((x) << 8)
+#define   MG_PLL_DIV0_FBDIV_INT(x)			((x) << 0)
+#define MG_PLL_DIV0(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_DIV0_PORT1, \
+				     _MG_PLL_DIV0_PORT2)
+
+#define _MG_PLL_DIV1_PORT1				0x168A04
+#define _MG_PLL_DIV1_PORT2				0x169A04
+#define _MG_PLL_DIV1_PORT3				0x16AA04
+#define _MG_PLL_DIV1_PORT4				0x16BA04
+#define   MG_PLL_DIV1_IREF_NDIVRATIO(x)			((x) << 16)
+#define   MG_PLL_DIV1_DITHER_DIV_1			(0 << 12)
+#define   MG_PLL_DIV1_DITHER_DIV_2			(1 << 12)
+#define   MG_PLL_DIV1_DITHER_DIV_4			(2 << 12)
+#define   MG_PLL_DIV1_DITHER_DIV_8			(3 << 12)
+#define   MG_PLL_DIV1_NDIVRATIO(x)			((x) << 4)
+#define   MG_PLL_DIV1_FBPREDIV(x)			((x) << 0)
+#define MG_PLL_DIV1(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_DIV1_PORT1, \
+				     _MG_PLL_DIV1_PORT2)
+
+#define _MG_PLL_LF_PORT1				0x168A08
+#define _MG_PLL_LF_PORT2				0x169A08
+#define _MG_PLL_LF_PORT3				0x16AA08
+#define _MG_PLL_LF_PORT4				0x16BA08
+#define   MG_PLL_LF_TDCTARGETCNT(x)			((x) << 24)
+#define   MG_PLL_LF_AFCCNTSEL_256			(0 << 20)
+#define   MG_PLL_LF_AFCCNTSEL_512			(1 << 20)
+#define   MG_PLL_LF_GAINCTRL(x)				((x) << 16)
+#define   MG_PLL_LF_INT_COEFF(x)			((x) << 8)
+#define   MG_PLL_LF_PROP_COEFF(x)			((x) << 0)
+#define MG_PLL_LF(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_LF_PORT1, \
+				   _MG_PLL_LF_PORT2)
+
+#define _MG_PLL_FRAC_LOCK_PORT1				0x168A0C
+#define _MG_PLL_FRAC_LOCK_PORT2				0x169A0C
+#define _MG_PLL_FRAC_LOCK_PORT3				0x16AA0C
+#define _MG_PLL_FRAC_LOCK_PORT4				0x16BA0C
+#define   MG_PLL_FRAC_LOCK_TRUELOCK_CRIT_32		(1 << 18)
+#define   MG_PLL_FRAC_LOCK_EARLYLOCK_CRIT_32		(1 << 16)
+#define   MG_PLL_FRAC_LOCK_LOCKTHRESH(x)		((x) << 11)
+#define   MG_PLL_FRAC_LOCK_DCODITHEREN			(1 << 10)
+#define   MG_PLL_FRAC_LOCK_FEEDFWRDCAL_EN		(1 << 8)
+#define   MG_PLL_FRAC_LOCK_FEEDFWRDGAIN(x)		((x) << 0)
+#define MG_PLL_FRAC_LOCK(port) _MMIO_PORT((port) - PORT_C, \
+					  _MG_PLL_FRAC_LOCK_PORT1, \
+					  _MG_PLL_FRAC_LOCK_PORT2)
+
+#define _MG_PLL_SSC_PORT1				0x168A10
+#define _MG_PLL_SSC_PORT2				0x169A10
+#define _MG_PLL_SSC_PORT3				0x16AA10
+#define _MG_PLL_SSC_PORT4				0x16BA10
+#define   MG_PLL_SSC_EN					(1 << 28)
+#define   MG_PLL_SSC_TYPE(x)				((x) << 26)
+#define   MG_PLL_SSC_STEPLENGTH(x)			((x) << 16)
+#define   MG_PLL_SSC_STEPNUM(x)				((x) << 10)
+#define   MG_PLL_SSC_FILEN				(1 << 9)
+#define   MG_PLL_SSC_STEPSIZE(x)			((x) << 0)
+#define MG_PLL_SSC(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_SSC_PORT1, \
+				    _MG_PLL_SSC_PORT2)
+
+#define _MG_PLL_BIAS_PORT1				0x168A14
+#define _MG_PLL_BIAS_PORT2				0x169A14
+#define _MG_PLL_BIAS_PORT3				0x16AA14
+#define _MG_PLL_BIAS_PORT4				0x16BA14
+#define   MG_PLL_BIAS_BIAS_GB_SEL(x)			((x) << 30)
+#define   MG_PLL_BIAS_INIT_DCOAMP(x)			((x) << 24)
+#define   MG_PLL_BIAS_BIAS_BONUS(x)			((x) << 16)
+#define   MG_PLL_BIAS_BIASCAL_EN			(1 << 15)
+#define   MG_PLL_BIAS_CTRIM(x)				((x) << 8)
+#define   MG_PLL_BIAS_VREF_RDAC(x)			((x) << 5)
+#define   MG_PLL_BIAS_IREFTRIM(x)			((x) << 0)
+#define MG_PLL_BIAS(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_BIAS_PORT1, \
+				     _MG_PLL_BIAS_PORT2)
+
+#define _MG_PLL_TDC_COLDST_BIAS_PORT1			0x168A18
+#define _MG_PLL_TDC_COLDST_BIAS_PORT2			0x169A18
+#define _MG_PLL_TDC_COLDST_BIAS_PORT3			0x16AA18
+#define _MG_PLL_TDC_COLDST_BIAS_PORT4			0x16BA18
+#define   MG_PLL_TDC_COLDST_IREFINT_EN			(1 << 27)
+#define   MG_PLL_TDC_COLDST_REFBIAS_START_PULSE_W(x)	((x) << 17)
+#define   MG_PLL_TDC_COLDST_COLDSTART			(1 << 16)
+#define   MG_PLL_TDC_TDCCOVCCORR_EN			(1 << 2)
+#define   MG_PLL_TDC_TDCSEL(x)				((x) << 0)
+#define MG_PLL_TDC_COLDST_BIAS(port) _MMIO_PORT((port) - PORT_C, \
+						_MG_PLL_TDC_COLDST_BIAS_PORT1, \
+						_MG_PLL_TDC_COLDST_BIAS_PORT2)
+
 #define _CNL_DPLL0_CFGCR0		0x6C000
 #define _CNL_DPLL1_CFGCR0		0x6C080
 #define  DPLL_CFGCR0_HDMI_MODE		(1 << 30)
 #define  DPLL_CFGCR0_SSC_ENABLE		(1 << 29)
+#define  DPLL_CFGCR0_SSC_ENABLE_ICL	(1 << 25)
 #define  DPLL_CFGCR0_LINK_RATE_MASK	(0xf << 25)
 #define  DPLL_CFGCR0_LINK_RATE_2700	(0 << 25)
 #define  DPLL_CFGCR0_LINK_RATE_1350	(1 << 25)
@@ -8966,8 +9104,19 @@ enum skl_power_gate {
 #define  DPLL_CFGCR1_PDIV_5		(4 << 2)
 #define  DPLL_CFGCR1_PDIV_7		(8 << 2)
 #define  DPLL_CFGCR1_CENTRAL_FREQ	(3 << 0)
+#define  DPLL_CFGCR1_CENTRAL_FREQ_8400	(3 << 0)
 #define CNL_DPLL_CFGCR1(pll)		_MMIO_PLL(pll, _CNL_DPLL0_CFGCR1, _CNL_DPLL1_CFGCR1)
 
+#define _ICL_DPLL0_CFGCR0		0x164000
+#define _ICL_DPLL1_CFGCR0		0x164080
+#define ICL_DPLL_CFGCR0(pll)		_MMIO_PLL(pll, _ICL_DPLL0_CFGCR0, \
+						  _ICL_DPLL1_CFGCR0)
+
+#define _ICL_DPLL0_CFGCR1		0x164004
+#define _ICL_DPLL1_CFGCR1		0x164084
+#define ICL_DPLL_CFGCR1(pll)		_MMIO_PLL(pll, _ICL_DPLL0_CFGCR1, \
+						  _ICL_DPLL1_CFGCR1)
+
 /* BXT display engine PLL */
 #define BXT_DE_PLL_CTL			_MMIO(0x6d000)
 #define   BXT_DE_PLL_RATIO(x)		(x)	/* {60,65,100} * 19.2MHz */
-- 
2.14.3

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

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

* [PATCH 02/17] drm/i915/icl: add basic support for the ICL clocks
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
  2018-02-22  3:55 ` [PATCH 01/17] drm/i915/icl: add definitions for the ICL PLL registers Paulo Zanoni
@ 2018-02-22  3:55 ` Paulo Zanoni
  2018-02-28  0:40   ` James Ausmus
  2018-02-22  3:55 ` [PATCH 03/17] drm/i915/icl: compute the combo PHY (DPLL) HDMI registers Paulo Zanoni
                   ` (18 subsequent siblings)
  20 siblings, 1 reply; 41+ messages in thread
From: Paulo Zanoni @ 2018-02-22  3:55 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

This commit introduces the definitions for the ICL clocks and adds the
basic functions to the shared DPLL framework. It adds code for the
Enable and Disable sequences for some PLLs, but it does not have the
code to compute the actual PLL values, which are marked as TODO
comments and should be introduced as separate commits.

v2:
 - Rebase around dpll_lock changes.
v3:
 - The spec now says what the timeouts should be.
 - Touch DPCLKA_CFGCR0_ICL at the appropriate time so we don't freeze
   the machine.
 - Checkpatch found a white space problem.
 - Small adjustments before upstreaming.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c   |  22 +++
 drivers/gpu/drm/i915/intel_ddi.c      | 102 ++++++++++-
 drivers/gpu/drm/i915/intel_display.c  |  14 ++
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 311 +++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_dpll_mgr.h |  41 +++++
 drivers/gpu/drm/i915/intel_drv.h      |   6 +
 6 files changed, 491 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 05b41045b8f9..7ccb5ef212a1 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3180,6 +3180,28 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused)
 		seq_printf(m, " fp0:     0x%08x\n", pll->state.hw_state.fp0);
 		seq_printf(m, " fp1:     0x%08x\n", pll->state.hw_state.fp1);
 		seq_printf(m, " wrpll:   0x%08x\n", pll->state.hw_state.wrpll);
+		seq_printf(m, " cfgcr0:  0x%08x\n", pll->state.hw_state.cfgcr0);
+		seq_printf(m, " cfgcr1:  0x%08x\n", pll->state.hw_state.cfgcr1);
+		seq_printf(m, " mg_refclkin_ctl:        0x%08x\n",
+			   pll->state.hw_state.mg_refclkin_ctl);
+		seq_printf(m, " mg_clktop2_coreclkctl1: 0x%08x\n",
+			   pll->state.hw_state.mg_clktop2_coreclkctl1);
+		seq_printf(m, " mg_clktop2_hsclkctl:    0x%08x\n",
+			   pll->state.hw_state.mg_clktop2_hsclkctl);
+		seq_printf(m, " mg_pll_div0:  0x%08x\n",
+			   pll->state.hw_state.mg_pll_div0);
+		seq_printf(m, " mg_pll_div1:  0x%08x\n",
+			   pll->state.hw_state.mg_pll_div1);
+		seq_printf(m, " mg_pll_lf:    0x%08x\n",
+			   pll->state.hw_state.mg_pll_lf);
+		seq_printf(m, " mg_pll_frac_lock: 0x%08x\n",
+			   pll->state.hw_state.mg_pll_frac_lock);
+		seq_printf(m, " mg_pll_ssc:   0x%08x\n",
+			   pll->state.hw_state.mg_pll_ssc);
+		seq_printf(m, " mg_pll_bias:  0x%08x\n",
+			   pll->state.hw_state.mg_pll_bias);
+		seq_printf(m, " mg_pll_tdc_coldst_bias: 0x%08x\n",
+			   pll->state.hw_state.mg_pll_tdc_coldst_bias);
 	}
 	drm_modeset_unlock_all(dev);
 
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 8ca376aca8bd..81383e3dc91f 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -893,6 +893,23 @@ static uint32_t hsw_pll_to_ddi_pll_sel(const struct intel_shared_dpll *pll)
 	}
 }
 
+static uint32_t icl_pll_to_ddi_pll_sel(struct intel_encoder *encoder,
+				       const struct intel_shared_dpll *pll)
+{
+	switch (pll->id) {
+	default:
+		MISSING_CASE(pll->id);
+	case DPLL_ID_ICL_DPLL0:
+	case DPLL_ID_ICL_DPLL1:
+		return DDI_CLK_SEL_NONE;
+	case DPLL_ID_ICL_MGPLL1:
+	case DPLL_ID_ICL_MGPLL2:
+	case DPLL_ID_ICL_MGPLL3:
+	case DPLL_ID_ICL_MGPLL4:
+		return DDI_CLK_SEL_MG;
+	}
+}
+
 /* 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.
@@ -2114,6 +2131,75 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
 	return DDI_BUF_TRANS_SELECT(level);
 }
 
+void icl_map_plls_to_ports(struct drm_crtc *crtc,
+			   struct intel_crtc_state *crtc_state,
+			   struct drm_atomic_state *old_state)
+{
+	struct intel_shared_dpll *pll = crtc_state->shared_dpll;
+	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
+	struct drm_connector_state *conn_state;
+	struct drm_connector *conn;
+	int i;
+
+	if (!IS_ICELAKE(dev_priv))
+		return;
+
+	for_each_new_connector_in_state(old_state, conn, conn_state, i) {
+		struct intel_encoder *encoder =
+			to_intel_encoder(conn_state->best_encoder);
+		enum port port = encoder->port;
+		uint32_t val;
+
+		if (conn_state->crtc != crtc)
+			continue;
+
+		mutex_lock(&dev_priv->dpll_lock);
+
+		val = I915_READ(DPCLKA_CFGCR0_ICL);
+		WARN_ON((val & DPCLKA_CFGCR0_DDI_CLK_OFF(port)) == 0);
+
+		if (port == PORT_A || port == PORT_B) {
+			val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port);
+			val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->id, port);
+			I915_WRITE(DPCLKA_CFGCR0_ICL, val);
+			POSTING_READ(DPCLKA_CFGCR0_ICL);
+		}
+
+		val &= ~DPCLKA_CFGCR0_DDI_CLK_OFF(port);
+		I915_WRITE(DPCLKA_CFGCR0_ICL, val);
+
+		mutex_unlock(&dev_priv->dpll_lock);
+	}
+}
+
+void icl_unmap_plls_to_ports(struct drm_crtc *crtc,
+			     struct intel_crtc_state *crtc_state,
+			     struct drm_atomic_state *old_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
+	struct drm_connector_state *conn_state;
+	struct drm_connector *conn;
+	int i;
+
+	if (!IS_ICELAKE(dev_priv))
+		return;
+
+	for_each_new_connector_in_state(old_state, conn, conn_state, i) {
+		struct intel_encoder *encoder =
+			to_intel_encoder(conn_state->best_encoder);
+		enum port port = encoder->port;
+
+		if (conn_state->crtc != crtc)
+			continue;
+
+		mutex_lock(&dev_priv->dpll_lock);
+		I915_WRITE(DPCLKA_CFGCR0_ICL,
+			   I915_READ(DPCLKA_CFGCR0_ICL) |
+			   DPCLKA_CFGCR0_DDI_CLK_OFF(port));
+		mutex_unlock(&dev_priv->dpll_lock);
+	}
+}
+
 static void intel_ddi_clk_select(struct intel_encoder *encoder,
 				 const struct intel_shared_dpll *pll)
 {
@@ -2126,7 +2212,11 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder,
 
 	mutex_lock(&dev_priv->dpll_lock);
 
-	if (IS_CANNONLAKE(dev_priv)) {
+	if (IS_ICELAKE(dev_priv)) {
+		if (port >= PORT_C)
+			I915_WRITE(DDI_CLK_SEL(port),
+				   icl_pll_to_ddi_pll_sel(encoder, pll));
+	} else if (IS_CANNONLAKE(dev_priv)) {
 		/* Configure DPCLKA_CFGCR0 to map the DPLL to the DDI. */
 		val = I915_READ(DPCLKA_CFGCR0);
 		val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port);
@@ -2164,14 +2254,18 @@ static void intel_ddi_clk_disable(struct intel_encoder *encoder)
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum port port = encoder->port;
 
-	if (IS_CANNONLAKE(dev_priv))
+	if (IS_ICELAKE(dev_priv)) {
+		if (port >= PORT_C)
+			I915_WRITE(DDI_CLK_SEL(port), DDI_CLK_SEL_NONE);
+	} else if (IS_CANNONLAKE(dev_priv)) {
 		I915_WRITE(DPCLKA_CFGCR0, I915_READ(DPCLKA_CFGCR0) |
 			   DPCLKA_CFGCR0_DDI_CLK_OFF(port));
-	else if (IS_GEN9_BC(dev_priv))
+	} else if (IS_GEN9_BC(dev_priv)) {
 		I915_WRITE(DPLL_CTRL2, I915_READ(DPLL_CTRL2) |
 			   DPLL_CTRL2_DDI_CLK_OFF(port));
-	else if (INTEL_GEN(dev_priv) < 9)
+	} else if (INTEL_GEN(dev_priv) < 9) {
 		I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
+	}
 }
 
 static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5d46771d58f6..bc4131a36c10 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5472,6 +5472,8 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 	if (intel_crtc->config->shared_dpll)
 		intel_enable_shared_dpll(intel_crtc);
 
+	icl_map_plls_to_ports(crtc, pipe_config, old_state);
+
 	if (intel_crtc_has_dp_encoder(intel_crtc->config))
 		intel_dp_set_m_n(intel_crtc, M1_N1);
 
@@ -5668,6 +5670,8 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
 	if (!transcoder_is_dsi(cpu_transcoder))
 		intel_ddi_disable_pipe_clock(intel_crtc->config);
 
+	icl_unmap_plls_to_ports(crtc, old_crtc_state, old_state);
+
 	intel_encoders_post_disable(crtc, old_crtc_state, old_state);
 }
 
@@ -11301,6 +11305,16 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
 	PIPE_CONF_CHECK_X(dpll_hw_state.pll9);
 	PIPE_CONF_CHECK_X(dpll_hw_state.pll10);
 	PIPE_CONF_CHECK_X(dpll_hw_state.pcsdw12);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_refclkin_ctl);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_coreclkctl1);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_hsclkctl);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div0);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div1);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_lf);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_frac_lock);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_ssc);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_bias);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_tdc_coldst_bias);
 
 	PIPE_CONF_CHECK_X(dsi_pll.ctrl);
 	PIPE_CONF_CHECK_X(dsi_pll.div);
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 51c5ae4e9116..8520a1b0279f 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -2384,6 +2384,313 @@ static const struct intel_dpll_mgr cnl_pll_mgr = {
 	.dump_hw_state = cnl_dump_hw_state,
 };
 
+static bool icl_calc_dpll_state(struct intel_crtc_state *crtc_state,
+				struct intel_encoder *encoder, int clock,
+				struct intel_dpll_hw_state *pll_state)
+{
+	/* TODO */
+	return true;
+}
+
+static enum port icl_mg_pll_id_to_port(enum intel_dpll_id id)
+{
+	return id - DPLL_ID_ICL_MGPLL1 + PORT_C;
+}
+
+static enum intel_dpll_id icl_port_to_mg_pll_id(enum port port)
+{
+	return port - PORT_C + DPLL_ID_ICL_MGPLL1;
+}
+
+static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
+				  struct intel_encoder *encoder, int clock,
+				  struct intel_dpll_hw_state *pll_state)
+{
+	/* TODO */
+	return true;
+}
+
+static struct intel_shared_dpll *
+icl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
+	     struct intel_encoder *encoder)
+{
+	struct intel_shared_dpll *pll;
+	struct intel_dpll_hw_state pll_state = {};
+	enum port port = encoder->port;
+	enum intel_dpll_id min, max;
+	int clock = crtc_state->port_clock;
+	bool ret;
+
+	switch (port) {
+	case PORT_A:
+	case PORT_B:
+		min = DPLL_ID_ICL_DPLL0;
+		max = DPLL_ID_ICL_DPLL1;
+		ret = icl_calc_dpll_state(crtc_state, encoder, clock,
+					  &pll_state);
+		break;
+	case PORT_C:
+	case PORT_D:
+	case PORT_E:
+	case PORT_F:
+		min = max = icl_port_to_mg_pll_id(port);
+		ret = icl_calc_mg_pll_state(crtc_state, encoder, clock,
+					    &pll_state);
+		break;
+	default:
+		MISSING_CASE(port);
+		return NULL;
+	}
+
+	if (!ret) {
+		DRM_DEBUG_KMS("Could not calculate PLL state.\n");
+		return NULL;
+	}
+
+	crtc_state->dpll_hw_state = pll_state;
+
+	pll = intel_find_shared_dpll(crtc, crtc_state, min, max);
+	if (!pll) {
+		DRM_DEBUG_KMS("No PLL selected\n");
+		return NULL;
+	}
+
+	intel_reference_shared_dpll(pll, crtc_state);
+
+	return pll;
+}
+
+static i915_reg_t icl_pll_id_to_enable_reg(enum intel_dpll_id id)
+{
+	switch (id) {
+	default:
+		MISSING_CASE(id);
+	case DPLL_ID_ICL_DPLL0:
+	case DPLL_ID_ICL_DPLL1:
+		return CNL_DPLL_ENABLE(id);
+	case DPLL_ID_ICL_MGPLL1:
+	case DPLL_ID_ICL_MGPLL2:
+	case DPLL_ID_ICL_MGPLL3:
+	case DPLL_ID_ICL_MGPLL4:
+		return MG_PLL_ENABLE(icl_mg_pll_id_to_port(id));
+	}
+}
+
+static bool icl_pll_get_hw_state(struct drm_i915_private *dev_priv,
+				 struct intel_shared_dpll *pll,
+				 struct intel_dpll_hw_state *hw_state)
+{
+	enum intel_dpll_id id = pll->id;
+	uint32_t val;
+	enum port port;
+	bool ret = false;
+
+	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
+		return false;
+
+	val = I915_READ(icl_pll_id_to_enable_reg(id));
+	if (!(val & PLL_ENABLE))
+		goto out;
+
+	switch (id) {
+	case DPLL_ID_ICL_DPLL0:
+	case DPLL_ID_ICL_DPLL1:
+		hw_state->cfgcr0 = I915_READ(ICL_DPLL_CFGCR0(id));
+		hw_state->cfgcr1 = I915_READ(ICL_DPLL_CFGCR1(id));
+		break;
+	case DPLL_ID_ICL_MGPLL1:
+	case DPLL_ID_ICL_MGPLL2:
+	case DPLL_ID_ICL_MGPLL3:
+	case DPLL_ID_ICL_MGPLL4:
+		port = icl_mg_pll_id_to_port(pll->id);
+		hw_state->mg_refclkin_ctl = I915_READ(MG_REFCLKIN_CTL(port));
+		hw_state->mg_clktop2_coreclkctl1 =
+			I915_READ(MG_CLKTOP2_CORECLKCTL1(port));
+		hw_state->mg_clktop2_hsclkctl =
+			I915_READ(MG_CLKTOP2_HSCLKCTL(port));
+		hw_state->mg_pll_div0 = I915_READ(MG_PLL_DIV0(port));
+		hw_state->mg_pll_div1 = I915_READ(MG_PLL_DIV1(port));
+		hw_state->mg_pll_lf = I915_READ(MG_PLL_LF(port));
+		hw_state->mg_pll_frac_lock = I915_READ(MG_PLL_FRAC_LOCK(port));
+		hw_state->mg_pll_ssc = I915_READ(MG_PLL_SSC(port));
+		hw_state->mg_pll_bias = I915_READ(MG_PLL_BIAS(port));
+		hw_state->mg_pll_tdc_coldst_bias =
+			I915_READ(MG_PLL_TDC_COLDST_BIAS(port));
+		break;
+	default:
+		MISSING_CASE(id);
+	}
+
+	ret = true;
+out:
+	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
+	return ret;
+}
+
+static void icl_dpll_write(struct drm_i915_private *dev_priv,
+			   struct intel_shared_dpll *pll)
+{
+	struct intel_dpll_hw_state *hw_state = &pll->state.hw_state;
+
+	I915_WRITE(ICL_DPLL_CFGCR0(pll->id), hw_state->cfgcr0);
+	I915_WRITE(ICL_DPLL_CFGCR1(pll->id), hw_state->cfgcr1);
+	POSTING_READ(ICL_DPLL_CFGCR1(pll->id));
+}
+
+static void icl_mg_pll_write(struct drm_i915_private *dev_priv,
+			     struct intel_shared_dpll *pll)
+{
+	struct intel_dpll_hw_state *hw_state = &pll->state.hw_state;
+	enum port port = icl_mg_pll_id_to_port(pll->id);
+
+	I915_WRITE(MG_REFCLKIN_CTL(port), hw_state->mg_refclkin_ctl);
+	I915_WRITE(MG_CLKTOP2_CORECLKCTL1(port),
+		   hw_state->mg_clktop2_coreclkctl1);
+	I915_WRITE(MG_CLKTOP2_HSCLKCTL(port), hw_state->mg_clktop2_hsclkctl);
+	I915_WRITE(MG_PLL_DIV0(port), hw_state->mg_pll_div0);
+	I915_WRITE(MG_PLL_DIV1(port), hw_state->mg_pll_div1);
+	I915_WRITE(MG_PLL_LF(port), hw_state->mg_pll_lf);
+	I915_WRITE(MG_PLL_FRAC_LOCK(port), hw_state->mg_pll_frac_lock);
+	I915_WRITE(MG_PLL_SSC(port), hw_state->mg_pll_ssc);
+	I915_WRITE(MG_PLL_BIAS(port), hw_state->mg_pll_bias);
+	I915_WRITE(MG_PLL_TDC_COLDST_BIAS(port),
+		   hw_state->mg_pll_tdc_coldst_bias);
+	POSTING_READ(MG_PLL_TDC_COLDST_BIAS(port));
+}
+
+static void icl_pll_enable(struct drm_i915_private *dev_priv,
+			   struct intel_shared_dpll *pll)
+{
+	enum intel_dpll_id id = pll->id;
+	i915_reg_t enable_reg = icl_pll_id_to_enable_reg(id);
+	uint32_t val;
+
+	val = I915_READ(enable_reg);
+	val |= PLL_POWER_ENABLE;
+	I915_WRITE(enable_reg, val);
+
+	/*
+	 * The spec says we need to "wait" but it also says it should be
+	 * immediate.
+	 */
+	if (intel_wait_for_register(dev_priv, enable_reg, PLL_POWER_STATE,
+				    PLL_POWER_STATE, 1))
+		DRM_ERROR("PLL %d Power not enabled\n", id);
+
+	switch (id) {
+	case DPLL_ID_ICL_DPLL0:
+	case DPLL_ID_ICL_DPLL1:
+		icl_dpll_write(dev_priv, pll);
+		break;
+	case DPLL_ID_ICL_MGPLL1:
+	case DPLL_ID_ICL_MGPLL2:
+	case DPLL_ID_ICL_MGPLL3:
+	case DPLL_ID_ICL_MGPLL4:
+		icl_mg_pll_write(dev_priv, pll);
+		break;
+	default:
+		MISSING_CASE(id);
+	}
+
+	/*
+	 * DVFS pre sequence would be here, but in our driver the cdclk code
+	 * paths should already be setting the appropriate voltage, hence we do
+	 * nothign here.
+	 */
+
+	val = I915_READ(enable_reg);
+	val |= PLL_ENABLE;
+	I915_WRITE(enable_reg, val);
+
+	if (intel_wait_for_register(dev_priv, enable_reg, PLL_LOCK, PLL_LOCK,
+				    1)) /* 600us actually. */
+		DRM_ERROR("PLL %d not locked\n", id);
+
+	/* DVFS post sequence would be here. See the comment above. */
+}
+
+static void icl_pll_disable(struct drm_i915_private *dev_priv,
+			    struct intel_shared_dpll *pll)
+{
+	enum intel_dpll_id id = pll->id;
+	i915_reg_t enable_reg = icl_pll_id_to_enable_reg(id);
+	uint32_t val;
+
+	/* The first steps are done by intel_ddi_post_disable(). */
+
+	/*
+	 * DVFS pre sequence would be here, but in our driver the cdclk code
+	 * paths should already be setting the appropriate voltage, hence we do
+	 * nothign here.
+	 */
+
+	val = I915_READ(enable_reg);
+	val &= ~PLL_ENABLE;
+	I915_WRITE(enable_reg, val);
+
+	/* Timeout is actually 1us. */
+	if (intel_wait_for_register(dev_priv, enable_reg, PLL_LOCK, 0, 1))
+		DRM_ERROR("PLL %d locked\n", id);
+
+	/* DVFS post sequence would be here. See the comment above. */
+
+	val = I915_READ(enable_reg);
+	val &= ~PLL_POWER_ENABLE;
+	I915_WRITE(enable_reg, val);
+
+	/*
+	 * The spec says we need to "wait" but it also says it should be
+	 * immediate.
+	 */
+	if (intel_wait_for_register(dev_priv, enable_reg, PLL_POWER_STATE, 0,
+				    1))
+		DRM_ERROR("PLL %d Power not disabled\n", id);
+}
+
+static void icl_dump_hw_state(struct drm_i915_private *dev_priv,
+			      struct intel_dpll_hw_state *hw_state)
+{
+	DRM_DEBUG_KMS("dpll_hw_state: cfgcr0: 0x%x, cfgcr1: 0x%x, "
+		      "mg_refclkin_ctl: 0x%x, hg_clktop2_coreclkctl1: 0x%x, "
+		      "mg_clktop2_hsclkctl: 0x%x, mg_pll_div0: 0x%x, "
+		      "mg_pll_div2: 0x%x, mg_pll_lf: 0x%x, "
+		      "mg_pll_frac_lock: 0x%x, mg_pll_ssc: 0x%x, "
+		      "mg_pll_bias: 0x%x, mg_pll_tdc_coldst_bias: 0x%x\n",
+		      hw_state->cfgcr0, hw_state->cfgcr1,
+		      hw_state->mg_refclkin_ctl,
+		      hw_state->mg_clktop2_coreclkctl1,
+		      hw_state->mg_clktop2_hsclkctl,
+		      hw_state->mg_pll_div0,
+		      hw_state->mg_pll_div1,
+		      hw_state->mg_pll_lf,
+		      hw_state->mg_pll_frac_lock,
+		      hw_state->mg_pll_ssc,
+		      hw_state->mg_pll_bias,
+		      hw_state->mg_pll_tdc_coldst_bias);
+}
+
+static const struct intel_shared_dpll_funcs icl_pll_funcs = {
+	.enable = icl_pll_enable,
+	.disable = icl_pll_disable,
+	.get_hw_state = icl_pll_get_hw_state,
+};
+
+static const struct dpll_info icl_plls[] = {
+	{ "DPLL 0",   DPLL_ID_ICL_DPLL0,  &icl_pll_funcs, 0 },
+	{ "DPLL 1",   DPLL_ID_ICL_DPLL1,  &icl_pll_funcs, 0 },
+	{ "MG PLL 1", DPLL_ID_ICL_MGPLL1, &icl_pll_funcs, 0 },
+	{ "MG PLL 2", DPLL_ID_ICL_MGPLL2, &icl_pll_funcs, 0 },
+	{ "MG PLL 3", DPLL_ID_ICL_MGPLL3, &icl_pll_funcs, 0 },
+	{ "MG PLL 4", DPLL_ID_ICL_MGPLL4, &icl_pll_funcs, 0 },
+	{ NULL, -1, NULL, 0 },
+};
+
+static const struct intel_dpll_mgr icl_pll_mgr = {
+	.dpll_info = icl_plls,
+	.get_dpll = icl_get_dpll,
+	.dump_hw_state = icl_dump_hw_state,
+};
+
 /**
  * intel_shared_dpll_init - Initialize shared DPLLs
  * @dev: drm device
@@ -2397,7 +2704,9 @@ void intel_shared_dpll_init(struct drm_device *dev)
 	const struct dpll_info *dpll_info;
 	int i;
 
-	if (IS_CANNONLAKE(dev_priv))
+	if (IS_ICELAKE(dev_priv))
+		dpll_mgr = &icl_pll_mgr;
+	else if (IS_CANNONLAKE(dev_priv))
 		dpll_mgr = &cnl_pll_mgr;
 	else if (IS_GEN9_BC(dev_priv))
 		dpll_mgr = &skl_pll_mgr;
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
index f24ccf443d25..eb0e10b24c6f 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -103,6 +103,32 @@ enum intel_dpll_id {
 	 * @DPLL_ID_SKL_DPLL3: SKL and later DPLL3
 	 */
 	DPLL_ID_SKL_DPLL3 = 3,
+
+
+	/**
+	 * @DPLL_ID_ICL_DPLL0: ICL combo PHY DPLL0
+	 */
+	DPLL_ID_ICL_DPLL0 = 0,
+	/**
+	 * @DPLL_ID_ICL_DPLL1: ICL combo PHY DPLL1
+	 */
+	DPLL_ID_ICL_DPLL1 = 1,
+	/**
+	 * @DPLL_ID_ICL_MGPLL1: ICL MG PLL 1 port 1 (C)
+	 */
+	DPLL_ID_ICL_MGPLL1 = 2,
+	/**
+	 * @DPLL_ID_ICL_MGPLL2: ICL MG PLL 1 port 2 (D)
+	 */
+	DPLL_ID_ICL_MGPLL2 = 3,
+	/**
+	 * @DPLL_ID_ICL_MGPLL3: ICL MG PLL 1 port 3 (E)
+	 */
+	DPLL_ID_ICL_MGPLL3 = 4,
+	/**
+	 * @DPLL_ID_ICL_MGPLL4: ICL MG PLL 1 port 4 (F)
+	 */
+	DPLL_ID_ICL_MGPLL4 = 5,
 };
 #define I915_NUM_PLLS 6
 
@@ -135,6 +161,21 @@ struct intel_dpll_hw_state {
 	/* bxt */
 	uint32_t ebb0, ebb4, pll0, pll1, pll2, pll3, pll6, pll8, pll9, pll10,
 		 pcsdw12;
+
+	/*
+	 * ICL uses the following, already defined:
+	 * uint32_t cfgcr0, cfgcr1;
+	 */
+	uint32_t mg_refclkin_ctl;
+	uint32_t mg_clktop2_coreclkctl1;
+	uint32_t mg_clktop2_hsclkctl;
+	uint32_t mg_pll_div0;
+	uint32_t mg_pll_div1;
+	uint32_t mg_pll_lf;
+	uint32_t mg_pll_frac_lock;
+	uint32_t mg_pll_ssc;
+	uint32_t mg_pll_bias;
+	uint32_t mg_pll_tdc_coldst_bias;
 };
 
 /**
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 50874f4035cf..47d40b8c31b4 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1385,6 +1385,12 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
 u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder);
 int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
 				     bool enable);
+void icl_map_plls_to_ports(struct drm_crtc *crtc,
+			   struct intel_crtc_state *crtc_state,
+			   struct drm_atomic_state *old_state);
+void icl_unmap_plls_to_ports(struct drm_crtc *crtc,
+			     struct intel_crtc_state *crtc_state,
+			     struct drm_atomic_state *old_state);
 
 unsigned int intel_fb_align_height(const struct drm_framebuffer *fb,
 				   int plane, unsigned int height);
-- 
2.14.3

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

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

* [PATCH 03/17] drm/i915/icl: compute the combo PHY (DPLL) HDMI registers
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
  2018-02-22  3:55 ` [PATCH 01/17] drm/i915/icl: add definitions for the ICL PLL registers Paulo Zanoni
  2018-02-22  3:55 ` Paulo Zanoni
@ 2018-02-22  3:55 ` Paulo Zanoni
  2018-02-28 19:59   ` James Ausmus
  2018-02-22  3:55 ` [PATCH 04/17] drm/i915/icl: compute the combo PHY (DPLL) DP registers Paulo Zanoni
                   ` (17 subsequent siblings)
  20 siblings, 1 reply; 41+ messages in thread
From: Paulo Zanoni @ 2018-02-22  3:55 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

HDMI mode DPLL programming on ICL is the same as CNL, so just reuse
the CNL code.

v2:
 - Properly detect HDMI crtcs.
 - Rebase after changes to the cnl function (clock * 1000).

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 34 +++++++++++++++++++++++++++++++---
 1 file changed, 31 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 8520a1b0279f..4d9265d14661 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -2203,6 +2203,7 @@ cnl_ddi_calculate_wrpll(int clock,
 			struct skl_wrpll_params *wrpll_params)
 {
 	u32 afe_clock = clock * 5;
+	uint32_t ref_clock;
 	u32 dco_min = 7998000;
 	u32 dco_max = 10000000;
 	u32 dco_mid = (dco_min + dco_max) / 2;
@@ -2235,8 +2236,12 @@ cnl_ddi_calculate_wrpll(int clock,
 
 	cnl_wrpll_get_multipliers(best_div, &pdiv, &qdiv, &kdiv);
 
-	cnl_wrpll_params_populate(wrpll_params, best_dco,
-				  dev_priv->cdclk.hw.ref, pdiv, qdiv, kdiv);
+	ref_clock = dev_priv->cdclk.hw.ref;
+	if (IS_ICELAKE(dev_priv) && ref_clock == 38400)
+		ref_clock = 19200;
+
+	cnl_wrpll_params_populate(wrpll_params, best_dco, ref_clock, pdiv, qdiv,
+				  kdiv);
 
 	return true;
 }
@@ -2388,7 +2393,30 @@ static bool icl_calc_dpll_state(struct intel_crtc_state *crtc_state,
 				struct intel_encoder *encoder, int clock,
 				struct intel_dpll_hw_state *pll_state)
 {
-	/* TODO */
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	uint32_t cfgcr0, cfgcr1;
+	struct skl_wrpll_params pll_params = { 0 };
+	bool ret;
+
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+		ret = cnl_ddi_calculate_wrpll(clock, dev_priv, &pll_params);
+	else
+		ret = false; /* TODO */
+
+	if (!ret)
+		return false;
+
+	cfgcr0 = DPLL_CFGCR0_DCO_FRACTION(pll_params.dco_fraction) |
+		 pll_params.dco_integer;
+
+	cfgcr1 = DPLL_CFGCR1_QDIV_RATIO(pll_params.qdiv_ratio) |
+		 DPLL_CFGCR1_QDIV_MODE(pll_params.qdiv_mode) |
+		 DPLL_CFGCR1_KDIV(pll_params.kdiv) |
+		 DPLL_CFGCR1_PDIV(pll_params.pdiv) |
+		 DPLL_CFGCR1_CENTRAL_FREQ_8400;
+
+	pll_state->cfgcr0 = cfgcr0;
+	pll_state->cfgcr1 = cfgcr1;
 	return true;
 }
 
-- 
2.14.3

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

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

* [PATCH 04/17] drm/i915/icl: compute the combo PHY (DPLL) DP registers
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
                   ` (2 preceding siblings ...)
  2018-02-22  3:55 ` [PATCH 03/17] drm/i915/icl: compute the combo PHY (DPLL) HDMI registers Paulo Zanoni
@ 2018-02-22  3:55 ` Paulo Zanoni
  2018-02-28 20:12   ` James Ausmus
  2018-02-22  3:55 ` [PATCH 05/17] drm/i915/icl: compute the MG PLL registers Paulo Zanoni
                   ` (16 subsequent siblings)
  20 siblings, 1 reply; 41+ messages in thread
From: Paulo Zanoni @ 2018-02-22  3:55 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

Just use the hardcoded tables provided by our spec.

v2: Rebase.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 86 ++++++++++++++++++++++++++++++++++-
 1 file changed, 85 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 4d9265d14661..5d7bacc80688 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -2389,6 +2389,90 @@ static const struct intel_dpll_mgr cnl_pll_mgr = {
 	.dump_hw_state = cnl_dump_hw_state,
 };
 
+/*
+ * These values alrea already adjusted: they're the bits we write to the
+ * registers, not the logical values.
+ */
+static const struct skl_wrpll_params icl_dp_combo_pll_24MHz_values[] = {
+	{ .dco_integer = 0x151, .dco_fraction = 0x4000,		/* [0]: 5.4 */
+	  .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
+	{ .dco_integer = 0x151, .dco_fraction = 0x4000,		/* [1]: 2.7 */
+	  .pdiv = 0x2 /* 3 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0},
+	{ .dco_integer = 0x151, .dco_fraction = 0x4000,		/* [2]: 1.62 */
+	  .pdiv = 0x4 /* 5 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0},
+	{ .dco_integer = 0x151, .dco_fraction = 0x4000,		/* [3]: 3.24 */
+	  .pdiv = 0x4 /* 5 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
+	{ .dco_integer = 0x168, .dco_fraction = 0x0000,		/* [4]: 2.16 */
+	  .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 1, .qdiv_ratio = 2},
+	{ .dco_integer = 0x168, .dco_fraction = 0x0000,		/* [5]: 4.32 */
+	  .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0},
+	{ .dco_integer = 0x195, .dco_fraction = 0x0000,		/* [6]: 6.48 */
+	  .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
+	{ .dco_integer = 0x151, .dco_fraction = 0x4000,		/* [7]: 8.1 */
+	  .pdiv = 0x1 /* 2 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
+};
+
+static const struct skl_wrpll_params icl_dp_combo_pll_19_2MHz_values[] = {
+	{ .dco_integer = 0x1A5, .dco_fraction = 0x7000,		/* [0]: 5.4 */
+	  .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
+	{ .dco_integer = 0x1A5, .dco_fraction = 0x7000,		/* [1]: 2.7 */
+	  .pdiv = 0x2 /* 3 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0},
+	{ .dco_integer = 0x1A5, .dco_fraction = 0x7000,		/* [2]: 1.62 */
+	  .pdiv = 0x4 /* 5 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0},
+	{ .dco_integer = 0x1A5, .dco_fraction = 0x7000,		/* [3]: 3.24 */
+	  .pdiv = 0x4 /* 5 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
+	{ .dco_integer = 0x1C2, .dco_fraction = 0x0000,		/* [4]: 2.16 */
+	  .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 1, .qdiv_ratio = 2},
+	{ .dco_integer = 0x1C2, .dco_fraction = 0x0000,		/* [5]: 4.32 */
+	  .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0},
+	{ .dco_integer = 0x1FA, .dco_fraction = 0x2000,		/* [6]: 6.48 */
+	  .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
+	{ .dco_integer = 0x1A5, .dco_fraction = 0x7000,		/* [7]: 8.1 */
+	  .pdiv = 0x1 /* 2 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
+};
+
+static bool icl_calc_dp_combo_pll(struct drm_i915_private *dev_priv, int clock,
+				  struct skl_wrpll_params *pll_params)
+{
+	const struct skl_wrpll_params *params;
+
+	params = dev_priv->cdclk.hw.ref == 24000 ?
+			icl_dp_combo_pll_24MHz_values :
+			icl_dp_combo_pll_19_2MHz_values;
+
+	switch (clock) {
+	case 540000:
+		*pll_params = params[0];
+		break;
+	case 270000:
+		*pll_params = params[1];
+		break;
+	case 162000:
+		*pll_params = params[2];
+		break;
+	case 324000:
+		*pll_params = params[3];
+		break;
+	case 216000:
+		*pll_params = params[4];
+		break;
+	case 432000:
+		*pll_params = params[5];
+		break;
+	case 648000:
+		*pll_params = params[6];
+		break;
+	case 810000:
+		*pll_params = params[7];
+		break;
+	default:
+		MISSING_CASE(clock);
+		return false;
+	}
+
+	return true;
+}
+
 static bool icl_calc_dpll_state(struct intel_crtc_state *crtc_state,
 				struct intel_encoder *encoder, int clock,
 				struct intel_dpll_hw_state *pll_state)
@@ -2401,7 +2485,7 @@ static bool icl_calc_dpll_state(struct intel_crtc_state *crtc_state,
 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
 		ret = cnl_ddi_calculate_wrpll(clock, dev_priv, &pll_params);
 	else
-		ret = false; /* TODO */
+		ret = icl_calc_dp_combo_pll(dev_priv, clock, &pll_params);
 
 	if (!ret)
 		return false;
-- 
2.14.3

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

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

* [PATCH 05/17] drm/i915/icl: compute the MG PLL registers
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
                   ` (3 preceding siblings ...)
  2018-02-22  3:55 ` [PATCH 04/17] drm/i915/icl: compute the combo PHY (DPLL) DP registers Paulo Zanoni
@ 2018-02-22  3:55 ` Paulo Zanoni
  2018-03-01 23:35   ` Manasi Navare
  2018-02-22  3:55 ` [PATCH 06/17] drm/i915/icl: Add register definitions for Combo PHY vswing sequences Paulo Zanoni
                   ` (15 subsequent siblings)
  20 siblings, 1 reply; 41+ messages in thread
From: Paulo Zanoni @ 2018-02-22  3:55 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

This implements the "MG PLL Programming" sequence from our spec. The
biggest problem was that the spec assumes real numbers, so we had to
adjust some numbers and alculations due to the fact that the Kernel
prefers to deal with integers.

I recommend grabbing some coffee, a pen and paper before reviewing
this patch.

v2:
 - Correctly identify DP encoders after upstream change.
 - Small checkpatch issues.
 - Rebase.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 217 +++++++++++++++++++++++++++++++++-
 1 file changed, 216 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 5d7bacc80688..9a2965e0b883 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -2514,11 +2514,226 @@ static enum intel_dpll_id icl_port_to_mg_pll_id(enum port port)
 	return port - PORT_C + DPLL_ID_ICL_MGPLL1;
 }
 
+static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
+				     uint32_t *target_dco_khz,
+				     struct intel_dpll_hw_state *state)
+{
+	uint32_t dco_min_freq, dco_max_freq;
+	int div1_vals[] = {7, 5, 3, 2};
+	unsigned int i;
+	int div2;
+
+	dco_min_freq = is_dp ? 8100000 : use_ssc ? 8000000 : 7992000;
+	dco_max_freq = is_dp ? 8100000 : 10000000;
+
+	for (i = 0; i < ARRAY_SIZE(div1_vals); i++) {
+		int div1 = div1_vals[i];
+
+		for (div2 = 10; div2 > 0; div2--) {
+			int dco = div1 * div2 * clock_khz * 5;
+			int a_divratio, tlinedrv, inputsel, hsdiv;
+
+			if (dco < dco_min_freq || dco > dco_max_freq)
+				continue;
+
+			if (div2 >= 2) {
+				a_divratio = is_dp ? 10 : 5;
+				tlinedrv = 2;
+			} else {
+				a_divratio = 5;
+				tlinedrv = 0;
+			}
+			inputsel = is_dp ? 0 : 1;
+
+			switch (div1) {
+			default:
+				MISSING_CASE(div1);
+			case 2:
+				hsdiv = 0;
+				break;
+			case 3:
+				hsdiv = 1;
+				break;
+			case 5:
+				hsdiv = 2;
+				break;
+			case 7:
+				hsdiv = 3;
+				break;
+			}
+
+			*target_dco_khz = dco;
+
+			state->mg_refclkin_ctl = MG_REFCLKIN_CTL_OD_2_MUX(1);
+
+			state->mg_clktop2_coreclkctl1 =
+				MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO(a_divratio);
+
+			state->mg_clktop2_hsclkctl =
+				MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL(tlinedrv) |
+				MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL(inputsel) |
+				MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO(hsdiv) |
+				MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO(div2);
+
+			return true;
+		}
+	}
+
+	return false;
+}
+
+/*
+ * The specification for this function uses real numbers, so the math had to be
+ * adapted to integer-only calculation, that's why it looks so different.
+ */
 static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
 				  struct intel_encoder *encoder, int clock,
 				  struct intel_dpll_hw_state *pll_state)
 {
-	/* TODO */
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	int refclk_khz = dev_priv->cdclk.hw.ref;
+	uint32_t dco_khz, m1div, m2div_int, m2div_rem, m2div_frac;
+	uint32_t iref_ndiv, iref_trim, iref_pulse_w;
+	uint32_t prop_coeff, int_coeff;
+	uint32_t tdc_targetcnt, feedfwgain;
+	uint64_t ssc_stepsize, ssc_steplen, ssc_steplog;
+	uint64_t tmp;
+	bool use_ssc = false;
+	bool is_dp = !intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI);
+
+	if (!icl_mg_pll_find_divisors(clock, is_dp, use_ssc, &dco_khz,
+				      pll_state)) {
+		DRM_DEBUG_KMS("Failed to find divisors for clock %d\n", clock);
+		return false;
+	}
+
+	m1div = 2;
+	m2div_int = dco_khz / (refclk_khz * m1div);
+	if (m2div_int > 255) {
+		m1div = 4;
+		m2div_int = dco_khz / (refclk_khz * m1div);
+		if (m2div_int > 255) {
+			DRM_DEBUG_KMS("Failed to find mdiv for clock %d\n",
+				      clock);
+			return false;
+		}
+	}
+	m2div_rem = dco_khz % (refclk_khz * m1div);
+
+	tmp = (uint64_t)m2div_rem * (1 << 22);
+	do_div(tmp, refclk_khz * m1div);
+	m2div_frac = tmp;
+
+	switch (refclk_khz) {
+	case 19200:
+		iref_ndiv = 1;
+		iref_trim = 28;
+		iref_pulse_w = 1;
+		break;
+	case 24000:
+		iref_ndiv = 1;
+		iref_trim = 25;
+		iref_pulse_w = 2;
+		break;
+	case 38400:
+		iref_ndiv = 2;
+		iref_trim = 28;
+		iref_pulse_w = 1;
+		break;
+	default:
+		MISSING_CASE(refclk_khz);
+		return false;
+	}
+
+	/*
+	 * tdc_res = 0.000003
+	 * tdc_targetcnt = int(2 / (tdc_res * 8 * 50 * 1.1) / refclk_mhz + 0.5)
+	 *
+	 * The multiplication by 1000 is due to refclk MHz to KHz conversion.
+	 * 0.000003 * 8 * 50 * 1.1 = 0.00132, also known as 132 / 100000.
+	 * The 0.5 transformed to 5 results in a multiplication by 10 and the
+	 * last division by 10.
+	 */
+	tdc_targetcnt = (2 * 1000 * 100000 * 10 / (132 * refclk_khz) + 5) / 10;
+
+	/*
+	 * Here we divide dco_khz by 10 in order to allow the dividend to fit in
+	 * 32 bits. That's not a problem since we round the division down
+	 * anyway.
+	 */
+	feedfwgain = (use_ssc || m2div_rem > 0) ?
+		m1div * 1000000 * 100 / (dco_khz * 3 / 10) : 0;
+
+	if (dco_khz >= 9000000) {
+		prop_coeff = 5;
+		int_coeff = 10;
+	} else {
+		prop_coeff = 4;
+		int_coeff = 8;
+	}
+
+	if (use_ssc) {
+		tmp = (uint64_t)dco_khz * 47 * 32;
+		do_div(tmp, refclk_khz * m1div * 10000);
+		ssc_stepsize = tmp;
+
+		tmp = (uint64_t)dco_khz * 1000;
+		ssc_steplen = DIV_ROUND_UP_ULL(tmp, 32 * 2 * 32);
+	} else {
+		ssc_stepsize = 0;
+		ssc_steplen = 0;
+	}
+	ssc_steplog = 4;
+
+	pll_state->mg_pll_div0 = (m2div_rem > 0 ? MG_PLL_DIV0_FRACNEN_H : 0) |
+				  MG_PLL_DIV0_FBDIV_FRAC(m2div_frac) |
+				  MG_PLL_DIV0_FBDIV_INT(m2div_int);
+
+	pll_state->mg_pll_div1 = MG_PLL_DIV1_IREF_NDIVRATIO(iref_ndiv) |
+				 MG_PLL_DIV1_DITHER_DIV_2 |
+				 MG_PLL_DIV1_NDIVRATIO(1) |
+				 MG_PLL_DIV1_FBPREDIV(m1div);
+
+	pll_state->mg_pll_lf = MG_PLL_LF_TDCTARGETCNT(tdc_targetcnt) |
+			       MG_PLL_LF_AFCCNTSEL_512 |
+			       MG_PLL_LF_GAINCTRL(1) |
+			       MG_PLL_LF_INT_COEFF(int_coeff) |
+			       MG_PLL_LF_PROP_COEFF(prop_coeff);
+
+	pll_state->mg_pll_frac_lock = MG_PLL_FRAC_LOCK_TRUELOCK_CRIT_32 |
+				      MG_PLL_FRAC_LOCK_EARLYLOCK_CRIT_32 |
+				      MG_PLL_FRAC_LOCK_LOCKTHRESH(10) |
+				      MG_PLL_FRAC_LOCK_DCODITHEREN |
+				      MG_PLL_FRAC_LOCK_FEEDFWRDGAIN(feedfwgain);
+	if (use_ssc || m2div_rem > 0)
+		pll_state->mg_pll_frac_lock |= MG_PLL_FRAC_LOCK_FEEDFWRDCAL_EN;
+
+	pll_state->mg_pll_ssc = (use_ssc ? MG_PLL_SSC_EN : 0) |
+				MG_PLL_SSC_TYPE(2) |
+				MG_PLL_SSC_STEPLENGTH(ssc_steplen) |
+				MG_PLL_SSC_STEPNUM(ssc_steplog) |
+				MG_PLL_SSC_FILEN |
+				MG_PLL_SSC_STEPSIZE(ssc_stepsize);
+
+	pll_state->mg_pll_tdc_coldst_bias = MG_PLL_TDC_COLDST_COLDSTART;
+
+	if (refclk_khz != 38400) {
+		pll_state->mg_pll_tdc_coldst_bias |=
+			MG_PLL_TDC_COLDST_IREFINT_EN |
+			MG_PLL_TDC_COLDST_REFBIAS_START_PULSE_W(iref_pulse_w) |
+			MG_PLL_TDC_COLDST_COLDSTART |
+			MG_PLL_TDC_TDCCOVCCORR_EN |
+			MG_PLL_TDC_TDCSEL(3);
+
+		pll_state->mg_pll_bias = MG_PLL_BIAS_BIAS_GB_SEL(3) |
+					 MG_PLL_BIAS_INIT_DCOAMP(0x3F) |
+					 MG_PLL_BIAS_BIAS_BONUS(10) |
+					 MG_PLL_BIAS_BIASCAL_EN |
+					 MG_PLL_BIAS_CTRIM(12) |
+					 MG_PLL_BIAS_VREF_RDAC(4) |
+					 MG_PLL_BIAS_IREFTRIM(iref_trim);
+	}
+
 	return true;
 }
 
-- 
2.14.3

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

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

* [PATCH 06/17] drm/i915/icl: Add register definitions for Combo PHY vswing sequences.
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
                   ` (4 preceding siblings ...)
  2018-02-22  3:55 ` [PATCH 05/17] drm/i915/icl: compute the MG PLL registers Paulo Zanoni
@ 2018-02-22  3:55 ` Paulo Zanoni
  2018-02-22  3:55 ` [PATCH 07/17] drm/i915/icl: Add Combo PHY DDI Buffer translation tables for Icelake Paulo Zanoni
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 41+ messages in thread
From: Paulo Zanoni @ 2018-02-22  3:55 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni, Rodrigo Vivi

From: Manasi Navare <manasi.d.navare@intel.com>

This patch defines register definitions required for ICL voltage
vswing programming for Combo PHY DDI Ports. It uses the same bit
definitions and macros as the CNL voltage swing sequences.

v7:
* Kill _MMIIO_PORT2_LN (Paulo)
v6:
* Replace some spaces with TAB (Paulo)
v5:
* Use _PORT instead of _PICK (Paulo)
* Remove DW7 defs for ICL, not used (Paulo)
v4:
* Rebase after _PICK was used instead of _PORT3
* Use _PICK for _MMIO_PORT2 since address of B is less
than address of A so cant use the math (Paulo)
v3:
* Make changes to the existing macro in a diff patch (Paulo)
v2:
* Add new defs fro ICL regs (Paulo)

Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h | 44 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index f62335c4a748..b45a9435ebff 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1959,6 +1959,16 @@ enum i915_power_well_id {
 						    _CNL_PORT_PCS_DW1_LN0_D, \
 						    _CNL_PORT_PCS_DW1_LN0_AE, \
 						    _CNL_PORT_PCS_DW1_LN0_F)
+#define _ICL_PORT_PCS_DW1_GRP_A		0x162604
+#define _ICL_PORT_PCS_DW1_GRP_B		0x6C604
+#define _ICL_PORT_PCS_DW1_LN0_A		0x162804
+#define _ICL_PORT_PCS_DW1_LN0_B		0x6C804
+#define ICL_PORT_PCS_DW1_GRP(port)	_MMIO_PORT(port,\
+						   _ICL_PORT_PCS_DW1_GRP_A, \
+						   _ICL_PORT_PCS_DW1_GRP_B)
+#define ICL_PORT_PCS_DW1_LN0(port)	_MMIO_PORT(port, \
+						   _ICL_PORT_PCS_DW1_LN0_A, \
+						   _ICL_PORT_PCS_DW1_LN0_B)
 #define   COMMON_KEEPER_EN		(1 << 26)
 
 #define _CNL_PORT_TX_DW2_GRP_AE		0x162348
@@ -1985,6 +1995,16 @@ enum i915_power_well_id {
 						    _CNL_PORT_TX_DW2_LN0_D, \
 						    _CNL_PORT_TX_DW2_LN0_AE, \
 						    _CNL_PORT_TX_DW2_LN0_F)
+#define _ICL_PORT_TX_DW2_GRP_A		0x162688
+#define _ICL_PORT_TX_DW2_GRP_B		0x6C688
+#define _ICL_PORT_TX_DW2_LN0_A		0x162888
+#define _ICL_PORT_TX_DW2_LN0_B		0x6C888
+#define ICL_PORT_TX_DW2_GRP(port)	_MMIO_PORT(port, \
+						   _ICL_PORT_TX_DW2_GRP_A, \
+						   _ICL_PORT_TX_DW2_GRP_B)
+#define ICL_PORT_TX_DW2_LN0(port)	_MMIO_PORT(port, \
+						   _ICL_PORT_TX_DW2_LN0_A, \
+						   _ICL_PORT_TX_DW2_LN0_B)
 #define   SWING_SEL_UPPER(x)		((x >> 3) << 15)
 #define   SWING_SEL_UPPER_MASK		(1 << 15)
 #define   SWING_SEL_LOWER(x)		((x & 0x7) << 11)
@@ -2018,6 +2038,19 @@ enum i915_power_well_id {
 						    _CNL_PORT_TX_DW4_LN0_D, \
 						    _CNL_PORT_TX_DW4_LN0_AE, \
 						    _CNL_PORT_TX_DW4_LN0_F)
+#define _ICL_PORT_TX_DW4_GRP_A		0x162690
+#define _ICL_PORT_TX_DW4_GRP_B		0x6C690
+#define _ICL_PORT_TX_DW4_LN0_A		0x162890
+#define _ICL_PORT_TX_DW4_LN1_A		0x162990
+#define _ICL_PORT_TX_DW4_LN0_B		0x6C890
+#define ICL_PORT_TX_DW4_GRP(port)	_MMIO_PORT(port, \
+						   _ICL_PORT_TX_DW4_GRP_A, \
+						   _ICL_PORT_TX_DW4_GRP_B)
+#define ICL_PORT_TX_DW4_LN(port, ln)	_MMIO(_PORT(port, \
+						   _ICL_PORT_TX_DW4_LN0_A, \
+						   _ICL_PORT_TX_DW4_LN0_B) + \
+					      (ln * (_ICL_PORT_TX_DW4_LN1_A - \
+						     _ICL_PORT_TX_DW4_LN0_A)))
 #define   LOADGEN_SELECT		(1 << 31)
 #define   POST_CURSOR_1(x)		((x) << 12)
 #define   POST_CURSOR_1_MASK		(0x3F << 12)
@@ -2050,7 +2083,18 @@ enum i915_power_well_id {
 						    _CNL_PORT_TX_DW5_LN0_D, \
 						    _CNL_PORT_TX_DW5_LN0_AE, \
 						    _CNL_PORT_TX_DW5_LN0_F)
+#define _ICL_PORT_TX_DW5_GRP_A		0x162694
+#define _ICL_PORT_TX_DW5_GRP_B		0x6C694
+#define _ICL_PORT_TX_DW5_LN0_A		0x162894
+#define _ICL_PORT_TX_DW5_LN0_B		0x6C894
+#define ICL_PORT_TX_DW5_GRP(port)	_MMIO_PORT(port, \
+						   _ICL_PORT_TX_DW5_GRP_A, \
+						   _ICL_PORT_TX_DW5_GRP_B)
+#define ICL_PORT_TX_DW5_LN0(port)	_MMIO_PORT(port, \
+						   _ICL_PORT_TX_DW5_LN0_A, \
+						   _ICL_PORT_TX_DW5_LN0_B)
 #define   TX_TRAINING_EN		(1 << 31)
+#define   TAP2_DISABLE			(1 << 30)
 #define   TAP3_DISABLE			(1 << 29)
 #define   SCALING_MODE_SEL(x)		((x) << 18)
 #define   SCALING_MODE_SEL_MASK		(0x7 << 18)
-- 
2.14.3

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

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

* [PATCH 07/17] drm/i915/icl: Add Combo PHY DDI Buffer translation tables for Icelake.
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
                   ` (5 preceding siblings ...)
  2018-02-22  3:55 ` [PATCH 06/17] drm/i915/icl: Add register definitions for Combo PHY vswing sequences Paulo Zanoni
@ 2018-02-22  3:55 ` Paulo Zanoni
  2018-02-22  3:55 ` [PATCH 08/17] drm/i915/icl: Implement voltage swing programming sequence for Combo PHY DDI Paulo Zanoni
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 41+ messages in thread
From: Paulo Zanoni @ 2018-02-22  3:55 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni, Rodrigo Vivi

From: Manasi Navare <manasi.d.navare@intel.com>

These tables are used on voltage vswing sequence initialization on
Icelake.

The swing_sel on the spec's table is defined in a 4 bits binary like
1010.  However the register bits are split in upper 1 bit swing_sel
and lower 3 bits swing sel.

In this table here we store this value as a single value in hex like
it is mentioned in the Bspec and split it to the upper and lower bit
values only while programming the registers.

For instance: b1010 is written as 0xA and then while writing to the
register, the upper 1 bit is obtained by (0xA & 0x8) and shifting by
appropriate bits while lower 3 bits are obtained by (0xA & 0x7) and
shifting by appropriate bits.

Some of the columns need to be updated after the spec is updated.

v5 (from Paulo):
* Checkpatch fixes.
v4 (from Paulo):
* Fix minor typo
* Coding style conformance
v3:
* Get rid of HDMI/DVI tables, same as DP (Paulo)
* Use combo_phy in ddi buf trans table defs (Paulo)
v2:
* Added DW4_scaling_hex column to the translation tables (Rodrigo)

Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 99 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 81383e3dc91f..0a4683991ec2 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -492,6 +492,105 @@ static const struct cnl_ddi_buf_trans cnl_ddi_translations_edp_1_05V[] = {
 	{ 0x2, 0x7F, 0x3F, 0x00, 0x00 },	/* 400   400      0.0   */
 };
 
+struct icl_combo_phy_ddi_buf_trans {
+	u32 dw2_swing_select;
+	u32 dw2_swing_scalar;
+	u32 dw4_scaling;
+};
+
+/* Voltage Swing Programming for VccIO 0.85V for DP */
+static const struct icl_combo_phy_ddi_buf_trans icl_combo_phy_ddi_translations_dp_hdmi_0_85V[] = {
+				/* Voltage mV  db    */
+	{ 0x2, 0x98, 0x0018 },	/* 400         0.0   */
+	{ 0x2, 0x98, 0x3015 },	/* 400         3.5   */
+	{ 0x2, 0x98, 0x6012 },	/* 400         6.0   */
+	{ 0x2, 0x98, 0x900F },	/* 400         9.5   */
+	{ 0xB, 0x70, 0x0018 },	/* 600         0.0   */
+	{ 0xB, 0x70, 0x3015 },	/* 600         3.5   */
+	{ 0xB, 0x70, 0x6012 },	/* 600         6.0   */
+	{ 0x5, 0x00, 0x0018 },	/* 800         0.0   */
+	{ 0x5, 0x00, 0x3015 },	/* 800         3.5   */
+	{ 0x6, 0x98, 0x0018 },	/* 1200        0.0   */
+};
+
+/* FIXME - After table is updated in Bspec */
+/* Voltage Swing Programming for VccIO 0.85V for eDP */
+static const struct icl_combo_phy_ddi_buf_trans icl_combo_phy_ddi_translations_edp_0_85V[] = {
+				/* Voltage mV  db    */
+	{ 0x0, 0x00, 0x00 },	/* 200         0.0   */
+	{ 0x0, 0x00, 0x00 },	/* 200         1.5   */
+	{ 0x0, 0x00, 0x00 },	/* 200         4.0   */
+	{ 0x0, 0x00, 0x00 },	/* 200         6.0   */
+	{ 0x0, 0x00, 0x00 },	/* 250         0.0   */
+	{ 0x0, 0x00, 0x00 },	/* 250         1.5   */
+	{ 0x0, 0x00, 0x00 },	/* 250         4.0   */
+	{ 0x0, 0x00, 0x00 },	/* 300         0.0   */
+	{ 0x0, 0x00, 0x00 },	/* 300         1.5   */
+	{ 0x0, 0x00, 0x00 },	/* 350         0.0   */
+};
+
+/* Voltage Swing Programming for VccIO 0.95V for DP */
+static const struct icl_combo_phy_ddi_buf_trans icl_combo_phy_ddi_translations_dp_hdmi_0_95V[] = {
+				/* Voltage mV  db    */
+	{ 0x2, 0x98, 0x0018 },	/* 400         0.0   */
+	{ 0x2, 0x98, 0x3015 },	/* 400         3.5   */
+	{ 0x2, 0x98, 0x6012 },	/* 400         6.0   */
+	{ 0x2, 0x98, 0x900F },	/* 400         9.5   */
+	{ 0x4, 0x98, 0x0018 },	/* 600         0.0   */
+	{ 0x4, 0x98, 0x3015 },	/* 600         3.5   */
+	{ 0x4, 0x98, 0x6012 },	/* 600         6.0   */
+	{ 0x5, 0x76, 0x0018 },	/* 800         0.0   */
+	{ 0x5, 0x76, 0x3015 },	/* 800         3.5   */
+	{ 0x6, 0x98, 0x0018 },	/* 1200        0.0   */
+};
+
+/* FIXME - After table is updated in Bspec */
+/* Voltage Swing Programming for VccIO 0.95V for eDP */
+static const struct icl_combo_phy_ddi_buf_trans icl_combo_phy_ddi_translations_edp_0_95V[] = {
+				/* Voltage mV  db    */
+	{ 0x0, 0x00, 0x00 },	/* 200         0.0   */
+	{ 0x0, 0x00, 0x00 },	/* 200         1.5   */
+	{ 0x0, 0x00, 0x00 },	/* 200         4.0   */
+	{ 0x0, 0x00, 0x00 },	/* 200         6.0   */
+	{ 0x0, 0x00, 0x00 },	/* 250         0.0   */
+	{ 0x0, 0x00, 0x00 },	/* 250         1.5   */
+	{ 0x0, 0x00, 0x00 },	/* 250         4.0   */
+	{ 0x0, 0x00, 0x00 },	/* 300         0.0   */
+	{ 0x0, 0x00, 0x00 },	/* 300         1.5   */
+	{ 0x0, 0x00, 0x00 },	/* 350         0.0   */
+};
+
+/* Voltage Swing Programming for VccIO 1.05V for DP */
+static const struct icl_combo_phy_ddi_buf_trans icl_combo_phy_ddi_translations_dp_hdmi_1_05V[] = {
+				/* Voltage mV  db    */
+	{ 0x2, 0x98, 0x0018 },	/* 400         0.0   */
+	{ 0x2, 0x98, 0x3015 },	/* 400         3.5   */
+	{ 0x2, 0x98, 0x6012 },	/* 400         6.0   */
+	{ 0x2, 0x98, 0x900F },	/* 400         9.5   */
+	{ 0x4, 0x98, 0x0018 },	/* 600         0.0   */
+	{ 0x4, 0x98, 0x3015 },	/* 600         3.5   */
+	{ 0x4, 0x98, 0x6012 },	/* 600         6.0   */
+	{ 0x5, 0x71, 0x0018 },	/* 800         0.0   */
+	{ 0x5, 0x71, 0x3015 },	/* 800         3.5   */
+	{ 0x6, 0x98, 0x0018 },	/* 1200        0.0   */
+};
+
+/* FIXME - After table is updated in Bspec */
+/* Voltage Swing Programming for VccIO 1.05V for eDP */
+static const struct icl_combo_phy_ddi_buf_trans icl_combo_phy_ddi_translations_edp_1_05V[] = {
+				/* Voltage mV  db    */
+	{ 0x0, 0x00, 0x00 },	/* 200         0.0   */
+	{ 0x0, 0x00, 0x00 },	/* 200         1.5   */
+	{ 0x0, 0x00, 0x00 },	/* 200         4.0   */
+	{ 0x0, 0x00, 0x00 },	/* 200         6.0   */
+	{ 0x0, 0x00, 0x00 },	/* 250         0.0   */
+	{ 0x0, 0x00, 0x00 },	/* 250         1.5   */
+	{ 0x0, 0x00, 0x00 },	/* 250         4.0   */
+	{ 0x0, 0x00, 0x00 },	/* 300         0.0   */
+	{ 0x0, 0x00, 0x00 },	/* 300         1.5   */
+	{ 0x0, 0x00, 0x00 },	/* 350         0.0   */
+};
+
 static const struct ddi_buf_trans *
 bdw_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
 {
-- 
2.14.3

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

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

* [PATCH 08/17] drm/i915/icl: Implement voltage swing programming sequence for Combo PHY DDI
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
                   ` (6 preceding siblings ...)
  2018-02-22  3:55 ` [PATCH 07/17] drm/i915/icl: Add Combo PHY DDI Buffer translation tables for Icelake Paulo Zanoni
@ 2018-02-22  3:55 ` Paulo Zanoni
  2018-03-22 22:23   ` Paulo Zanoni
                     ` (2 more replies)
  2018-02-22  3:55 ` [PATCH 09/17] drm/i915/icl: Add register defs for voltage swing sequences for MG " Paulo Zanoni
                   ` (12 subsequent siblings)
  20 siblings, 3 replies; 41+ messages in thread
From: Paulo Zanoni @ 2018-02-22  3:55 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni, Rodrigo Vivi

From: Manasi Navare <manasi.d.navare@intel.com>

This is an important part of the DDI initalization as well as
for changing the voltage during DisplayPort link training.

The Voltage swing seqeuence is similar to Cannonlake.
However it has different register definitions and hence
it makes sense to create a separate vswing sequence and
program functions for ICL to leave room for more changes
in case the Bspec changes later and deviates from CNL sequence.

v2:
Use ~TAP3_DISABLE for enbaling that bit (Jani Nikula)

v3:
* Use dw4_scaling column for PORT_TX_DW4 values (Rodrigo)

v4:
* Call it combo_vswing, use switch statement (Paulo)

v5 (from Paulo):
* Fix a typo.
* s/rate < 600000/rate <= 600000/.
* Don't remove blank lines that should be there.

v6:
* Rebased by Rodrigo on top of Cannonlake changes
  where non vswing sequences are not aligned with iboost
  anymore.

v7: Another rebase after an upstream rework.

v8 (from Paulo):
* Adjust the code to the upstream output type changes.
* Squash the patch that moved some functions up.
* Merge both get_combo_buf_trans functions in order to simplify the
  code.
* Change the changelog format.

Cc: Jani Nikula <jani.nikula@linux.intel.com>
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v5)
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 189 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 186 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 0a4683991ec2..c38873cb98ca 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -849,6 +849,45 @@ cnl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
 	}
 }
 
+static const struct icl_combo_phy_ddi_buf_trans *
+icl_get_combo_buf_trans(struct drm_i915_private *dev_priv, enum port port,
+			int type, int *n_entries)
+{
+	u32 voltage = I915_READ(ICL_PORT_COMP_DW3(port)) & VOLTAGE_INFO_MASK;
+
+	if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.low_vswing) {
+		switch (voltage) {
+		case VOLTAGE_INFO_0_85V:
+			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_85V);
+			return icl_combo_phy_ddi_translations_edp_0_85V;
+		case VOLTAGE_INFO_0_95V:
+			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_95V);
+			return icl_combo_phy_ddi_translations_edp_0_95V;
+		case VOLTAGE_INFO_1_05V:
+			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_1_05V);
+			return icl_combo_phy_ddi_translations_edp_1_05V;
+		default:
+			MISSING_CASE(voltage);
+			return NULL;
+		}
+	} else {
+		switch (voltage) {
+		case VOLTAGE_INFO_0_85V:
+			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_85V);
+			return icl_combo_phy_ddi_translations_dp_hdmi_0_85V;
+		case VOLTAGE_INFO_0_95V:
+			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_95V);
+			return icl_combo_phy_ddi_translations_dp_hdmi_0_95V;
+		case VOLTAGE_INFO_1_05V:
+			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_1_05V);
+			return icl_combo_phy_ddi_translations_dp_hdmi_1_05V;
+		default:
+			MISSING_CASE(voltage);
+			return NULL;
+		}
+	}
+}
+
 static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port port)
 {
 	int n_entries, level, default_entry;
@@ -2178,6 +2217,144 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
 	I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val);
 }
 
+static void icl_ddi_combo_vswing_program(struct drm_i915_private *dev_priv,
+					 u32 level, enum port port, int type)
+{
+	const struct icl_combo_phy_ddi_buf_trans *ddi_translations = NULL;
+	u32 n_entries, val;
+	int ln;
+
+	ddi_translations = icl_get_combo_buf_trans(dev_priv, port, type,
+						   &n_entries);
+	if (!ddi_translations)
+		return;
+
+	if (level >= n_entries) {
+		DRM_DEBUG_KMS("DDI translation not found for level %d. Using %d instead.", level, n_entries - 1);
+		level = n_entries - 1;
+	}
+
+	/* Set PORT_TX_DW5 Scaling Mode Sel to 110b. */
+	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
+	val &= ~SCALING_MODE_SEL_MASK;
+	val |= SCALING_MODE_SEL(0x6);
+	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
+
+	/* Program PORT_TX_DW5 */
+	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
+	/* Set DisableTap2 and DisableTap3 if MIPI DSI
+	 * Clear DisableTap2 and DisableTap3 for all other Ports
+	 */
+	if (type == INTEL_OUTPUT_DSI) {
+		val |= TAP2_DISABLE;
+		val |= TAP3_DISABLE;
+	} else {
+		val &= ~TAP2_DISABLE;
+		val &= ~TAP3_DISABLE;
+	}
+	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
+
+	/* Program PORT_TX_DW2 */
+	val = I915_READ(ICL_PORT_TX_DW2_LN0(port));
+	val &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
+		 RCOMP_SCALAR_MASK);
+	val |= SWING_SEL_UPPER(ddi_translations[level].dw2_swing_select);
+	val |= SWING_SEL_LOWER(ddi_translations[level].dw2_swing_select);
+	/* Program Rcomp scalar for every table entry */
+	val |= RCOMP_SCALAR(ddi_translations[level].dw2_swing_scalar);
+	I915_WRITE(ICL_PORT_TX_DW2_GRP(port), val);
+
+	/* Program PORT_TX_DW4 */
+	/* We cannot write to GRP. It would overwrite individual loadgen. */
+	for (ln = 0; ln <= 3; ln++) {
+		val = I915_READ(ICL_PORT_TX_DW4_LN(port, ln));
+		val &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
+			 CURSOR_COEFF_MASK);
+		val |= ddi_translations[level].dw4_scaling;
+		I915_WRITE(ICL_PORT_TX_DW4_LN(port, ln), val);
+	}
+}
+
+static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	enum port port = encoder->port;
+	int type = encoder->type;
+	int width = 0;
+	int rate = 0;
+	u32 val;
+	int ln = 0;
+
+	if (type == INTEL_OUTPUT_HDMI) {
+		width = 4;
+		/* Rate is always < than 6GHz for HDMI */
+	} else {
+		struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+
+		width = intel_dp->lane_count;
+		rate = intel_dp->link_rate;
+	}
+
+	/*
+	 * 1. If port type is eDP or DP,
+	 * set PORT_PCS_DW1 cmnkeeper_enable to 1b,
+	 * else clear to 0b.
+	 */
+	val = I915_READ(ICL_PORT_PCS_DW1_LN0(port));
+	if (type == INTEL_OUTPUT_HDMI)
+		val &= ~COMMON_KEEPER_EN;
+	else
+		val |= COMMON_KEEPER_EN;
+	I915_WRITE(ICL_PORT_PCS_DW1_GRP(port), val);
+
+	/* 2. Program loadgen select */
+	/*
+	 * Program PORT_TX_DW4_LN depending on Bit rate and used lanes
+	 * <= 6 GHz and 4 lanes (LN0=0, LN1=1, LN2=1, LN3=1)
+	 * <= 6 GHz and 1,2 lanes (LN0=0, LN1=1, LN2=1, LN3=0)
+	 * > 6 GHz (LN0=0, LN1=0, LN2=0, LN3=0)
+	 */
+	for (ln = 0; ln <= 3; ln++) {
+		val = I915_READ(ICL_PORT_TX_DW4_LN(port, ln));
+		val &= ~LOADGEN_SELECT;
+
+		if ((rate <= 600000 && width == 4 && ln >= 1) ||
+		    (rate <= 600000 && width < 4 && (ln == 1 || ln == 2))) {
+			val |= LOADGEN_SELECT;
+		}
+		I915_WRITE(ICL_PORT_TX_DW4_LN(port, ln), val);
+	}
+
+	/* 3. Set PORT_CL_DW5 SUS Clock Config to 11b */
+	val = I915_READ(ICL_PORT_CL_DW5(port));
+	val |= SUS_CLOCK_CONFIG;
+	I915_WRITE(ICL_PORT_CL_DW5(port), val);
+
+	/* 4. Clear training enable to change swing values */
+	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
+	val &= ~TX_TRAINING_EN;
+	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
+
+	/* 5. Program swing and de-emphasis */
+	icl_ddi_combo_vswing_program(dev_priv, level, port, type);
+
+	/* 6. Set training enable to trigger update */
+	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
+	val |= TX_TRAINING_EN;
+	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
+}
+
+static void icl_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level)
+{
+	enum port port = encoder->port;
+
+	if (port == PORT_A || port == PORT_B)
+		icl_combo_phy_ddi_vswing_sequence(encoder, level);
+	else
+		/* Not Implemented Yet */
+		WARN_ON(1);
+}
+
 static uint32_t translate_signal_level(int signal_levels)
 {
 	int i;
@@ -2209,7 +2386,9 @@ u32 bxt_signal_levels(struct intel_dp *intel_dp)
 	struct intel_encoder *encoder = &dport->base;
 	int level = intel_ddi_dp_level(intel_dp);
 
-	if (IS_CANNONLAKE(dev_priv))
+	if (IS_ICELAKE(dev_priv))
+		icl_ddi_vswing_sequence(encoder, level);
+	else if (IS_CANNONLAKE(dev_priv))
 		cnl_ddi_vswing_sequence(encoder, level, encoder->type);
 	else
 		bxt_ddi_vswing_sequence(encoder, level, encoder->type);
@@ -2389,7 +2568,9 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
 
 	intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain);
 
-	if (IS_CANNONLAKE(dev_priv))
+	if (IS_ICELAKE(dev_priv))
+		icl_ddi_vswing_sequence(encoder, level);
+	else if (IS_CANNONLAKE(dev_priv))
 		cnl_ddi_vswing_sequence(encoder, level, encoder->type);
 	else if (IS_GEN9_LP(dev_priv))
 		bxt_ddi_vswing_sequence(encoder, level, encoder->type);
@@ -2420,7 +2601,9 @@ static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
 
 	intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain);
 
-	if (IS_CANNONLAKE(dev_priv))
+	if (IS_ICELAKE(dev_priv))
+		icl_ddi_vswing_sequence(encoder, level);
+	else if (IS_CANNONLAKE(dev_priv))
 		cnl_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
 	else if (IS_GEN9_LP(dev_priv))
 		bxt_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
-- 
2.14.3

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

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

* [PATCH 09/17] drm/i915/icl: Add register defs for voltage swing sequences for MG PHY DDI
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
                   ` (7 preceding siblings ...)
  2018-02-22  3:55 ` [PATCH 08/17] drm/i915/icl: Implement voltage swing programming sequence for Combo PHY DDI Paulo Zanoni
@ 2018-02-22  3:55 ` Paulo Zanoni
  2018-02-22  3:55 ` [PATCH 10/17] drm/i915/icl: Add Voltage swing table for MG PHY DDI Buffer Paulo Zanoni
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 41+ messages in thread
From: Paulo Zanoni @ 2018-02-22  3:55 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni, Rodrigo Vivi

From: Manasi Navare <manasi.d.navare@intel.com>

On Icelake platform, MG PHY is used when operating in DP alternate
mode or the legacy HDMI or DP modes. DDI Ports C, D, E, F are MG PHY
DDI ports on ICL.

This patch adds the necessary voltage swing programming related
register definitions and macros for MG PHY DDI ports.

v4 (from Paulo):
* Use _PORT instead of _PICK
* Change some mask names to our current coding standards
* Stay under 80 columns
v3:
* Rebase on new revision of patches
v2:
* Remove whitespaces in the #defines (Paulo)

Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h | 116 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 116 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index b45a9435ebff..a389d4030b7f 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2128,6 +2128,122 @@ enum i915_power_well_id {
 #define   N_SCALAR(x)			((x) << 24)
 #define   N_SCALAR_MASK			(0x7F << 24)
 
+#define _ICL_MG_PHY_PORT_LN(port, ln, ln0p1, ln0p2, ln1p1) \
+	_MMIO(_PORT((port) - PORT_C, ln0p1, ln0p2) + (ln) * ((ln1p1) - (ln0p1)))
+
+#define _ICL_MG_TX_LINK_PARAMS_TX1LN0_PORT1		0x16812C
+#define _ICL_MG_TX_LINK_PARAMS_TX1LN1_PORT1		0x16852C
+#define _ICL_MG_TX_LINK_PARAMS_TX1LN0_PORT2		0x16912C
+#define _ICL_MG_TX_LINK_PARAMS_TX1LN1_PORT2		0x16952C
+#define _ICL_MG_TX_LINK_PARAMS_TX1LN0_PORT3		0x16A12C
+#define _ICL_MG_TX_LINK_PARAMS_TX1LN1_PORT3		0x16A52C
+#define _ICL_MG_TX_LINK_PARAMS_TX1LN0_PORT4		0x16B12C
+#define _ICL_MG_TX_LINK_PARAMS_TX1LN1_PORT4		0x16B52C
+#define ICL_PORT_MG_TX1_LINK_PARAMS(port, ln) \
+	_ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_LINK_PARAMS_TX1LN0_PORT1, \
+				      _ICL_MG_TX_LINK_PARAMS_TX1LN0_PORT2, \
+				      _ICL_MG_TX_LINK_PARAMS_TX1LN1_PORT1)
+
+#define _ICL_MG_TX_LINK_PARAMS_TX2LN0_PORT1		0x1680AC
+#define _ICL_MG_TX_LINK_PARAMS_TX2LN1_PORT1		0x1684AC
+#define _ICL_MG_TX_LINK_PARAMS_TX2LN0_PORT2		0x1690AC
+#define _ICL_MG_TX_LINK_PARAMS_TX2LN1_PORT2		0x1694AC
+#define _ICL_MG_TX_LINK_PARAMS_TX2LN0_PORT3		0x16A0AC
+#define _ICL_MG_TX_LINK_PARAMS_TX2LN1_PORT3		0x16A4AC
+#define _ICL_MG_TX_LINK_PARAMS_TX2LN0_PORT4		0x16B0AC
+#define _ICL_MG_TX_LINK_PARAMS_TX2LN1_PORT4		0x16B4AC
+#define ICL_PORT_MG_TX2_LINK_PARAMS(port, ln) \
+	_ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_LINK_PARAMS_TX2LN0_PORT1, \
+				      _ICL_MG_TX_LINK_PARAMS_TX2LN0_PORT2, \
+				      _ICL_MG_TX_LINK_PARAMS_TX2LN1_PORT1)
+#define CRI_USE_FS32			(1 << 5)
+
+#define _ICL_MG_TX_PISO_READLOAD_TX1LN0_PORT1		0x16814C
+#define _ICL_MG_TX_PISO_READLOAD_TX1LN1_PORT1		0x16854C
+#define _ICL_MG_TX_PISO_READLOAD_TX1LN0_PORT2		0x16914C
+#define _ICL_MG_TX_PISO_READLOAD_TX1LN1_PORT2		0x16954C
+#define _ICL_MG_TX_PISO_READLOAD_TX1LN0_PORT3		0x16A14C
+#define _ICL_MG_TX_PISO_READLOAD_TX1LN1_PORT3		0x16A54C
+#define _ICL_MG_TX_PISO_READLOAD_TX1LN0_PORT4		0x16B14C
+#define _ICL_MG_TX_PISO_READLOAD_TX1LN1_PORT4		0x16B54C
+#define ICL_PORT_MG_TX1_PISO_READLOAD(port, ln) \
+	_ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_PISO_READLOAD_TX1LN0_PORT1, \
+				      _ICL_MG_TX_PISO_READLOAD_TX1LN0_PORT2, \
+				      _ICL_MG_TX_PISO_READLOAD_TX1LN1_PORT1)
+
+#define _ICL_MG_TX_PISO_READLOAD_TX2LN0_PORT1		0x1680CC
+#define _ICL_MG_TX_PISO_READLOAD_TX2LN1_PORT1		0x1684CC
+#define _ICL_MG_TX_PISO_READLOAD_TX2LN0_PORT2		0x1690CC
+#define _ICL_MG_TX_PISO_READLOAD_TX2LN1_PORT2		0x1694CC
+#define _ICL_MG_TX_PISO_READLOAD_TX2LN0_PORT3		0x16A0CC
+#define _ICL_MG_TX_PISO_READLOAD_TX2LN1_PORT3		0x16A4CC
+#define _ICL_MG_TX_PISO_READLOAD_TX2LN0_PORT4		0x16B0CC
+#define _ICL_MG_TX_PISO_READLOAD_TX2LN1_PORT4		0x16B4CC
+#define ICL_PORT_MG_TX2_PISO_READLOAD(port, ln) \
+	_ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_PISO_READLOAD_TX2LN0_PORT1, \
+				      _ICL_MG_TX_PISO_READLOAD_TX2LN0_PORT2, \
+				      _ICL_MG_TX_PISO_READLOAD_TX2LN1_PORT1)
+#define CRI_CALCINIT					(1 << 1)
+
+#define _ICL_MG_TX_SWINGCTRL_TX1LN0_PORT1		0x168148
+#define _ICL_MG_TX_SWINGCTRL_TX1LN1_PORT1		0x168548
+#define _ICL_MG_TX_SWINGCTRL_TX1LN0_PORT2		0x169148
+#define _ICL_MG_TX_SWINGCTRL_TX1LN1_PORT2		0x169548
+#define _ICL_MG_TX_SWINGCTRL_TX1LN0_PORT3		0x16A148
+#define _ICL_MG_TX_SWINGCTRL_TX1LN1_PORT3		0x16A548
+#define _ICL_MG_TX_SWINGCTRL_TX1LN0_PORT4		0x16B148
+#define _ICL_MG_TX_SWINGCTRL_TX1LN1_PORT4		0x16B548
+#define ICL_PORT_MG_TX1_SWINGCTRL(port, ln) \
+	_ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_SWINGCTRL_TX1LN0_PORT1, \
+				      _ICL_MG_TX_SWINGCTRL_TX1LN0_PORT2, \
+				      _ICL_MG_TX_SWINGCTRL_TX1LN1_PORT1)
+
+#define _ICL_MG_TX_SWINGCTRL_TX2LN0_PORT1		0x1680C8
+#define _ICL_MG_TX_SWINGCTRL_TX2LN1_PORT1		0x1684C8
+#define _ICL_MG_TX_SWINGCTRL_TX2LN0_PORT2		0x1690C8
+#define _ICL_MG_TX_SWINGCTRL_TX2LN1_PORT2		0x1694C8
+#define _ICL_MG_TX_SWINGCTRL_TX2LN0_PORT3		0x16A0C8
+#define _ICL_MG_TX_SWINGCTRL_TX2LN1_PORT3		0x16A4C8
+#define _ICL_MG_TX_SWINGCTRL_TX2LN0_PORT4		0x16B0C8
+#define _ICL_MG_TX_SWINGCTRL_TX2LN1_PORT4		0x16B4C8
+#define ICL_PORT_MG_TX2_SWINGCTRL(port, ln) \
+	_ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_SWINGCTRL_TX2LN0_PORT1, \
+				      _ICL_MG_TX_SWINGCTRL_TX2LN0_PORT2, \
+				      _ICL_MG_TX_SWINGCTRL_TX2LN1_PORT1)
+#define CRI_TXDEEMPH_OVERRIDE_17_12(x)			((x) << 0)
+#define CRI_TXDEEMPH_OVERRIDE_17_12_MASK		(0x3F << 0)
+
+#define _ICL_MG_TX_DRVCTRL_TX1LN0_PORT1			0x168144
+#define _ICL_MG_TX_DRVCTRL_TX1LN1_PORT1			0x168544
+#define _ICL_MG_TX_DRVCTRL_TX1LN0_PORT2			0x169144
+#define _ICL_MG_TX_DRVCTRL_TX1LN1_PORT2			0x169544
+#define _ICL_MG_TX_DRVCTRL_TX1LN0_PORT3			0x16A144
+#define _ICL_MG_TX_DRVCTRL_TX1LN1_PORT3			0x16A544
+#define _ICL_MG_TX_DRVCTRL_TX1LN0_PORT4			0x16B144
+#define _ICL_MG_TX_DRVCTRL_TX1LN1_PORT4			0x16B544
+#define ICL_PORT_MG_TX1_DRVCTRL(port, ln) \
+	_ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_DRVCTRL_TX1LN0_PORT1, \
+				      _ICL_MG_TX_DRVCTRL_TX1LN0_PORT2, \
+				      _ICL_MG_TX_DRVCTRL_TX1LN1_PORT1)
+
+#define _ICL_MG_TX_DRVCTRL_TX2LN0_PORT1			0x1680C4
+#define _ICL_MG_TX_DRVCTRL_TX2LN1_PORT1			0x1684C4
+#define _ICL_MG_TX_DRVCTRL_TX2LN0_PORT2			0x1690C4
+#define _ICL_MG_TX_DRVCTRL_TX2LN1_PORT2			0x1694C4
+#define _ICL_MG_TX_DRVCTRL_TX2LN0_PORT3			0x16A0C4
+#define _ICL_MG_TX_DRVCTRL_TX2LN1_PORT3			0x16A4C4
+#define _ICL_MG_TX_DRVCTRL_TX2LN0_PORT4			0x16B0C4
+#define _ICL_MG_TX_DRVCTRL_TX2LN1_PORT4			0x16B4C4
+#define ICL_PORT_MG_TX2_DRVCTRL(port, ln) \
+	_ICL_MG_PHY_PORT_LN(port, ln, _ICL_MG_TX_DRVCTRL_TX2LN0_PORT1, \
+				      _ICL_MG_TX_DRVCTRL_TX2LN0_PORT2, \
+				      _ICL_MG_TX_DRVCTRL_TX2LN1_PORT1)
+#define CRI_TXDEEMPH_OVERRIDE_11_6(x)			((x) << 24)
+#define CRI_TXDEEMPH_OVERRIDE_11_6_MASK			(0x3F << 24)
+#define CRI_TXDEEMPH_OVERRIDE_EN			(1 << 22)
+#define CRI_TXDEEMPH_OVERRIDE_5_0(x)			((x) << 16)
+#define CRI_TXDEEMPH_OVERRIDE_5_0_MASK			(0x3F << 16)
+
 /* The spec defines this only for BXT PHY0, but lets assume that this
  * would exist for PHY1 too if it had a second channel.
  */
-- 
2.14.3

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

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

* [PATCH 10/17] drm/i915/icl: Add Voltage swing table for MG PHY DDI Buffer
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
                   ` (8 preceding siblings ...)
  2018-02-22  3:55 ` [PATCH 09/17] drm/i915/icl: Add register defs for voltage swing sequences for MG " Paulo Zanoni
@ 2018-02-22  3:55 ` Paulo Zanoni
  2018-02-22  3:55 ` [PATCH 11/17] drm/i915/icl: Implement voltage swing programming sequence for MG PHY DDI Paulo Zanoni
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 41+ messages in thread
From: Paulo Zanoni @ 2018-02-22  3:55 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni, Rodrigo Vivi

From: Manasi Navare <manasi.d.navare@intel.com>

This table is used for voltage swing programming sequence during DDI
Buffer initialization for MG PHY DDI Buffers on Icelake.

v2 (from Paulo):
* Fix white space issues.

Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index c38873cb98ca..98471b5c5f70 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -591,6 +591,26 @@ static const struct icl_combo_phy_ddi_buf_trans icl_combo_phy_ddi_translations_e
 	{ 0x0, 0x00, 0x00 },	/* 350         0.0   */
 };
 
+struct icl_mg_phy_ddi_buf_trans {
+	u32 cri_txdeemph_override_5_0;
+	u32 cri_txdeemph_override_11_6;
+	u32 cri_txdeemph_override_17_12;
+};
+
+static const struct icl_mg_phy_ddi_buf_trans icl_mg_phy_ddi_translations[] = {
+				/* Voltage swing  pre-emphasis */
+	{ 0x0, 0x1B, 0x00 },	/* 0              0   */
+	{ 0x0, 0x23, 0x08 },	/* 0              1   */
+	{ 0x0, 0x2D, 0x12 },	/* 0              2   */
+	{ 0x0, 0x00, 0x00 },	/* 0              3   */
+	{ 0x0, 0x23, 0x00 },	/* 1              0   */
+	{ 0x0, 0x2B, 0x09 },	/* 1              1   */
+	{ 0x0, 0x2E, 0x11 },	/* 1              2   */
+	{ 0x0, 0x2F, 0x00 },	/* 2              0   */
+	{ 0x0, 0x33, 0x0C },	/* 2              1   */
+	{ 0x0, 0x00, 0x00 },	/* 3              0   */
+};
+
 static const struct ddi_buf_trans *
 bdw_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
 {
-- 
2.14.3

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

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

* [PATCH 11/17] drm/i915/icl: Implement voltage swing programming sequence for MG PHY DDI
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
                   ` (9 preceding siblings ...)
  2018-02-22  3:55 ` [PATCH 10/17] drm/i915/icl: Add Voltage swing table for MG PHY DDI Buffer Paulo Zanoni
@ 2018-02-22  3:55 ` Paulo Zanoni
  2018-03-22 22:58   ` Paulo Zanoni
  2018-02-22  3:55 ` [PATCH 12/17] drm/i915/icl: HPD pin for port F Paulo Zanoni
                   ` (9 subsequent siblings)
  20 siblings, 1 reply; 41+ messages in thread
From: Paulo Zanoni @ 2018-02-22  3:55 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni, Rodrigo Vivi

From: Manasi Navare <manasi.d.navare@intel.com>

This sequence is used to setup voltage swing before enabling MG PHY DDI
as well as for changing the voltage during DisplayPort Link training.

For ICL, there are two types of DDIs. This sequence needs to be used
for MG PHY DDI which is ports C-F.

v5 (from Paulo):
* Checkpatch.
v4 (from Paulo):
* Fix bogus error message
* Fix copy+paste bugs (missing s/TX1/TX2/ after copy+paste)
* Use the new mask names
* Stay under 80 columns
* Add some blank lines
v3:
* Clear the regs before writing (Paulo)
v2:
* Rename to MG PHY in the function def (Jani Nikula)
* Rebase on top of new revision of other patches in series

Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 85 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 83 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 98471b5c5f70..88a6c5107975 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2364,6 +2364,88 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, u32
 	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
 }
 
+static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
+					   u32 level)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	enum port port = encoder->port;
+	const struct icl_mg_phy_ddi_buf_trans *ddi_translations;
+	u32 n_entries, val;
+	int ln;
+
+	/*
+	 * Values are listed in voltage swing programming tables.
+	 * Same values for all voltage levels and port types.
+	 */
+	n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations);
+	ddi_translations = icl_mg_phy_ddi_translations;
+	/* The table does not have values for level 3 and level 9. */
+	if (level >= n_entries || level == 3 || level == 9) {
+		DRM_DEBUG_KMS("DDI translation not found for level %d. Using %d instead.",
+			      level, n_entries - 2);
+		level = n_entries - 2;
+	}
+
+	/* Set MG_TX_LINK_PARAMS cri_use_fs32 to 0. */
+	for (ln = 0; ln < 2; ln++) {
+		val = I915_READ(ICL_PORT_MG_TX1_LINK_PARAMS(port, ln));
+		val &= ~CRI_USE_FS32;
+		I915_WRITE(ICL_PORT_MG_TX1_LINK_PARAMS(port, ln), val);
+
+		val = I915_READ(ICL_PORT_MG_TX2_LINK_PARAMS(port, ln));
+		val &= ~CRI_USE_FS32;
+		I915_WRITE(ICL_PORT_MG_TX2_LINK_PARAMS(port, ln), val);
+	}
+
+	/* Program MG_TX_SWINGCTRL with values from vswing table */
+	for (ln = 0; ln < 2; ln++) {
+		val = I915_READ(ICL_PORT_MG_TX1_SWINGCTRL(port, ln));
+		val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK;
+		val |= CRI_TXDEEMPH_OVERRIDE_17_12(
+			ddi_translations[level].cri_txdeemph_override_17_12);
+		I915_WRITE(ICL_PORT_MG_TX1_SWINGCTRL(port, ln), val);
+
+		val = I915_READ(ICL_PORT_MG_TX2_SWINGCTRL(port, ln));
+		val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK;
+		val |= CRI_TXDEEMPH_OVERRIDE_17_12(
+			ddi_translations[level].cri_txdeemph_override_17_12);
+		I915_WRITE(ICL_PORT_MG_TX2_SWINGCTRL(port, ln), val);
+	}
+
+	/* Program MG_TX_DRVCTRL with values from vswing table */
+	for (ln = 0; ln < 2; ln++) {
+		val = I915_READ(ICL_PORT_MG_TX1_DRVCTRL(port, ln));
+		val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK |
+			 CRI_TXDEEMPH_OVERRIDE_5_0_MASK);
+		val |= CRI_TXDEEMPH_OVERRIDE_5_0(
+			ddi_translations[level].cri_txdeemph_override_5_0) |
+		       CRI_TXDEEMPH_OVERRIDE_11_6(
+			ddi_translations[level].cri_txdeemph_override_11_6) |
+		       CRI_TXDEEMPH_OVERRIDE_EN;
+		I915_WRITE(ICL_PORT_MG_TX1_DRVCTRL(port, ln), val);
+
+		val = I915_READ(ICL_PORT_MG_TX2_DRVCTRL(port, ln));
+		val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK |
+			 CRI_TXDEEMPH_OVERRIDE_5_0_MASK);
+		val |= CRI_TXDEEMPH_OVERRIDE_5_0(
+			ddi_translations[level].cri_txdeemph_override_5_0) |
+		       CRI_TXDEEMPH_OVERRIDE_11_6(
+			ddi_translations[level].cri_txdeemph_override_11_6) |
+		      CRI_TXDEEMPH_OVERRIDE_EN;
+		I915_WRITE(ICL_PORT_MG_TX2_DRVCTRL(port, ln), val);
+	}
+	/* Program MG_TX_PISO_READLOAD with values from vswing table */
+	for (ln = 0; ln < 2; ln++) {
+		val = I915_READ(ICL_PORT_MG_TX1_PISO_READLOAD(port, ln));
+		val |= CRI_CALCINIT;
+		I915_WRITE(ICL_PORT_MG_TX1_PISO_READLOAD(port, ln), val);
+
+		val = I915_READ(ICL_PORT_MG_TX2_PISO_READLOAD(port, ln));
+		val |= CRI_CALCINIT;
+		I915_WRITE(ICL_PORT_MG_TX2_PISO_READLOAD(port, ln), val);
+	}
+}
+
 static void icl_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level)
 {
 	enum port port = encoder->port;
@@ -2371,8 +2453,7 @@ static void icl_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level)
 	if (port == PORT_A || port == PORT_B)
 		icl_combo_phy_ddi_vswing_sequence(encoder, level);
 	else
-		/* Not Implemented Yet */
-		WARN_ON(1);
+		icl_mg_phy_ddi_vswing_sequence(encoder, level);
 }
 
 static uint32_t translate_signal_level(int signal_levels)
-- 
2.14.3

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

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

* [PATCH 12/17] drm/i915/icl: HPD pin for port F
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
                   ` (10 preceding siblings ...)
  2018-02-22  3:55 ` [PATCH 11/17] drm/i915/icl: Implement voltage swing programming sequence for MG PHY DDI Paulo Zanoni
@ 2018-02-22  3:55 ` Paulo Zanoni
  2018-02-22 20:16   ` Rodrigo Vivi
  2018-02-22  3:55 ` [PATCH 13/17] drm/i915/icl: Added 5k source scaling support for Gen11 platform Paulo Zanoni
                   ` (8 subsequent siblings)
  20 siblings, 1 reply; 41+ messages in thread
From: Paulo Zanoni @ 2018-02-22  3:55 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni, Dhinakaran Pandiyan, Rodrigo Vivi

From: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>

Extend enum hpd_pin to port F so that we can start using this for ICL.

v2: Rebase.

Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      | 1 +
 drivers/gpu/drm/i915/intel_hotplug.c | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 92883a40bdd5..b7fb8e368762 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -261,6 +261,7 @@ enum hpd_pin {
 	HPD_PORT_C,
 	HPD_PORT_D,
 	HPD_PORT_E,
+	HPD_PORT_F,
 	HPD_NUM_PINS
 };
 
diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
index fe28c1ea84a5..8bb9d8436486 100644
--- a/drivers/gpu/drm/i915/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/intel_hotplug.c
@@ -100,6 +100,8 @@ enum port intel_hpd_pin_to_port(struct drm_i915_private *dev_priv,
 		if (IS_CNL_WITH_PORT_F(dev_priv))
 			return PORT_F;
 		return PORT_E;
+	case HPD_PORT_F:
+		return PORT_F;
 	default:
 		return PORT_NONE; /* no port for this pin */
 	}
@@ -132,6 +134,7 @@ enum hpd_pin intel_hpd_pin_default(struct drm_i915_private *dev_priv,
 	case PORT_F:
 		if (IS_CNL_WITH_PORT_F(dev_priv))
 			return HPD_PORT_E;
+		return HPD_PORT_F;
 	default:
 		MISSING_CASE(port);
 		return HPD_NONE;
-- 
2.14.3

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

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

* [PATCH 13/17] drm/i915/icl: Added 5k source scaling support for Gen11 platform
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
                   ` (11 preceding siblings ...)
  2018-02-22  3:55 ` [PATCH 12/17] drm/i915/icl: HPD pin for port F Paulo Zanoni
@ 2018-02-22  3:55 ` Paulo Zanoni
  2018-02-22  3:55 ` [PATCH 14/17] drm/i915/icl: Calculate link clock using the new registers Paulo Zanoni
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 41+ messages in thread
From: Paulo Zanoni @ 2018-02-22  3:55 UTC (permalink / raw)
  To: intel-gfx

From: Nabendu Maiti <nabendu.bikash.maiti@intel.com>

Gen11 supports upto 5k source scaling

v2: Re-factoring of code as per review
v3: Corrected max Vertical size and indentation
v4: Added max Vertical dst size in same patch

Signed-off-by: Nabendu Maiti <nabendu.bikash.maiti@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 11 +++++++----
 drivers/gpu/drm/i915/intel_drv.h     |  4 ++++
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index bc4131a36c10..aa5c04788041 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4735,10 +4735,13 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
 
 	/* range checks */
 	if (src_w < SKL_MIN_SRC_W || src_h < SKL_MIN_SRC_H ||
-		dst_w < SKL_MIN_DST_W || dst_h < SKL_MIN_DST_H ||
-
-		src_w > SKL_MAX_SRC_W || src_h > SKL_MAX_SRC_H ||
-		dst_w > SKL_MAX_DST_W || dst_h > SKL_MAX_DST_H) {
+	    dst_w < SKL_MIN_DST_W || dst_h < SKL_MIN_DST_H ||
+	    (IS_GEN11(dev_priv) &&
+	     (src_w > ICL_MAX_SRC_W || src_h > ICL_MAX_SRC_H ||
+	      dst_w > ICL_MAX_DST_W || dst_h > ICL_MAX_DST_H)) ||
+	    (!IS_GEN11(dev_priv) &&
+	     (src_w > SKL_MAX_SRC_W || src_h > SKL_MAX_SRC_H ||
+	      dst_w > SKL_MAX_DST_W || dst_h > SKL_MAX_DST_H)))	{
 		DRM_DEBUG_KMS("scaler_user index %u.%u: src %ux%u dst %ux%u "
 			"size is out of scaler range\n",
 			intel_crtc->pipe, scaler_user, src_w, src_h, dst_w, dst_h);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 47d40b8c31b4..f536b7fc7c92 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -547,6 +547,10 @@ struct intel_initial_plane_config {
 #define SKL_MAX_DST_W 4096
 #define SKL_MIN_DST_H 8
 #define SKL_MAX_DST_H 4096
+#define ICL_MAX_SRC_W 5120
+#define ICL_MAX_SRC_H 4096
+#define ICL_MAX_DST_W 5120
+#define ICL_MAX_DST_H 4096
 
 struct intel_scaler {
 	int in_use;
-- 
2.14.3

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

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

* [PATCH 14/17] drm/i915/icl: Calculate link clock using the new registers
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
                   ` (12 preceding siblings ...)
  2018-02-22  3:55 ` [PATCH 13/17] drm/i915/icl: Added 5k source scaling support for Gen11 platform Paulo Zanoni
@ 2018-02-22  3:55 ` Paulo Zanoni
  2018-03-22 23:20   ` Paulo Zanoni
  2018-02-22  3:55 ` [PATCH 15/17] drm/i915/icl: Don't set pipe CSC/Gamma in PLANE_COLOR_CTL Paulo Zanoni
                   ` (6 subsequent siblings)
  20 siblings, 1 reply; 41+ messages in thread
From: Paulo Zanoni @ 2018-02-22  3:55 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

From: Arkadiusz Hiler <arkadiusz.hiler@intel.com>

Start using the new registers for ICL and on.

Cc: Manasi Navare <manasi.d.navare@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 88a6c5107975..c1f1966d471c 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1371,8 +1371,13 @@ static int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv,
 	uint32_t cfgcr0, cfgcr1;
 	uint32_t p0, p1, p2, dco_freq, ref_clock;
 
-	cfgcr0 = I915_READ(CNL_DPLL_CFGCR0(pll_id));
-	cfgcr1 = I915_READ(CNL_DPLL_CFGCR1(pll_id));
+	if (INTEL_GEN(dev_priv) >= 11) {
+		cfgcr0 = I915_READ(ICL_DPLL_CFGCR0(pll_id));
+		cfgcr1 = I915_READ(ICL_DPLL_CFGCR1(pll_id));
+	} else {
+		cfgcr0 = I915_READ(CNL_DPLL_CFGCR0(pll_id));
+		cfgcr1 = I915_READ(CNL_DPLL_CFGCR1(pll_id));
+	}
 
 	p0 = cfgcr1 & DPLL_CFGCR1_PDIV_MASK;
 	p2 = cfgcr1 & DPLL_CFGCR1_KDIV_MASK;
-- 
2.14.3

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

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

* [PATCH 15/17] drm/i915/icl: Don't set pipe CSC/Gamma in PLANE_COLOR_CTL
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
                   ` (13 preceding siblings ...)
  2018-02-22  3:55 ` [PATCH 14/17] drm/i915/icl: Calculate link clock using the new registers Paulo Zanoni
@ 2018-02-22  3:55 ` Paulo Zanoni
  2018-02-22  3:55 ` [PATCH 16/17] drm/i915/gen11: all the DDI ports on gen 11 support 4 lanes Paulo Zanoni
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 41+ messages in thread
From: Paulo Zanoni @ 2018-02-22  3:55 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

From: James Ausmus <james.ausmus@intel.com>

These fields have been deprecated and moved in ICL+. Stop setting the
bits.

They have moved to GAMMA_MODE and CSC_MODE, respectively. This patch
is just to stop incorrectly setting bits in PLANE_COLOR_CTL while
we're waiting for the new replacement functionality to be done.

v2: Drop useless comment, and change !(GEN >= 11) to (GEN < 11). (Ville)

v3: No changes

Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: James Ausmus <james.ausmus@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h      | 4 ++--
 drivers/gpu/drm/i915/intel_display.c | 8 ++++++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index a389d4030b7f..fc13d9b63c74 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6611,8 +6611,8 @@ enum {
 #define _PLANE_COLOR_CTL_1_A			0x701CC /* GLK+ */
 #define _PLANE_COLOR_CTL_2_A			0x702CC /* GLK+ */
 #define _PLANE_COLOR_CTL_3_A			0x703CC /* GLK+ */
-#define   PLANE_COLOR_PIPE_GAMMA_ENABLE		(1 << 30)
-#define   PLANE_COLOR_PIPE_CSC_ENABLE		(1 << 23)
+#define   PLANE_COLOR_PIPE_GAMMA_ENABLE		(1 << 30) /* Pre-ICL */
+#define   PLANE_COLOR_PIPE_CSC_ENABLE		(1 << 23) /* Pre-ICL */
 #define   PLANE_COLOR_PLANE_GAMMA_DISABLE	(1 << 13)
 #define   PLANE_COLOR_ALPHA_MASK		(0x3 << 4)
 #define   PLANE_COLOR_ALPHA_DISABLE		(0 << 4)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index aa5c04788041..8ca828c446a6 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3585,11 +3585,15 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
 u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
 			const struct intel_plane_state *plane_state)
 {
+	struct drm_i915_private *dev_priv =
+		to_i915(plane_state->base.plane->dev);
 	const struct drm_framebuffer *fb = plane_state->base.fb;
 	u32 plane_color_ctl = 0;
 
-	plane_color_ctl |= PLANE_COLOR_PIPE_GAMMA_ENABLE;
-	plane_color_ctl |= PLANE_COLOR_PIPE_CSC_ENABLE;
+	if (INTEL_GEN(dev_priv) < 11) {
+		plane_color_ctl |= PLANE_COLOR_PIPE_GAMMA_ENABLE;
+		plane_color_ctl |= PLANE_COLOR_PIPE_CSC_ENABLE;
+	}
 	plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE;
 	plane_color_ctl |= glk_plane_color_ctl_alpha(fb->format->format);
 
-- 
2.14.3

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

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

* [PATCH 16/17] drm/i915/gen11: all the DDI ports on gen 11 support 4 lanes
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
                   ` (14 preceding siblings ...)
  2018-02-22  3:55 ` [PATCH 15/17] drm/i915/icl: Don't set pipe CSC/Gamma in PLANE_COLOR_CTL Paulo Zanoni
@ 2018-02-22  3:55 ` Paulo Zanoni
  2018-02-22  3:55 ` [PATCH 17/17] drm/i915/icl: Fix the DP Max Voltage for ICL Paulo Zanoni
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 41+ messages in thread
From: Paulo Zanoni @ 2018-02-22  3:55 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

And the DDI_A_4_LANES bit from DDI_BUF_CTL doesn't even exist anymore.

This commit prevents us from auto picking a maximum of 2 lanes, which
makes some panels useless by rejecting their only native mode.

Thanks to Manasi for the help debugging this one.

v2: Typo fix (Rodrigo).

Cc: Manasi Navare <manasi.d.navare@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index c1f1966d471c..ad82ef91263e 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -3300,6 +3300,13 @@ static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dport)
 {
 	struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev);
 
+	/*
+	 * Starting on gen 11, all ports support 4 lanes, don't print messages
+	 * related to this.
+	 */
+	if (INTEL_GEN(dev_priv) >= 11)
+		return false;
+
 	if (dport->base.port != PORT_A)
 		return false;
 
@@ -3332,7 +3339,9 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
 	bool init_hdmi, init_dp, init_lspcon = false;
 	int max_lanes;
 
-	if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
+	if (INTEL_GEN(dev_priv) >= 11) {
+		max_lanes = 4;
+	} else if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
 		switch (port) {
 		case PORT_A:
 			max_lanes = 4;
@@ -3403,9 +3412,13 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
 	intel_encoder->suspend = intel_dp_encoder_suspend;
 	intel_encoder->get_power_domains = intel_ddi_get_power_domains;
 
-	intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
-					  (DDI_BUF_PORT_REVERSAL |
-					   DDI_A_4_LANES);
+	if (INTEL_GEN(dev_priv) >= 11)
+		intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
+						  DDI_BUF_PORT_REVERSAL;
+	else
+		intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
+						  (DDI_BUF_PORT_REVERSAL |
+						   DDI_A_4_LANES);
 
 	switch (port) {
 	case PORT_A:
-- 
2.14.3

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

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

* [PATCH 17/17] drm/i915/icl: Fix the DP Max Voltage for ICL
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
                   ` (15 preceding siblings ...)
  2018-02-22  3:55 ` [PATCH 16/17] drm/i915/gen11: all the DDI ports on gen 11 support 4 lanes Paulo Zanoni
@ 2018-02-22  3:55 ` Paulo Zanoni
  2018-03-23  0:03   ` Rodrigo Vivi
  2018-02-22  4:09 ` ✗ Fi.CI.CHECKPATCH: warning for ICL PLLs, DP/HDMI and misc display Patchwork
                   ` (3 subsequent siblings)
  20 siblings, 1 reply; 41+ messages in thread
From: Paulo Zanoni @ 2018-02-22  3:55 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni, Rodrigo Vivi

From: Manasi Navare <manasi.d.navare@intel.com>

On clock recovery this function is called to find out
the max voltage swing level that we could go.

However gen 9 functions use the old buffer translation tables
to figure that out. ICL uses different set of tables for eDP
and DP for both Combo and MG PHY ports. This patch adds the hook
for ICL for getting this information from appropriate buf trans tables.

v5 (from Paulo):
* New rebase after changes to earlier patches.
v4:
* Rebase.
v3:
* Follow the coding conventions here
(https://cgit.freedesktop.org/drm-intel/tree/Documentation/process/codin
g-style.rst#n191) (Paulo)
v2:
* Rebase after patch that adds voltage check inside buf trans
function (Rodrigo)

Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index ad82ef91263e..fbdd2340c8aa 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2085,7 +2085,13 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder)
 	enum port port = encoder->port;
 	int n_entries;
 
-	if (IS_CANNONLAKE(dev_priv)) {
+	if (IS_ICELAKE(dev_priv)) {
+		if (port == PORT_A || port == PORT_B)
+			icl_get_combo_buf_trans(dev_priv, port, encoder->type,
+						&n_entries);
+		else
+			n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations);
+	} else if (IS_CANNONLAKE(dev_priv)) {
 		if (encoder->type == INTEL_OUTPUT_EDP)
 			cnl_get_buf_trans_edp(dev_priv, &n_entries);
 		else
-- 
2.14.3

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

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

* ✗ Fi.CI.CHECKPATCH: warning for ICL PLLs, DP/HDMI and misc display
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
                   ` (16 preceding siblings ...)
  2018-02-22  3:55 ` [PATCH 17/17] drm/i915/icl: Fix the DP Max Voltage for ICL Paulo Zanoni
@ 2018-02-22  4:09 ` Patchwork
  2018-02-22  4:24 ` ✗ Fi.CI.BAT: " Patchwork
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 41+ messages in thread
From: Patchwork @ 2018-02-22  4:09 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx

== Series Details ==

Series: ICL PLLs, DP/HDMI and misc display
URL   : https://patchwork.freedesktop.org/series/38737/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
176365bcdda2 drm/i915/icl: add definitions for the ICL PLL registers
-:87: CHECK: Prefer using the BIT macro
#87: FILE: drivers/gpu/drm/i915/i915_reg.h:8982:
+#define   MG_PLL_DIV0_FRACNEN_H				(1 << 30)

-:99: CHECK: Prefer using the BIT macro
#99: FILE: drivers/gpu/drm/i915/i915_reg.h:8994:
+#define   MG_PLL_DIV1_DITHER_DIV_2			(1 << 12)

-:113: CHECK: Prefer using the BIT macro
#113: FILE: drivers/gpu/drm/i915/i915_reg.h:9008:
+#define   MG_PLL_LF_AFCCNTSEL_512			(1 << 20)

-:124: CHECK: Prefer using the BIT macro
#124: FILE: drivers/gpu/drm/i915/i915_reg.h:9019:
+#define   MG_PLL_FRAC_LOCK_TRUELOCK_CRIT_32		(1 << 18)

-:125: CHECK: Prefer using the BIT macro
#125: FILE: drivers/gpu/drm/i915/i915_reg.h:9020:
+#define   MG_PLL_FRAC_LOCK_EARLYLOCK_CRIT_32		(1 << 16)

-:127: CHECK: Prefer using the BIT macro
#127: FILE: drivers/gpu/drm/i915/i915_reg.h:9022:
+#define   MG_PLL_FRAC_LOCK_DCODITHEREN			(1 << 10)

-:128: CHECK: Prefer using the BIT macro
#128: FILE: drivers/gpu/drm/i915/i915_reg.h:9023:
+#define   MG_PLL_FRAC_LOCK_FEEDFWRDCAL_EN		(1 << 8)

-:138: CHECK: Prefer using the BIT macro
#138: FILE: drivers/gpu/drm/i915/i915_reg.h:9033:
+#define   MG_PLL_SSC_EN					(1 << 28)

-:142: CHECK: Prefer using the BIT macro
#142: FILE: drivers/gpu/drm/i915/i915_reg.h:9037:
+#define   MG_PLL_SSC_FILEN				(1 << 9)

-:154: CHECK: Prefer using the BIT macro
#154: FILE: drivers/gpu/drm/i915/i915_reg.h:9049:
+#define   MG_PLL_BIAS_BIASCAL_EN			(1 << 15)

-:165: CHECK: Prefer using the BIT macro
#165: FILE: drivers/gpu/drm/i915/i915_reg.h:9060:
+#define   MG_PLL_TDC_COLDST_IREFINT_EN			(1 << 27)

-:167: CHECK: Prefer using the BIT macro
#167: FILE: drivers/gpu/drm/i915/i915_reg.h:9062:
+#define   MG_PLL_TDC_COLDST_COLDSTART			(1 << 16)

-:168: CHECK: Prefer using the BIT macro
#168: FILE: drivers/gpu/drm/i915/i915_reg.h:9063:
+#define   MG_PLL_TDC_TDCCOVCCORR_EN			(1 << 2)

-:178: CHECK: Prefer using the BIT macro
#178: FILE: drivers/gpu/drm/i915/i915_reg.h:9073:
+#define  DPLL_CFGCR0_SSC_ENABLE_ICL	(1 << 25)

total: 0 errors, 0 warnings, 14 checks, 179 lines checked
0212a3eaf876 drm/i915/icl: add basic support for the ICL clocks
-:105: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#105: FILE: drivers/gpu/drm/i915/intel_ddi.c:2151:
+		uint32_t val;

-:291: CHECK: multiple assignments should be avoided
#291: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.c:2436:
+		min = max = icl_port_to_mg_pll_id(port);

-:339: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#339: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.c:2484:
+	uint32_t val;

-:421: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#421: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.c:2566:
+	uint32_t val;

-:472: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#472: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.c:2617:
+	uint32_t val;

-:509: WARNING: quoted string split across lines
#509: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.c:2654:
+	DRM_DEBUG_KMS("dpll_hw_state: cfgcr0: 0x%x, cfgcr1: 0x%x, "
+		      "mg_refclkin_ctl: 0x%x, hg_clktop2_coreclkctl1: 0x%x, "

-:510: WARNING: quoted string split across lines
#510: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.c:2655:
+		      "mg_refclkin_ctl: 0x%x, hg_clktop2_coreclkctl1: 0x%x, "
+		      "mg_clktop2_hsclkctl: 0x%x, mg_pll_div0: 0x%x, "

-:511: WARNING: quoted string split across lines
#511: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.c:2656:
+		      "mg_clktop2_hsclkctl: 0x%x, mg_pll_div0: 0x%x, "
+		      "mg_pll_div2: 0x%x, mg_pll_lf: 0x%x, "

-:512: WARNING: quoted string split across lines
#512: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.c:2657:
+		      "mg_pll_div2: 0x%x, mg_pll_lf: 0x%x, "
+		      "mg_pll_frac_lock: 0x%x, mg_pll_ssc: 0x%x, "

-:513: WARNING: quoted string split across lines
#513: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.c:2658:
+		      "mg_pll_frac_lock: 0x%x, mg_pll_ssc: 0x%x, "
+		      "mg_pll_bias: 0x%x, mg_pll_tdc_coldst_bias: 0x%x\n",

-:572: CHECK: Please don't use multiple blank lines
#572: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.h:107:
+
+

-:609: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#609: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.h:169:
+	uint32_t mg_refclkin_ctl;

-:610: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#610: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.h:170:
+	uint32_t mg_clktop2_coreclkctl1;

-:611: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#611: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.h:171:
+	uint32_t mg_clktop2_hsclkctl;

-:612: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#612: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.h:172:
+	uint32_t mg_pll_div0;

-:613: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#613: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.h:173:
+	uint32_t mg_pll_div1;

-:614: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#614: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.h:174:
+	uint32_t mg_pll_lf;

-:615: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#615: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.h:175:
+	uint32_t mg_pll_frac_lock;

-:616: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#616: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.h:176:
+	uint32_t mg_pll_ssc;

-:617: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#617: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.h:177:
+	uint32_t mg_pll_bias;

-:618: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#618: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.h:178:
+	uint32_t mg_pll_tdc_coldst_bias;

total: 0 errors, 5 warnings, 16 checks, 579 lines checked
394ce70a7d01 drm/i915/icl: compute the combo PHY (DPLL) HDMI registers
-:23: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#23: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.c:2206:
+	uint32_t ref_clock;

-:48: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#48: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.c:2397:
+	uint32_t cfgcr0, cfgcr1;

total: 0 errors, 0 warnings, 2 checks, 52 lines checked
083e316a0ea3 drm/i915/icl: compute the combo PHY (DPLL) DP registers
756e2fb14b68 drm/i915/icl: compute the MG PLL registers
-:30: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#30: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.c:2518:
+				     uint32_t *target_dco_khz,

-:33: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#33: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.c:2521:
+	uint32_t dco_min_freq, dco_max_freq;

-:108: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#108: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.c:2595:
+	uint32_t dco_khz, m1div, m2div_int, m2div_rem, m2div_frac;

-:109: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#109: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.c:2596:
+	uint32_t iref_ndiv, iref_trim, iref_pulse_w;

-:110: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#110: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.c:2597:
+	uint32_t prop_coeff, int_coeff;

-:111: CHECK: Prefer kernel type 'u32' over 'uint32_t'
#111: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.c:2598:
+	uint32_t tdc_targetcnt, feedfwgain;

-:112: CHECK: Prefer kernel type 'u64' over 'uint64_t'
#112: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.c:2599:
+	uint64_t ssc_stepsize, ssc_steplen, ssc_steplog;

-:113: CHECK: Prefer kernel type 'u64' over 'uint64_t'
#113: FILE: drivers/gpu/drm/i915/intel_dpll_mgr.c:2600:
+	uint64_t tmp;

total: 0 errors, 0 warnings, 8 checks, 227 lines checked
96d7a0b68153 drm/i915/icl: Add register definitions for Combo PHY vswing sequences.
-:106: CHECK: Prefer using the BIT macro
#106: FILE: drivers/gpu/drm/i915/i915_reg.h:2097:
+#define   TAP2_DISABLE			(1 << 30)

total: 0 errors, 0 warnings, 1 checks, 69 lines checked
7767df908beb drm/i915/icl: Add Combo PHY DDI Buffer translation tables for Icelake.
-:57: WARNING: line over 80 characters
#57: FILE: drivers/gpu/drm/i915/intel_ddi.c:502:
+static const struct icl_combo_phy_ddi_buf_trans icl_combo_phy_ddi_translations_dp_hdmi_0_85V[] = {

-:73: WARNING: line over 80 characters
#73: FILE: drivers/gpu/drm/i915/intel_ddi.c:518:
+static const struct icl_combo_phy_ddi_buf_trans icl_combo_phy_ddi_translations_edp_0_85V[] = {

-:88: WARNING: line over 80 characters
#88: FILE: drivers/gpu/drm/i915/intel_ddi.c:533:
+static const struct icl_combo_phy_ddi_buf_trans icl_combo_phy_ddi_translations_dp_hdmi_0_95V[] = {

-:104: WARNING: line over 80 characters
#104: FILE: drivers/gpu/drm/i915/intel_ddi.c:549:
+static const struct icl_combo_phy_ddi_buf_trans icl_combo_phy_ddi_translations_edp_0_95V[] = {

-:119: WARNING: line over 80 characters
#119: FILE: drivers/gpu/drm/i915/intel_ddi.c:564:
+static const struct icl_combo_phy_ddi_buf_trans icl_combo_phy_ddi_translations_dp_hdmi_1_05V[] = {

-:135: WARNING: line over 80 characters
#135: FILE: drivers/gpu/drm/i915/intel_ddi.c:580:
+static const struct icl_combo_phy_ddi_buf_trans icl_combo_phy_ddi_translations_edp_1_05V[] = {

total: 0 errors, 6 warnings, 0 checks, 105 lines checked
f68122f9a0b6 drm/i915/icl: Implement voltage swing programming sequence for Combo PHY DDI
-:67: WARNING: line over 80 characters
#67: FILE: drivers/gpu/drm/i915/intel_ddi.c:861:
+			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_85V);

-:70: WARNING: line over 80 characters
#70: FILE: drivers/gpu/drm/i915/intel_ddi.c:864:
+			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_95V);

-:73: WARNING: line over 80 characters
#73: FILE: drivers/gpu/drm/i915/intel_ddi.c:867:
+			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_1_05V);

-:82: WARNING: line over 80 characters
#82: FILE: drivers/gpu/drm/i915/intel_ddi.c:876:
+			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_85V);

-:85: WARNING: line over 80 characters
#85: FILE: drivers/gpu/drm/i915/intel_ddi.c:879:
+			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_95V);

-:88: WARNING: line over 80 characters
#88: FILE: drivers/gpu/drm/i915/intel_ddi.c:882:
+			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_1_05V);

-:117: WARNING: line over 80 characters
#117: FILE: drivers/gpu/drm/i915/intel_ddi.c:2233:
+		DRM_DEBUG_KMS("DDI translation not found for level %d. Using %d instead.", level, n_entries - 1);

-:162: WARNING: line over 80 characters
#162: FILE: drivers/gpu/drm/i915/intel_ddi.c:2278:
+static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level)

total: 0 errors, 8 warnings, 0 checks, 219 lines checked
95188dc60dea drm/i915/icl: Add register defs for voltage swing sequences for MG PHY DDI
-:36: CHECK: Macro argument reuse 'ln0p1' - possible side-effects?
#36: FILE: drivers/gpu/drm/i915/i915_reg.h:2131:
+#define _ICL_MG_PHY_PORT_LN(port, ln, ln0p1, ln0p2, ln1p1) \
+	_MMIO(_PORT((port) - PORT_C, ln0p1, ln0p2) + (ln) * ((ln1p1) - (ln0p1)))

-:64: CHECK: Prefer using the BIT macro
#64: FILE: drivers/gpu/drm/i915/i915_reg.h:2159:
+#define CRI_USE_FS32			(1 << 5)

-:91: CHECK: Prefer using the BIT macro
#91: FILE: drivers/gpu/drm/i915/i915_reg.h:2186:
+#define CRI_CALCINIT					(1 << 1)

-:148: CHECK: Prefer using the BIT macro
#148: FILE: drivers/gpu/drm/i915/i915_reg.h:2243:
+#define CRI_TXDEEMPH_OVERRIDE_EN			(1 << 22)

total: 0 errors, 0 warnings, 4 checks, 122 lines checked
87682ffe4e06 drm/i915/icl: Add Voltage swing table for MG PHY DDI Buffer
a996d61691a8 drm/i915/icl: Implement voltage swing programming sequence for MG PHY DDI
-:57: WARNING: line over 80 characters
#57: FILE: drivers/gpu/drm/i915/intel_ddi.c:2384:
+		DRM_DEBUG_KMS("DDI translation not found for level %d. Using %d instead.",

-:77: CHECK: Lines should not end with a '('
#77: FILE: drivers/gpu/drm/i915/intel_ddi.c:2404:
+		val |= CRI_TXDEEMPH_OVERRIDE_17_12(

-:83: CHECK: Lines should not end with a '('
#83: FILE: drivers/gpu/drm/i915/intel_ddi.c:2410:
+		val |= CRI_TXDEEMPH_OVERRIDE_17_12(

-:93: CHECK: Lines should not end with a '('
#93: FILE: drivers/gpu/drm/i915/intel_ddi.c:2420:
+		val |= CRI_TXDEEMPH_OVERRIDE_5_0(

-:95: CHECK: Lines should not end with a '('
#95: FILE: drivers/gpu/drm/i915/intel_ddi.c:2422:
+		       CRI_TXDEEMPH_OVERRIDE_11_6(

-:103: CHECK: Lines should not end with a '('
#103: FILE: drivers/gpu/drm/i915/intel_ddi.c:2430:
+		val |= CRI_TXDEEMPH_OVERRIDE_5_0(

-:105: CHECK: Lines should not end with a '('
#105: FILE: drivers/gpu/drm/i915/intel_ddi.c:2432:
+		       CRI_TXDEEMPH_OVERRIDE_11_6(

total: 0 errors, 1 warnings, 6 checks, 97 lines checked
564b8c7a2810 drm/i915/icl: HPD pin for port F
390f90f94037 drm/i915/icl: Added 5k source scaling support for Gen11 platform
137ca2ea6e11 drm/i915/icl: Calculate link clock using the new registers
f39480af7607 drm/i915/icl: Don't set pipe CSC/Gamma in PLANE_COLOR_CTL
-:34: CHECK: Prefer using the BIT macro
#34: FILE: drivers/gpu/drm/i915/i915_reg.h:6614:
+#define   PLANE_COLOR_PIPE_GAMMA_ENABLE		(1 << 30) /* Pre-ICL */

-:35: CHECK: Prefer using the BIT macro
#35: FILE: drivers/gpu/drm/i915/i915_reg.h:6615:
+#define   PLANE_COLOR_PIPE_CSC_ENABLE		(1 << 23) /* Pre-ICL */

total: 0 errors, 0 warnings, 2 checks, 27 lines checked
78a0633561af drm/i915/gen11: all the DDI ports on gen 11 support 4 lanes
b154a6a9c427 drm/i915/icl: Fix the DP Max Voltage for ICL

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

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

* ✗ Fi.CI.BAT: warning for ICL PLLs, DP/HDMI and misc display
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
                   ` (17 preceding siblings ...)
  2018-02-22  4:09 ` ✗ Fi.CI.CHECKPATCH: warning for ICL PLLs, DP/HDMI and misc display Patchwork
@ 2018-02-22  4:24 ` Patchwork
  2018-03-23  0:05 ` [PATCH 00/17] " Paulo Zanoni
  2018-03-23  1:00 ` ✗ Fi.CI.BAT: failure for ICL PLLs, DP/HDMI and misc display (rev4) Patchwork
  20 siblings, 0 replies; 41+ messages in thread
From: Patchwork @ 2018-02-22  4:24 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx

== Series Details ==

Series: ICL PLLs, DP/HDMI and misc display
URL   : https://patchwork.freedesktop.org/series/38737/
State : warning

== Summary ==

Series 38737v1 ICL PLLs, DP/HDMI and misc display
https://patchwork.freedesktop.org/api/1.0/series/38737/revisions/1/mbox/

Test gem_exec_suspend:
        Subgroup basic-s4-devices:
                pass       -> DMESG-WARN (fi-kbl-7500u)
Test gem_mmap_gtt:
        Subgroup basic-small-bo-tiledx:
                fail       -> PASS       (fi-gdg-551) fdo#102575
Test kms_chamelium:
        Subgroup dp-edid-read:
                pass       -> FAIL       (fi-kbl-7500u) fdo#102505
Test kms_pipe_crc_basic:
        Subgroup suspend-read-crc-pipe-c:
                incomplete -> PASS       (fi-bxt-dsi) fdo#103927

fdo#102575 
fdo#102505 
fdo#103927 

fi-bdw-5557u     total:288  pass:267  dwarn:0   dfail:0   fail:0   skip:21  time:418s
fi-bdw-gvtdvm    total:288  pass:264  dwarn:0   dfail:0   fail:0   skip:24  time:425s
fi-blb-e6850     total:288  pass:223  dwarn:1   dfail:0   fail:0   skip:64  time:375s
fi-bsw-n3050     total:288  pass:242  dwarn:0   dfail:0   fail:0   skip:46  time:490s
fi-bwr-2160      total:288  pass:183  dwarn:0   dfail:0   fail:0   skip:105 time:287s
fi-bxt-dsi       total:288  pass:258  dwarn:0   dfail:0   fail:0   skip:30  time:480s
fi-bxt-j4205     total:288  pass:259  dwarn:0   dfail:0   fail:0   skip:29  time:479s
fi-byt-j1900     total:288  pass:253  dwarn:0   dfail:0   fail:0   skip:35  time:469s
fi-byt-n2820     total:288  pass:249  dwarn:0   dfail:0   fail:0   skip:39  time:459s
fi-cfl-s2        total:288  pass:262  dwarn:0   dfail:0   fail:0   skip:26  time:568s
fi-elk-e7500     total:288  pass:229  dwarn:0   dfail:0   fail:0   skip:59  time:414s
fi-gdg-551       total:288  pass:180  dwarn:0   dfail:0   fail:0   skip:108 time:284s
fi-glk-1         total:288  pass:260  dwarn:0   dfail:0   fail:0   skip:28  time:508s
fi-hsw-4770      total:288  pass:261  dwarn:0   dfail:0   fail:0   skip:27  time:385s
fi-ilk-650       total:288  pass:228  dwarn:0   dfail:0   fail:0   skip:60  time:411s
fi-ivb-3520m     total:288  pass:259  dwarn:0   dfail:0   fail:0   skip:29  time:461s
fi-ivb-3770      total:288  pass:255  dwarn:0   dfail:0   fail:0   skip:33  time:408s
fi-kbl-7500u     total:288  pass:261  dwarn:2   dfail:0   fail:1   skip:24  time:460s
fi-kbl-7560u     total:288  pass:269  dwarn:0   dfail:0   fail:0   skip:19  time:489s
fi-kbl-7567u     total:288  pass:268  dwarn:0   dfail:0   fail:0   skip:20  time:446s
fi-kbl-r         total:288  pass:261  dwarn:0   dfail:0   fail:0   skip:27  time:492s
fi-pnv-d510      total:288  pass:222  dwarn:1   dfail:0   fail:0   skip:65  time:594s
fi-skl-6260u     total:288  pass:268  dwarn:0   dfail:0   fail:0   skip:20  time:430s
fi-skl-6600u     total:288  pass:261  dwarn:0   dfail:0   fail:0   skip:27  time:504s
fi-skl-6700hq    total:288  pass:262  dwarn:0   dfail:0   fail:0   skip:26  time:523s
fi-skl-6700k2    total:288  pass:264  dwarn:0   dfail:0   fail:0   skip:24  time:491s
fi-skl-6770hq    total:288  pass:268  dwarn:0   dfail:0   fail:0   skip:20  time:472s
fi-skl-guc       total:288  pass:260  dwarn:0   dfail:0   fail:0   skip:28  time:406s
fi-skl-gvtdvm    total:288  pass:265  dwarn:0   dfail:0   fail:0   skip:23  time:430s
fi-snb-2520m     total:288  pass:248  dwarn:0   dfail:0   fail:0   skip:40  time:516s
fi-snb-2600      total:288  pass:248  dwarn:0   dfail:0   fail:0   skip:40  time:393s

42016703e66b7b572d4ab651946b715cdbff3050 drm-tip: 2018y-02m-21d-21h-26m-53s UTC integration manifest
b154a6a9c427 drm/i915/icl: Fix the DP Max Voltage for ICL
78a0633561af drm/i915/gen11: all the DDI ports on gen 11 support 4 lanes
f39480af7607 drm/i915/icl: Don't set pipe CSC/Gamma in PLANE_COLOR_CTL
137ca2ea6e11 drm/i915/icl: Calculate link clock using the new registers
390f90f94037 drm/i915/icl: Added 5k source scaling support for Gen11 platform
564b8c7a2810 drm/i915/icl: HPD pin for port F
a996d61691a8 drm/i915/icl: Implement voltage swing programming sequence for MG PHY DDI
87682ffe4e06 drm/i915/icl: Add Voltage swing table for MG PHY DDI Buffer
95188dc60dea drm/i915/icl: Add register defs for voltage swing sequences for MG PHY DDI
f68122f9a0b6 drm/i915/icl: Implement voltage swing programming sequence for Combo PHY DDI
7767df908beb drm/i915/icl: Add Combo PHY DDI Buffer translation tables for Icelake.
96d7a0b68153 drm/i915/icl: Add register definitions for Combo PHY vswing sequences.
756e2fb14b68 drm/i915/icl: compute the MG PLL registers
083e316a0ea3 drm/i915/icl: compute the combo PHY (DPLL) DP registers
394ce70a7d01 drm/i915/icl: compute the combo PHY (DPLL) HDMI registers
0212a3eaf876 drm/i915/icl: add basic support for the ICL clocks
176365bcdda2 drm/i915/icl: add definitions for the ICL PLL registers

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_8116/issues.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 12/17] drm/i915/icl: HPD pin for port F
  2018-02-22  3:55 ` [PATCH 12/17] drm/i915/icl: HPD pin for port F Paulo Zanoni
@ 2018-02-22 20:16   ` Rodrigo Vivi
  0 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Vivi @ 2018-02-22 20:16 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx, Dhinakaran Pandiyan

On Thu, Feb 22, 2018 at 12:55:14AM -0300, Paulo Zanoni wrote:
> From: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> 
> Extend enum hpd_pin to port F so that we can start using this for ICL.
> 
> v2: Rebase.
> 
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
> Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

> ---
>  drivers/gpu/drm/i915/i915_drv.h      | 1 +
>  drivers/gpu/drm/i915/intel_hotplug.c | 3 +++
>  2 files changed, 4 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 92883a40bdd5..b7fb8e368762 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -261,6 +261,7 @@ enum hpd_pin {
>  	HPD_PORT_C,
>  	HPD_PORT_D,
>  	HPD_PORT_E,
> +	HPD_PORT_F,
>  	HPD_NUM_PINS
>  };
>  
> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
> index fe28c1ea84a5..8bb9d8436486 100644
> --- a/drivers/gpu/drm/i915/intel_hotplug.c
> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
> @@ -100,6 +100,8 @@ enum port intel_hpd_pin_to_port(struct drm_i915_private *dev_priv,
>  		if (IS_CNL_WITH_PORT_F(dev_priv))
>  			return PORT_F;
>  		return PORT_E;
> +	case HPD_PORT_F:
> +		return PORT_F;
>  	default:
>  		return PORT_NONE; /* no port for this pin */
>  	}
> @@ -132,6 +134,7 @@ enum hpd_pin intel_hpd_pin_default(struct drm_i915_private *dev_priv,
>  	case PORT_F:
>  		if (IS_CNL_WITH_PORT_F(dev_priv))
>  			return HPD_PORT_E;
> +		return HPD_PORT_F;
>  	default:
>  		MISSING_CASE(port);
>  		return HPD_NONE;
> -- 
> 2.14.3
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 01/17] drm/i915/icl: add definitions for the ICL PLL registers
  2018-02-22  3:55 ` [PATCH 01/17] drm/i915/icl: add definitions for the ICL PLL registers Paulo Zanoni
@ 2018-02-27 22:22   ` James Ausmus
  2018-03-21 21:34     ` Paulo Zanoni
  2018-03-23  0:07   ` Paulo Zanoni
  2018-03-23  0:08   ` [PATCH 02/17] drm/i915/icl: add basic support for the ICL clocks Paulo Zanoni
  2 siblings, 1 reply; 41+ messages in thread
From: James Ausmus @ 2018-02-27 22:22 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx, arthur.j.runyan

On Thu, Feb 22, 2018 at 12:55:03AM -0300, Paulo Zanoni wrote:
> There's a lot of code for the PLL enabling, so let's first only
> introduce the register definitions in order to make patch reviewing a
> little easier.
> 
> v2: Coding style (Jani).
> v3: Preparation for upstreaming.
> 
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_reg.h | 149 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 149 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 1412abcb27d4..f62335c4a748 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -8783,6 +8783,12 @@ enum skl_power_gate {
>  #define  PORT_CLK_SEL_NONE		(7<<29)
>  #define  PORT_CLK_SEL_MASK		(7<<29)
>  
> +/* On ICL+ this is the same as PORT_CLK_SEL, but all bits change. */
> +#define DDI_CLK_SEL(port)		PORT_CLK_SEL(port)
> +#define  DDI_CLK_SEL_NONE		(0x0 << 28)
> +#define  DDI_CLK_SEL_MG			(0x8 << 28)
> +#define  DDI_CLK_SEL_MASK		(0xF << 28)
> +
>  /* Transcoder clock selection */
>  #define _TRANS_CLK_SEL_A		0x46140
>  #define _TRANS_CLK_SEL_B		0x46144
> @@ -8913,6 +8919,7 @@ enum skl_power_gate {
>   * CNL Clocks
>   */
>  #define DPCLKA_CFGCR0				_MMIO(0x6C200)
> +#define DPCLKA_CFGCR0_ICL			_MMIO(0x164280)
>  #define  DPCLKA_CFGCR0_DDI_CLK_OFF(port)	(1 << ((port) ==  PORT_F ? 23 : \
>  						      (port)+10))
>  #define  DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port)	((port) == PORT_F ? 21 : \
> @@ -8929,10 +8936,141 @@ enum skl_power_gate {
>  #define  PLL_POWER_STATE	(1 << 26)
>  #define CNL_DPLL_ENABLE(pll)	_MMIO_PLL(pll, DPLL0_ENABLE, DPLL1_ENABLE)
>  
> +#define _MG_PLL1_ENABLE		0x46030
> +#define _MG_PLL2_ENABLE		0x46034
> +#define _MG_PLL3_ENABLE		0x46038
> +#define _MG_PLL4_ENABLE		0x4603C
> +/* Bits are the same as DPLL0_ENABLE */
> +#define MG_PLL_ENABLE(port)	_MMIO_PORT((port) - PORT_C, _MG_PLL1_ENABLE, \
> +					   _MG_PLL2_ENABLE)
> +
> +#define _MG_REFCLKIN_CTL_PORT1				0x16892C
> +#define _MG_REFCLKIN_CTL_PORT2				0x16992C
> +#define _MG_REFCLKIN_CTL_PORT3				0x16A92C
> +#define _MG_REFCLKIN_CTL_PORT4				0x16B92C
> +#define   MG_REFCLKIN_CTL_OD_2_MUX(x)			((x) << 8)
> +#define MG_REFCLKIN_CTL(port) _MMIO_PORT((port) - PORT_C, \
> +					 _MG_REFCLKIN_CTL_PORT1, \
> +					 _MG_REFCLKIN_CTL_PORT2)
> +
> +#define _MG_CLKTOP2_CORECLKCTL1_PORT1			0x1690D8
> +#define _MG_CLKTOP2_CORECLKCTL1_PORT2			0x16B0D8
> +#define _MG_CLKTOP2_CORECLKCTL1_PORT3			0x16D0D8
> +#define _MG_CLKTOP2_CORECLKCTL1_PORT4			0x16F0D8
> +#define   MG_CLKTOP2_CORECLKCTL1_B_DIVRATIO(x)		((x) << 16)
> +#define   MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO(x)		((x) << 8)
> +#define MG_CLKTOP2_CORECLKCTL1(port) _MMIO_PORT((port) - PORT_C, \
> +						_MG_CLKTOP2_CORECLKCTL1_PORT1, \
> +						_MG_CLKTOP2_CORECLKCTL1_PORT2)

BSpec 21736 says this register is unused and pending deletion, but in 20845 it also
says to program this register. Art, can you shed any light here?

Hmm, on further study, it looks like the MG_CLKTOP_CORECLKCTL1 group
(21340) names the port instances as MG_CLKTOP2_CORECLKCTL1_PORTx, so it
looks like *that* is the actual register group you want (and the
register bit definitions match as well), but, in that case, the
addresses are wrong - they need to be: 0x1688D8, 0x1698D8, 0x16A8D8, and
0x16B8D8, respectively.

> +
> +#define _MG_CLKTOP2_HSCLKCTL_PORT1			0x1688D4
> +#define _MG_CLKTOP2_HSCLKCTL_PORT2			0x1698D4
> +#define _MG_CLKTOP2_HSCLKCTL_PORT3			0x16A8D4
> +#define _MG_CLKTOP2_HSCLKCTL_PORT4			0x16B8D4
> +#define   MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL(x)		((x) << 16)
> +#define   MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL(x)	((x) << 14)
> +#define   MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO(x)		((x) << 12)
> +#define   MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO(x)		((x) << 8)
> +#define MG_CLKTOP2_HSCLKCTL(port) _MMIO_PORT((port) - PORT_C, \
> +					     _MG_CLKTOP2_HSCLKCTL_PORT1, \
> +					     _MG_CLKTOP2_HSCLKCTL_PORT2)
> +
> +#define _MG_PLL_DIV0_PORT1				0x168A00
> +#define _MG_PLL_DIV0_PORT2				0x169A00
> +#define _MG_PLL_DIV0_PORT3				0x16AA00
> +#define _MG_PLL_DIV0_PORT4				0x16BA00
> +#define   MG_PLL_DIV0_FRACNEN_H				(1 << 30)
> +#define   MG_PLL_DIV0_FBDIV_FRAC(x)			((x) << 8)
> +#define   MG_PLL_DIV0_FBDIV_INT(x)			((x) << 0)
> +#define MG_PLL_DIV0(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_DIV0_PORT1, \
> +				     _MG_PLL_DIV0_PORT2)
> +
> +#define _MG_PLL_DIV1_PORT1				0x168A04
> +#define _MG_PLL_DIV1_PORT2				0x169A04
> +#define _MG_PLL_DIV1_PORT3				0x16AA04
> +#define _MG_PLL_DIV1_PORT4				0x16BA04
> +#define   MG_PLL_DIV1_IREF_NDIVRATIO(x)			((x) << 16)
> +#define   MG_PLL_DIV1_DITHER_DIV_1			(0 << 12)
> +#define   MG_PLL_DIV1_DITHER_DIV_2			(1 << 12)
> +#define   MG_PLL_DIV1_DITHER_DIV_4			(2 << 12)
> +#define   MG_PLL_DIV1_DITHER_DIV_8			(3 << 12)
> +#define   MG_PLL_DIV1_NDIVRATIO(x)			((x) << 4)
> +#define   MG_PLL_DIV1_FBPREDIV(x)			((x) << 0)
> +#define MG_PLL_DIV1(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_DIV1_PORT1, \
> +				     _MG_PLL_DIV1_PORT2)
> +
> +#define _MG_PLL_LF_PORT1				0x168A08
> +#define _MG_PLL_LF_PORT2				0x169A08
> +#define _MG_PLL_LF_PORT3				0x16AA08
> +#define _MG_PLL_LF_PORT4				0x16BA08
> +#define   MG_PLL_LF_TDCTARGETCNT(x)			((x) << 24)
> +#define   MG_PLL_LF_AFCCNTSEL_256			(0 << 20)
> +#define   MG_PLL_LF_AFCCNTSEL_512			(1 << 20)
> +#define   MG_PLL_LF_GAINCTRL(x)				((x) << 16)
> +#define   MG_PLL_LF_INT_COEFF(x)			((x) << 8)
> +#define   MG_PLL_LF_PROP_COEFF(x)			((x) << 0)
> +#define MG_PLL_LF(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_LF_PORT1, \
> +				   _MG_PLL_LF_PORT2)
> +
> +#define _MG_PLL_FRAC_LOCK_PORT1				0x168A0C
> +#define _MG_PLL_FRAC_LOCK_PORT2				0x169A0C
> +#define _MG_PLL_FRAC_LOCK_PORT3				0x16AA0C
> +#define _MG_PLL_FRAC_LOCK_PORT4				0x16BA0C
> +#define   MG_PLL_FRAC_LOCK_TRUELOCK_CRIT_32		(1 << 18)
> +#define   MG_PLL_FRAC_LOCK_EARLYLOCK_CRIT_32		(1 << 16)
> +#define   MG_PLL_FRAC_LOCK_LOCKTHRESH(x)		((x) << 11)
> +#define   MG_PLL_FRAC_LOCK_DCODITHEREN			(1 << 10)
> +#define   MG_PLL_FRAC_LOCK_FEEDFWRDCAL_EN		(1 << 8)
> +#define   MG_PLL_FRAC_LOCK_FEEDFWRDGAIN(x)		((x) << 0)
> +#define MG_PLL_FRAC_LOCK(port) _MMIO_PORT((port) - PORT_C, \
> +					  _MG_PLL_FRAC_LOCK_PORT1, \
> +					  _MG_PLL_FRAC_LOCK_PORT2)
> +
> +#define _MG_PLL_SSC_PORT1				0x168A10
> +#define _MG_PLL_SSC_PORT2				0x169A10
> +#define _MG_PLL_SSC_PORT3				0x16AA10
> +#define _MG_PLL_SSC_PORT4				0x16BA10
> +#define   MG_PLL_SSC_EN					(1 << 28)
> +#define   MG_PLL_SSC_TYPE(x)				((x) << 26)
> +#define   MG_PLL_SSC_STEPLENGTH(x)			((x) << 16)
> +#define   MG_PLL_SSC_STEPNUM(x)				((x) << 10)
> +#define   MG_PLL_SSC_FILEN				(1 << 9)
		^^^
This should be MG_PLL_SSC_FLLEN

> +#define   MG_PLL_SSC_STEPSIZE(x)			((x) << 0)
> +#define MG_PLL_SSC(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_SSC_PORT1, \
> +				    _MG_PLL_SSC_PORT2)
> +
> +#define _MG_PLL_BIAS_PORT1				0x168A14
> +#define _MG_PLL_BIAS_PORT2				0x169A14
> +#define _MG_PLL_BIAS_PORT3				0x16AA14
> +#define _MG_PLL_BIAS_PORT4				0x16BA14
> +#define   MG_PLL_BIAS_BIAS_GB_SEL(x)			((x) << 30)
> +#define   MG_PLL_BIAS_INIT_DCOAMP(x)			((x) << 24)
> +#define   MG_PLL_BIAS_BIAS_BONUS(x)			((x) << 16)
> +#define   MG_PLL_BIAS_BIASCAL_EN			(1 << 15)
> +#define   MG_PLL_BIAS_CTRIM(x)				((x) << 8)
> +#define   MG_PLL_BIAS_VREF_RDAC(x)			((x) << 5)
> +#define   MG_PLL_BIAS_IREFTRIM(x)			((x) << 0)
> +#define MG_PLL_BIAS(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_BIAS_PORT1, \
> +				     _MG_PLL_BIAS_PORT2)
> +
> +#define _MG_PLL_TDC_COLDST_BIAS_PORT1			0x168A18
> +#define _MG_PLL_TDC_COLDST_BIAS_PORT2			0x169A18
> +#define _MG_PLL_TDC_COLDST_BIAS_PORT3			0x16AA18
> +#define _MG_PLL_TDC_COLDST_BIAS_PORT4			0x16BA18
> +#define   MG_PLL_TDC_COLDST_IREFINT_EN			(1 << 27)
> +#define   MG_PLL_TDC_COLDST_REFBIAS_START_PULSE_W(x)	((x) << 17)
> +#define   MG_PLL_TDC_COLDST_COLDSTART			(1 << 16)
> +#define   MG_PLL_TDC_TDCCOVCCORR_EN			(1 << 2)
		^^^^
Should be MG_PLL_TDC_TDCOVCCORR_EN

> +#define   MG_PLL_TDC_TDCSEL(x)				((x) << 0)
> +#define MG_PLL_TDC_COLDST_BIAS(port) _MMIO_PORT((port) - PORT_C, \
> +						_MG_PLL_TDC_COLDST_BIAS_PORT1, \
> +						_MG_PLL_TDC_COLDST_BIAS_PORT2)
> +
>  #define _CNL_DPLL0_CFGCR0		0x6C000
>  #define _CNL_DPLL1_CFGCR0		0x6C080
>  #define  DPLL_CFGCR0_HDMI_MODE		(1 << 30)
>  #define  DPLL_CFGCR0_SSC_ENABLE		(1 << 29)
> +#define  DPLL_CFGCR0_SSC_ENABLE_ICL	(1 << 25)
>  #define  DPLL_CFGCR0_LINK_RATE_MASK	(0xf << 25)
>  #define  DPLL_CFGCR0_LINK_RATE_2700	(0 << 25)
>  #define  DPLL_CFGCR0_LINK_RATE_1350	(1 << 25)
> @@ -8966,8 +9104,19 @@ enum skl_power_gate {
>  #define  DPLL_CFGCR1_PDIV_5		(4 << 2)
>  #define  DPLL_CFGCR1_PDIV_7		(8 << 2)
>  #define  DPLL_CFGCR1_CENTRAL_FREQ	(3 << 0)
> +#define  DPLL_CFGCR1_CENTRAL_FREQ_8400	(3 << 0)
>  #define CNL_DPLL_CFGCR1(pll)		_MMIO_PLL(pll, _CNL_DPLL0_CFGCR1, _CNL_DPLL1_CFGCR1)
>  
> +#define _ICL_DPLL0_CFGCR0		0x164000
> +#define _ICL_DPLL1_CFGCR0		0x164080
> +#define ICL_DPLL_CFGCR0(pll)		_MMIO_PLL(pll, _ICL_DPLL0_CFGCR0, \
> +						  _ICL_DPLL1_CFGCR0)
> +
> +#define _ICL_DPLL0_CFGCR1		0x164004
> +#define _ICL_DPLL1_CFGCR1		0x164084
> +#define ICL_DPLL_CFGCR1(pll)		_MMIO_PLL(pll, _ICL_DPLL0_CFGCR1, \
> +						  _ICL_DPLL1_CFGCR1)
> +
>  /* BXT display engine PLL */
>  #define BXT_DE_PLL_CTL			_MMIO(0x6d000)
>  #define   BXT_DE_PLL_RATIO(x)		(x)	/* {60,65,100} * 19.2MHz */
> -- 
> 2.14.3
> 
> _______________________________________________
> 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] 41+ messages in thread

* Re: [PATCH 02/17] drm/i915/icl: add basic support for the ICL clocks
  2018-02-22  3:55 ` Paulo Zanoni
@ 2018-02-28  0:40   ` James Ausmus
  0 siblings, 0 replies; 41+ messages in thread
From: James Ausmus @ 2018-02-28  0:40 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx

On Thu, Feb 22, 2018 at 12:55:04AM -0300, Paulo Zanoni wrote:
> This commit introduces the definitions for the ICL clocks and adds the
> basic functions to the shared DPLL framework. It adds code for the
> Enable and Disable sequences for some PLLs, but it does not have the
> code to compute the actual PLL values, which are marked as TODO
> comments and should be introduced as separate commits.
> 
> v2:
>  - Rebase around dpll_lock changes.
> v3:
>  - The spec now says what the timeouts should be.
>  - Touch DPCLKA_CFGCR0_ICL at the appropriate time so we don't freeze
>    the machine.
>  - Checkpatch found a white space problem.
>  - Small adjustments before upstreaming.
> 
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c   |  22 +++
>  drivers/gpu/drm/i915/intel_ddi.c      | 102 ++++++++++-
>  drivers/gpu/drm/i915/intel_display.c  |  14 ++
>  drivers/gpu/drm/i915/intel_dpll_mgr.c | 311 +++++++++++++++++++++++++++++++++-
>  drivers/gpu/drm/i915/intel_dpll_mgr.h |  41 +++++
>  drivers/gpu/drm/i915/intel_drv.h      |   6 +
>  6 files changed, 491 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 05b41045b8f9..7ccb5ef212a1 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -3180,6 +3180,28 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused)
>  		seq_printf(m, " fp0:     0x%08x\n", pll->state.hw_state.fp0);
>  		seq_printf(m, " fp1:     0x%08x\n", pll->state.hw_state.fp1);
>  		seq_printf(m, " wrpll:   0x%08x\n", pll->state.hw_state.wrpll);
> +		seq_printf(m, " cfgcr0:  0x%08x\n", pll->state.hw_state.cfgcr0);
> +		seq_printf(m, " cfgcr1:  0x%08x\n", pll->state.hw_state.cfgcr1);
> +		seq_printf(m, " mg_refclkin_ctl:        0x%08x\n",
> +			   pll->state.hw_state.mg_refclkin_ctl);
> +		seq_printf(m, " mg_clktop2_coreclkctl1: 0x%08x\n",
> +			   pll->state.hw_state.mg_clktop2_coreclkctl1);
> +		seq_printf(m, " mg_clktop2_hsclkctl:    0x%08x\n",
> +			   pll->state.hw_state.mg_clktop2_hsclkctl);
> +		seq_printf(m, " mg_pll_div0:  0x%08x\n",
> +			   pll->state.hw_state.mg_pll_div0);
> +		seq_printf(m, " mg_pll_div1:  0x%08x\n",
> +			   pll->state.hw_state.mg_pll_div1);
> +		seq_printf(m, " mg_pll_lf:    0x%08x\n",
> +			   pll->state.hw_state.mg_pll_lf);
> +		seq_printf(m, " mg_pll_frac_lock: 0x%08x\n",
> +			   pll->state.hw_state.mg_pll_frac_lock);
> +		seq_printf(m, " mg_pll_ssc:   0x%08x\n",
> +			   pll->state.hw_state.mg_pll_ssc);
> +		seq_printf(m, " mg_pll_bias:  0x%08x\n",
> +			   pll->state.hw_state.mg_pll_bias);
> +		seq_printf(m, " mg_pll_tdc_coldst_bias: 0x%08x\n",
> +			   pll->state.hw_state.mg_pll_tdc_coldst_bias);
>  	}
>  	drm_modeset_unlock_all(dev);
>  
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 8ca376aca8bd..81383e3dc91f 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -893,6 +893,23 @@ static uint32_t hsw_pll_to_ddi_pll_sel(const struct intel_shared_dpll *pll)
>  	}
>  }
>  
> +static uint32_t icl_pll_to_ddi_pll_sel(struct intel_encoder *encoder,
> +				       const struct intel_shared_dpll *pll)
> +{
> +	switch (pll->id) {
> +	default:
> +		MISSING_CASE(pll->id);
> +	case DPLL_ID_ICL_DPLL0:
> +	case DPLL_ID_ICL_DPLL1:
> +		return DDI_CLK_SEL_NONE;
> +	case DPLL_ID_ICL_MGPLL1:
> +	case DPLL_ID_ICL_MGPLL2:
> +	case DPLL_ID_ICL_MGPLL3:
> +	case DPLL_ID_ICL_MGPLL4:
> +		return DDI_CLK_SEL_MG;
> +	}
> +}
> +
>  /* 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.
> @@ -2114,6 +2131,75 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
>  	return DDI_BUF_TRANS_SELECT(level);
>  }
>  
> +void icl_map_plls_to_ports(struct drm_crtc *crtc,
> +			   struct intel_crtc_state *crtc_state,
> +			   struct drm_atomic_state *old_state)
> +{
> +	struct intel_shared_dpll *pll = crtc_state->shared_dpll;
> +	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
> +	struct drm_connector_state *conn_state;
> +	struct drm_connector *conn;
> +	int i;
> +
> +	if (!IS_ICELAKE(dev_priv))
> +		return;
> +
> +	for_each_new_connector_in_state(old_state, conn, conn_state, i) {
> +		struct intel_encoder *encoder =
> +			to_intel_encoder(conn_state->best_encoder);
> +		enum port port = encoder->port;
> +		uint32_t val;
> +
> +		if (conn_state->crtc != crtc)
> +			continue;
> +
> +		mutex_lock(&dev_priv->dpll_lock);
> +
> +		val = I915_READ(DPCLKA_CFGCR0_ICL);
> +		WARN_ON((val & DPCLKA_CFGCR0_DDI_CLK_OFF(port)) == 0);
> +
> +		if (port == PORT_A || port == PORT_B) {
> +			val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port);
> +			val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->id, port);
> +			I915_WRITE(DPCLKA_CFGCR0_ICL, val);
> +			POSTING_READ(DPCLKA_CFGCR0_ICL);
> +		}
> +
> +		val &= ~DPCLKA_CFGCR0_DDI_CLK_OFF(port);
> +		I915_WRITE(DPCLKA_CFGCR0_ICL, val);
> +
> +		mutex_unlock(&dev_priv->dpll_lock);
> +	}
> +}
> +
> +void icl_unmap_plls_to_ports(struct drm_crtc *crtc,
> +			     struct intel_crtc_state *crtc_state,
> +			     struct drm_atomic_state *old_state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
> +	struct drm_connector_state *conn_state;
> +	struct drm_connector *conn;
> +	int i;
> +
> +	if (!IS_ICELAKE(dev_priv))
> +		return;
> +
> +	for_each_new_connector_in_state(old_state, conn, conn_state, i) {
> +		struct intel_encoder *encoder =
> +			to_intel_encoder(conn_state->best_encoder);
> +		enum port port = encoder->port;
> +
> +		if (conn_state->crtc != crtc)
> +			continue;
> +
> +		mutex_lock(&dev_priv->dpll_lock);
> +		I915_WRITE(DPCLKA_CFGCR0_ICL,
> +			   I915_READ(DPCLKA_CFGCR0_ICL) |
> +			   DPCLKA_CFGCR0_DDI_CLK_OFF(port));
> +		mutex_unlock(&dev_priv->dpll_lock);
> +	}
> +}
> +
>  static void intel_ddi_clk_select(struct intel_encoder *encoder,
>  				 const struct intel_shared_dpll *pll)
>  {
> @@ -2126,7 +2212,11 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder,
>  
>  	mutex_lock(&dev_priv->dpll_lock);
>  
> -	if (IS_CANNONLAKE(dev_priv)) {
> +	if (IS_ICELAKE(dev_priv)) {
> +		if (port >= PORT_C)
> +			I915_WRITE(DDI_CLK_SEL(port),
> +				   icl_pll_to_ddi_pll_sel(encoder, pll));
> +	} else if (IS_CANNONLAKE(dev_priv)) {
>  		/* Configure DPCLKA_CFGCR0 to map the DPLL to the DDI. */
>  		val = I915_READ(DPCLKA_CFGCR0);
>  		val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port);
> @@ -2164,14 +2254,18 @@ static void intel_ddi_clk_disable(struct intel_encoder *encoder)
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	enum port port = encoder->port;
>  
> -	if (IS_CANNONLAKE(dev_priv))
> +	if (IS_ICELAKE(dev_priv)) {
> +		if (port >= PORT_C)
> +			I915_WRITE(DDI_CLK_SEL(port), DDI_CLK_SEL_NONE);
> +	} else if (IS_CANNONLAKE(dev_priv)) {
>  		I915_WRITE(DPCLKA_CFGCR0, I915_READ(DPCLKA_CFGCR0) |
>  			   DPCLKA_CFGCR0_DDI_CLK_OFF(port));
> -	else if (IS_GEN9_BC(dev_priv))
> +	} else if (IS_GEN9_BC(dev_priv)) {
>  		I915_WRITE(DPLL_CTRL2, I915_READ(DPLL_CTRL2) |
>  			   DPLL_CTRL2_DDI_CLK_OFF(port));
> -	else if (INTEL_GEN(dev_priv) < 9)
> +	} else if (INTEL_GEN(dev_priv) < 9) {
>  		I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
> +	}
>  }
>  
>  static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 5d46771d58f6..bc4131a36c10 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -5472,6 +5472,8 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
>  	if (intel_crtc->config->shared_dpll)
>  		intel_enable_shared_dpll(intel_crtc);
>  
> +	icl_map_plls_to_ports(crtc, pipe_config, old_state);

It feels wrong to unconditionally call an ICL function in
haswell_crtc_enable. icl_map_plls_to_ports does return if !IS_ICELAKE,
but the standard everywhere else for platform-specific or
feature-specific function calls is to check the condition before calling
the function, rather than having the function check and early return.

Everything else matches my read of the sequence in BSpec, so with

if (IS_ICELAKE(dev_priv))
	icl_map_plls_to_ports(crtc, pipe_config, old_state);

and dropping the IS_ICELAKE inside of icl_map_plls_to_ports:

Reviewed-by: James Ausmus <james.ausmus@intel.com>

> +
>  	if (intel_crtc_has_dp_encoder(intel_crtc->config))
>  		intel_dp_set_m_n(intel_crtc, M1_N1);
>  
> @@ -5668,6 +5670,8 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
>  	if (!transcoder_is_dsi(cpu_transcoder))
>  		intel_ddi_disable_pipe_clock(intel_crtc->config);
>  
> +	icl_unmap_plls_to_ports(crtc, old_crtc_state, old_state);
> +
>  	intel_encoders_post_disable(crtc, old_crtc_state, old_state);
>  }
>  
> @@ -11301,6 +11305,16 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
>  	PIPE_CONF_CHECK_X(dpll_hw_state.pll9);
>  	PIPE_CONF_CHECK_X(dpll_hw_state.pll10);
>  	PIPE_CONF_CHECK_X(dpll_hw_state.pcsdw12);
> +	PIPE_CONF_CHECK_X(dpll_hw_state.mg_refclkin_ctl);
> +	PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_coreclkctl1);
> +	PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_hsclkctl);
> +	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div0);
> +	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div1);
> +	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_lf);
> +	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_frac_lock);
> +	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_ssc);
> +	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_bias);
> +	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_tdc_coldst_bias);
>  
>  	PIPE_CONF_CHECK_X(dsi_pll.ctrl);
>  	PIPE_CONF_CHECK_X(dsi_pll.div);
> diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> index 51c5ae4e9116..8520a1b0279f 100644
> --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
> +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> @@ -2384,6 +2384,313 @@ static const struct intel_dpll_mgr cnl_pll_mgr = {
>  	.dump_hw_state = cnl_dump_hw_state,
>  };
>  
> +static bool icl_calc_dpll_state(struct intel_crtc_state *crtc_state,
> +				struct intel_encoder *encoder, int clock,
> +				struct intel_dpll_hw_state *pll_state)
> +{
> +	/* TODO */
> +	return true;
> +}
> +
> +static enum port icl_mg_pll_id_to_port(enum intel_dpll_id id)
> +{
> +	return id - DPLL_ID_ICL_MGPLL1 + PORT_C;
> +}
> +
> +static enum intel_dpll_id icl_port_to_mg_pll_id(enum port port)
> +{
> +	return port - PORT_C + DPLL_ID_ICL_MGPLL1;
> +}
> +
> +static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
> +				  struct intel_encoder *encoder, int clock,
> +				  struct intel_dpll_hw_state *pll_state)
> +{
> +	/* TODO */
> +	return true;
> +}
> +
> +static struct intel_shared_dpll *
> +icl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
> +	     struct intel_encoder *encoder)
> +{
> +	struct intel_shared_dpll *pll;
> +	struct intel_dpll_hw_state pll_state = {};
> +	enum port port = encoder->port;
> +	enum intel_dpll_id min, max;
> +	int clock = crtc_state->port_clock;
> +	bool ret;
> +
> +	switch (port) {
> +	case PORT_A:
> +	case PORT_B:
> +		min = DPLL_ID_ICL_DPLL0;
> +		max = DPLL_ID_ICL_DPLL1;
> +		ret = icl_calc_dpll_state(crtc_state, encoder, clock,
> +					  &pll_state);
> +		break;
> +	case PORT_C:
> +	case PORT_D:
> +	case PORT_E:
> +	case PORT_F:
> +		min = max = icl_port_to_mg_pll_id(port);
> +		ret = icl_calc_mg_pll_state(crtc_state, encoder, clock,
> +					    &pll_state);
> +		break;
> +	default:
> +		MISSING_CASE(port);
> +		return NULL;
> +	}
> +
> +	if (!ret) {
> +		DRM_DEBUG_KMS("Could not calculate PLL state.\n");
> +		return NULL;
> +	}
> +
> +	crtc_state->dpll_hw_state = pll_state;
> +
> +	pll = intel_find_shared_dpll(crtc, crtc_state, min, max);
> +	if (!pll) {
> +		DRM_DEBUG_KMS("No PLL selected\n");
> +		return NULL;
> +	}
> +
> +	intel_reference_shared_dpll(pll, crtc_state);
> +
> +	return pll;
> +}
> +
> +static i915_reg_t icl_pll_id_to_enable_reg(enum intel_dpll_id id)
> +{
> +	switch (id) {
> +	default:
> +		MISSING_CASE(id);
> +	case DPLL_ID_ICL_DPLL0:
> +	case DPLL_ID_ICL_DPLL1:
> +		return CNL_DPLL_ENABLE(id);
> +	case DPLL_ID_ICL_MGPLL1:
> +	case DPLL_ID_ICL_MGPLL2:
> +	case DPLL_ID_ICL_MGPLL3:
> +	case DPLL_ID_ICL_MGPLL4:
> +		return MG_PLL_ENABLE(icl_mg_pll_id_to_port(id));
> +	}
> +}
> +
> +static bool icl_pll_get_hw_state(struct drm_i915_private *dev_priv,
> +				 struct intel_shared_dpll *pll,
> +				 struct intel_dpll_hw_state *hw_state)
> +{
> +	enum intel_dpll_id id = pll->id;
> +	uint32_t val;
> +	enum port port;
> +	bool ret = false;
> +
> +	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
> +		return false;
> +
> +	val = I915_READ(icl_pll_id_to_enable_reg(id));
> +	if (!(val & PLL_ENABLE))
> +		goto out;
> +
> +	switch (id) {
> +	case DPLL_ID_ICL_DPLL0:
> +	case DPLL_ID_ICL_DPLL1:
> +		hw_state->cfgcr0 = I915_READ(ICL_DPLL_CFGCR0(id));
> +		hw_state->cfgcr1 = I915_READ(ICL_DPLL_CFGCR1(id));
> +		break;
> +	case DPLL_ID_ICL_MGPLL1:
> +	case DPLL_ID_ICL_MGPLL2:
> +	case DPLL_ID_ICL_MGPLL3:
> +	case DPLL_ID_ICL_MGPLL4:
> +		port = icl_mg_pll_id_to_port(pll->id);
> +		hw_state->mg_refclkin_ctl = I915_READ(MG_REFCLKIN_CTL(port));
> +		hw_state->mg_clktop2_coreclkctl1 =
> +			I915_READ(MG_CLKTOP2_CORECLKCTL1(port));
> +		hw_state->mg_clktop2_hsclkctl =
> +			I915_READ(MG_CLKTOP2_HSCLKCTL(port));
> +		hw_state->mg_pll_div0 = I915_READ(MG_PLL_DIV0(port));
> +		hw_state->mg_pll_div1 = I915_READ(MG_PLL_DIV1(port));
> +		hw_state->mg_pll_lf = I915_READ(MG_PLL_LF(port));
> +		hw_state->mg_pll_frac_lock = I915_READ(MG_PLL_FRAC_LOCK(port));
> +		hw_state->mg_pll_ssc = I915_READ(MG_PLL_SSC(port));
> +		hw_state->mg_pll_bias = I915_READ(MG_PLL_BIAS(port));
> +		hw_state->mg_pll_tdc_coldst_bias =
> +			I915_READ(MG_PLL_TDC_COLDST_BIAS(port));
> +		break;
> +	default:
> +		MISSING_CASE(id);
> +	}
> +
> +	ret = true;
> +out:
> +	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
> +	return ret;
> +}
> +
> +static void icl_dpll_write(struct drm_i915_private *dev_priv,
> +			   struct intel_shared_dpll *pll)
> +{
> +	struct intel_dpll_hw_state *hw_state = &pll->state.hw_state;
> +
> +	I915_WRITE(ICL_DPLL_CFGCR0(pll->id), hw_state->cfgcr0);
> +	I915_WRITE(ICL_DPLL_CFGCR1(pll->id), hw_state->cfgcr1);
> +	POSTING_READ(ICL_DPLL_CFGCR1(pll->id));
> +}
> +
> +static void icl_mg_pll_write(struct drm_i915_private *dev_priv,
> +			     struct intel_shared_dpll *pll)
> +{
> +	struct intel_dpll_hw_state *hw_state = &pll->state.hw_state;
> +	enum port port = icl_mg_pll_id_to_port(pll->id);
> +
> +	I915_WRITE(MG_REFCLKIN_CTL(port), hw_state->mg_refclkin_ctl);
> +	I915_WRITE(MG_CLKTOP2_CORECLKCTL1(port),
> +		   hw_state->mg_clktop2_coreclkctl1);
> +	I915_WRITE(MG_CLKTOP2_HSCLKCTL(port), hw_state->mg_clktop2_hsclkctl);
> +	I915_WRITE(MG_PLL_DIV0(port), hw_state->mg_pll_div0);
> +	I915_WRITE(MG_PLL_DIV1(port), hw_state->mg_pll_div1);
> +	I915_WRITE(MG_PLL_LF(port), hw_state->mg_pll_lf);
> +	I915_WRITE(MG_PLL_FRAC_LOCK(port), hw_state->mg_pll_frac_lock);
> +	I915_WRITE(MG_PLL_SSC(port), hw_state->mg_pll_ssc);
> +	I915_WRITE(MG_PLL_BIAS(port), hw_state->mg_pll_bias);
> +	I915_WRITE(MG_PLL_TDC_COLDST_BIAS(port),
> +		   hw_state->mg_pll_tdc_coldst_bias);
> +	POSTING_READ(MG_PLL_TDC_COLDST_BIAS(port));
> +}
> +
> +static void icl_pll_enable(struct drm_i915_private *dev_priv,
> +			   struct intel_shared_dpll *pll)
> +{
> +	enum intel_dpll_id id = pll->id;
> +	i915_reg_t enable_reg = icl_pll_id_to_enable_reg(id);
> +	uint32_t val;
> +
> +	val = I915_READ(enable_reg);
> +	val |= PLL_POWER_ENABLE;
> +	I915_WRITE(enable_reg, val);
> +
> +	/*
> +	 * The spec says we need to "wait" but it also says it should be
> +	 * immediate.
> +	 */
> +	if (intel_wait_for_register(dev_priv, enable_reg, PLL_POWER_STATE,
> +				    PLL_POWER_STATE, 1))
> +		DRM_ERROR("PLL %d Power not enabled\n", id);
> +
> +	switch (id) {
> +	case DPLL_ID_ICL_DPLL0:
> +	case DPLL_ID_ICL_DPLL1:
> +		icl_dpll_write(dev_priv, pll);
> +		break;
> +	case DPLL_ID_ICL_MGPLL1:
> +	case DPLL_ID_ICL_MGPLL2:
> +	case DPLL_ID_ICL_MGPLL3:
> +	case DPLL_ID_ICL_MGPLL4:
> +		icl_mg_pll_write(dev_priv, pll);
> +		break;
> +	default:
> +		MISSING_CASE(id);
> +	}
> +
> +	/*
> +	 * DVFS pre sequence would be here, but in our driver the cdclk code
> +	 * paths should already be setting the appropriate voltage, hence we do
> +	 * nothign here.
> +	 */
> +
> +	val = I915_READ(enable_reg);
> +	val |= PLL_ENABLE;
> +	I915_WRITE(enable_reg, val);
> +
> +	if (intel_wait_for_register(dev_priv, enable_reg, PLL_LOCK, PLL_LOCK,
> +				    1)) /* 600us actually. */
> +		DRM_ERROR("PLL %d not locked\n", id);
> +
> +	/* DVFS post sequence would be here. See the comment above. */
> +}
> +
> +static void icl_pll_disable(struct drm_i915_private *dev_priv,
> +			    struct intel_shared_dpll *pll)
> +{
> +	enum intel_dpll_id id = pll->id;
> +	i915_reg_t enable_reg = icl_pll_id_to_enable_reg(id);
> +	uint32_t val;
> +
> +	/* The first steps are done by intel_ddi_post_disable(). */
> +
> +	/*
> +	 * DVFS pre sequence would be here, but in our driver the cdclk code
> +	 * paths should already be setting the appropriate voltage, hence we do
> +	 * nothign here.
> +	 */
> +
> +	val = I915_READ(enable_reg);
> +	val &= ~PLL_ENABLE;
> +	I915_WRITE(enable_reg, val);
> +
> +	/* Timeout is actually 1us. */
> +	if (intel_wait_for_register(dev_priv, enable_reg, PLL_LOCK, 0, 1))
> +		DRM_ERROR("PLL %d locked\n", id);
> +
> +	/* DVFS post sequence would be here. See the comment above. */
> +
> +	val = I915_READ(enable_reg);
> +	val &= ~PLL_POWER_ENABLE;
> +	I915_WRITE(enable_reg, val);
> +
> +	/*
> +	 * The spec says we need to "wait" but it also says it should be
> +	 * immediate.
> +	 */
> +	if (intel_wait_for_register(dev_priv, enable_reg, PLL_POWER_STATE, 0,
> +				    1))
> +		DRM_ERROR("PLL %d Power not disabled\n", id);
> +}
> +
> +static void icl_dump_hw_state(struct drm_i915_private *dev_priv,
> +			      struct intel_dpll_hw_state *hw_state)
> +{
> +	DRM_DEBUG_KMS("dpll_hw_state: cfgcr0: 0x%x, cfgcr1: 0x%x, "
> +		      "mg_refclkin_ctl: 0x%x, hg_clktop2_coreclkctl1: 0x%x, "
> +		      "mg_clktop2_hsclkctl: 0x%x, mg_pll_div0: 0x%x, "
> +		      "mg_pll_div2: 0x%x, mg_pll_lf: 0x%x, "
> +		      "mg_pll_frac_lock: 0x%x, mg_pll_ssc: 0x%x, "
> +		      "mg_pll_bias: 0x%x, mg_pll_tdc_coldst_bias: 0x%x\n",
> +		      hw_state->cfgcr0, hw_state->cfgcr1,
> +		      hw_state->mg_refclkin_ctl,
> +		      hw_state->mg_clktop2_coreclkctl1,
> +		      hw_state->mg_clktop2_hsclkctl,
> +		      hw_state->mg_pll_div0,
> +		      hw_state->mg_pll_div1,
> +		      hw_state->mg_pll_lf,
> +		      hw_state->mg_pll_frac_lock,
> +		      hw_state->mg_pll_ssc,
> +		      hw_state->mg_pll_bias,
> +		      hw_state->mg_pll_tdc_coldst_bias);
> +}
> +
> +static const struct intel_shared_dpll_funcs icl_pll_funcs = {
> +	.enable = icl_pll_enable,
> +	.disable = icl_pll_disable,
> +	.get_hw_state = icl_pll_get_hw_state,
> +};
> +
> +static const struct dpll_info icl_plls[] = {
> +	{ "DPLL 0",   DPLL_ID_ICL_DPLL0,  &icl_pll_funcs, 0 },
> +	{ "DPLL 1",   DPLL_ID_ICL_DPLL1,  &icl_pll_funcs, 0 },
> +	{ "MG PLL 1", DPLL_ID_ICL_MGPLL1, &icl_pll_funcs, 0 },
> +	{ "MG PLL 2", DPLL_ID_ICL_MGPLL2, &icl_pll_funcs, 0 },
> +	{ "MG PLL 3", DPLL_ID_ICL_MGPLL3, &icl_pll_funcs, 0 },
> +	{ "MG PLL 4", DPLL_ID_ICL_MGPLL4, &icl_pll_funcs, 0 },
> +	{ NULL, -1, NULL, 0 },
> +};
> +
> +static const struct intel_dpll_mgr icl_pll_mgr = {
> +	.dpll_info = icl_plls,
> +	.get_dpll = icl_get_dpll,
> +	.dump_hw_state = icl_dump_hw_state,
> +};
> +
>  /**
>   * intel_shared_dpll_init - Initialize shared DPLLs
>   * @dev: drm device
> @@ -2397,7 +2704,9 @@ void intel_shared_dpll_init(struct drm_device *dev)
>  	const struct dpll_info *dpll_info;
>  	int i;
>  
> -	if (IS_CANNONLAKE(dev_priv))
> +	if (IS_ICELAKE(dev_priv))
> +		dpll_mgr = &icl_pll_mgr;
> +	else if (IS_CANNONLAKE(dev_priv))
>  		dpll_mgr = &cnl_pll_mgr;
>  	else if (IS_GEN9_BC(dev_priv))
>  		dpll_mgr = &skl_pll_mgr;
> diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
> index f24ccf443d25..eb0e10b24c6f 100644
> --- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
> +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
> @@ -103,6 +103,32 @@ enum intel_dpll_id {
>  	 * @DPLL_ID_SKL_DPLL3: SKL and later DPLL3
>  	 */
>  	DPLL_ID_SKL_DPLL3 = 3,
> +
> +
> +	/**
> +	 * @DPLL_ID_ICL_DPLL0: ICL combo PHY DPLL0
> +	 */
> +	DPLL_ID_ICL_DPLL0 = 0,
> +	/**
> +	 * @DPLL_ID_ICL_DPLL1: ICL combo PHY DPLL1
> +	 */
> +	DPLL_ID_ICL_DPLL1 = 1,
> +	/**
> +	 * @DPLL_ID_ICL_MGPLL1: ICL MG PLL 1 port 1 (C)
> +	 */
> +	DPLL_ID_ICL_MGPLL1 = 2,
> +	/**
> +	 * @DPLL_ID_ICL_MGPLL2: ICL MG PLL 1 port 2 (D)
> +	 */
> +	DPLL_ID_ICL_MGPLL2 = 3,
> +	/**
> +	 * @DPLL_ID_ICL_MGPLL3: ICL MG PLL 1 port 3 (E)
> +	 */
> +	DPLL_ID_ICL_MGPLL3 = 4,
> +	/**
> +	 * @DPLL_ID_ICL_MGPLL4: ICL MG PLL 1 port 4 (F)
> +	 */
> +	DPLL_ID_ICL_MGPLL4 = 5,
>  };
>  #define I915_NUM_PLLS 6
>  
> @@ -135,6 +161,21 @@ struct intel_dpll_hw_state {
>  	/* bxt */
>  	uint32_t ebb0, ebb4, pll0, pll1, pll2, pll3, pll6, pll8, pll9, pll10,
>  		 pcsdw12;
> +
> +	/*
> +	 * ICL uses the following, already defined:
> +	 * uint32_t cfgcr0, cfgcr1;
> +	 */
> +	uint32_t mg_refclkin_ctl;
> +	uint32_t mg_clktop2_coreclkctl1;
> +	uint32_t mg_clktop2_hsclkctl;
> +	uint32_t mg_pll_div0;
> +	uint32_t mg_pll_div1;
> +	uint32_t mg_pll_lf;
> +	uint32_t mg_pll_frac_lock;
> +	uint32_t mg_pll_ssc;
> +	uint32_t mg_pll_bias;
> +	uint32_t mg_pll_tdc_coldst_bias;
>  };
>  
>  /**
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 50874f4035cf..47d40b8c31b4 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1385,6 +1385,12 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
>  u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder);
>  int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
>  				     bool enable);
> +void icl_map_plls_to_ports(struct drm_crtc *crtc,
> +			   struct intel_crtc_state *crtc_state,
> +			   struct drm_atomic_state *old_state);
> +void icl_unmap_plls_to_ports(struct drm_crtc *crtc,
> +			     struct intel_crtc_state *crtc_state,
> +			     struct drm_atomic_state *old_state);
>  
>  unsigned int intel_fb_align_height(const struct drm_framebuffer *fb,
>  				   int plane, unsigned int height);
> -- 
> 2.14.3
> 
> _______________________________________________
> 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] 41+ messages in thread

* Re: [PATCH 03/17] drm/i915/icl: compute the combo PHY (DPLL) HDMI registers
  2018-02-22  3:55 ` [PATCH 03/17] drm/i915/icl: compute the combo PHY (DPLL) HDMI registers Paulo Zanoni
@ 2018-02-28 19:59   ` James Ausmus
  0 siblings, 0 replies; 41+ messages in thread
From: James Ausmus @ 2018-02-28 19:59 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx

On Thu, Feb 22, 2018 at 12:55:05AM -0300, Paulo Zanoni wrote:
> HDMI mode DPLL programming on ICL is the same as CNL, so just reuse
> the CNL code.
> 
> v2:
>  - Properly detect HDMI crtcs.
>  - Rebase after changes to the cnl function (clock * 1000).
> 
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dpll_mgr.c | 34 +++++++++++++++++++++++++++++++---
>  1 file changed, 31 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> index 8520a1b0279f..4d9265d14661 100644
> --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
> +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> @@ -2203,6 +2203,7 @@ cnl_ddi_calculate_wrpll(int clock,
>  			struct skl_wrpll_params *wrpll_params)
>  {
>  	u32 afe_clock = clock * 5;
> +	uint32_t ref_clock;
>  	u32 dco_min = 7998000;
>  	u32 dco_max = 10000000;
>  	u32 dco_mid = (dco_min + dco_max) / 2;
> @@ -2235,8 +2236,12 @@ cnl_ddi_calculate_wrpll(int clock,
>  
>  	cnl_wrpll_get_multipliers(best_div, &pdiv, &qdiv, &kdiv);
>  
> -	cnl_wrpll_params_populate(wrpll_params, best_dco,
> -				  dev_priv->cdclk.hw.ref, pdiv, qdiv, kdiv);
> +	ref_clock = dev_priv->cdclk.hw.ref;
> +	if (IS_ICELAKE(dev_priv) && ref_clock == 38400)

This could use a comment - something like

/* 
 * ICL BSpec states "If reference frequency is 38.4, use 19.2 because
 * the DPLL automatically divides that by 2."
 */


With that -

Reviewed-by: James Ausmus <james.ausmus@intel.com>

> +		ref_clock = 19200;
> +
> +	cnl_wrpll_params_populate(wrpll_params, best_dco, ref_clock, pdiv, qdiv,
> +				  kdiv);
>  
>  	return true;
>  }
> @@ -2388,7 +2393,30 @@ static bool icl_calc_dpll_state(struct intel_crtc_state *crtc_state,
>  				struct intel_encoder *encoder, int clock,
>  				struct intel_dpll_hw_state *pll_state)
>  {
> -	/* TODO */
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	uint32_t cfgcr0, cfgcr1;
> +	struct skl_wrpll_params pll_params = { 0 };
> +	bool ret;
> +
> +	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
> +		ret = cnl_ddi_calculate_wrpll(clock, dev_priv, &pll_params);
> +	else
> +		ret = false; /* TODO */
> +
> +	if (!ret)
> +		return false;
> +
> +	cfgcr0 = DPLL_CFGCR0_DCO_FRACTION(pll_params.dco_fraction) |
> +		 pll_params.dco_integer;
> +
> +	cfgcr1 = DPLL_CFGCR1_QDIV_RATIO(pll_params.qdiv_ratio) |
> +		 DPLL_CFGCR1_QDIV_MODE(pll_params.qdiv_mode) |
> +		 DPLL_CFGCR1_KDIV(pll_params.kdiv) |
> +		 DPLL_CFGCR1_PDIV(pll_params.pdiv) |
> +		 DPLL_CFGCR1_CENTRAL_FREQ_8400;
> +
> +	pll_state->cfgcr0 = cfgcr0;
> +	pll_state->cfgcr1 = cfgcr1;
>  	return true;
>  }
>  
> -- 
> 2.14.3
> 
> _______________________________________________
> 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] 41+ messages in thread

* Re: [PATCH 04/17] drm/i915/icl: compute the combo PHY (DPLL) DP registers
  2018-02-22  3:55 ` [PATCH 04/17] drm/i915/icl: compute the combo PHY (DPLL) DP registers Paulo Zanoni
@ 2018-02-28 20:12   ` James Ausmus
  0 siblings, 0 replies; 41+ messages in thread
From: James Ausmus @ 2018-02-28 20:12 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx

On Thu, Feb 22, 2018 at 12:55:06AM -0300, Paulo Zanoni wrote:
> Just use the hardcoded tables provided by our spec.
> 
> v2: Rebase.
> 
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dpll_mgr.c | 86 ++++++++++++++++++++++++++++++++++-
>  1 file changed, 85 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> index 4d9265d14661..5d7bacc80688 100644
> --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
> +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> @@ -2389,6 +2389,90 @@ static const struct intel_dpll_mgr cnl_pll_mgr = {
>  	.dump_hw_state = cnl_dump_hw_state,
>  };
>  
> +/*
> + * These values alrea already adjusted: they're the bits we write to the
> + * registers, not the logical values.
> + */
> +static const struct skl_wrpll_params icl_dp_combo_pll_24MHz_values[] = {
> +	{ .dco_integer = 0x151, .dco_fraction = 0x4000,		/* [0]: 5.4 */
> +	  .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
> +	{ .dco_integer = 0x151, .dco_fraction = 0x4000,		/* [1]: 2.7 */
> +	  .pdiv = 0x2 /* 3 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0},
> +	{ .dco_integer = 0x151, .dco_fraction = 0x4000,		/* [2]: 1.62 */
> +	  .pdiv = 0x4 /* 5 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0},
> +	{ .dco_integer = 0x151, .dco_fraction = 0x4000,		/* [3]: 3.24 */
> +	  .pdiv = 0x4 /* 5 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
> +	{ .dco_integer = 0x168, .dco_fraction = 0x0000,		/* [4]: 2.16 */
> +	  .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 1, .qdiv_ratio = 2},
> +	{ .dco_integer = 0x168, .dco_fraction = 0x0000,		/* [5]: 4.32 */
> +	  .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0},
> +	{ .dco_integer = 0x195, .dco_fraction = 0x0000,		/* [6]: 6.48 */
> +	  .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
> +	{ .dco_integer = 0x151, .dco_fraction = 0x4000,		/* [7]: 8.1 */
> +	  .pdiv = 0x1 /* 2 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
> +};
> +

Maybe:

/* Also used for 38.4MHz values */

Either way -

Reviewed-by: James Ausmus <james.ausmus@intel.com>

> +static const struct skl_wrpll_params icl_dp_combo_pll_19_2MHz_values[] = {
> +	{ .dco_integer = 0x1A5, .dco_fraction = 0x7000,		/* [0]: 5.4 */
> +	  .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
> +	{ .dco_integer = 0x1A5, .dco_fraction = 0x7000,		/* [1]: 2.7 */
> +	  .pdiv = 0x2 /* 3 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0},
> +	{ .dco_integer = 0x1A5, .dco_fraction = 0x7000,		/* [2]: 1.62 */
> +	  .pdiv = 0x4 /* 5 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0},
> +	{ .dco_integer = 0x1A5, .dco_fraction = 0x7000,		/* [3]: 3.24 */
> +	  .pdiv = 0x4 /* 5 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
> +	{ .dco_integer = 0x1C2, .dco_fraction = 0x0000,		/* [4]: 2.16 */
> +	  .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 1, .qdiv_ratio = 2},
> +	{ .dco_integer = 0x1C2, .dco_fraction = 0x0000,		/* [5]: 4.32 */
> +	  .pdiv = 0x1 /* 2 */, .kdiv = 2, .qdiv_mode = 0, .qdiv_ratio = 0},
> +	{ .dco_integer = 0x1FA, .dco_fraction = 0x2000,		/* [6]: 6.48 */
> +	  .pdiv = 0x2 /* 3 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
> +	{ .dco_integer = 0x1A5, .dco_fraction = 0x7000,		/* [7]: 8.1 */
> +	  .pdiv = 0x1 /* 2 */, .kdiv = 1, .qdiv_mode = 0, .qdiv_ratio = 0},
> +};
> +
> +static bool icl_calc_dp_combo_pll(struct drm_i915_private *dev_priv, int clock,
> +				  struct skl_wrpll_params *pll_params)
> +{
> +	const struct skl_wrpll_params *params;
> +
> +	params = dev_priv->cdclk.hw.ref == 24000 ?
> +			icl_dp_combo_pll_24MHz_values :
> +			icl_dp_combo_pll_19_2MHz_values;
> +
> +	switch (clock) {
> +	case 540000:
> +		*pll_params = params[0];
> +		break;
> +	case 270000:
> +		*pll_params = params[1];
> +		break;
> +	case 162000:
> +		*pll_params = params[2];
> +		break;
> +	case 324000:
> +		*pll_params = params[3];
> +		break;
> +	case 216000:
> +		*pll_params = params[4];
> +		break;
> +	case 432000:
> +		*pll_params = params[5];
> +		break;
> +	case 648000:
> +		*pll_params = params[6];
> +		break;
> +	case 810000:
> +		*pll_params = params[7];
> +		break;
> +	default:
> +		MISSING_CASE(clock);
> +		return false;
> +	}
> +
> +	return true;
> +}
> +
>  static bool icl_calc_dpll_state(struct intel_crtc_state *crtc_state,
>  				struct intel_encoder *encoder, int clock,
>  				struct intel_dpll_hw_state *pll_state)
> @@ -2401,7 +2485,7 @@ static bool icl_calc_dpll_state(struct intel_crtc_state *crtc_state,
>  	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
>  		ret = cnl_ddi_calculate_wrpll(clock, dev_priv, &pll_params);
>  	else
> -		ret = false; /* TODO */
> +		ret = icl_calc_dp_combo_pll(dev_priv, clock, &pll_params);
>  
>  	if (!ret)
>  		return false;
> -- 
> 2.14.3
> 
> _______________________________________________
> 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] 41+ messages in thread

* Re: [PATCH 05/17] drm/i915/icl: compute the MG PLL registers
  2018-02-22  3:55 ` [PATCH 05/17] drm/i915/icl: compute the MG PLL registers Paulo Zanoni
@ 2018-03-01 23:35   ` Manasi Navare
  0 siblings, 0 replies; 41+ messages in thread
From: Manasi Navare @ 2018-03-01 23:35 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx

On Thu, Feb 22, 2018 at 12:55:07AM -0300, Paulo Zanoni wrote:
> This implements the "MG PLL Programming" sequence from our spec. The
> biggest problem was that the spec assumes real numbers, so we had to
> adjust some numbers and alculations due to the fact that the Kernel
> prefers to deal with integers.
> 
> I recommend grabbing some coffee, a pen and paper before reviewing
> this patch.
> 
> v2:
>  - Correctly identify DP encoders after upstream change.
>  - Small checkpatch issues.
>  - Rebase.
> 
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dpll_mgr.c | 217 +++++++++++++++++++++++++++++++++-
>  1 file changed, 216 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> index 5d7bacc80688..9a2965e0b883 100644
> --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
> +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> @@ -2514,11 +2514,226 @@ static enum intel_dpll_id icl_port_to_mg_pll_id(enum port port)
>  	return port - PORT_C + DPLL_ID_ICL_MGPLL1;
>  }
>  
> +static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
> +				     uint32_t *target_dco_khz,
> +				     struct intel_dpll_hw_state *state)
> +{
> +	uint32_t dco_min_freq, dco_max_freq;
> +	int div1_vals[] = {7, 5, 3, 2};
> +	unsigned int i;
> +	int div2;
> +
> +	dco_min_freq = is_dp ? 8100000 : use_ssc ? 8000000 : 7992000;
> +	dco_max_freq = is_dp ? 8100000 : 10000000;
> +
> +	for (i = 0; i < ARRAY_SIZE(div1_vals); i++) {
> +		int div1 = div1_vals[i];
> +
> +		for (div2 = 10; div2 > 0; div2--) {
> +			int dco = div1 * div2 * clock_khz * 5;
> +			int a_divratio, tlinedrv, inputsel, hsdiv;
> +
> +			if (dco < dco_min_freq || dco > dco_max_freq)
> +				continue;
> +
> +			if (div2 >= 2) {
> +				a_divratio = is_dp ? 10 : 5;
> +				tlinedrv = 2;
> +			} else {
> +				a_divratio = 5;
> +				tlinedrv = 0;
> +			}
> +			inputsel = is_dp ? 0 : 1;
> +
> +			switch (div1) {
> +			default:
> +				MISSING_CASE(div1);
> +			case 2:
> +				hsdiv = 0;
> +				break;
> +			case 3:
> +				hsdiv = 1;
> +				break;
> +			case 5:
> +				hsdiv = 2;
> +				break;
> +			case 7:
> +				hsdiv = 3;
> +				break;
> +			}
> +
> +			*target_dco_khz = dco;
> +
> +			state->mg_refclkin_ctl = MG_REFCLKIN_CTL_OD_2_MUX(1);
> +
> +			state->mg_clktop2_coreclkctl1 =
> +				MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO(a_divratio);
> +
> +			state->mg_clktop2_hsclkctl =
> +				MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL(tlinedrv) |
> +				MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL(inputsel) |
> +				MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO(hsdiv) |
> +				MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO(div2);
> +
> +			return true;
> +		}
> +	}
> +
> +	return false;
> +}
> +
> +/*
> + * The specification for this function uses real numbers, so the math had to be
> + * adapted to integer-only calculation, that's why it looks so different.
> + */
>  static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
>  				  struct intel_encoder *encoder, int clock,
>  				  struct intel_dpll_hw_state *pll_state)
>  {
> -	/* TODO */
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	int refclk_khz = dev_priv->cdclk.hw.ref;
> +	uint32_t dco_khz, m1div, m2div_int, m2div_rem, m2div_frac;
> +	uint32_t iref_ndiv, iref_trim, iref_pulse_w;
> +	uint32_t prop_coeff, int_coeff;
> +	uint32_t tdc_targetcnt, feedfwgain;
> +	uint64_t ssc_stepsize, ssc_steplen, ssc_steplog;
> +	uint64_t tmp;
> +	bool use_ssc = false;
> +	bool is_dp = !intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI);
> +
> +	if (!icl_mg_pll_find_divisors(clock, is_dp, use_ssc, &dco_khz,
> +				      pll_state)) {
> +		DRM_DEBUG_KMS("Failed to find divisors for clock %d\n", clock);
> +		return false;
> +	}
> +
> +	m1div = 2;
> +	m2div_int = dco_khz / (refclk_khz * m1div);
> +	if (m2div_int > 255) {
> +		m1div = 4;
> +		m2div_int = dco_khz / (refclk_khz * m1div);
> +		if (m2div_int > 255) {
> +			DRM_DEBUG_KMS("Failed to find mdiv for clock %d\n",
> +				      clock);
> +			return false;
> +		}
> +	}
> +	m2div_rem = dco_khz % (refclk_khz * m1div);
> +
> +	tmp = (uint64_t)m2div_rem * (1 << 22);
> +	do_div(tmp, refclk_khz * m1div);
> +	m2div_frac = tmp;
> +
> +	switch (refclk_khz) {
> +	case 19200:
> +		iref_ndiv = 1;
> +		iref_trim = 28;
> +		iref_pulse_w = 1;
> +		break;
> +	case 24000:
> +		iref_ndiv = 1;
> +		iref_trim = 25;
> +		iref_pulse_w = 2;
> +		break;
> +	case 38400:
> +		iref_ndiv = 2;
> +		iref_trim = 28;
> +		iref_pulse_w = 1;
> +		break;
> +	default:
> +		MISSING_CASE(refclk_khz);
> +		return false;
> +	}
> +
> +	/*
> +	 * tdc_res = 0.000003
> +	 * tdc_targetcnt = int(2 / (tdc_res * 8 * 50 * 1.1) / refclk_mhz + 0.5)
> +	 *
> +	 * The multiplication by 1000 is due to refclk MHz to KHz conversion.
> +	 * 0.000003 * 8 * 50 * 1.1 = 0.00132, also known as 132 / 100000.
> +	 * The 0.5 transformed to 5 results in a multiplication by 10 and the
> +	 * last division by 10.
> +	 */

Just a nit here in the comment above since that definitely got me confused with the
refclk in Mhz to Khz conversion. So in the equation below, we are converting the value in Khz to Mhz
so its a division by 1000 that becomes a multiplier by 1000 in the numerator. So I think the comment should
be updated to clarify this.

Apart from this, double checked all the calculations from the spec and look good. So

Reviewed-by; Manasi Navare <manasi.d.navare@intel.com>

Manasi

> +	tdc_targetcnt = (2 * 1000 * 100000 * 10 / (132 * refclk_khz) + 5) / 10;
> +
> +	/*
> +	 * Here we divide dco_khz by 10 in order to allow the dividend to fit in
> +	 * 32 bits. That's not a problem since we round the division down
> +	 * anyway.
> +	 */
> +	feedfwgain = (use_ssc || m2div_rem > 0) ?
> +		m1div * 1000000 * 100 / (dco_khz * 3 / 10) : 0;
> +
> +	if (dco_khz >= 9000000) {
> +		prop_coeff = 5;
> +		int_coeff = 10;
> +	} else {
> +		prop_coeff = 4;
> +		int_coeff = 8;
> +	}
> +
> +	if (use_ssc) {
> +		tmp = (uint64_t)dco_khz * 47 * 32;
> +		do_div(tmp, refclk_khz * m1div * 10000);
> +		ssc_stepsize = tmp;
> +
> +		tmp = (uint64_t)dco_khz * 1000;
> +		ssc_steplen = DIV_ROUND_UP_ULL(tmp, 32 * 2 * 32);
> +	} else {
> +		ssc_stepsize = 0;
> +		ssc_steplen = 0;
> +	}
> +	ssc_steplog = 4;
> +
> +	pll_state->mg_pll_div0 = (m2div_rem > 0 ? MG_PLL_DIV0_FRACNEN_H : 0) |
> +				  MG_PLL_DIV0_FBDIV_FRAC(m2div_frac) |
> +				  MG_PLL_DIV0_FBDIV_INT(m2div_int);
> +
> +	pll_state->mg_pll_div1 = MG_PLL_DIV1_IREF_NDIVRATIO(iref_ndiv) |
> +				 MG_PLL_DIV1_DITHER_DIV_2 |
> +				 MG_PLL_DIV1_NDIVRATIO(1) |
> +				 MG_PLL_DIV1_FBPREDIV(m1div);
> +
> +	pll_state->mg_pll_lf = MG_PLL_LF_TDCTARGETCNT(tdc_targetcnt) |
> +			       MG_PLL_LF_AFCCNTSEL_512 |
> +			       MG_PLL_LF_GAINCTRL(1) |
> +			       MG_PLL_LF_INT_COEFF(int_coeff) |
> +			       MG_PLL_LF_PROP_COEFF(prop_coeff);
> +
> +	pll_state->mg_pll_frac_lock = MG_PLL_FRAC_LOCK_TRUELOCK_CRIT_32 |
> +				      MG_PLL_FRAC_LOCK_EARLYLOCK_CRIT_32 |
> +				      MG_PLL_FRAC_LOCK_LOCKTHRESH(10) |
> +				      MG_PLL_FRAC_LOCK_DCODITHEREN |
> +				      MG_PLL_FRAC_LOCK_FEEDFWRDGAIN(feedfwgain);
> +	if (use_ssc || m2div_rem > 0)
> +		pll_state->mg_pll_frac_lock |= MG_PLL_FRAC_LOCK_FEEDFWRDCAL_EN;
> +
> +	pll_state->mg_pll_ssc = (use_ssc ? MG_PLL_SSC_EN : 0) |
> +				MG_PLL_SSC_TYPE(2) |
> +				MG_PLL_SSC_STEPLENGTH(ssc_steplen) |
> +				MG_PLL_SSC_STEPNUM(ssc_steplog) |
> +				MG_PLL_SSC_FILEN |
> +				MG_PLL_SSC_STEPSIZE(ssc_stepsize);
> +
> +	pll_state->mg_pll_tdc_coldst_bias = MG_PLL_TDC_COLDST_COLDSTART;
> +
> +	if (refclk_khz != 38400) {
> +		pll_state->mg_pll_tdc_coldst_bias |=
> +			MG_PLL_TDC_COLDST_IREFINT_EN |
> +			MG_PLL_TDC_COLDST_REFBIAS_START_PULSE_W(iref_pulse_w) |
> +			MG_PLL_TDC_COLDST_COLDSTART |
> +			MG_PLL_TDC_TDCCOVCCORR_EN |
> +			MG_PLL_TDC_TDCSEL(3);
> +
> +		pll_state->mg_pll_bias = MG_PLL_BIAS_BIAS_GB_SEL(3) |
> +					 MG_PLL_BIAS_INIT_DCOAMP(0x3F) |
> +					 MG_PLL_BIAS_BIAS_BONUS(10) |
> +					 MG_PLL_BIAS_BIASCAL_EN |
> +					 MG_PLL_BIAS_CTRIM(12) |
> +					 MG_PLL_BIAS_VREF_RDAC(4) |
> +					 MG_PLL_BIAS_IREFTRIM(iref_trim);
> +	}
> +
>  	return true;
>  }
>  
> -- 
> 2.14.3
> 
> _______________________________________________
> 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] 41+ messages in thread

* Re: [PATCH 01/17] drm/i915/icl: add definitions for the ICL PLL registers
  2018-02-27 22:22   ` James Ausmus
@ 2018-03-21 21:34     ` Paulo Zanoni
  0 siblings, 0 replies; 41+ messages in thread
From: Paulo Zanoni @ 2018-03-21 21:34 UTC (permalink / raw)
  To: James Ausmus; +Cc: intel-gfx, arthur.j.runyan

Em Ter, 2018-02-27 às 14:22 -0800, James Ausmus escreveu:
> On Thu, Feb 22, 2018 at 12:55:03AM -0300, Paulo Zanoni wrote:
> > There's a lot of code for the PLL enabling, so let's first only
> > introduce the register definitions in order to make patch reviewing
> > a
> > little easier.
> > 
> > v2: Coding style (Jani).
> > v3: Preparation for upstreaming.
> > 
> > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_reg.h | 149
> > ++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 149 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h
> > b/drivers/gpu/drm/i915/i915_reg.h
> > index 1412abcb27d4..f62335c4a748 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -8783,6 +8783,12 @@ enum skl_power_gate {
> >  #define  PORT_CLK_SEL_NONE		(7<<29)
> >  #define  PORT_CLK_SEL_MASK		(7<<29)
> >  
> > +/* On ICL+ this is the same as PORT_CLK_SEL, but all bits change.
> > */
> > +#define DDI_CLK_SEL(port)		PORT_CLK_SEL(port)
> > +#define  DDI_CLK_SEL_NONE		(0x0 << 28)
> > +#define  DDI_CLK_SEL_MG			(0x8 << 28)
> > +#define  DDI_CLK_SEL_MASK		(0xF << 28)
> > +
> >  /* Transcoder clock selection */
> >  #define _TRANS_CLK_SEL_A		0x46140
> >  #define _TRANS_CLK_SEL_B		0x46144
> > @@ -8913,6 +8919,7 @@ enum skl_power_gate {
> >   * CNL Clocks
> >   */
> >  #define DPCLKA_CFGCR0				_MMIO(0x6C200
> > )
> > +#define DPCLKA_CFGCR0_ICL			_MMIO(0x164280)
> >  #define  DPCLKA_CFGCR0_DDI_CLK_OFF(port)	(1 << ((port)
> > ==  PORT_F ? 23 : \
> >  						      (port)+10))
> >  #define  DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port)	((port) ==
> > PORT_F ? 21 : \
> > @@ -8929,10 +8936,141 @@ enum skl_power_gate {
> >  #define  PLL_POWER_STATE	(1 << 26)
> >  #define CNL_DPLL_ENABLE(pll)	_MMIO_PLL(pll, DPLL0_ENABLE,
> > DPLL1_ENABLE)
> >  
> > +#define _MG_PLL1_ENABLE		0x46030
> > +#define _MG_PLL2_ENABLE		0x46034
> > +#define _MG_PLL3_ENABLE		0x46038
> > +#define _MG_PLL4_ENABLE		0x4603C
> > +/* Bits are the same as DPLL0_ENABLE */
> > +#define MG_PLL_ENABLE(port)	_MMIO_PORT((port) - PORT_C,
> > _MG_PLL1_ENABLE, \
> > +					   _MG_PLL2_ENABLE)
> > +
> > +#define _MG_REFCLKIN_CTL_PORT1				0x16
> > 892C
> > +#define _MG_REFCLKIN_CTL_PORT2				0x16
> > 992C
> > +#define _MG_REFCLKIN_CTL_PORT3				0x16
> > A92C
> > +#define _MG_REFCLKIN_CTL_PORT4				0x16
> > B92C
> > +#define   MG_REFCLKIN_CTL_OD_2_MUX(x)			((x)
> > << 8)
> > +#define MG_REFCLKIN_CTL(port) _MMIO_PORT((port) - PORT_C, \
> > +					 _MG_REFCLKIN_CTL_PORT1, \
> > +					 _MG_REFCLKIN_CTL_PORT2)
> > +
> > +#define _MG_CLKTOP2_CORECLKCTL1_PORT1			0x169
> > 0D8
> > +#define _MG_CLKTOP2_CORECLKCTL1_PORT2			0x16B
> > 0D8
> > +#define _MG_CLKTOP2_CORECLKCTL1_PORT3			0x16D
> > 0D8
> > +#define _MG_CLKTOP2_CORECLKCTL1_PORT4			0x16F
> > 0D8
> > +#define   MG_CLKTOP2_CORECLKCTL1_B_DIVRATIO(x)		((x)
> > << 16)
> > +#define   MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO(x)		((x)
> > << 8)
> > +#define MG_CLKTOP2_CORECLKCTL1(port) _MMIO_PORT((port) - PORT_C, \
> > +						_MG_CLKTOP2_CORECL
> > KCTL1_PORT1, \
> > +						_MG_CLKTOP2_CORECL
> > KCTL1_PORT2)
> 
> BSpec 21736 says this register is unused and pending deletion, but in
> 20845 it also
> says to program this register. Art, can you shed any light here?
> 

21736 is for a different platform. If you filter for ICL the page
becomes blank.


> Hmm, on further study, it looks like the MG_CLKTOP_CORECLKCTL1 group
> (21340) names the port instances as MG_CLKTOP2_CORECLKCTL1_PORTx, so
> it
> looks like *that* is the actual register group you want (and the
> register bit definitions match as well), 

And it's the one that opens when you click it from the icl clocks page
:).

> but, in that case, the
> addresses are wrong - they need to be: 0x1688D8, 0x1698D8, 0x16A8D8,
> and
> 0x16B8D8, respectively.

You're correct, I got this wrong.


> 
> > +
> > +#define _MG_CLKTOP2_HSCLKCTL_PORT1			0x1688D4
> > +#define _MG_CLKTOP2_HSCLKCTL_PORT2			0x1698D4
> > +#define _MG_CLKTOP2_HSCLKCTL_PORT3			0x16A8D4
> > +#define _MG_CLKTOP2_HSCLKCTL_PORT4			0x16B8D4
> > +#define   MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL(x)		((x)
> > << 16)
> > +#define   MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL(x)	((x) <<
> > 14)
> > +#define   MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO(x)		((x)
> > << 12)
> > +#define   MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO(x)		((x)
> > << 8)
> > +#define MG_CLKTOP2_HSCLKCTL(port) _MMIO_PORT((port) - PORT_C, \
> > +					     _MG_CLKTOP2_HSCLKCTL_
> > PORT1, \
> > +					     _MG_CLKTOP2_HSCLKCTL_
> > PORT2)
> > +
> > +#define _MG_PLL_DIV0_PORT1				0x168A00
> > +#define _MG_PLL_DIV0_PORT2				0x169A00
> > +#define _MG_PLL_DIV0_PORT3				0x16AA00
> > +#define _MG_PLL_DIV0_PORT4				0x16BA00
> > +#define   MG_PLL_DIV0_FRACNEN_H				(1
> > << 30)
> > +#define   MG_PLL_DIV0_FBDIV_FRAC(x)			((x) <<
> > 8)
> > +#define   MG_PLL_DIV0_FBDIV_INT(x)			((x) <<
> > 0)
> > +#define MG_PLL_DIV0(port) _MMIO_PORT((port) - PORT_C,
> > _MG_PLL_DIV0_PORT1, \
> > +				     _MG_PLL_DIV0_PORT2)
> > +
> > +#define _MG_PLL_DIV1_PORT1				0x168A04
> > +#define _MG_PLL_DIV1_PORT2				0x169A04
> > +#define _MG_PLL_DIV1_PORT3				0x16AA04
> > +#define _MG_PLL_DIV1_PORT4				0x16BA04
> > +#define   MG_PLL_DIV1_IREF_NDIVRATIO(x)			((x
> > ) << 16)
> > +#define   MG_PLL_DIV1_DITHER_DIV_1			(0 <<
> > 12)
> > +#define   MG_PLL_DIV1_DITHER_DIV_2			(1 <<
> > 12)
> > +#define   MG_PLL_DIV1_DITHER_DIV_4			(2 <<
> > 12)
> > +#define   MG_PLL_DIV1_DITHER_DIV_8			(3 <<
> > 12)
> > +#define   MG_PLL_DIV1_NDIVRATIO(x)			((x) <<
> > 4)
> > +#define   MG_PLL_DIV1_FBPREDIV(x)			((x) <<
> > 0)
> > +#define MG_PLL_DIV1(port) _MMIO_PORT((port) - PORT_C,
> > _MG_PLL_DIV1_PORT1, \
> > +				     _MG_PLL_DIV1_PORT2)
> > +
> > +#define _MG_PLL_LF_PORT1				0x168A08
> > +#define _MG_PLL_LF_PORT2				0x169A08
> > +#define _MG_PLL_LF_PORT3				0x16AA08
> > +#define _MG_PLL_LF_PORT4				0x16BA08
> > +#define   MG_PLL_LF_TDCTARGETCNT(x)			((x) <<
> > 24)
> > +#define   MG_PLL_LF_AFCCNTSEL_256			(0 << 20)
> > +#define   MG_PLL_LF_AFCCNTSEL_512			(1 << 20)
> > +#define   MG_PLL_LF_GAINCTRL(x)				((x
> > ) << 16)
> > +#define   MG_PLL_LF_INT_COEFF(x)			((x) << 8)
> > +#define   MG_PLL_LF_PROP_COEFF(x)			((x) <<
> > 0)
> > +#define MG_PLL_LF(port) _MMIO_PORT((port) - PORT_C,
> > _MG_PLL_LF_PORT1, \
> > +				   _MG_PLL_LF_PORT2)
> > +
> > +#define _MG_PLL_FRAC_LOCK_PORT1				0x1
> > 68A0C
> > +#define _MG_PLL_FRAC_LOCK_PORT2				0x1
> > 69A0C
> > +#define _MG_PLL_FRAC_LOCK_PORT3				0x1
> > 6AA0C
> > +#define _MG_PLL_FRAC_LOCK_PORT4				0x1
> > 6BA0C
> > +#define   MG_PLL_FRAC_LOCK_TRUELOCK_CRIT_32		(1 <<
> > 18)
> > +#define   MG_PLL_FRAC_LOCK_EARLYLOCK_CRIT_32		(1 <<
> > 16)
> > +#define   MG_PLL_FRAC_LOCK_LOCKTHRESH(x)		((x) <<
> > 11)
> > +#define   MG_PLL_FRAC_LOCK_DCODITHEREN			(1
> > << 10)
> > +#define   MG_PLL_FRAC_LOCK_FEEDFWRDCAL_EN		(1 << 8)
> > +#define   MG_PLL_FRAC_LOCK_FEEDFWRDGAIN(x)		((x) <<
> > 0)
> > +#define MG_PLL_FRAC_LOCK(port) _MMIO_PORT((port) - PORT_C, \
> > +					  _MG_PLL_FRAC_LOCK_PORT1,
> > \
> > +					  _MG_PLL_FRAC_LOCK_PORT2)
> > +
> > +#define _MG_PLL_SSC_PORT1				0x168A10
> > +#define _MG_PLL_SSC_PORT2				0x169A10
> > +#define _MG_PLL_SSC_PORT3				0x16AA10
> > +#define _MG_PLL_SSC_PORT4				0x16BA10
> > +#define   MG_PLL_SSC_EN					(1
> > << 28)
> > +#define   MG_PLL_SSC_TYPE(x)				((x)
> > << 26)
> > +#define   MG_PLL_SSC_STEPLENGTH(x)			((x) <<
> > 16)
> > +#define   MG_PLL_SSC_STEPNUM(x)				((x
> > ) << 10)
> > +#define   MG_PLL_SSC_FILEN				(1 << 9)
> 
> 		^^^
> This should be MG_PLL_SSC_FLLEN

-ENOGLASSES when I wrote this

> 
> > +#define   MG_PLL_SSC_STEPSIZE(x)			((x) << 0)
> > +#define MG_PLL_SSC(port) _MMIO_PORT((port) - PORT_C,
> > _MG_PLL_SSC_PORT1, \
> > +				    _MG_PLL_SSC_PORT2)
> > +
> > +#define _MG_PLL_BIAS_PORT1				0x168A14
> > +#define _MG_PLL_BIAS_PORT2				0x169A14
> > +#define _MG_PLL_BIAS_PORT3				0x16AA14
> > +#define _MG_PLL_BIAS_PORT4				0x16BA14
> > +#define   MG_PLL_BIAS_BIAS_GB_SEL(x)			((x)
> > << 30)
> > +#define   MG_PLL_BIAS_INIT_DCOAMP(x)			((x)
> > << 24)
> > +#define   MG_PLL_BIAS_BIAS_BONUS(x)			((x) <<
> > 16)
> > +#define   MG_PLL_BIAS_BIASCAL_EN			(1 << 15)
> > +#define   MG_PLL_BIAS_CTRIM(x)				((x)
> > << 8)
> > +#define   MG_PLL_BIAS_VREF_RDAC(x)			((x) <<
> > 5)
> > +#define   MG_PLL_BIAS_IREFTRIM(x)			((x) <<
> > 0)
> > +#define MG_PLL_BIAS(port) _MMIO_PORT((port) - PORT_C,
> > _MG_PLL_BIAS_PORT1, \
> > +				     _MG_PLL_BIAS_PORT2)
> > +
> > +#define _MG_PLL_TDC_COLDST_BIAS_PORT1			0x168
> > A18
> > +#define _MG_PLL_TDC_COLDST_BIAS_PORT2			0x169
> > A18
> > +#define _MG_PLL_TDC_COLDST_BIAS_PORT3			0x16A
> > A18
> > +#define _MG_PLL_TDC_COLDST_BIAS_PORT4			0x16B
> > A18
> > +#define   MG_PLL_TDC_COLDST_IREFINT_EN			(1
> > << 27)
> > +#define   MG_PLL_TDC_COLDST_REFBIAS_START_PULSE_W(x)	((x)
> > << 17)
> > +#define   MG_PLL_TDC_COLDST_COLDSTART			(1 <<
> > 16)
> > +#define   MG_PLL_TDC_TDCCOVCCORR_EN			(1 <<
> > 2)
> 
> 		^^^^
> Should be MG_PLL_TDC_TDCOVCCORR_EN

Right.

Thanks for the review!

> 
> > +#define   MG_PLL_TDC_TDCSEL(x)				((x)
> > << 0)
> > +#define MG_PLL_TDC_COLDST_BIAS(port) _MMIO_PORT((port) - PORT_C, \
> > +						_MG_PLL_TDC_COLDST
> > _BIAS_PORT1, \
> > +						_MG_PLL_TDC_COLDST
> > _BIAS_PORT2)
> > +
> >  #define _CNL_DPLL0_CFGCR0		0x6C000
> >  #define _CNL_DPLL1_CFGCR0		0x6C080
> >  #define  DPLL_CFGCR0_HDMI_MODE		(1 << 30)
> >  #define  DPLL_CFGCR0_SSC_ENABLE		(1 << 29)
> > +#define  DPLL_CFGCR0_SSC_ENABLE_ICL	(1 << 25)
> >  #define  DPLL_CFGCR0_LINK_RATE_MASK	(0xf << 25)
> >  #define  DPLL_CFGCR0_LINK_RATE_2700	(0 << 25)
> >  #define  DPLL_CFGCR0_LINK_RATE_1350	(1 << 25)
> > @@ -8966,8 +9104,19 @@ enum skl_power_gate {
> >  #define  DPLL_CFGCR1_PDIV_5		(4 << 2)
> >  #define  DPLL_CFGCR1_PDIV_7		(8 << 2)
> >  #define  DPLL_CFGCR1_CENTRAL_FREQ	(3 << 0)
> > +#define  DPLL_CFGCR1_CENTRAL_FREQ_8400	(3 << 0)
> >  #define CNL_DPLL_CFGCR1(pll)		_MMIO_PLL(pll,
> > _CNL_DPLL0_CFGCR1, _CNL_DPLL1_CFGCR1)
> >  
> > +#define _ICL_DPLL0_CFGCR0		0x164000
> > +#define _ICL_DPLL1_CFGCR0		0x164080
> > +#define ICL_DPLL_CFGCR0(pll)		_MMIO_PLL(pll,
> > _ICL_DPLL0_CFGCR0, \
> > +						  _ICL_DPLL1_CFGCR
> > 0)
> > +
> > +#define _ICL_DPLL0_CFGCR1		0x164004
> > +#define _ICL_DPLL1_CFGCR1		0x164084
> > +#define ICL_DPLL_CFGCR1(pll)		_MMIO_PLL(pll,
> > _ICL_DPLL0_CFGCR1, \
> > +						  _ICL_DPLL1_CFGCR
> > 1)
> > +
> >  /* BXT display engine PLL */
> >  #define BXT_DE_PLL_CTL			_MMIO(0x6d000)
> >  #define   BXT_DE_PLL_RATIO(x)		(x)	/*
> > {60,65,100} * 19.2MHz */
> > -- 
> > 2.14.3
> > 
> > _______________________________________________
> > 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] 41+ messages in thread

* Re: [PATCH 08/17] drm/i915/icl: Implement voltage swing programming sequence for Combo PHY DDI
  2018-02-22  3:55 ` [PATCH 08/17] drm/i915/icl: Implement voltage swing programming sequence for Combo PHY DDI Paulo Zanoni
@ 2018-03-22 22:23   ` Paulo Zanoni
  2018-03-23  0:10   ` Paulo Zanoni
  2018-04-06  0:20   ` Rodrigo Vivi
  2 siblings, 0 replies; 41+ messages in thread
From: Paulo Zanoni @ 2018-03-22 22:23 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

Em Qui, 2018-02-22 às 00:55 -0300, Paulo Zanoni escreveu:
> From: Manasi Navare <manasi.d.navare@intel.com>
> 
> This is an important part of the DDI initalization as well as
> for changing the voltage during DisplayPort link training.
> 
> The Voltage swing seqeuence is similar to Cannonlake.
> However it has different register definitions and hence
> it makes sense to create a separate vswing sequence and
> program functions for ICL to leave room for more changes
> in case the Bspec changes later and deviates from CNL sequence.
> 
> v2:
> Use ~TAP3_DISABLE for enbaling that bit (Jani Nikula)
> 
> v3:
> * Use dw4_scaling column for PORT_TX_DW4 values (Rodrigo)
> 
> v4:
> * Call it combo_vswing, use switch statement (Paulo)
> 
> v5 (from Paulo):
> * Fix a typo.
> * s/rate < 600000/rate <= 600000/.
> * Don't remove blank lines that should be there.
> 
> v6:
> * Rebased by Rodrigo on top of Cannonlake changes
>   where non vswing sequences are not aligned with iboost
>   anymore.
> 
> v7: Another rebase after an upstream rework.
> 
> v8 (from Paulo):
> * Adjust the code to the upstream output type changes.
> * Squash the patch that moved some functions up.
> * Merge both get_combo_buf_trans functions in order to simplify the
>   code.
> * Change the changelog format.
> 
> Cc: Jani Nikula <jani.nikula@linux.intel.com>
> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v5)
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 189
> ++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 186 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c
> b/drivers/gpu/drm/i915/intel_ddi.c
> index 0a4683991ec2..c38873cb98ca 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -849,6 +849,45 @@ cnl_get_buf_trans_edp(struct drm_i915_private
> *dev_priv, int *n_entries)
>  	}
>  }
>  
> +static const struct icl_combo_phy_ddi_buf_trans *
> +icl_get_combo_buf_trans(struct drm_i915_private *dev_priv, enum port
> port,
> +			int type, int *n_entries)
> +{
> +	u32 voltage = I915_READ(ICL_PORT_COMP_DW3(port)) &
> VOLTAGE_INFO_MASK;
> +
> +	if (type == INTEL_OUTPUT_EDP && dev_priv-
> >vbt.edp.low_vswing) {
> +		switch (voltage) {
> +		case VOLTAGE_INFO_0_85V:
> +			*n_entries =
> ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_85V);
> +			return
> icl_combo_phy_ddi_translations_edp_0_85V;
> +		case VOLTAGE_INFO_0_95V:
> +			*n_entries =
> ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_95V);
> +			return
> icl_combo_phy_ddi_translations_edp_0_95V;
> +		case VOLTAGE_INFO_1_05V:
> +			*n_entries =
> ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_1_05V);
> +			return
> icl_combo_phy_ddi_translations_edp_1_05V;
> +		default:
> +			MISSING_CASE(voltage);
> +			return NULL;
> +		}
> +	} else {
> +		switch (voltage) {
> +		case VOLTAGE_INFO_0_85V:
> +			*n_entries =
> ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_85V);
> +			return
> icl_combo_phy_ddi_translations_dp_hdmi_0_85V;
> +		case VOLTAGE_INFO_0_95V:
> +			*n_entries =
> ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_95V);
> +			return
> icl_combo_phy_ddi_translations_dp_hdmi_0_95V;
> +		case VOLTAGE_INFO_1_05V:
> +			*n_entries =
> ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_1_05V);
> +			return
> icl_combo_phy_ddi_translations_dp_hdmi_1_05V;
> +		default:
> +			MISSING_CASE(voltage);
> +			return NULL;
> +		}
> +	}
> +}
> +
>  static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv,
> enum port port)
>  {
>  	int n_entries, level, default_entry;
> @@ -2178,6 +2217,144 @@ static void cnl_ddi_vswing_sequence(struct
> intel_encoder *encoder,
>  	I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val);
>  }
>  
> +static void icl_ddi_combo_vswing_program(struct drm_i915_private
> *dev_priv,
> +					 u32 level, enum port port,
> int type)
> +{
> +	const struct icl_combo_phy_ddi_buf_trans *ddi_translations =
> NULL;
> +	u32 n_entries, val;
> +	int ln;
> +
> +	ddi_translations = icl_get_combo_buf_trans(dev_priv, port,
> type,
> +						   &n_entries);
> +	if (!ddi_translations)
> +		return;
> +
> +	if (level >= n_entries) {
> +		DRM_DEBUG_KMS("DDI translation not found for level
> %d. Using %d instead.", level, n_entries - 1);
> +		level = n_entries - 1;
> +	}
> +
> +	/* Set PORT_TX_DW5 Scaling Mode Sel to 110b. */
> +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> +	val &= ~SCALING_MODE_SEL_MASK;
> +	val |= SCALING_MODE_SEL(0x6);

This should be RTERM_SEL.


> +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> +
> +	/* Program PORT_TX_DW5 */
> +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> +	/* Set DisableTap2 and DisableTap3 if MIPI DSI
> +	 * Clear DisableTap2 and DisableTap3 for all other Ports
> +	 */
> +	if (type == INTEL_OUTPUT_DSI) {
> +		val |= TAP2_DISABLE;
> +		val |= TAP3_DISABLE;
> +	} else {
> +		val &= ~TAP2_DISABLE;
> +		val &= ~TAP3_DISABLE;
> +	}
> +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> +
> +	/* Program PORT_TX_DW2 */
> +	val = I915_READ(ICL_PORT_TX_DW2_LN0(port));
> +	val &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
> +		 RCOMP_SCALAR_MASK);
> +	val |=
> SWING_SEL_UPPER(ddi_translations[level].dw2_swing_select);
> +	val |=
> SWING_SEL_LOWER(ddi_translations[level].dw2_swing_select);
> +	/* Program Rcomp scalar for every table entry */
> +	val |=
> RCOMP_SCALAR(ddi_translations[level].dw2_swing_scalar);
> +	I915_WRITE(ICL_PORT_TX_DW2_GRP(port), val);
> +
> +	/* Program PORT_TX_DW4 */
> +	/* We cannot write to GRP. It would overwrite individual
> loadgen. */
> +	for (ln = 0; ln <= 3; ln++) {
> +		val = I915_READ(ICL_PORT_TX_DW4_LN(port, ln));
> +		val &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
> +			 CURSOR_COEFF_MASK);
> +		val |= ddi_translations[level].dw4_scaling;
> +		I915_WRITE(ICL_PORT_TX_DW4_LN(port, ln), val);
> +	}
> +}
> +
> +static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder
> *encoder, u32 level)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(encoder-
> >base.dev);
> +	enum port port = encoder->port;
> +	int type = encoder->type;
> +	int width = 0;
> +	int rate = 0;
> +	u32 val;
> +	int ln = 0;
> +
> +	if (type == INTEL_OUTPUT_HDMI) {
> +		width = 4;
> +		/* Rate is always < than 6GHz for HDMI */
> +	} else {
> +		struct intel_dp *intel_dp =
> enc_to_intel_dp(&encoder->base);
> +
> +		width = intel_dp->lane_count;
> +		rate = intel_dp->link_rate;
> +	}
> +
> +	/*
> +	 * 1. If port type is eDP or DP,
> +	 * set PORT_PCS_DW1 cmnkeeper_enable to 1b,
> +	 * else clear to 0b.
> +	 */
> +	val = I915_READ(ICL_PORT_PCS_DW1_LN0(port));
> +	if (type == INTEL_OUTPUT_HDMI)
> +		val &= ~COMMON_KEEPER_EN;
> +	else
> +		val |= COMMON_KEEPER_EN;
> +	I915_WRITE(ICL_PORT_PCS_DW1_GRP(port), val);
> +
> +	/* 2. Program loadgen select */
> +	/*
> +	 * Program PORT_TX_DW4_LN depending on Bit rate and used
> lanes
> +	 * <= 6 GHz and 4 lanes (LN0=0, LN1=1, LN2=1, LN3=1)
> +	 * <= 6 GHz and 1,2 lanes (LN0=0, LN1=1, LN2=1, LN3=0)
> +	 * > 6 GHz (LN0=0, LN1=0, LN2=0, LN3=0)
> +	 */
> +	for (ln = 0; ln <= 3; ln++) {
> +		val = I915_READ(ICL_PORT_TX_DW4_LN(port, ln));
> +		val &= ~LOADGEN_SELECT;
> +
> +		if ((rate <= 600000 && width == 4 && ln >= 1) ||
> +		    (rate <= 600000 && width < 4 && (ln == 1 || ln
> == 2))) {
> +			val |= LOADGEN_SELECT;
> +		}
> +		I915_WRITE(ICL_PORT_TX_DW4_LN(port, ln), val);
> +	}
> +
> +	/* 3. Set PORT_CL_DW5 SUS Clock Config to 11b */
> +	val = I915_READ(ICL_PORT_CL_DW5(port));
> +	val |= SUS_CLOCK_CONFIG;
> +	I915_WRITE(ICL_PORT_CL_DW5(port), val);
> +
> +	/* 4. Clear training enable to change swing values */
> +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> +	val &= ~TX_TRAINING_EN;
> +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> +
> +	/* 5. Program swing and de-emphasis */
> +	icl_ddi_combo_vswing_program(dev_priv, level, port, type);
> +
> +	/* 6. Set training enable to trigger update */
> +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> +	val |= TX_TRAINING_EN;
> +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> +}
> +
> +static void icl_ddi_vswing_sequence(struct intel_encoder *encoder,
> u32 level)
> +{
> +	enum port port = encoder->port;
> +
> +	if (port == PORT_A || port == PORT_B)
> +		icl_combo_phy_ddi_vswing_sequence(encoder, level);
> +	else
> +		/* Not Implemented Yet */
> +		WARN_ON(1);
> +}
> +
>  static uint32_t translate_signal_level(int signal_levels)
>  {
>  	int i;
> @@ -2209,7 +2386,9 @@ u32 bxt_signal_levels(struct intel_dp
> *intel_dp)
>  	struct intel_encoder *encoder = &dport->base;
>  	int level = intel_ddi_dp_level(intel_dp);
>  
> -	if (IS_CANNONLAKE(dev_priv))
> +	if (IS_ICELAKE(dev_priv))
> +		icl_ddi_vswing_sequence(encoder, level);

I was 100% sure I had already reworked the patch to follow the new
standard for the other platforms, but I guess I was wrong.

I'll update this patch based on my review, but I guess now we'll be at
a point where I changed the patch so much that we'll need a new
reviewer.

> +	else if (IS_CANNONLAKE(dev_priv))
>  		cnl_ddi_vswing_sequence(encoder, level, encoder-
> >type);
>  	else
>  		bxt_ddi_vswing_sequence(encoder, level, encoder-
> >type);
> @@ -2389,7 +2568,9 @@ static void intel_ddi_pre_enable_dp(struct
> intel_encoder *encoder,
>  
>  	intel_display_power_get(dev_priv, dig_port-
> >ddi_io_power_domain);
>  
> -	if (IS_CANNONLAKE(dev_priv))
> +	if (IS_ICELAKE(dev_priv))
> +		icl_ddi_vswing_sequence(encoder, level);
> +	else if (IS_CANNONLAKE(dev_priv))
>  		cnl_ddi_vswing_sequence(encoder, level, encoder-
> >type);
>  	else if (IS_GEN9_LP(dev_priv))
>  		bxt_ddi_vswing_sequence(encoder, level, encoder-
> >type);
> @@ -2420,7 +2601,9 @@ static void intel_ddi_pre_enable_hdmi(struct
> intel_encoder *encoder,
>  
>  	intel_display_power_get(dev_priv, dig_port-
> >ddi_io_power_domain);
>  
> -	if (IS_CANNONLAKE(dev_priv))
> +	if (IS_ICELAKE(dev_priv))
> +		icl_ddi_vswing_sequence(encoder, level);
> +	else if (IS_CANNONLAKE(dev_priv))
>  		cnl_ddi_vswing_sequence(encoder, level,
> INTEL_OUTPUT_HDMI);
>  	else if (IS_GEN9_LP(dev_priv))
>  		bxt_ddi_vswing_sequence(encoder, level,
> INTEL_OUTPUT_HDMI);
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 11/17] drm/i915/icl: Implement voltage swing programming sequence for MG PHY DDI
  2018-02-22  3:55 ` [PATCH 11/17] drm/i915/icl: Implement voltage swing programming sequence for MG PHY DDI Paulo Zanoni
@ 2018-03-22 22:58   ` Paulo Zanoni
  0 siblings, 0 replies; 41+ messages in thread
From: Paulo Zanoni @ 2018-03-22 22:58 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

Em Qui, 2018-02-22 às 00:55 -0300, Paulo Zanoni escreveu:
> From: Manasi Navare <manasi.d.navare@intel.com>
> 
> This sequence is used to setup voltage swing before enabling MG PHY
> DDI
> as well as for changing the voltage during DisplayPort Link training.
> 
> For ICL, there are two types of DDIs. This sequence needs to be used
> for MG PHY DDI which is ports C-F.
> 
> v5 (from Paulo):
> * Checkpatch.
> v4 (from Paulo):
> * Fix bogus error message
> * Fix copy+paste bugs (missing s/TX1/TX2/ after copy+paste)
> * Use the new mask names
> * Stay under 80 columns
> * Add some blank lines
> v3:
> * Clear the regs before writing (Paulo)
> v2:
> * Rename to MG PHY in the function def (Jani Nikula)
> * Rebase on top of new revision of other patches in series

The spec has changed since this patch was written. There are two new
tables to consider.

Manasi, can you look into this?

> 
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Cc: Jani Nikula <jani.nikula@linux.intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 85
> +++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 83 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c
> b/drivers/gpu/drm/i915/intel_ddi.c
> index 98471b5c5f70..88a6c5107975 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -2364,6 +2364,88 @@ static void
> icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, u32
>  	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
>  }
>  
> +static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder
> *encoder,
> +					   u32 level)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(encoder-
> >base.dev);
> +	enum port port = encoder->port;
> +	const struct icl_mg_phy_ddi_buf_trans *ddi_translations;
> +	u32 n_entries, val;
> +	int ln;
> +
> +	/*
> +	 * Values are listed in voltage swing programming tables.
> +	 * Same values for all voltage levels and port types.
> +	 */
> +	n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations);
> +	ddi_translations = icl_mg_phy_ddi_translations;
> +	/* The table does not have values for level 3 and level 9.
> */
> +	if (level >= n_entries || level == 3 || level == 9) {
> +		DRM_DEBUG_KMS("DDI translation not found for level
> %d. Using %d instead.",
> +			      level, n_entries - 2);
> +		level = n_entries - 2;
> +	}
> +
> +	/* Set MG_TX_LINK_PARAMS cri_use_fs32 to 0. */
> +	for (ln = 0; ln < 2; ln++) {
> +		val = I915_READ(ICL_PORT_MG_TX1_LINK_PARAMS(port,
> ln));
> +		val &= ~CRI_USE_FS32;
> +		I915_WRITE(ICL_PORT_MG_TX1_LINK_PARAMS(port, ln),
> val);
> +
> +		val = I915_READ(ICL_PORT_MG_TX2_LINK_PARAMS(port,
> ln));
> +		val &= ~CRI_USE_FS32;
> +		I915_WRITE(ICL_PORT_MG_TX2_LINK_PARAMS(port, ln),
> val);
> +	}
> +
> +	/* Program MG_TX_SWINGCTRL with values from vswing table */
> +	for (ln = 0; ln < 2; ln++) {
> +		val = I915_READ(ICL_PORT_MG_TX1_SWINGCTRL(port,
> ln));
> +		val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK;
> +		val |= CRI_TXDEEMPH_OVERRIDE_17_12(
> +			ddi_translations[level].cri_txdeemph_overrid
> e_17_12);
> +		I915_WRITE(ICL_PORT_MG_TX1_SWINGCTRL(port, ln),
> val);
> +
> +		val = I915_READ(ICL_PORT_MG_TX2_SWINGCTRL(port,
> ln));
> +		val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK;
> +		val |= CRI_TXDEEMPH_OVERRIDE_17_12(
> +			ddi_translations[level].cri_txdeemph_overrid
> e_17_12);
> +		I915_WRITE(ICL_PORT_MG_TX2_SWINGCTRL(port, ln),
> val);
> +	}
> +
> +	/* Program MG_TX_DRVCTRL with values from vswing table */
> +	for (ln = 0; ln < 2; ln++) {
> +		val = I915_READ(ICL_PORT_MG_TX1_DRVCTRL(port, ln));
> +		val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK |
> +			 CRI_TXDEEMPH_OVERRIDE_5_0_MASK);
> +		val |= CRI_TXDEEMPH_OVERRIDE_5_0(
> +			ddi_translations[level].cri_txdeemph_overrid
> e_5_0) |
> +		       CRI_TXDEEMPH_OVERRIDE_11_6(
> +			ddi_translations[level].cri_txdeemph_overrid
> e_11_6) |
> +		       CRI_TXDEEMPH_OVERRIDE_EN;
> +		I915_WRITE(ICL_PORT_MG_TX1_DRVCTRL(port, ln), val);
> +
> +		val = I915_READ(ICL_PORT_MG_TX2_DRVCTRL(port, ln));
> +		val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK |
> +			 CRI_TXDEEMPH_OVERRIDE_5_0_MASK);
> +		val |= CRI_TXDEEMPH_OVERRIDE_5_0(
> +			ddi_translations[level].cri_txdeemph_overrid
> e_5_0) |
> +		       CRI_TXDEEMPH_OVERRIDE_11_6(
> +			ddi_translations[level].cri_txdeemph_overrid
> e_11_6) |
> +		      CRI_TXDEEMPH_OVERRIDE_EN;
> +		I915_WRITE(ICL_PORT_MG_TX2_DRVCTRL(port, ln), val);
> +	}
> +	/* Program MG_TX_PISO_READLOAD with values from vswing table
> */
> +	for (ln = 0; ln < 2; ln++) {
> +		val = I915_READ(ICL_PORT_MG_TX1_PISO_READLOAD(port,
> ln));
> +		val |= CRI_CALCINIT;
> +		I915_WRITE(ICL_PORT_MG_TX1_PISO_READLOAD(port, ln),
> val);
> +
> +		val = I915_READ(ICL_PORT_MG_TX2_PISO_READLOAD(port,
> ln));
> +		val |= CRI_CALCINIT;
> +		I915_WRITE(ICL_PORT_MG_TX2_PISO_READLOAD(port, ln),
> val);
> +	}
> +}
> +
>  static void icl_ddi_vswing_sequence(struct intel_encoder *encoder,
> u32 level)
>  {
>  	enum port port = encoder->port;
> @@ -2371,8 +2453,7 @@ static void icl_ddi_vswing_sequence(struct
> intel_encoder *encoder, u32 level)
>  	if (port == PORT_A || port == PORT_B)
>  		icl_combo_phy_ddi_vswing_sequence(encoder, level);
>  	else
> -		/* Not Implemented Yet */
> -		WARN_ON(1);
> +		icl_mg_phy_ddi_vswing_sequence(encoder, level);
>  }
>  
>  static uint32_t translate_signal_level(int signal_levels)
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 14/17] drm/i915/icl: Calculate link clock using the new registers
  2018-02-22  3:55 ` [PATCH 14/17] drm/i915/icl: Calculate link clock using the new registers Paulo Zanoni
@ 2018-03-22 23:20   ` Paulo Zanoni
  0 siblings, 0 replies; 41+ messages in thread
From: Paulo Zanoni @ 2018-03-22 23:20 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi

Em Qui, 2018-02-22 às 00:55 -0300, Paulo Zanoni escreveu:
> From: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
> 
> Start using the new registers for ICL and on.

This patch doesn't make sense at this point of the series since we
don't run this code on ICL. I'll put it at the correct series.

> 
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c
> b/drivers/gpu/drm/i915/intel_ddi.c
> index 88a6c5107975..c1f1966d471c 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1371,8 +1371,13 @@ static int cnl_calc_wrpll_link(struct
> drm_i915_private *dev_priv,
>  	uint32_t cfgcr0, cfgcr1;
>  	uint32_t p0, p1, p2, dco_freq, ref_clock;
>  
> -	cfgcr0 = I915_READ(CNL_DPLL_CFGCR0(pll_id));
> -	cfgcr1 = I915_READ(CNL_DPLL_CFGCR1(pll_id));
> +	if (INTEL_GEN(dev_priv) >= 11) {
> +		cfgcr0 = I915_READ(ICL_DPLL_CFGCR0(pll_id));
> +		cfgcr1 = I915_READ(ICL_DPLL_CFGCR1(pll_id));
> +	} else {
> +		cfgcr0 = I915_READ(CNL_DPLL_CFGCR0(pll_id));
> +		cfgcr1 = I915_READ(CNL_DPLL_CFGCR1(pll_id));
> +	}
>  
>  	p0 = cfgcr1 & DPLL_CFGCR1_PDIV_MASK;
>  	p2 = cfgcr1 & DPLL_CFGCR1_KDIV_MASK;
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 17/17] drm/i915/icl: Fix the DP Max Voltage for ICL
  2018-02-22  3:55 ` [PATCH 17/17] drm/i915/icl: Fix the DP Max Voltage for ICL Paulo Zanoni
@ 2018-03-23  0:03   ` Rodrigo Vivi
  0 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Vivi @ 2018-03-23  0:03 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx

On Thu, Feb 22, 2018 at 12:55:19AM -0300, Paulo Zanoni wrote:
> From: Manasi Navare <manasi.d.navare@intel.com>
> 
> On clock recovery this function is called to find out
> the max voltage swing level that we could go.
> 
> However gen 9 functions use the old buffer translation tables
> to figure that out. ICL uses different set of tables for eDP
> and DP for both Combo and MG PHY ports. This patch adds the hook
> for ICL for getting this information from appropriate buf trans tables.
> 
> v5 (from Paulo):
> * New rebase after changes to earlier patches.
> v4:
> * Rebase.
> v3:
> * Follow the coding conventions here
> (https://cgit.freedesktop.org/drm-intel/tree/Documentation/process/codin
> g-style.rst#n191) (Paulo)
> v2:
> * Rebase after patch that adds voltage check inside buf trans
> function (Rodrigo)
> 
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

seems a lot change since my first review, but everything looks
correct to me still on this newer version. So

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index ad82ef91263e..fbdd2340c8aa 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -2085,7 +2085,13 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder)
>  	enum port port = encoder->port;
>  	int n_entries;
>  
> -	if (IS_CANNONLAKE(dev_priv)) {
> +	if (IS_ICELAKE(dev_priv)) {
> +		if (port == PORT_A || port == PORT_B)
> +			icl_get_combo_buf_trans(dev_priv, port, encoder->type,
> +						&n_entries);
> +		else
> +			n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations);
> +	} else if (IS_CANNONLAKE(dev_priv)) {
>  		if (encoder->type == INTEL_OUTPUT_EDP)
>  			cnl_get_buf_trans_edp(dev_priv, &n_entries);
>  		else
> -- 
> 2.14.3
> 
> _______________________________________________
> 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] 41+ messages in thread

* Re: [PATCH 00/17] ICL PLLs, DP/HDMI and misc display
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
                   ` (18 preceding siblings ...)
  2018-02-22  4:24 ` ✗ Fi.CI.BAT: " Patchwork
@ 2018-03-23  0:05 ` Paulo Zanoni
  2018-03-23  1:00 ` ✗ Fi.CI.BAT: failure for ICL PLLs, DP/HDMI and misc display (rev4) Patchwork
  20 siblings, 0 replies; 41+ messages in thread
From: Paulo Zanoni @ 2018-03-23  0:05 UTC (permalink / raw)
  To: intel-gfx

Em Qui, 2018-02-22 às 00:55 -0300, Paulo Zanoni escreveu:
> Hello
> 
> Here are some more ICL patches, now with the Combo & MG PLLs, some
> DP/HDMI
> initialization code and a few misc fixes.
> 
> Again, the R-B tags already present in some of the patches (including
> those form
> me) were given a long time ago, so they need to be re-issued due to
> the
> rebasing.

The following patches have my Reviewed-by: 6, 7, 9, 10, 13 and 15.

I'll send updated patches soon.

> 
> Thanks,
> Paulo
> 
> Arkadiusz Hiler (1):
>   drm/i915/icl: Calculate link clock using the new registers
> 
> Dhinakaran Pandiyan (1):
>   drm/i915/icl: HPD pin for port F
> 
> James Ausmus (1):
>   drm/i915/icl: Don't set pipe CSC/Gamma in PLANE_COLOR_CTL
> 
> Manasi Navare (7):
>   drm/i915/icl: Add register definitions for Combo PHY vswing
> sequences.
>   drm/i915/icl: Add Combo PHY DDI Buffer translation tables for
> Icelake.
>   drm/i915/icl: Implement voltage swing programming sequence for
> Combo
>     PHY DDI
>   drm/i915/icl: Add register defs for voltage swing sequences for MG
> PHY
>     DDI
>   drm/i915/icl: Add Voltage swing table for MG PHY DDI Buffer
>   drm/i915/icl: Implement voltage swing programming sequence for MG
> PHY
>     DDI
>   drm/i915/icl: Fix the DP Max Voltage for ICL
> 
> Nabendu Maiti (1):
>   drm/i915/icl: Added 5k source scaling support for Gen11 platform
> 
> Paulo Zanoni (6):
>   drm/i915/icl: add definitions for the ICL PLL registers
>   drm/i915/icl: add basic support for the ICL clocks
>   drm/i915/icl: compute the combo PHY (DPLL) HDMI registers
>   drm/i915/icl: compute the combo PHY (DPLL) DP registers
>   drm/i915/icl: compute the MG PLL registers
>   drm/i915/gen11: all the DDI ports on gen 11 support 4 lanes
> 
>  drivers/gpu/drm/i915/i915_debugfs.c   |  22 ++
>  drivers/gpu/drm/i915/i915_drv.h       |   1 +
>  drivers/gpu/drm/i915/i915_reg.h       | 313 ++++++++++++++++-
>  drivers/gpu/drm/i915/intel_ddi.c      | 529
> +++++++++++++++++++++++++++-
>  drivers/gpu/drm/i915/intel_display.c  |  33 +-
>  drivers/gpu/drm/i915/intel_dpll_mgr.c | 642
> +++++++++++++++++++++++++++++++++-
>  drivers/gpu/drm/i915/intel_dpll_mgr.h |  41 +++
>  drivers/gpu/drm/i915/intel_drv.h      |  10 +
>  drivers/gpu/drm/i915/intel_hotplug.c  |   3 +
>  9 files changed, 1569 insertions(+), 25 deletions(-)
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 01/17] drm/i915/icl: add definitions for the ICL PLL registers
  2018-02-22  3:55 ` [PATCH 01/17] drm/i915/icl: add definitions for the ICL PLL registers Paulo Zanoni
  2018-02-27 22:22   ` James Ausmus
@ 2018-03-23  0:07   ` Paulo Zanoni
  2018-03-23  0:08   ` [PATCH 02/17] drm/i915/icl: add basic support for the ICL clocks Paulo Zanoni
  2 siblings, 0 replies; 41+ messages in thread
From: Paulo Zanoni @ 2018-03-23  0:07 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

There's a lot of code for the PLL enabling, so let's first only
introduce the register definitions in order to make patch reviewing a
little easier.

v2: Coding style (Jani).
v3: Preparation for upstreaming.
v4: Fix MG_CLKTOP2_CORECLKCTL1 address and random typos (James).

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h | 149 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 149 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index da2f6c623ab2..d123c5f57421 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -8535,6 +8535,12 @@ enum skl_power_gate {
 #define  PORT_CLK_SEL_NONE		(7<<29)
 #define  PORT_CLK_SEL_MASK		(7<<29)
 
+/* On ICL+ this is the same as PORT_CLK_SEL, but all bits change. */
+#define DDI_CLK_SEL(port)		PORT_CLK_SEL(port)
+#define  DDI_CLK_SEL_NONE		(0x0 << 28)
+#define  DDI_CLK_SEL_MG			(0x8 << 28)
+#define  DDI_CLK_SEL_MASK		(0xF << 28)
+
 /* Transcoder clock selection */
 #define _TRANS_CLK_SEL_A		0x46140
 #define _TRANS_CLK_SEL_B		0x46144
@@ -8665,6 +8671,7 @@ enum skl_power_gate {
  * CNL Clocks
  */
 #define DPCLKA_CFGCR0				_MMIO(0x6C200)
+#define DPCLKA_CFGCR0_ICL			_MMIO(0x164280)
 #define  DPCLKA_CFGCR0_DDI_CLK_OFF(port)	(1 << ((port) ==  PORT_F ? 23 : \
 						      (port)+10))
 #define  DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port)	((port) == PORT_F ? 21 : \
@@ -8681,10 +8688,141 @@ enum skl_power_gate {
 #define  PLL_POWER_STATE	(1 << 26)
 #define CNL_DPLL_ENABLE(pll)	_MMIO_PLL(pll, DPLL0_ENABLE, DPLL1_ENABLE)
 
+#define _MG_PLL1_ENABLE		0x46030
+#define _MG_PLL2_ENABLE		0x46034
+#define _MG_PLL3_ENABLE		0x46038
+#define _MG_PLL4_ENABLE		0x4603C
+/* Bits are the same as DPLL0_ENABLE */
+#define MG_PLL_ENABLE(port)	_MMIO_PORT((port) - PORT_C, _MG_PLL1_ENABLE, \
+					   _MG_PLL2_ENABLE)
+
+#define _MG_REFCLKIN_CTL_PORT1				0x16892C
+#define _MG_REFCLKIN_CTL_PORT2				0x16992C
+#define _MG_REFCLKIN_CTL_PORT3				0x16A92C
+#define _MG_REFCLKIN_CTL_PORT4				0x16B92C
+#define   MG_REFCLKIN_CTL_OD_2_MUX(x)			((x) << 8)
+#define MG_REFCLKIN_CTL(port) _MMIO_PORT((port) - PORT_C, \
+					 _MG_REFCLKIN_CTL_PORT1, \
+					 _MG_REFCLKIN_CTL_PORT2)
+
+#define _MG_CLKTOP2_CORECLKCTL1_PORT1			0x1688D8
+#define _MG_CLKTOP2_CORECLKCTL1_PORT2			0x1698D8
+#define _MG_CLKTOP2_CORECLKCTL1_PORT3			0x16A8D8
+#define _MG_CLKTOP2_CORECLKCTL1_PORT4			0x16B8D8
+#define   MG_CLKTOP2_CORECLKCTL1_B_DIVRATIO(x)		((x) << 16)
+#define   MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO(x)		((x) << 8)
+#define MG_CLKTOP2_CORECLKCTL1(port) _MMIO_PORT((port) - PORT_C, \
+						_MG_CLKTOP2_CORECLKCTL1_PORT1, \
+						_MG_CLKTOP2_CORECLKCTL1_PORT2)
+
+#define _MG_CLKTOP2_HSCLKCTL_PORT1			0x1688D4
+#define _MG_CLKTOP2_HSCLKCTL_PORT2			0x1698D4
+#define _MG_CLKTOP2_HSCLKCTL_PORT3			0x16A8D4
+#define _MG_CLKTOP2_HSCLKCTL_PORT4			0x16B8D4
+#define   MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL(x)		((x) << 16)
+#define   MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL(x)	((x) << 14)
+#define   MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO(x)		((x) << 12)
+#define   MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO(x)		((x) << 8)
+#define MG_CLKTOP2_HSCLKCTL(port) _MMIO_PORT((port) - PORT_C, \
+					     _MG_CLKTOP2_HSCLKCTL_PORT1, \
+					     _MG_CLKTOP2_HSCLKCTL_PORT2)
+
+#define _MG_PLL_DIV0_PORT1				0x168A00
+#define _MG_PLL_DIV0_PORT2				0x169A00
+#define _MG_PLL_DIV0_PORT3				0x16AA00
+#define _MG_PLL_DIV0_PORT4				0x16BA00
+#define   MG_PLL_DIV0_FRACNEN_H				(1 << 30)
+#define   MG_PLL_DIV0_FBDIV_FRAC(x)			((x) << 8)
+#define   MG_PLL_DIV0_FBDIV_INT(x)			((x) << 0)
+#define MG_PLL_DIV0(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_DIV0_PORT1, \
+				     _MG_PLL_DIV0_PORT2)
+
+#define _MG_PLL_DIV1_PORT1				0x168A04
+#define _MG_PLL_DIV1_PORT2				0x169A04
+#define _MG_PLL_DIV1_PORT3				0x16AA04
+#define _MG_PLL_DIV1_PORT4				0x16BA04
+#define   MG_PLL_DIV1_IREF_NDIVRATIO(x)			((x) << 16)
+#define   MG_PLL_DIV1_DITHER_DIV_1			(0 << 12)
+#define   MG_PLL_DIV1_DITHER_DIV_2			(1 << 12)
+#define   MG_PLL_DIV1_DITHER_DIV_4			(2 << 12)
+#define   MG_PLL_DIV1_DITHER_DIV_8			(3 << 12)
+#define   MG_PLL_DIV1_NDIVRATIO(x)			((x) << 4)
+#define   MG_PLL_DIV1_FBPREDIV(x)			((x) << 0)
+#define MG_PLL_DIV1(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_DIV1_PORT1, \
+				     _MG_PLL_DIV1_PORT2)
+
+#define _MG_PLL_LF_PORT1				0x168A08
+#define _MG_PLL_LF_PORT2				0x169A08
+#define _MG_PLL_LF_PORT3				0x16AA08
+#define _MG_PLL_LF_PORT4				0x16BA08
+#define   MG_PLL_LF_TDCTARGETCNT(x)			((x) << 24)
+#define   MG_PLL_LF_AFCCNTSEL_256			(0 << 20)
+#define   MG_PLL_LF_AFCCNTSEL_512			(1 << 20)
+#define   MG_PLL_LF_GAINCTRL(x)				((x) << 16)
+#define   MG_PLL_LF_INT_COEFF(x)			((x) << 8)
+#define   MG_PLL_LF_PROP_COEFF(x)			((x) << 0)
+#define MG_PLL_LF(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_LF_PORT1, \
+				   _MG_PLL_LF_PORT2)
+
+#define _MG_PLL_FRAC_LOCK_PORT1				0x168A0C
+#define _MG_PLL_FRAC_LOCK_PORT2				0x169A0C
+#define _MG_PLL_FRAC_LOCK_PORT3				0x16AA0C
+#define _MG_PLL_FRAC_LOCK_PORT4				0x16BA0C
+#define   MG_PLL_FRAC_LOCK_TRUELOCK_CRIT_32		(1 << 18)
+#define   MG_PLL_FRAC_LOCK_EARLYLOCK_CRIT_32		(1 << 16)
+#define   MG_PLL_FRAC_LOCK_LOCKTHRESH(x)		((x) << 11)
+#define   MG_PLL_FRAC_LOCK_DCODITHEREN			(1 << 10)
+#define   MG_PLL_FRAC_LOCK_FEEDFWRDCAL_EN		(1 << 8)
+#define   MG_PLL_FRAC_LOCK_FEEDFWRDGAIN(x)		((x) << 0)
+#define MG_PLL_FRAC_LOCK(port) _MMIO_PORT((port) - PORT_C, \
+					  _MG_PLL_FRAC_LOCK_PORT1, \
+					  _MG_PLL_FRAC_LOCK_PORT2)
+
+#define _MG_PLL_SSC_PORT1				0x168A10
+#define _MG_PLL_SSC_PORT2				0x169A10
+#define _MG_PLL_SSC_PORT3				0x16AA10
+#define _MG_PLL_SSC_PORT4				0x16BA10
+#define   MG_PLL_SSC_EN					(1 << 28)
+#define   MG_PLL_SSC_TYPE(x)				((x) << 26)
+#define   MG_PLL_SSC_STEPLENGTH(x)			((x) << 16)
+#define   MG_PLL_SSC_STEPNUM(x)				((x) << 10)
+#define   MG_PLL_SSC_FLLEN				(1 << 9)
+#define   MG_PLL_SSC_STEPSIZE(x)			((x) << 0)
+#define MG_PLL_SSC(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_SSC_PORT1, \
+				    _MG_PLL_SSC_PORT2)
+
+#define _MG_PLL_BIAS_PORT1				0x168A14
+#define _MG_PLL_BIAS_PORT2				0x169A14
+#define _MG_PLL_BIAS_PORT3				0x16AA14
+#define _MG_PLL_BIAS_PORT4				0x16BA14
+#define   MG_PLL_BIAS_BIAS_GB_SEL(x)			((x) << 30)
+#define   MG_PLL_BIAS_INIT_DCOAMP(x)			((x) << 24)
+#define   MG_PLL_BIAS_BIAS_BONUS(x)			((x) << 16)
+#define   MG_PLL_BIAS_BIASCAL_EN			(1 << 15)
+#define   MG_PLL_BIAS_CTRIM(x)				((x) << 8)
+#define   MG_PLL_BIAS_VREF_RDAC(x)			((x) << 5)
+#define   MG_PLL_BIAS_IREFTRIM(x)			((x) << 0)
+#define MG_PLL_BIAS(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_BIAS_PORT1, \
+				     _MG_PLL_BIAS_PORT2)
+
+#define _MG_PLL_TDC_COLDST_BIAS_PORT1			0x168A18
+#define _MG_PLL_TDC_COLDST_BIAS_PORT2			0x169A18
+#define _MG_PLL_TDC_COLDST_BIAS_PORT3			0x16AA18
+#define _MG_PLL_TDC_COLDST_BIAS_PORT4			0x16BA18
+#define   MG_PLL_TDC_COLDST_IREFINT_EN			(1 << 27)
+#define   MG_PLL_TDC_COLDST_REFBIAS_START_PULSE_W(x)	((x) << 17)
+#define   MG_PLL_TDC_COLDST_COLDSTART			(1 << 16)
+#define   MG_PLL_TDC_TDCOVCCORR_EN			(1 << 2)
+#define   MG_PLL_TDC_TDCSEL(x)				((x) << 0)
+#define MG_PLL_TDC_COLDST_BIAS(port) _MMIO_PORT((port) - PORT_C, \
+						_MG_PLL_TDC_COLDST_BIAS_PORT1, \
+						_MG_PLL_TDC_COLDST_BIAS_PORT2)
+
 #define _CNL_DPLL0_CFGCR0		0x6C000
 #define _CNL_DPLL1_CFGCR0		0x6C080
 #define  DPLL_CFGCR0_HDMI_MODE		(1 << 30)
 #define  DPLL_CFGCR0_SSC_ENABLE		(1 << 29)
+#define  DPLL_CFGCR0_SSC_ENABLE_ICL	(1 << 25)
 #define  DPLL_CFGCR0_LINK_RATE_MASK	(0xf << 25)
 #define  DPLL_CFGCR0_LINK_RATE_2700	(0 << 25)
 #define  DPLL_CFGCR0_LINK_RATE_1350	(1 << 25)
@@ -8718,8 +8856,19 @@ enum skl_power_gate {
 #define  DPLL_CFGCR1_PDIV_5		(4 << 2)
 #define  DPLL_CFGCR1_PDIV_7		(8 << 2)
 #define  DPLL_CFGCR1_CENTRAL_FREQ	(3 << 0)
+#define  DPLL_CFGCR1_CENTRAL_FREQ_8400	(3 << 0)
 #define CNL_DPLL_CFGCR1(pll)		_MMIO_PLL(pll, _CNL_DPLL0_CFGCR1, _CNL_DPLL1_CFGCR1)
 
+#define _ICL_DPLL0_CFGCR0		0x164000
+#define _ICL_DPLL1_CFGCR0		0x164080
+#define ICL_DPLL_CFGCR0(pll)		_MMIO_PLL(pll, _ICL_DPLL0_CFGCR0, \
+						  _ICL_DPLL1_CFGCR0)
+
+#define _ICL_DPLL0_CFGCR1		0x164004
+#define _ICL_DPLL1_CFGCR1		0x164084
+#define ICL_DPLL_CFGCR1(pll)		_MMIO_PLL(pll, _ICL_DPLL0_CFGCR1, \
+						  _ICL_DPLL1_CFGCR1)
+
 /* BXT display engine PLL */
 #define BXT_DE_PLL_CTL			_MMIO(0x6d000)
 #define   BXT_DE_PLL_RATIO(x)		(x)	/* {60,65,100} * 19.2MHz */
-- 
2.14.3

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

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

* [PATCH 02/17] drm/i915/icl: add basic support for the ICL clocks
  2018-02-22  3:55 ` [PATCH 01/17] drm/i915/icl: add definitions for the ICL PLL registers Paulo Zanoni
  2018-02-27 22:22   ` James Ausmus
  2018-03-23  0:07   ` Paulo Zanoni
@ 2018-03-23  0:08   ` Paulo Zanoni
  2 siblings, 0 replies; 41+ messages in thread
From: Paulo Zanoni @ 2018-03-23  0:08 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

This commit introduces the definitions for the ICL clocks and adds the
basic functions to the shared DPLL framework. It adds code for the
Enable and Disable sequences for some PLLs, but it does not have the
code to compute the actual PLL values, which are marked as TODO
comments and should be introduced as separate commits.

Special thanks to James Ausmus for investigating and fixing a bug with
the placement of icl_unmap_plls_to_ports() function.

v2:
 - Rebase around dpll_lock changes.
v3:
 - The spec now says what the timeouts should be.
 - Touch DPCLKA_CFGCR0_ICL at the appropriate time so we don't freeze
   the machine.
 - Checkpatch found a white space problem.
 - Small adjustments before upstreaming.
v4:
 - Move the ICL checks out of the *map_plls_to_ports() functions
  (James)
 - Add extra encoder check (James)
 - Call icl_unmap_plls_to_ports() later (James)

Cc: James Ausmus <james.ausmus@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c   |  22 +++
 drivers/gpu/drm/i915/intel_ddi.c      |  96 ++++++++++-
 drivers/gpu/drm/i915/intel_display.c  |  16 ++
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 311 +++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_dpll_mgr.h |  41 +++++
 drivers/gpu/drm/i915/intel_drv.h      |   6 +
 6 files changed, 487 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 7816cd53100a..d932f1540397 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3295,6 +3295,28 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused)
 		seq_printf(m, " fp0:     0x%08x\n", pll->state.hw_state.fp0);
 		seq_printf(m, " fp1:     0x%08x\n", pll->state.hw_state.fp1);
 		seq_printf(m, " wrpll:   0x%08x\n", pll->state.hw_state.wrpll);
+		seq_printf(m, " cfgcr0:  0x%08x\n", pll->state.hw_state.cfgcr0);
+		seq_printf(m, " cfgcr1:  0x%08x\n", pll->state.hw_state.cfgcr1);
+		seq_printf(m, " mg_refclkin_ctl:        0x%08x\n",
+			   pll->state.hw_state.mg_refclkin_ctl);
+		seq_printf(m, " mg_clktop2_coreclkctl1: 0x%08x\n",
+			   pll->state.hw_state.mg_clktop2_coreclkctl1);
+		seq_printf(m, " mg_clktop2_hsclkctl:    0x%08x\n",
+			   pll->state.hw_state.mg_clktop2_hsclkctl);
+		seq_printf(m, " mg_pll_div0:  0x%08x\n",
+			   pll->state.hw_state.mg_pll_div0);
+		seq_printf(m, " mg_pll_div1:  0x%08x\n",
+			   pll->state.hw_state.mg_pll_div1);
+		seq_printf(m, " mg_pll_lf:    0x%08x\n",
+			   pll->state.hw_state.mg_pll_lf);
+		seq_printf(m, " mg_pll_frac_lock: 0x%08x\n",
+			   pll->state.hw_state.mg_pll_frac_lock);
+		seq_printf(m, " mg_pll_ssc:   0x%08x\n",
+			   pll->state.hw_state.mg_pll_ssc);
+		seq_printf(m, " mg_pll_bias:  0x%08x\n",
+			   pll->state.hw_state.mg_pll_bias);
+		seq_printf(m, " mg_pll_tdc_coldst_bias: 0x%08x\n",
+			   pll->state.hw_state.mg_pll_tdc_coldst_bias);
 	}
 	drm_modeset_unlock_all(dev);
 
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 8c2d778560f0..78cc332bf3fe 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -894,6 +894,23 @@ static uint32_t hsw_pll_to_ddi_pll_sel(const struct intel_shared_dpll *pll)
 	}
 }
 
+static uint32_t icl_pll_to_ddi_pll_sel(struct intel_encoder *encoder,
+				       const struct intel_shared_dpll *pll)
+{
+	switch (pll->id) {
+	default:
+		MISSING_CASE(pll->id);
+	case DPLL_ID_ICL_DPLL0:
+	case DPLL_ID_ICL_DPLL1:
+		return DDI_CLK_SEL_NONE;
+	case DPLL_ID_ICL_MGPLL1:
+	case DPLL_ID_ICL_MGPLL2:
+	case DPLL_ID_ICL_MGPLL3:
+	case DPLL_ID_ICL_MGPLL4:
+		return DDI_CLK_SEL_MG;
+	}
+}
+
 /* 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.
@@ -2115,6 +2132,69 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
 	return DDI_BUF_TRANS_SELECT(level);
 }
 
+void icl_map_plls_to_ports(struct drm_crtc *crtc,
+			   struct intel_crtc_state *crtc_state,
+			   struct drm_atomic_state *old_state)
+{
+	struct intel_shared_dpll *pll = crtc_state->shared_dpll;
+	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
+	struct drm_connector_state *conn_state;
+	struct drm_connector *conn;
+	int i;
+
+	for_each_new_connector_in_state(old_state, conn, conn_state, i) {
+		struct intel_encoder *encoder =
+			to_intel_encoder(conn_state->best_encoder);
+		enum port port = encoder->port;
+		uint32_t val;
+
+		if (conn_state->crtc != crtc)
+			continue;
+
+		mutex_lock(&dev_priv->dpll_lock);
+
+		val = I915_READ(DPCLKA_CFGCR0_ICL);
+		WARN_ON((val & DPCLKA_CFGCR0_DDI_CLK_OFF(port)) == 0);
+
+		if (port == PORT_A || port == PORT_B) {
+			val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port);
+			val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->id, port);
+			I915_WRITE(DPCLKA_CFGCR0_ICL, val);
+			POSTING_READ(DPCLKA_CFGCR0_ICL);
+		}
+
+		val &= ~DPCLKA_CFGCR0_DDI_CLK_OFF(port);
+		I915_WRITE(DPCLKA_CFGCR0_ICL, val);
+
+		mutex_unlock(&dev_priv->dpll_lock);
+	}
+}
+
+void icl_unmap_plls_to_ports(struct drm_crtc *crtc,
+			     struct intel_crtc_state *crtc_state,
+			     struct drm_atomic_state *old_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
+	struct drm_connector_state *conn_state;
+	struct drm_connector *conn;
+	int i;
+
+	for_each_new_connector_in_state(old_state, conn, conn_state, i) {
+		struct intel_encoder *encoder =
+			to_intel_encoder(conn_state->best_encoder);
+		enum port port = encoder->port;
+
+		if (!encoder || conn_state->crtc != crtc)
+			continue;
+
+		mutex_lock(&dev_priv->dpll_lock);
+		I915_WRITE(DPCLKA_CFGCR0_ICL,
+			   I915_READ(DPCLKA_CFGCR0_ICL) |
+			   DPCLKA_CFGCR0_DDI_CLK_OFF(port));
+		mutex_unlock(&dev_priv->dpll_lock);
+	}
+}
+
 static void intel_ddi_clk_select(struct intel_encoder *encoder,
 				 const struct intel_shared_dpll *pll)
 {
@@ -2127,7 +2207,11 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder,
 
 	mutex_lock(&dev_priv->dpll_lock);
 
-	if (IS_CANNONLAKE(dev_priv)) {
+	if (IS_ICELAKE(dev_priv)) {
+		if (port >= PORT_C)
+			I915_WRITE(DDI_CLK_SEL(port),
+				   icl_pll_to_ddi_pll_sel(encoder, pll));
+	} else if (IS_CANNONLAKE(dev_priv)) {
 		/* Configure DPCLKA_CFGCR0 to map the DPLL to the DDI. */
 		val = I915_READ(DPCLKA_CFGCR0);
 		val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port);
@@ -2165,14 +2249,18 @@ static void intel_ddi_clk_disable(struct intel_encoder *encoder)
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum port port = encoder->port;
 
-	if (IS_CANNONLAKE(dev_priv))
+	if (IS_ICELAKE(dev_priv)) {
+		if (port >= PORT_C)
+			I915_WRITE(DDI_CLK_SEL(port), DDI_CLK_SEL_NONE);
+	} else if (IS_CANNONLAKE(dev_priv)) {
 		I915_WRITE(DPCLKA_CFGCR0, I915_READ(DPCLKA_CFGCR0) |
 			   DPCLKA_CFGCR0_DDI_CLK_OFF(port));
-	else if (IS_GEN9_BC(dev_priv))
+	} else if (IS_GEN9_BC(dev_priv)) {
 		I915_WRITE(DPLL_CTRL2, I915_READ(DPLL_CTRL2) |
 			   DPLL_CTRL2_DDI_CLK_OFF(port));
-	else if (INTEL_GEN(dev_priv) < 9)
+	} else if (INTEL_GEN(dev_priv) < 9) {
 		I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
+	}
 }
 
 static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3e7ab75e1b41..4d9279161957 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5501,6 +5501,9 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 	if (intel_crtc->config->shared_dpll)
 		intel_enable_shared_dpll(intel_crtc);
 
+	if (INTEL_GEN(dev_priv) >= 11)
+		icl_map_plls_to_ports(crtc, pipe_config, old_state);
+
 	if (intel_crtc_has_dp_encoder(intel_crtc->config))
 		intel_dp_set_m_n(intel_crtc, M1_N1);
 
@@ -5698,6 +5701,9 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
 		intel_ddi_disable_pipe_clock(intel_crtc->config);
 
 	intel_encoders_post_disable(crtc, old_crtc_state, old_state);
+
+	if (INTEL_GEN(dev_priv) >= 11)
+		icl_unmap_plls_to_ports(crtc, old_crtc_state, old_state);
 }
 
 static void i9xx_pfit_enable(struct intel_crtc *crtc)
@@ -11317,6 +11323,16 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
 	PIPE_CONF_CHECK_X(dpll_hw_state.pll9);
 	PIPE_CONF_CHECK_X(dpll_hw_state.pll10);
 	PIPE_CONF_CHECK_X(dpll_hw_state.pcsdw12);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_refclkin_ctl);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_coreclkctl1);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_hsclkctl);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div0);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div1);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_lf);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_frac_lock);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_ssc);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_bias);
+	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_tdc_coldst_bias);
 
 	PIPE_CONF_CHECK_X(dsi_pll.ctrl);
 	PIPE_CONF_CHECK_X(dsi_pll.div);
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 51c5ae4e9116..8520a1b0279f 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -2384,6 +2384,313 @@ static const struct intel_dpll_mgr cnl_pll_mgr = {
 	.dump_hw_state = cnl_dump_hw_state,
 };
 
+static bool icl_calc_dpll_state(struct intel_crtc_state *crtc_state,
+				struct intel_encoder *encoder, int clock,
+				struct intel_dpll_hw_state *pll_state)
+{
+	/* TODO */
+	return true;
+}
+
+static enum port icl_mg_pll_id_to_port(enum intel_dpll_id id)
+{
+	return id - DPLL_ID_ICL_MGPLL1 + PORT_C;
+}
+
+static enum intel_dpll_id icl_port_to_mg_pll_id(enum port port)
+{
+	return port - PORT_C + DPLL_ID_ICL_MGPLL1;
+}
+
+static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
+				  struct intel_encoder *encoder, int clock,
+				  struct intel_dpll_hw_state *pll_state)
+{
+	/* TODO */
+	return true;
+}
+
+static struct intel_shared_dpll *
+icl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
+	     struct intel_encoder *encoder)
+{
+	struct intel_shared_dpll *pll;
+	struct intel_dpll_hw_state pll_state = {};
+	enum port port = encoder->port;
+	enum intel_dpll_id min, max;
+	int clock = crtc_state->port_clock;
+	bool ret;
+
+	switch (port) {
+	case PORT_A:
+	case PORT_B:
+		min = DPLL_ID_ICL_DPLL0;
+		max = DPLL_ID_ICL_DPLL1;
+		ret = icl_calc_dpll_state(crtc_state, encoder, clock,
+					  &pll_state);
+		break;
+	case PORT_C:
+	case PORT_D:
+	case PORT_E:
+	case PORT_F:
+		min = max = icl_port_to_mg_pll_id(port);
+		ret = icl_calc_mg_pll_state(crtc_state, encoder, clock,
+					    &pll_state);
+		break;
+	default:
+		MISSING_CASE(port);
+		return NULL;
+	}
+
+	if (!ret) {
+		DRM_DEBUG_KMS("Could not calculate PLL state.\n");
+		return NULL;
+	}
+
+	crtc_state->dpll_hw_state = pll_state;
+
+	pll = intel_find_shared_dpll(crtc, crtc_state, min, max);
+	if (!pll) {
+		DRM_DEBUG_KMS("No PLL selected\n");
+		return NULL;
+	}
+
+	intel_reference_shared_dpll(pll, crtc_state);
+
+	return pll;
+}
+
+static i915_reg_t icl_pll_id_to_enable_reg(enum intel_dpll_id id)
+{
+	switch (id) {
+	default:
+		MISSING_CASE(id);
+	case DPLL_ID_ICL_DPLL0:
+	case DPLL_ID_ICL_DPLL1:
+		return CNL_DPLL_ENABLE(id);
+	case DPLL_ID_ICL_MGPLL1:
+	case DPLL_ID_ICL_MGPLL2:
+	case DPLL_ID_ICL_MGPLL3:
+	case DPLL_ID_ICL_MGPLL4:
+		return MG_PLL_ENABLE(icl_mg_pll_id_to_port(id));
+	}
+}
+
+static bool icl_pll_get_hw_state(struct drm_i915_private *dev_priv,
+				 struct intel_shared_dpll *pll,
+				 struct intel_dpll_hw_state *hw_state)
+{
+	enum intel_dpll_id id = pll->id;
+	uint32_t val;
+	enum port port;
+	bool ret = false;
+
+	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
+		return false;
+
+	val = I915_READ(icl_pll_id_to_enable_reg(id));
+	if (!(val & PLL_ENABLE))
+		goto out;
+
+	switch (id) {
+	case DPLL_ID_ICL_DPLL0:
+	case DPLL_ID_ICL_DPLL1:
+		hw_state->cfgcr0 = I915_READ(ICL_DPLL_CFGCR0(id));
+		hw_state->cfgcr1 = I915_READ(ICL_DPLL_CFGCR1(id));
+		break;
+	case DPLL_ID_ICL_MGPLL1:
+	case DPLL_ID_ICL_MGPLL2:
+	case DPLL_ID_ICL_MGPLL3:
+	case DPLL_ID_ICL_MGPLL4:
+		port = icl_mg_pll_id_to_port(pll->id);
+		hw_state->mg_refclkin_ctl = I915_READ(MG_REFCLKIN_CTL(port));
+		hw_state->mg_clktop2_coreclkctl1 =
+			I915_READ(MG_CLKTOP2_CORECLKCTL1(port));
+		hw_state->mg_clktop2_hsclkctl =
+			I915_READ(MG_CLKTOP2_HSCLKCTL(port));
+		hw_state->mg_pll_div0 = I915_READ(MG_PLL_DIV0(port));
+		hw_state->mg_pll_div1 = I915_READ(MG_PLL_DIV1(port));
+		hw_state->mg_pll_lf = I915_READ(MG_PLL_LF(port));
+		hw_state->mg_pll_frac_lock = I915_READ(MG_PLL_FRAC_LOCK(port));
+		hw_state->mg_pll_ssc = I915_READ(MG_PLL_SSC(port));
+		hw_state->mg_pll_bias = I915_READ(MG_PLL_BIAS(port));
+		hw_state->mg_pll_tdc_coldst_bias =
+			I915_READ(MG_PLL_TDC_COLDST_BIAS(port));
+		break;
+	default:
+		MISSING_CASE(id);
+	}
+
+	ret = true;
+out:
+	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
+	return ret;
+}
+
+static void icl_dpll_write(struct drm_i915_private *dev_priv,
+			   struct intel_shared_dpll *pll)
+{
+	struct intel_dpll_hw_state *hw_state = &pll->state.hw_state;
+
+	I915_WRITE(ICL_DPLL_CFGCR0(pll->id), hw_state->cfgcr0);
+	I915_WRITE(ICL_DPLL_CFGCR1(pll->id), hw_state->cfgcr1);
+	POSTING_READ(ICL_DPLL_CFGCR1(pll->id));
+}
+
+static void icl_mg_pll_write(struct drm_i915_private *dev_priv,
+			     struct intel_shared_dpll *pll)
+{
+	struct intel_dpll_hw_state *hw_state = &pll->state.hw_state;
+	enum port port = icl_mg_pll_id_to_port(pll->id);
+
+	I915_WRITE(MG_REFCLKIN_CTL(port), hw_state->mg_refclkin_ctl);
+	I915_WRITE(MG_CLKTOP2_CORECLKCTL1(port),
+		   hw_state->mg_clktop2_coreclkctl1);
+	I915_WRITE(MG_CLKTOP2_HSCLKCTL(port), hw_state->mg_clktop2_hsclkctl);
+	I915_WRITE(MG_PLL_DIV0(port), hw_state->mg_pll_div0);
+	I915_WRITE(MG_PLL_DIV1(port), hw_state->mg_pll_div1);
+	I915_WRITE(MG_PLL_LF(port), hw_state->mg_pll_lf);
+	I915_WRITE(MG_PLL_FRAC_LOCK(port), hw_state->mg_pll_frac_lock);
+	I915_WRITE(MG_PLL_SSC(port), hw_state->mg_pll_ssc);
+	I915_WRITE(MG_PLL_BIAS(port), hw_state->mg_pll_bias);
+	I915_WRITE(MG_PLL_TDC_COLDST_BIAS(port),
+		   hw_state->mg_pll_tdc_coldst_bias);
+	POSTING_READ(MG_PLL_TDC_COLDST_BIAS(port));
+}
+
+static void icl_pll_enable(struct drm_i915_private *dev_priv,
+			   struct intel_shared_dpll *pll)
+{
+	enum intel_dpll_id id = pll->id;
+	i915_reg_t enable_reg = icl_pll_id_to_enable_reg(id);
+	uint32_t val;
+
+	val = I915_READ(enable_reg);
+	val |= PLL_POWER_ENABLE;
+	I915_WRITE(enable_reg, val);
+
+	/*
+	 * The spec says we need to "wait" but it also says it should be
+	 * immediate.
+	 */
+	if (intel_wait_for_register(dev_priv, enable_reg, PLL_POWER_STATE,
+				    PLL_POWER_STATE, 1))
+		DRM_ERROR("PLL %d Power not enabled\n", id);
+
+	switch (id) {
+	case DPLL_ID_ICL_DPLL0:
+	case DPLL_ID_ICL_DPLL1:
+		icl_dpll_write(dev_priv, pll);
+		break;
+	case DPLL_ID_ICL_MGPLL1:
+	case DPLL_ID_ICL_MGPLL2:
+	case DPLL_ID_ICL_MGPLL3:
+	case DPLL_ID_ICL_MGPLL4:
+		icl_mg_pll_write(dev_priv, pll);
+		break;
+	default:
+		MISSING_CASE(id);
+	}
+
+	/*
+	 * DVFS pre sequence would be here, but in our driver the cdclk code
+	 * paths should already be setting the appropriate voltage, hence we do
+	 * nothign here.
+	 */
+
+	val = I915_READ(enable_reg);
+	val |= PLL_ENABLE;
+	I915_WRITE(enable_reg, val);
+
+	if (intel_wait_for_register(dev_priv, enable_reg, PLL_LOCK, PLL_LOCK,
+				    1)) /* 600us actually. */
+		DRM_ERROR("PLL %d not locked\n", id);
+
+	/* DVFS post sequence would be here. See the comment above. */
+}
+
+static void icl_pll_disable(struct drm_i915_private *dev_priv,
+			    struct intel_shared_dpll *pll)
+{
+	enum intel_dpll_id id = pll->id;
+	i915_reg_t enable_reg = icl_pll_id_to_enable_reg(id);
+	uint32_t val;
+
+	/* The first steps are done by intel_ddi_post_disable(). */
+
+	/*
+	 * DVFS pre sequence would be here, but in our driver the cdclk code
+	 * paths should already be setting the appropriate voltage, hence we do
+	 * nothign here.
+	 */
+
+	val = I915_READ(enable_reg);
+	val &= ~PLL_ENABLE;
+	I915_WRITE(enable_reg, val);
+
+	/* Timeout is actually 1us. */
+	if (intel_wait_for_register(dev_priv, enable_reg, PLL_LOCK, 0, 1))
+		DRM_ERROR("PLL %d locked\n", id);
+
+	/* DVFS post sequence would be here. See the comment above. */
+
+	val = I915_READ(enable_reg);
+	val &= ~PLL_POWER_ENABLE;
+	I915_WRITE(enable_reg, val);
+
+	/*
+	 * The spec says we need to "wait" but it also says it should be
+	 * immediate.
+	 */
+	if (intel_wait_for_register(dev_priv, enable_reg, PLL_POWER_STATE, 0,
+				    1))
+		DRM_ERROR("PLL %d Power not disabled\n", id);
+}
+
+static void icl_dump_hw_state(struct drm_i915_private *dev_priv,
+			      struct intel_dpll_hw_state *hw_state)
+{
+	DRM_DEBUG_KMS("dpll_hw_state: cfgcr0: 0x%x, cfgcr1: 0x%x, "
+		      "mg_refclkin_ctl: 0x%x, hg_clktop2_coreclkctl1: 0x%x, "
+		      "mg_clktop2_hsclkctl: 0x%x, mg_pll_div0: 0x%x, "
+		      "mg_pll_div2: 0x%x, mg_pll_lf: 0x%x, "
+		      "mg_pll_frac_lock: 0x%x, mg_pll_ssc: 0x%x, "
+		      "mg_pll_bias: 0x%x, mg_pll_tdc_coldst_bias: 0x%x\n",
+		      hw_state->cfgcr0, hw_state->cfgcr1,
+		      hw_state->mg_refclkin_ctl,
+		      hw_state->mg_clktop2_coreclkctl1,
+		      hw_state->mg_clktop2_hsclkctl,
+		      hw_state->mg_pll_div0,
+		      hw_state->mg_pll_div1,
+		      hw_state->mg_pll_lf,
+		      hw_state->mg_pll_frac_lock,
+		      hw_state->mg_pll_ssc,
+		      hw_state->mg_pll_bias,
+		      hw_state->mg_pll_tdc_coldst_bias);
+}
+
+static const struct intel_shared_dpll_funcs icl_pll_funcs = {
+	.enable = icl_pll_enable,
+	.disable = icl_pll_disable,
+	.get_hw_state = icl_pll_get_hw_state,
+};
+
+static const struct dpll_info icl_plls[] = {
+	{ "DPLL 0",   DPLL_ID_ICL_DPLL0,  &icl_pll_funcs, 0 },
+	{ "DPLL 1",   DPLL_ID_ICL_DPLL1,  &icl_pll_funcs, 0 },
+	{ "MG PLL 1", DPLL_ID_ICL_MGPLL1, &icl_pll_funcs, 0 },
+	{ "MG PLL 2", DPLL_ID_ICL_MGPLL2, &icl_pll_funcs, 0 },
+	{ "MG PLL 3", DPLL_ID_ICL_MGPLL3, &icl_pll_funcs, 0 },
+	{ "MG PLL 4", DPLL_ID_ICL_MGPLL4, &icl_pll_funcs, 0 },
+	{ NULL, -1, NULL, 0 },
+};
+
+static const struct intel_dpll_mgr icl_pll_mgr = {
+	.dpll_info = icl_plls,
+	.get_dpll = icl_get_dpll,
+	.dump_hw_state = icl_dump_hw_state,
+};
+
 /**
  * intel_shared_dpll_init - Initialize shared DPLLs
  * @dev: drm device
@@ -2397,7 +2704,9 @@ void intel_shared_dpll_init(struct drm_device *dev)
 	const struct dpll_info *dpll_info;
 	int i;
 
-	if (IS_CANNONLAKE(dev_priv))
+	if (IS_ICELAKE(dev_priv))
+		dpll_mgr = &icl_pll_mgr;
+	else if (IS_CANNONLAKE(dev_priv))
 		dpll_mgr = &cnl_pll_mgr;
 	else if (IS_GEN9_BC(dev_priv))
 		dpll_mgr = &skl_pll_mgr;
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
index f24ccf443d25..eb0e10b24c6f 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -103,6 +103,32 @@ enum intel_dpll_id {
 	 * @DPLL_ID_SKL_DPLL3: SKL and later DPLL3
 	 */
 	DPLL_ID_SKL_DPLL3 = 3,
+
+
+	/**
+	 * @DPLL_ID_ICL_DPLL0: ICL combo PHY DPLL0
+	 */
+	DPLL_ID_ICL_DPLL0 = 0,
+	/**
+	 * @DPLL_ID_ICL_DPLL1: ICL combo PHY DPLL1
+	 */
+	DPLL_ID_ICL_DPLL1 = 1,
+	/**
+	 * @DPLL_ID_ICL_MGPLL1: ICL MG PLL 1 port 1 (C)
+	 */
+	DPLL_ID_ICL_MGPLL1 = 2,
+	/**
+	 * @DPLL_ID_ICL_MGPLL2: ICL MG PLL 1 port 2 (D)
+	 */
+	DPLL_ID_ICL_MGPLL2 = 3,
+	/**
+	 * @DPLL_ID_ICL_MGPLL3: ICL MG PLL 1 port 3 (E)
+	 */
+	DPLL_ID_ICL_MGPLL3 = 4,
+	/**
+	 * @DPLL_ID_ICL_MGPLL4: ICL MG PLL 1 port 4 (F)
+	 */
+	DPLL_ID_ICL_MGPLL4 = 5,
 };
 #define I915_NUM_PLLS 6
 
@@ -135,6 +161,21 @@ struct intel_dpll_hw_state {
 	/* bxt */
 	uint32_t ebb0, ebb4, pll0, pll1, pll2, pll3, pll6, pll8, pll9, pll10,
 		 pcsdw12;
+
+	/*
+	 * ICL uses the following, already defined:
+	 * uint32_t cfgcr0, cfgcr1;
+	 */
+	uint32_t mg_refclkin_ctl;
+	uint32_t mg_clktop2_coreclkctl1;
+	uint32_t mg_clktop2_hsclkctl;
+	uint32_t mg_pll_div0;
+	uint32_t mg_pll_div1;
+	uint32_t mg_pll_lf;
+	uint32_t mg_pll_frac_lock;
+	uint32_t mg_pll_ssc;
+	uint32_t mg_pll_bias;
+	uint32_t mg_pll_tdc_coldst_bias;
 };
 
 /**
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index a215aa78b0be..99976690db76 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1389,6 +1389,12 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
 u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder);
 int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
 				     bool enable);
+void icl_map_plls_to_ports(struct drm_crtc *crtc,
+			   struct intel_crtc_state *crtc_state,
+			   struct drm_atomic_state *old_state);
+void icl_unmap_plls_to_ports(struct drm_crtc *crtc,
+			     struct intel_crtc_state *crtc_state,
+			     struct drm_atomic_state *old_state);
 
 unsigned int intel_fb_align_height(const struct drm_framebuffer *fb,
 				   int plane, unsigned int height);
-- 
2.14.3

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

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

* [PATCH 08/17] drm/i915/icl: Implement voltage swing programming sequence for Combo PHY DDI
  2018-02-22  3:55 ` [PATCH 08/17] drm/i915/icl: Implement voltage swing programming sequence for Combo PHY DDI Paulo Zanoni
  2018-03-22 22:23   ` Paulo Zanoni
@ 2018-03-23  0:10   ` Paulo Zanoni
  2018-04-28  0:28     ` Rodrigo Vivi
  2018-04-06  0:20   ` Rodrigo Vivi
  2 siblings, 1 reply; 41+ messages in thread
From: Paulo Zanoni @ 2018-03-23  0:10 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi, Paulo Zanoni

From: Manasi Navare <manasi.d.navare@intel.com>

This is an important part of the DDI initalization as well as
for changing the voltage during DisplayPort link training.

The Voltage swing seqeuence is similar to Cannonlake.
However it has different register definitions and hence
it makes sense to create a separate vswing sequence and
program functions for ICL to leave room for more changes
in case the Bspec changes later and deviates from CNL sequence.

v2:
Use ~TAP3_DISABLE for enbaling that bit (Jani Nikula)

v3:
* Use dw4_scaling column for PORT_TX_DW4 values (Rodrigo)

v4:
* Call it combo_vswing, use switch statement (Paulo)

v5 (from Paulo):
* Fix a typo.
* s/rate < 600000/rate <= 600000/.
* Don't remove blank lines that should be there.

v6:
* Rebased by Rodrigo on top of Cannonlake changes
  where non vswing sequences are not aligned with iboost
  anymore.

v7: Another rebase after an upstream rework.

v8 (from Paulo):
* Adjust the code to the upstream output type changes.
* Squash the patch that moved some functions up.
* Merge both get_combo_buf_trans functions in order to simplify the
  code.
* Change the changelog format.

v9 (from Paulo):
* Use RTERM_SELECT instead of SCALING_MODE_SEL.
* Adjust the output type handling according to how the other platforms
  do it now.

Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 191 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 188 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 355dd4729ae8..15bafc850907 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -850,6 +850,45 @@ cnl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
 	}
 }
 
+static const struct icl_combo_phy_ddi_buf_trans *
+icl_get_combo_buf_trans(struct drm_i915_private *dev_priv, enum port port,
+			int type, int *n_entries)
+{
+	u32 voltage = I915_READ(ICL_PORT_COMP_DW3(port)) & VOLTAGE_INFO_MASK;
+
+	if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.low_vswing) {
+		switch (voltage) {
+		case VOLTAGE_INFO_0_85V:
+			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_85V);
+			return icl_combo_phy_ddi_translations_edp_0_85V;
+		case VOLTAGE_INFO_0_95V:
+			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_95V);
+			return icl_combo_phy_ddi_translations_edp_0_95V;
+		case VOLTAGE_INFO_1_05V:
+			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_1_05V);
+			return icl_combo_phy_ddi_translations_edp_1_05V;
+		default:
+			MISSING_CASE(voltage);
+			return NULL;
+		}
+	} else {
+		switch (voltage) {
+		case VOLTAGE_INFO_0_85V:
+			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_85V);
+			return icl_combo_phy_ddi_translations_dp_hdmi_0_85V;
+		case VOLTAGE_INFO_0_95V:
+			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_95V);
+			return icl_combo_phy_ddi_translations_dp_hdmi_0_95V;
+		case VOLTAGE_INFO_1_05V:
+			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_1_05V);
+			return icl_combo_phy_ddi_translations_dp_hdmi_1_05V;
+		default:
+			MISSING_CASE(voltage);
+			return NULL;
+		}
+	}
+}
+
 static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port port)
 {
 	int n_entries, level, default_entry;
@@ -2179,6 +2218,146 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
 	I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val);
 }
 
+static void icl_ddi_combo_vswing_program(struct drm_i915_private *dev_priv,
+					 u32 level, enum port port, int type)
+{
+	const struct icl_combo_phy_ddi_buf_trans *ddi_translations = NULL;
+	u32 n_entries, val;
+	int ln;
+
+	ddi_translations = icl_get_combo_buf_trans(dev_priv, port, type,
+						   &n_entries);
+	if (!ddi_translations)
+		return;
+
+	if (level >= n_entries) {
+		DRM_DEBUG_KMS("DDI translation not found for level %d. Using %d instead.", level, n_entries - 1);
+		level = n_entries - 1;
+	}
+
+	/* Set PORT_TX_DW5 Scaling Mode Sel to 110b. */
+	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
+	val &= ~RTERM_SELECT_MASK;
+	val |= RTERM_SELECT(0x6);
+	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
+
+	/* Program PORT_TX_DW5 */
+	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
+	/* Set DisableTap2 and DisableTap3 if MIPI DSI
+	 * Clear DisableTap2 and DisableTap3 for all other Ports
+	 */
+	if (type == INTEL_OUTPUT_DSI) {
+		val |= TAP2_DISABLE;
+		val |= TAP3_DISABLE;
+	} else {
+		val &= ~TAP2_DISABLE;
+		val &= ~TAP3_DISABLE;
+	}
+	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
+
+	/* Program PORT_TX_DW2 */
+	val = I915_READ(ICL_PORT_TX_DW2_LN0(port));
+	val &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
+		 RCOMP_SCALAR_MASK);
+	val |= SWING_SEL_UPPER(ddi_translations[level].dw2_swing_select);
+	val |= SWING_SEL_LOWER(ddi_translations[level].dw2_swing_select);
+	/* Program Rcomp scalar for every table entry */
+	val |= RCOMP_SCALAR(ddi_translations[level].dw2_swing_scalar);
+	I915_WRITE(ICL_PORT_TX_DW2_GRP(port), val);
+
+	/* Program PORT_TX_DW4 */
+	/* We cannot write to GRP. It would overwrite individual loadgen. */
+	for (ln = 0; ln <= 3; ln++) {
+		val = I915_READ(ICL_PORT_TX_DW4_LN(port, ln));
+		val &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
+			 CURSOR_COEFF_MASK);
+		val |= ddi_translations[level].dw4_scaling;
+		I915_WRITE(ICL_PORT_TX_DW4_LN(port, ln), val);
+	}
+}
+
+static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
+					      u32 level,
+					      enum intel_output_type type)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	enum port port = encoder->port;
+	int width = 0;
+	int rate = 0;
+	u32 val;
+	int ln = 0;
+
+	if (type == INTEL_OUTPUT_HDMI) {
+		width = 4;
+		/* Rate is always < than 6GHz for HDMI */
+	} else {
+		struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+
+		width = intel_dp->lane_count;
+		rate = intel_dp->link_rate;
+	}
+
+	/*
+	 * 1. If port type is eDP or DP,
+	 * set PORT_PCS_DW1 cmnkeeper_enable to 1b,
+	 * else clear to 0b.
+	 */
+	val = I915_READ(ICL_PORT_PCS_DW1_LN0(port));
+	if (type == INTEL_OUTPUT_HDMI)
+		val &= ~COMMON_KEEPER_EN;
+	else
+		val |= COMMON_KEEPER_EN;
+	I915_WRITE(ICL_PORT_PCS_DW1_GRP(port), val);
+
+	/* 2. Program loadgen select */
+	/*
+	 * Program PORT_TX_DW4_LN depending on Bit rate and used lanes
+	 * <= 6 GHz and 4 lanes (LN0=0, LN1=1, LN2=1, LN3=1)
+	 * <= 6 GHz and 1,2 lanes (LN0=0, LN1=1, LN2=1, LN3=0)
+	 * > 6 GHz (LN0=0, LN1=0, LN2=0, LN3=0)
+	 */
+	for (ln = 0; ln <= 3; ln++) {
+		val = I915_READ(ICL_PORT_TX_DW4_LN(port, ln));
+		val &= ~LOADGEN_SELECT;
+
+		if ((rate <= 600000 && width == 4 && ln >= 1) ||
+		    (rate <= 600000 && width < 4 && (ln == 1 || ln == 2))) {
+			val |= LOADGEN_SELECT;
+		}
+		I915_WRITE(ICL_PORT_TX_DW4_LN(port, ln), val);
+	}
+
+	/* 3. Set PORT_CL_DW5 SUS Clock Config to 11b */
+	val = I915_READ(ICL_PORT_CL_DW5(port));
+	val |= SUS_CLOCK_CONFIG;
+	I915_WRITE(ICL_PORT_CL_DW5(port), val);
+
+	/* 4. Clear training enable to change swing values */
+	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
+	val &= ~TX_TRAINING_EN;
+	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
+
+	/* 5. Program swing and de-emphasis */
+	icl_ddi_combo_vswing_program(dev_priv, level, port, type);
+
+	/* 6. Set training enable to trigger update */
+	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
+	val |= TX_TRAINING_EN;
+	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
+}
+
+static void icl_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level,
+				    enum intel_output_type type)
+{
+	enum port port = encoder->port;
+
+	if (port == PORT_A || port == PORT_B)
+		icl_combo_phy_ddi_vswing_sequence(encoder, level, type);
+	else
+		/* Not Implemented Yet */
+		WARN_ON(1);
+}
+
 static uint32_t translate_signal_level(int signal_levels)
 {
 	int i;
@@ -2210,7 +2389,9 @@ u32 bxt_signal_levels(struct intel_dp *intel_dp)
 	struct intel_encoder *encoder = &dport->base;
 	int level = intel_ddi_dp_level(intel_dp);
 
-	if (IS_CANNONLAKE(dev_priv))
+	if (IS_ICELAKE(dev_priv))
+		icl_ddi_vswing_sequence(encoder, level, encoder->type);
+	else if (IS_CANNONLAKE(dev_priv))
 		cnl_ddi_vswing_sequence(encoder, level, encoder->type);
 	else
 		bxt_ddi_vswing_sequence(encoder, level, encoder->type);
@@ -2384,7 +2565,9 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
 
 	intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain);
 
-	if (IS_CANNONLAKE(dev_priv))
+	if (IS_ICELAKE(dev_priv))
+		icl_ddi_vswing_sequence(encoder, level, encoder->type);
+	else if (IS_CANNONLAKE(dev_priv))
 		cnl_ddi_vswing_sequence(encoder, level, encoder->type);
 	else if (IS_GEN9_LP(dev_priv))
 		bxt_ddi_vswing_sequence(encoder, level, encoder->type);
@@ -2414,7 +2597,9 @@ static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
 
 	intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain);
 
-	if (IS_CANNONLAKE(dev_priv))
+	if (IS_ICELAKE(dev_priv))
+		icl_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
+	else if (IS_CANNONLAKE(dev_priv))
 		cnl_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
 	else if (IS_GEN9_LP(dev_priv))
 		bxt_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
-- 
2.14.3

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

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

* ✗ Fi.CI.BAT: failure for ICL PLLs, DP/HDMI and misc display (rev4)
  2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
                   ` (19 preceding siblings ...)
  2018-03-23  0:05 ` [PATCH 00/17] " Paulo Zanoni
@ 2018-03-23  1:00 ` Patchwork
  20 siblings, 0 replies; 41+ messages in thread
From: Patchwork @ 2018-03-23  1:00 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx

== Series Details ==

Series: ICL PLLs, DP/HDMI and misc display (rev4)
URL   : https://patchwork.freedesktop.org/series/38737/
State : failure

== Summary ==

Applying: drm/i915/icl: add basic support for the ICL clocks
Applying: drm/i915/icl: add basic support for the ICL clocks
error: Failed to merge in the changes.
Using index info to reconstruct a base tree...
M	drivers/gpu/drm/i915/i915_debugfs.c
M	drivers/gpu/drm/i915/intel_ddi.c
M	drivers/gpu/drm/i915/intel_display.c
M	drivers/gpu/drm/i915/intel_dpll_mgr.c
M	drivers/gpu/drm/i915/intel_dpll_mgr.h
M	drivers/gpu/drm/i915/intel_drv.h
Falling back to patching base and 3-way merge...
Auto-merging drivers/gpu/drm/i915/intel_display.c
CONFLICT (content): Merge conflict in drivers/gpu/drm/i915/intel_display.c
Auto-merging drivers/gpu/drm/i915/intel_ddi.c
CONFLICT (content): Merge conflict in drivers/gpu/drm/i915/intel_ddi.c
Patch failed at 0002 drm/i915/icl: add basic support for the ICL clocks
The copy of the patch that failed is found in: .git/rebase-apply/patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

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

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

* Re: [PATCH 08/17] drm/i915/icl: Implement voltage swing programming sequence for Combo PHY DDI
  2018-02-22  3:55 ` [PATCH 08/17] drm/i915/icl: Implement voltage swing programming sequence for Combo PHY DDI Paulo Zanoni
  2018-03-22 22:23   ` Paulo Zanoni
  2018-03-23  0:10   ` Paulo Zanoni
@ 2018-04-06  0:20   ` Rodrigo Vivi
  2018-04-25  0:34     ` Paulo Zanoni
  2 siblings, 1 reply; 41+ messages in thread
From: Rodrigo Vivi @ 2018-04-06  0:20 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx

On Thu, Feb 22, 2018 at 12:55:10AM -0300, Paulo Zanoni wrote:
> From: Manasi Navare <manasi.d.navare@intel.com>
> 
> This is an important part of the DDI initalization as well as
> for changing the voltage during DisplayPort link training.
> 
> The Voltage swing seqeuence is similar to Cannonlake.
> However it has different register definitions and hence
> it makes sense to create a separate vswing sequence and
> program functions for ICL to leave room for more changes
> in case the Bspec changes later and deviates from CNL sequence.
> 
> v2:
> Use ~TAP3_DISABLE for enbaling that bit (Jani Nikula)
> 
> v3:
> * Use dw4_scaling column for PORT_TX_DW4 values (Rodrigo)
> 
> v4:
> * Call it combo_vswing, use switch statement (Paulo)
> 
> v5 (from Paulo):
> * Fix a typo.
> * s/rate < 600000/rate <= 600000/.
> * Don't remove blank lines that should be there.
> 
> v6:
> * Rebased by Rodrigo on top of Cannonlake changes
>   where non vswing sequences are not aligned with iboost
>   anymore.
> 
> v7: Another rebase after an upstream rework.
> 
> v8 (from Paulo):
> * Adjust the code to the upstream output type changes.
> * Squash the patch that moved some functions up.
> * Merge both get_combo_buf_trans functions in order to simplify the
>   code.
> * Change the changelog format.
> 
> Cc: Jani Nikula <jani.nikula@linux.intel.com>
> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v5)
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 189 ++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 186 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 0a4683991ec2..c38873cb98ca 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -849,6 +849,45 @@ cnl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
>  	}
>  }
>  
> +static const struct icl_combo_phy_ddi_buf_trans *
> +icl_get_combo_buf_trans(struct drm_i915_private *dev_priv, enum port port,
> +			int type, int *n_entries)
> +{
> +	u32 voltage = I915_READ(ICL_PORT_COMP_DW3(port)) & VOLTAGE_INFO_MASK;
> +
> +	if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.low_vswing) {
> +		switch (voltage) {
> +		case VOLTAGE_INFO_0_85V:
> +			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_85V);
> +			return icl_combo_phy_ddi_translations_edp_0_85V;
> +		case VOLTAGE_INFO_0_95V:
> +			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_95V);
> +			return icl_combo_phy_ddi_translations_edp_0_95V;
> +		case VOLTAGE_INFO_1_05V:
> +			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_1_05V);
> +			return icl_combo_phy_ddi_translations_edp_1_05V;
> +		default:
> +			MISSING_CASE(voltage);
> +			return NULL;
> +		}
> +	} else {

DP ends up here on HDMI?
This is strange...

Also, for clarity, why not to split this into separated functions
like all other platforms?

> +		switch (voltage) {
> +		case VOLTAGE_INFO_0_85V:
> +			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_85V);
> +			return icl_combo_phy_ddi_translations_dp_hdmi_0_85V;
> +		case VOLTAGE_INFO_0_95V:
> +			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_95V);
> +			return icl_combo_phy_ddi_translations_dp_hdmi_0_95V;
> +		case VOLTAGE_INFO_1_05V:
> +			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_1_05V);
> +			return icl_combo_phy_ddi_translations_dp_hdmi_1_05V;
> +		default:
> +			MISSING_CASE(voltage);
> +			return NULL;
> +		}
> +	}
> +}
> +
>  static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port port)
>  {
>  	int n_entries, level, default_entry;
> @@ -2178,6 +2217,144 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
>  	I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val);
>  }
>  
> +static void icl_ddi_combo_vswing_program(struct drm_i915_private *dev_priv,
> +					 u32 level, enum port port, int type)
> +{
> +	const struct icl_combo_phy_ddi_buf_trans *ddi_translations = NULL;
> +	u32 n_entries, val;
> +	int ln;
> +
> +	ddi_translations = icl_get_combo_buf_trans(dev_priv, port, type,
> +						   &n_entries);
> +	if (!ddi_translations)
> +		return;
> +
> +	if (level >= n_entries) {
> +		DRM_DEBUG_KMS("DDI translation not found for level %d. Using %d instead.", level, n_entries - 1);
> +		level = n_entries - 1;
> +	}
> +
> +	/* Set PORT_TX_DW5 Scaling Mode Sel to 110b. */
> +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> +	val &= ~SCALING_MODE_SEL_MASK;
> +	val |= SCALING_MODE_SEL(0x6);
> +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> +
> +	/* Program PORT_TX_DW5 */
> +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> +	/* Set DisableTap2 and DisableTap3 if MIPI DSI
> +	 * Clear DisableTap2 and DisableTap3 for all other Ports
> +	 */
> +	if (type == INTEL_OUTPUT_DSI) {
> +		val |= TAP2_DISABLE;
> +		val |= TAP3_DISABLE;
> +	} else {
> +		val &= ~TAP2_DISABLE;
> +		val &= ~TAP3_DISABLE;
> +	}
> +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> +
> +	/* Program PORT_TX_DW2 */
> +	val = I915_READ(ICL_PORT_TX_DW2_LN0(port));
> +	val &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
> +		 RCOMP_SCALAR_MASK);
> +	val |= SWING_SEL_UPPER(ddi_translations[level].dw2_swing_select);
> +	val |= SWING_SEL_LOWER(ddi_translations[level].dw2_swing_select);
> +	/* Program Rcomp scalar for every table entry */
> +	val |= RCOMP_SCALAR(ddi_translations[level].dw2_swing_scalar);
> +	I915_WRITE(ICL_PORT_TX_DW2_GRP(port), val);
> +
> +	/* Program PORT_TX_DW4 */
> +	/* We cannot write to GRP. It would overwrite individual loadgen. */
> +	for (ln = 0; ln <= 3; ln++) {
> +		val = I915_READ(ICL_PORT_TX_DW4_LN(port, ln));
> +		val &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
> +			 CURSOR_COEFF_MASK);
> +		val |= ddi_translations[level].dw4_scaling;
> +		I915_WRITE(ICL_PORT_TX_DW4_LN(port, ln), val);
> +	}
> +}
> +
> +static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	enum port port = encoder->port;
> +	int type = encoder->type;
> +	int width = 0;
> +	int rate = 0;
> +	u32 val;
> +	int ln = 0;
> +
> +	if (type == INTEL_OUTPUT_HDMI) {
> +		width = 4;
> +		/* Rate is always < than 6GHz for HDMI */
> +	} else {
> +		struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
> +
> +		width = intel_dp->lane_count;
> +		rate = intel_dp->link_rate;
> +	}
> +
> +	/*
> +	 * 1. If port type is eDP or DP,
> +	 * set PORT_PCS_DW1 cmnkeeper_enable to 1b,
> +	 * else clear to 0b.
> +	 */
> +	val = I915_READ(ICL_PORT_PCS_DW1_LN0(port));
> +	if (type == INTEL_OUTPUT_HDMI)
> +		val &= ~COMMON_KEEPER_EN;
> +	else
> +		val |= COMMON_KEEPER_EN;
> +	I915_WRITE(ICL_PORT_PCS_DW1_GRP(port), val);
> +
> +	/* 2. Program loadgen select */
> +	/*
> +	 * Program PORT_TX_DW4_LN depending on Bit rate and used lanes
> +	 * <= 6 GHz and 4 lanes (LN0=0, LN1=1, LN2=1, LN3=1)
> +	 * <= 6 GHz and 1,2 lanes (LN0=0, LN1=1, LN2=1, LN3=0)
> +	 * > 6 GHz (LN0=0, LN1=0, LN2=0, LN3=0)
> +	 */
> +	for (ln = 0; ln <= 3; ln++) {
> +		val = I915_READ(ICL_PORT_TX_DW4_LN(port, ln));
> +		val &= ~LOADGEN_SELECT;
> +
> +		if ((rate <= 600000 && width == 4 && ln >= 1) ||
> +		    (rate <= 600000 && width < 4 && (ln == 1 || ln == 2))) {
> +			val |= LOADGEN_SELECT;
> +		}
> +		I915_WRITE(ICL_PORT_TX_DW4_LN(port, ln), val);
> +	}
> +
> +	/* 3. Set PORT_CL_DW5 SUS Clock Config to 11b */
> +	val = I915_READ(ICL_PORT_CL_DW5(port));
> +	val |= SUS_CLOCK_CONFIG;
> +	I915_WRITE(ICL_PORT_CL_DW5(port), val);
> +
> +	/* 4. Clear training enable to change swing values */
> +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> +	val &= ~TX_TRAINING_EN;
> +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> +
> +	/* 5. Program swing and de-emphasis */
> +	icl_ddi_combo_vswing_program(dev_priv, level, port, type);
> +
> +	/* 6. Set training enable to trigger update */
> +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> +	val |= TX_TRAINING_EN;
> +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> +}
> +
> +static void icl_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level)
> +{
> +	enum port port = encoder->port;
> +
> +	if (port == PORT_A || port == PORT_B)
> +		icl_combo_phy_ddi_vswing_sequence(encoder, level);
> +	else
> +		/* Not Implemented Yet */
> +		WARN_ON(1);
> +}
> +
>  static uint32_t translate_signal_level(int signal_levels)
>  {
>  	int i;
> @@ -2209,7 +2386,9 @@ u32 bxt_signal_levels(struct intel_dp *intel_dp)
>  	struct intel_encoder *encoder = &dport->base;
>  	int level = intel_ddi_dp_level(intel_dp);
>  
> -	if (IS_CANNONLAKE(dev_priv))
> +	if (IS_ICELAKE(dev_priv))
> +		icl_ddi_vswing_sequence(encoder, level);
> +	else if (IS_CANNONLAKE(dev_priv))
>  		cnl_ddi_vswing_sequence(encoder, level, encoder->type);
>  	else
>  		bxt_ddi_vswing_sequence(encoder, level, encoder->type);
> @@ -2389,7 +2568,9 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
>  
>  	intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain);
>  
> -	if (IS_CANNONLAKE(dev_priv))
> +	if (IS_ICELAKE(dev_priv))
> +		icl_ddi_vswing_sequence(encoder, level);
> +	else if (IS_CANNONLAKE(dev_priv))
>  		cnl_ddi_vswing_sequence(encoder, level, encoder->type);
>  	else if (IS_GEN9_LP(dev_priv))
>  		bxt_ddi_vswing_sequence(encoder, level, encoder->type);
> @@ -2420,7 +2601,9 @@ static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
>  
>  	intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain);
>  
> -	if (IS_CANNONLAKE(dev_priv))
> +	if (IS_ICELAKE(dev_priv))
> +		icl_ddi_vswing_sequence(encoder, level);
> +	else if (IS_CANNONLAKE(dev_priv))
>  		cnl_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
>  	else if (IS_GEN9_LP(dev_priv))
>  		bxt_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
> -- 
> 2.14.3
> 
> _______________________________________________
> 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] 41+ messages in thread

* Re: [PATCH 08/17] drm/i915/icl: Implement voltage swing programming sequence for Combo PHY DDI
  2018-04-06  0:20   ` Rodrigo Vivi
@ 2018-04-25  0:34     ` Paulo Zanoni
  2018-04-25 18:01       ` Rodrigo Vivi
  0 siblings, 1 reply; 41+ messages in thread
From: Paulo Zanoni @ 2018-04-25  0:34 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

Em Qui, 2018-04-05 às 17:20 -0700, Rodrigo Vivi escreveu:
> On Thu, Feb 22, 2018 at 12:55:10AM -0300, Paulo Zanoni wrote:
> > From: Manasi Navare <manasi.d.navare@intel.com>
> > 
> > This is an important part of the DDI initalization as well as
> > for changing the voltage during DisplayPort link training.
> > 
> > The Voltage swing seqeuence is similar to Cannonlake.
> > However it has different register definitions and hence
> > it makes sense to create a separate vswing sequence and
> > program functions for ICL to leave room for more changes
> > in case the Bspec changes later and deviates from CNL sequence.
> > 
> > v2:
> > Use ~TAP3_DISABLE for enbaling that bit (Jani Nikula)
> > 
> > v3:
> > * Use dw4_scaling column for PORT_TX_DW4 values (Rodrigo)
> > 
> > v4:
> > * Call it combo_vswing, use switch statement (Paulo)
> > 
> > v5 (from Paulo):
> > * Fix a typo.
> > * s/rate < 600000/rate <= 600000/.
> > * Don't remove blank lines that should be there.
> > 
> > v6:
> > * Rebased by Rodrigo on top of Cannonlake changes
> >   where non vswing sequences are not aligned with iboost
> >   anymore.
> > 
> > v7: Another rebase after an upstream rework.
> > 
> > v8 (from Paulo):
> > * Adjust the code to the upstream output type changes.
> > * Squash the patch that moved some functions up.
> > * Merge both get_combo_buf_trans functions in order to simplify the
> >   code.
> > * Change the changelog format.
> > 
> > Cc: Jani Nikula <jani.nikula@linux.intel.com>
> > Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v5)
> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_ddi.c | 189
> > ++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 186 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c
> > b/drivers/gpu/drm/i915/intel_ddi.c
> > index 0a4683991ec2..c38873cb98ca 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -849,6 +849,45 @@ cnl_get_buf_trans_edp(struct drm_i915_private
> > *dev_priv, int *n_entries)
> >  	}
> >  }
> >  
> > +static const struct icl_combo_phy_ddi_buf_trans *
> > +icl_get_combo_buf_trans(struct drm_i915_private *dev_priv, enum
> > port port,
> > +			int type, int *n_entries)
> > +{
> > +	u32 voltage = I915_READ(ICL_PORT_COMP_DW3(port)) &
> > VOLTAGE_INFO_MASK;
> > +
> > +	if (type == INTEL_OUTPUT_EDP && dev_priv-
> > >vbt.edp.low_vswing) {
> > +		switch (voltage) {
> > +		case VOLTAGE_INFO_0_85V:
> > +			*n_entries =
> > ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_85V);
> > +			return
> > icl_combo_phy_ddi_translations_edp_0_85V;
> > +		case VOLTAGE_INFO_0_95V:
> > +			*n_entries =
> > ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_95V);
> > +			return
> > icl_combo_phy_ddi_translations_edp_0_95V;
> > +		case VOLTAGE_INFO_1_05V:
> > +			*n_entries =
> > ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_1_05V);
> > +			return
> > icl_combo_phy_ddi_translations_edp_1_05V;
> > +		default:
> > +			MISSING_CASE(voltage);
> > +			return NULL;
> > +		}
> > +	} else {
> 
> DP ends up here on HDMI?
> This is strange...

DP ends on the "dp_hdmi" part, while edp ends on the "edp" part. What
is strange about that?

> 
> Also, for clarity, why not to split this into separated functions
> like all other platforms?

So we don't end up reading PORT_COMP_DW3 multiple times (like we do for
CNL), and as a bonus the code looks better IMHO.



> 
> > +		switch (voltage) {
> > +		case VOLTAGE_INFO_0_85V:
> > +			*n_entries =
> > ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_85V);
> > +			return
> > icl_combo_phy_ddi_translations_dp_hdmi_0_85V;
> > +		case VOLTAGE_INFO_0_95V:
> > +			*n_entries =
> > ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_95V);
> > +			return
> > icl_combo_phy_ddi_translations_dp_hdmi_0_95V;
> > +		case VOLTAGE_INFO_1_05V:
> > +			*n_entries =
> > ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_1_05V);
> > +			return
> > icl_combo_phy_ddi_translations_dp_hdmi_1_05V;
> > +		default:
> > +			MISSING_CASE(voltage);
> > +			return NULL;
> > +		}
> > +	}
> > +}
> > +
> >  static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv,
> > enum port port)
> >  {
> >  	int n_entries, level, default_entry;
> > @@ -2178,6 +2217,144 @@ static void cnl_ddi_vswing_sequence(struct
> > intel_encoder *encoder,
> >  	I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val);
> >  }
> >  
> > +static void icl_ddi_combo_vswing_program(struct drm_i915_private
> > *dev_priv,
> > +					 u32 level, enum port
> > port, int type)
> > +{
> > +	const struct icl_combo_phy_ddi_buf_trans *ddi_translations
> > = NULL;
> > +	u32 n_entries, val;
> > +	int ln;
> > +
> > +	ddi_translations = icl_get_combo_buf_trans(dev_priv, port,
> > type,
> > +						   &n_entries);
> > +	if (!ddi_translations)
> > +		return;
> > +
> > +	if (level >= n_entries) {
> > +		DRM_DEBUG_KMS("DDI translation not found for level
> > %d. Using %d instead.", level, n_entries - 1);
> > +		level = n_entries - 1;
> > +	}
> > +
> > +	/* Set PORT_TX_DW5 Scaling Mode Sel to 110b. */
> > +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> > +	val &= ~SCALING_MODE_SEL_MASK;
> > +	val |= SCALING_MODE_SEL(0x6);
> > +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> > +
> > +	/* Program PORT_TX_DW5 */
> > +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> > +	/* Set DisableTap2 and DisableTap3 if MIPI DSI
> > +	 * Clear DisableTap2 and DisableTap3 for all other Ports
> > +	 */
> > +	if (type == INTEL_OUTPUT_DSI) {
> > +		val |= TAP2_DISABLE;
> > +		val |= TAP3_DISABLE;
> > +	} else {
> > +		val &= ~TAP2_DISABLE;
> > +		val &= ~TAP3_DISABLE;
> > +	}
> > +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> > +
> > +	/* Program PORT_TX_DW2 */
> > +	val = I915_READ(ICL_PORT_TX_DW2_LN0(port));
> > +	val &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
> > +		 RCOMP_SCALAR_MASK);
> > +	val |=
> > SWING_SEL_UPPER(ddi_translations[level].dw2_swing_select);
> > +	val |=
> > SWING_SEL_LOWER(ddi_translations[level].dw2_swing_select);
> > +	/* Program Rcomp scalar for every table entry */
> > +	val |=
> > RCOMP_SCALAR(ddi_translations[level].dw2_swing_scalar);
> > +	I915_WRITE(ICL_PORT_TX_DW2_GRP(port), val);
> > +
> > +	/* Program PORT_TX_DW4 */
> > +	/* We cannot write to GRP. It would overwrite individual
> > loadgen. */
> > +	for (ln = 0; ln <= 3; ln++) {
> > +		val = I915_READ(ICL_PORT_TX_DW4_LN(port, ln));
> > +		val &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
> > +			 CURSOR_COEFF_MASK);
> > +		val |= ddi_translations[level].dw4_scaling;
> > +		I915_WRITE(ICL_PORT_TX_DW4_LN(port, ln), val);
> > +	}
> > +}
> > +
> > +static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder
> > *encoder, u32 level)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(encoder-
> > >base.dev);
> > +	enum port port = encoder->port;
> > +	int type = encoder->type;
> > +	int width = 0;
> > +	int rate = 0;
> > +	u32 val;
> > +	int ln = 0;
> > +
> > +	if (type == INTEL_OUTPUT_HDMI) {
> > +		width = 4;
> > +		/* Rate is always < than 6GHz for HDMI */
> > +	} else {
> > +		struct intel_dp *intel_dp =
> > enc_to_intel_dp(&encoder->base);
> > +
> > +		width = intel_dp->lane_count;
> > +		rate = intel_dp->link_rate;
> > +	}
> > +
> > +	/*
> > +	 * 1. If port type is eDP or DP,
> > +	 * set PORT_PCS_DW1 cmnkeeper_enable to 1b,
> > +	 * else clear to 0b.
> > +	 */
> > +	val = I915_READ(ICL_PORT_PCS_DW1_LN0(port));
> > +	if (type == INTEL_OUTPUT_HDMI)
> > +		val &= ~COMMON_KEEPER_EN;
> > +	else
> > +		val |= COMMON_KEEPER_EN;
> > +	I915_WRITE(ICL_PORT_PCS_DW1_GRP(port), val);
> > +
> > +	/* 2. Program loadgen select */
> > +	/*
> > +	 * Program PORT_TX_DW4_LN depending on Bit rate and used
> > lanes
> > +	 * <= 6 GHz and 4 lanes (LN0=0, LN1=1, LN2=1, LN3=1)
> > +	 * <= 6 GHz and 1,2 lanes (LN0=0, LN1=1, LN2=1, LN3=0)
> > +	 * > 6 GHz (LN0=0, LN1=0, LN2=0, LN3=0)
> > +	 */
> > +	for (ln = 0; ln <= 3; ln++) {
> > +		val = I915_READ(ICL_PORT_TX_DW4_LN(port, ln));
> > +		val &= ~LOADGEN_SELECT;
> > +
> > +		if ((rate <= 600000 && width == 4 && ln >= 1) ||
> > +		    (rate <= 600000 && width < 4 && (ln == 1 || ln
> > == 2))) {
> > +			val |= LOADGEN_SELECT;
> > +		}
> > +		I915_WRITE(ICL_PORT_TX_DW4_LN(port, ln), val);
> > +	}
> > +
> > +	/* 3. Set PORT_CL_DW5 SUS Clock Config to 11b */
> > +	val = I915_READ(ICL_PORT_CL_DW5(port));
> > +	val |= SUS_CLOCK_CONFIG;
> > +	I915_WRITE(ICL_PORT_CL_DW5(port), val);
> > +
> > +	/* 4. Clear training enable to change swing values */
> > +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> > +	val &= ~TX_TRAINING_EN;
> > +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> > +
> > +	/* 5. Program swing and de-emphasis */
> > +	icl_ddi_combo_vswing_program(dev_priv, level, port, type);
> > +
> > +	/* 6. Set training enable to trigger update */
> > +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> > +	val |= TX_TRAINING_EN;
> > +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> > +}
> > +
> > +static void icl_ddi_vswing_sequence(struct intel_encoder *encoder,
> > u32 level)
> > +{
> > +	enum port port = encoder->port;
> > +
> > +	if (port == PORT_A || port == PORT_B)
> > +		icl_combo_phy_ddi_vswing_sequence(encoder, level);
> > +	else
> > +		/* Not Implemented Yet */
> > +		WARN_ON(1);
> > +}
> > +
> >  static uint32_t translate_signal_level(int signal_levels)
> >  {
> >  	int i;
> > @@ -2209,7 +2386,9 @@ u32 bxt_signal_levels(struct intel_dp
> > *intel_dp)
> >  	struct intel_encoder *encoder = &dport->base;
> >  	int level = intel_ddi_dp_level(intel_dp);
> >  
> > -	if (IS_CANNONLAKE(dev_priv))
> > +	if (IS_ICELAKE(dev_priv))
> > +		icl_ddi_vswing_sequence(encoder, level);
> > +	else if (IS_CANNONLAKE(dev_priv))
> >  		cnl_ddi_vswing_sequence(encoder, level, encoder-
> > >type);
> >  	else
> >  		bxt_ddi_vswing_sequence(encoder, level, encoder-
> > >type);
> > @@ -2389,7 +2568,9 @@ static void intel_ddi_pre_enable_dp(struct
> > intel_encoder *encoder,
> >  
> >  	intel_display_power_get(dev_priv, dig_port-
> > >ddi_io_power_domain);
> >  
> > -	if (IS_CANNONLAKE(dev_priv))
> > +	if (IS_ICELAKE(dev_priv))
> > +		icl_ddi_vswing_sequence(encoder, level);
> > +	else if (IS_CANNONLAKE(dev_priv))
> >  		cnl_ddi_vswing_sequence(encoder, level, encoder-
> > >type);
> >  	else if (IS_GEN9_LP(dev_priv))
> >  		bxt_ddi_vswing_sequence(encoder, level, encoder-
> > >type);
> > @@ -2420,7 +2601,9 @@ static void intel_ddi_pre_enable_hdmi(struct
> > intel_encoder *encoder,
> >  
> >  	intel_display_power_get(dev_priv, dig_port-
> > >ddi_io_power_domain);
> >  
> > -	if (IS_CANNONLAKE(dev_priv))
> > +	if (IS_ICELAKE(dev_priv))
> > +		icl_ddi_vswing_sequence(encoder, level);
> > +	else if (IS_CANNONLAKE(dev_priv))
> >  		cnl_ddi_vswing_sequence(encoder, level,
> > INTEL_OUTPUT_HDMI);
> >  	else if (IS_GEN9_LP(dev_priv))
> >  		bxt_ddi_vswing_sequence(encoder, level,
> > INTEL_OUTPUT_HDMI);
> > -- 
> > 2.14.3
> > 
> > _______________________________________________
> > 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] 41+ messages in thread

* Re: [PATCH 08/17] drm/i915/icl: Implement voltage swing programming sequence for Combo PHY DDI
  2018-04-25  0:34     ` Paulo Zanoni
@ 2018-04-25 18:01       ` Rodrigo Vivi
  2018-04-25 23:33         ` Paulo Zanoni
  0 siblings, 1 reply; 41+ messages in thread
From: Rodrigo Vivi @ 2018-04-25 18:01 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx

On Tue, Apr 24, 2018 at 05:34:14PM -0700, Paulo Zanoni wrote:
> Em Qui, 2018-04-05 às 17:20 -0700, Rodrigo Vivi escreveu:
> > On Thu, Feb 22, 2018 at 12:55:10AM -0300, Paulo Zanoni wrote:
> > > From: Manasi Navare <manasi.d.navare@intel.com>
> > > 
> > > This is an important part of the DDI initalization as well as
> > > for changing the voltage during DisplayPort link training.
> > > 
> > > The Voltage swing seqeuence is similar to Cannonlake.
> > > However it has different register definitions and hence
> > > it makes sense to create a separate vswing sequence and
> > > program functions for ICL to leave room for more changes
> > > in case the Bspec changes later and deviates from CNL sequence.
> > > 
> > > v2:
> > > Use ~TAP3_DISABLE for enbaling that bit (Jani Nikula)
> > > 
> > > v3:
> > > * Use dw4_scaling column for PORT_TX_DW4 values (Rodrigo)
> > > 
> > > v4:
> > > * Call it combo_vswing, use switch statement (Paulo)
> > > 
> > > v5 (from Paulo):
> > > * Fix a typo.
> > > * s/rate < 600000/rate <= 600000/.
> > > * Don't remove blank lines that should be there.
> > > 
> > > v6:
> > > * Rebased by Rodrigo on top of Cannonlake changes
> > >   where non vswing sequences are not aligned with iboost
> > >   anymore.
> > > 
> > > v7: Another rebase after an upstream rework.
> > > 
> > > v8 (from Paulo):
> > > * Adjust the code to the upstream output type changes.
> > > * Squash the patch that moved some functions up.
> > > * Merge both get_combo_buf_trans functions in order to simplify the
> > >   code.
> > > * Change the changelog format.
> > > 
> > > Cc: Jani Nikula <jani.nikula@linux.intel.com>
> > > Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v5)
> > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/intel_ddi.c | 189
> > > ++++++++++++++++++++++++++++++++++++++-
> > >  1 file changed, 186 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_ddi.c
> > > b/drivers/gpu/drm/i915/intel_ddi.c
> > > index 0a4683991ec2..c38873cb98ca 100644
> > > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > > @@ -849,6 +849,45 @@ cnl_get_buf_trans_edp(struct drm_i915_private
> > > *dev_priv, int *n_entries)
> > >  	}
> > >  }
> > >  
> > > +static const struct icl_combo_phy_ddi_buf_trans *
> > > +icl_get_combo_buf_trans(struct drm_i915_private *dev_priv, enum
> > > port port,
> > > +			int type, int *n_entries)
> > > +{
> > > +	u32 voltage = I915_READ(ICL_PORT_COMP_DW3(port)) &
> > > VOLTAGE_INFO_MASK;
> > > +
> > > +	if (type == INTEL_OUTPUT_EDP && dev_priv-
> > > >vbt.edp.low_vswing) {
> > > +		switch (voltage) {
> > > +		case VOLTAGE_INFO_0_85V:
> > > +			*n_entries =
> > > ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_85V);
> > > +			return
> > > icl_combo_phy_ddi_translations_edp_0_85V;
> > > +		case VOLTAGE_INFO_0_95V:
> > > +			*n_entries =
> > > ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_95V);
> > > +			return
> > > icl_combo_phy_ddi_translations_edp_0_95V;
> > > +		case VOLTAGE_INFO_1_05V:
> > > +			*n_entries =
> > > ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_1_05V);
> > > +			return
> > > icl_combo_phy_ddi_translations_edp_1_05V;
> > > +		default:
> > > +			MISSING_CASE(voltage);
> > > +			return NULL;
> > > +		}
> > > +	} else {
> > 
> > DP ends up here on HDMI?
> > This is strange...
> 
> DP ends on the "dp_hdmi" part, while edp ends on the "edp" part. What
> is strange about that?

Oh... actually spec is strange...
They have 2 tables, 1 for DP and 1 for HDMI.
I just read them again and they are the same indeed.
So, nothing wrong here.

> 
> > 
> > Also, for clarity, why not to split this into separated functions
> > like all other platforms?
> 
> So we don't end up reading PORT_COMP_DW3 multiple times (like we do for
> CNL), and as a bonus the code looks better IMHO.

Agree.

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

> 
> 
> 
> > 
> > > +		switch (voltage) {
> > > +		case VOLTAGE_INFO_0_85V:
> > > +			*n_entries =
> > > ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_85V);
> > > +			return
> > > icl_combo_phy_ddi_translations_dp_hdmi_0_85V;
> > > +		case VOLTAGE_INFO_0_95V:
> > > +			*n_entries =
> > > ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_95V);
> > > +			return
> > > icl_combo_phy_ddi_translations_dp_hdmi_0_95V;
> > > +		case VOLTAGE_INFO_1_05V:
> > > +			*n_entries =
> > > ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_1_05V);
> > > +			return
> > > icl_combo_phy_ddi_translations_dp_hdmi_1_05V;
> > > +		default:
> > > +			MISSING_CASE(voltage);
> > > +			return NULL;
> > > +		}
> > > +	}
> > > +}
> > > +
> > >  static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv,
> > > enum port port)
> > >  {
> > >  	int n_entries, level, default_entry;
> > > @@ -2178,6 +2217,144 @@ static void cnl_ddi_vswing_sequence(struct
> > > intel_encoder *encoder,
> > >  	I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val);
> > >  }
> > >  
> > > +static void icl_ddi_combo_vswing_program(struct drm_i915_private
> > > *dev_priv,
> > > +					 u32 level, enum port
> > > port, int type)
> > > +{
> > > +	const struct icl_combo_phy_ddi_buf_trans *ddi_translations
> > > = NULL;
> > > +	u32 n_entries, val;
> > > +	int ln;
> > > +
> > > +	ddi_translations = icl_get_combo_buf_trans(dev_priv, port,
> > > type,
> > > +						   &n_entries);
> > > +	if (!ddi_translations)
> > > +		return;
> > > +
> > > +	if (level >= n_entries) {
> > > +		DRM_DEBUG_KMS("DDI translation not found for level
> > > %d. Using %d instead.", level, n_entries - 1);
> > > +		level = n_entries - 1;
> > > +	}
> > > +
> > > +	/* Set PORT_TX_DW5 Scaling Mode Sel to 110b. */
> > > +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> > > +	val &= ~SCALING_MODE_SEL_MASK;
> > > +	val |= SCALING_MODE_SEL(0x6);
> > > +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> > > +
> > > +	/* Program PORT_TX_DW5 */
> > > +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> > > +	/* Set DisableTap2 and DisableTap3 if MIPI DSI
> > > +	 * Clear DisableTap2 and DisableTap3 for all other Ports
> > > +	 */
> > > +	if (type == INTEL_OUTPUT_DSI) {
> > > +		val |= TAP2_DISABLE;
> > > +		val |= TAP3_DISABLE;
> > > +	} else {
> > > +		val &= ~TAP2_DISABLE;
> > > +		val &= ~TAP3_DISABLE;
> > > +	}
> > > +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> > > +
> > > +	/* Program PORT_TX_DW2 */
> > > +	val = I915_READ(ICL_PORT_TX_DW2_LN0(port));
> > > +	val &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
> > > +		 RCOMP_SCALAR_MASK);
> > > +	val |=
> > > SWING_SEL_UPPER(ddi_translations[level].dw2_swing_select);
> > > +	val |=
> > > SWING_SEL_LOWER(ddi_translations[level].dw2_swing_select);
> > > +	/* Program Rcomp scalar for every table entry */
> > > +	val |=
> > > RCOMP_SCALAR(ddi_translations[level].dw2_swing_scalar);
> > > +	I915_WRITE(ICL_PORT_TX_DW2_GRP(port), val);
> > > +
> > > +	/* Program PORT_TX_DW4 */
> > > +	/* We cannot write to GRP. It would overwrite individual
> > > loadgen. */
> > > +	for (ln = 0; ln <= 3; ln++) {
> > > +		val = I915_READ(ICL_PORT_TX_DW4_LN(port, ln));
> > > +		val &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
> > > +			 CURSOR_COEFF_MASK);
> > > +		val |= ddi_translations[level].dw4_scaling;
> > > +		I915_WRITE(ICL_PORT_TX_DW4_LN(port, ln), val);
> > > +	}
> > > +}
> > > +
> > > +static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder
> > > *encoder, u32 level)
> > > +{
> > > +	struct drm_i915_private *dev_priv = to_i915(encoder-
> > > >base.dev);
> > > +	enum port port = encoder->port;
> > > +	int type = encoder->type;
> > > +	int width = 0;
> > > +	int rate = 0;
> > > +	u32 val;
> > > +	int ln = 0;
> > > +
> > > +	if (type == INTEL_OUTPUT_HDMI) {
> > > +		width = 4;
> > > +		/* Rate is always < than 6GHz for HDMI */
> > > +	} else {
> > > +		struct intel_dp *intel_dp =
> > > enc_to_intel_dp(&encoder->base);
> > > +
> > > +		width = intel_dp->lane_count;
> > > +		rate = intel_dp->link_rate;
> > > +	}
> > > +
> > > +	/*
> > > +	 * 1. If port type is eDP or DP,
> > > +	 * set PORT_PCS_DW1 cmnkeeper_enable to 1b,
> > > +	 * else clear to 0b.
> > > +	 */
> > > +	val = I915_READ(ICL_PORT_PCS_DW1_LN0(port));
> > > +	if (type == INTEL_OUTPUT_HDMI)
> > > +		val &= ~COMMON_KEEPER_EN;
> > > +	else
> > > +		val |= COMMON_KEEPER_EN;
> > > +	I915_WRITE(ICL_PORT_PCS_DW1_GRP(port), val);
> > > +
> > > +	/* 2. Program loadgen select */
> > > +	/*
> > > +	 * Program PORT_TX_DW4_LN depending on Bit rate and used
> > > lanes
> > > +	 * <= 6 GHz and 4 lanes (LN0=0, LN1=1, LN2=1, LN3=1)
> > > +	 * <= 6 GHz and 1,2 lanes (LN0=0, LN1=1, LN2=1, LN3=0)
> > > +	 * > 6 GHz (LN0=0, LN1=0, LN2=0, LN3=0)
> > > +	 */
> > > +	for (ln = 0; ln <= 3; ln++) {
> > > +		val = I915_READ(ICL_PORT_TX_DW4_LN(port, ln));
> > > +		val &= ~LOADGEN_SELECT;
> > > +
> > > +		if ((rate <= 600000 && width == 4 && ln >= 1) ||
> > > +		    (rate <= 600000 && width < 4 && (ln == 1 || ln
> > > == 2))) {
> > > +			val |= LOADGEN_SELECT;
> > > +		}
> > > +		I915_WRITE(ICL_PORT_TX_DW4_LN(port, ln), val);
> > > +	}
> > > +
> > > +	/* 3. Set PORT_CL_DW5 SUS Clock Config to 11b */
> > > +	val = I915_READ(ICL_PORT_CL_DW5(port));
> > > +	val |= SUS_CLOCK_CONFIG;
> > > +	I915_WRITE(ICL_PORT_CL_DW5(port), val);
> > > +
> > > +	/* 4. Clear training enable to change swing values */
> > > +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> > > +	val &= ~TX_TRAINING_EN;
> > > +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> > > +
> > > +	/* 5. Program swing and de-emphasis */
> > > +	icl_ddi_combo_vswing_program(dev_priv, level, port, type);
> > > +
> > > +	/* 6. Set training enable to trigger update */
> > > +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> > > +	val |= TX_TRAINING_EN;
> > > +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> > > +}
> > > +
> > > +static void icl_ddi_vswing_sequence(struct intel_encoder *encoder,
> > > u32 level)
> > > +{
> > > +	enum port port = encoder->port;
> > > +
> > > +	if (port == PORT_A || port == PORT_B)
> > > +		icl_combo_phy_ddi_vswing_sequence(encoder, level);
> > > +	else
> > > +		/* Not Implemented Yet */
> > > +		WARN_ON(1);
> > > +}
> > > +
> > >  static uint32_t translate_signal_level(int signal_levels)
> > >  {
> > >  	int i;
> > > @@ -2209,7 +2386,9 @@ u32 bxt_signal_levels(struct intel_dp
> > > *intel_dp)
> > >  	struct intel_encoder *encoder = &dport->base;
> > >  	int level = intel_ddi_dp_level(intel_dp);
> > >  
> > > -	if (IS_CANNONLAKE(dev_priv))
> > > +	if (IS_ICELAKE(dev_priv))
> > > +		icl_ddi_vswing_sequence(encoder, level);
> > > +	else if (IS_CANNONLAKE(dev_priv))
> > >  		cnl_ddi_vswing_sequence(encoder, level, encoder-
> > > >type);
> > >  	else
> > >  		bxt_ddi_vswing_sequence(encoder, level, encoder-
> > > >type);
> > > @@ -2389,7 +2568,9 @@ static void intel_ddi_pre_enable_dp(struct
> > > intel_encoder *encoder,
> > >  
> > >  	intel_display_power_get(dev_priv, dig_port-
> > > >ddi_io_power_domain);
> > >  
> > > -	if (IS_CANNONLAKE(dev_priv))
> > > +	if (IS_ICELAKE(dev_priv))
> > > +		icl_ddi_vswing_sequence(encoder, level);
> > > +	else if (IS_CANNONLAKE(dev_priv))
> > >  		cnl_ddi_vswing_sequence(encoder, level, encoder-
> > > >type);
> > >  	else if (IS_GEN9_LP(dev_priv))
> > >  		bxt_ddi_vswing_sequence(encoder, level, encoder-
> > > >type);
> > > @@ -2420,7 +2601,9 @@ static void intel_ddi_pre_enable_hdmi(struct
> > > intel_encoder *encoder,
> > >  
> > >  	intel_display_power_get(dev_priv, dig_port-
> > > >ddi_io_power_domain);
> > >  
> > > -	if (IS_CANNONLAKE(dev_priv))
> > > +	if (IS_ICELAKE(dev_priv))
> > > +		icl_ddi_vswing_sequence(encoder, level);
> > > +	else if (IS_CANNONLAKE(dev_priv))
> > >  		cnl_ddi_vswing_sequence(encoder, level,
> > > INTEL_OUTPUT_HDMI);
> > >  	else if (IS_GEN9_LP(dev_priv))
> > >  		bxt_ddi_vswing_sequence(encoder, level,
> > > INTEL_OUTPUT_HDMI);
> > > -- 
> > > 2.14.3
> > > 
> > > _______________________________________________
> > > 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
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 08/17] drm/i915/icl: Implement voltage swing programming sequence for Combo PHY DDI
  2018-04-25 18:01       ` Rodrigo Vivi
@ 2018-04-25 23:33         ` Paulo Zanoni
  0 siblings, 0 replies; 41+ messages in thread
From: Paulo Zanoni @ 2018-04-25 23:33 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

Em Qua, 2018-04-25 às 11:01 -0700, Rodrigo Vivi escreveu:
> On Tue, Apr 24, 2018 at 05:34:14PM -0700, Paulo Zanoni wrote:
> > Em Qui, 2018-04-05 às 17:20 -0700, Rodrigo Vivi escreveu:
> > > On Thu, Feb 22, 2018 at 12:55:10AM -0300, Paulo Zanoni wrote:
> > > > From: Manasi Navare <manasi.d.navare@intel.com>
> > > > 
> > > > This is an important part of the DDI initalization as well as
> > > > for changing the voltage during DisplayPort link training.
> > > > 
> > > > The Voltage swing seqeuence is similar to Cannonlake.
> > > > However it has different register definitions and hence
> > > > it makes sense to create a separate vswing sequence and
> > > > program functions for ICL to leave room for more changes
> > > > in case the Bspec changes later and deviates from CNL sequence.
> > > > 
> > > > v2:
> > > > Use ~TAP3_DISABLE for enbaling that bit (Jani Nikula)
> > > > 
> > > > v3:
> > > > * Use dw4_scaling column for PORT_TX_DW4 values (Rodrigo)
> > > > 
> > > > v4:
> > > > * Call it combo_vswing, use switch statement (Paulo)
> > > > 
> > > > v5 (from Paulo):
> > > > * Fix a typo.
> > > > * s/rate < 600000/rate <= 600000/.
> > > > * Don't remove blank lines that should be there.
> > > > 
> > > > v6:
> > > > * Rebased by Rodrigo on top of Cannonlake changes
> > > >   where non vswing sequences are not aligned with iboost
> > > >   anymore.
> > > > 
> > > > v7: Another rebase after an upstream rework.
> > > > 
> > > > v8 (from Paulo):
> > > > * Adjust the code to the upstream output type changes.
> > > > * Squash the patch that moved some functions up.
> > > > * Merge both get_combo_buf_trans functions in order to simplify
> > > > the
> > > >   code.
> > > > * Change the changelog format.
> > > > 
> > > > Cc: Jani Nikula <jani.nikula@linux.intel.com>
> > > > Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v5)
> > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/intel_ddi.c | 189
> > > > ++++++++++++++++++++++++++++++++++++++-
> > > >  1 file changed, 186 insertions(+), 3 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/intel_ddi.c
> > > > b/drivers/gpu/drm/i915/intel_ddi.c
> > > > index 0a4683991ec2..c38873cb98ca 100644
> > > > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > > > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > > > @@ -849,6 +849,45 @@ cnl_get_buf_trans_edp(struct
> > > > drm_i915_private
> > > > *dev_priv, int *n_entries)
> > > >  	}
> > > >  }
> > > >  
> > > > +static const struct icl_combo_phy_ddi_buf_trans *
> > > > +icl_get_combo_buf_trans(struct drm_i915_private *dev_priv,
> > > > enum
> > > > port port,
> > > > +			int type, int *n_entries)
> > > > +{
> > > > +	u32 voltage = I915_READ(ICL_PORT_COMP_DW3(port)) &
> > > > VOLTAGE_INFO_MASK;
> > > > +
> > > > +	if (type == INTEL_OUTPUT_EDP && dev_priv-
> > > > > vbt.edp.low_vswing) {
> > > > 
> > > > +		switch (voltage) {
> > > > +		case VOLTAGE_INFO_0_85V:
> > > > +			*n_entries =
> > > > ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_85V);
> > > > +			return
> > > > icl_combo_phy_ddi_translations_edp_0_85V;
> > > > +		case VOLTAGE_INFO_0_95V:
> > > > +			*n_entries =
> > > > ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_95V);
> > > > +			return
> > > > icl_combo_phy_ddi_translations_edp_0_95V;
> > > > +		case VOLTAGE_INFO_1_05V:
> > > > +			*n_entries =
> > > > ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_1_05V);
> > > > +			return
> > > > icl_combo_phy_ddi_translations_edp_1_05V;
> > > > +		default:
> > > > +			MISSING_CASE(voltage);
> > > > +			return NULL;
> > > > +		}
> > > > +	} else {
> > > 
> > > DP ends up here on HDMI?
> > > This is strange...
> > 
> > DP ends on the "dp_hdmi" part, while edp ends on the "edp" part.
> > What
> > is strange about that?
> 
> Oh... actually spec is strange...
> They have 2 tables, 1 for DP and 1 for HDMI.
> I just read them again and they are the same indeed.
> So, nothing wrong here.
> 
> > 
> > > 
> > > Also, for clarity, why not to split this into separated functions
> > > like all other platforms?
> > 
> > So we don't end up reading PORT_COMP_DW3 multiple times (like we do
> > for
> > CNL), and as a bonus the code looks better IMHO.
> 
> Agree.
> 
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

You're reviewing v8 of the patch. This thread already has v9 (as a
reply to v8). Does the r-b also apply to it?

v9 was also resent as https://patchwork.freedesktop.org/patch/213515/

> 
> > 
> > 
> > 
> > > 
> > > > +		switch (voltage) {
> > > > +		case VOLTAGE_INFO_0_85V:
> > > > +			*n_entries =
> > > > ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_85V);
> > > > +			return
> > > > icl_combo_phy_ddi_translations_dp_hdmi_0_85V;
> > > > +		case VOLTAGE_INFO_0_95V:
> > > > +			*n_entries =
> > > > ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_95V);
> > > > +			return
> > > > icl_combo_phy_ddi_translations_dp_hdmi_0_95V;
> > > > +		case VOLTAGE_INFO_1_05V:
> > > > +			*n_entries =
> > > > ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_1_05V);
> > > > +			return
> > > > icl_combo_phy_ddi_translations_dp_hdmi_1_05V;
> > > > +		default:
> > > > +			MISSING_CASE(voltage);
> > > > +			return NULL;
> > > > +		}
> > > > +	}
> > > > +}
> > > > +
> > > >  static int intel_ddi_hdmi_level(struct drm_i915_private
> > > > *dev_priv,
> > > > enum port port)
> > > >  {
> > > >  	int n_entries, level, default_entry;
> > > > @@ -2178,6 +2217,144 @@ static void
> > > > cnl_ddi_vswing_sequence(struct
> > > > intel_encoder *encoder,
> > > >  	I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val);
> > > >  }
> > > >  
> > > > +static void icl_ddi_combo_vswing_program(struct
> > > > drm_i915_private
> > > > *dev_priv,
> > > > +					 u32 level, enum port
> > > > port, int type)
> > > > +{
> > > > +	const struct icl_combo_phy_ddi_buf_trans
> > > > *ddi_translations
> > > > = NULL;
> > > > +	u32 n_entries, val;
> > > > +	int ln;
> > > > +
> > > > +	ddi_translations = icl_get_combo_buf_trans(dev_priv,
> > > > port,
> > > > type,
> > > > +						   &n_entries)
> > > > ;
> > > > +	if (!ddi_translations)
> > > > +		return;
> > > > +
> > > > +	if (level >= n_entries) {
> > > > +		DRM_DEBUG_KMS("DDI translation not found for
> > > > level
> > > > %d. Using %d instead.", level, n_entries - 1);
> > > > +		level = n_entries - 1;
> > > > +	}
> > > > +
> > > > +	/* Set PORT_TX_DW5 Scaling Mode Sel to 110b. */
> > > > +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> > > > +	val &= ~SCALING_MODE_SEL_MASK;
> > > > +	val |= SCALING_MODE_SEL(0x6);
> > > > +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> > > > +
> > > > +	/* Program PORT_TX_DW5 */
> > > > +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> > > > +	/* Set DisableTap2 and DisableTap3 if MIPI DSI
> > > > +	 * Clear DisableTap2 and DisableTap3 for all other
> > > > Ports
> > > > +	 */
> > > > +	if (type == INTEL_OUTPUT_DSI) {
> > > > +		val |= TAP2_DISABLE;
> > > > +		val |= TAP3_DISABLE;
> > > > +	} else {
> > > > +		val &= ~TAP2_DISABLE;
> > > > +		val &= ~TAP3_DISABLE;
> > > > +	}
> > > > +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> > > > +
> > > > +	/* Program PORT_TX_DW2 */
> > > > +	val = I915_READ(ICL_PORT_TX_DW2_LN0(port));
> > > > +	val &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
> > > > +		 RCOMP_SCALAR_MASK);
> > > > +	val |=
> > > > SWING_SEL_UPPER(ddi_translations[level].dw2_swing_select);
> > > > +	val |=
> > > > SWING_SEL_LOWER(ddi_translations[level].dw2_swing_select);
> > > > +	/* Program Rcomp scalar for every table entry */
> > > > +	val |=
> > > > RCOMP_SCALAR(ddi_translations[level].dw2_swing_scalar);
> > > > +	I915_WRITE(ICL_PORT_TX_DW2_GRP(port), val);
> > > > +
> > > > +	/* Program PORT_TX_DW4 */
> > > > +	/* We cannot write to GRP. It would overwrite
> > > > individual
> > > > loadgen. */
> > > > +	for (ln = 0; ln <= 3; ln++) {
> > > > +		val = I915_READ(ICL_PORT_TX_DW4_LN(port, ln));
> > > > +		val &= ~(POST_CURSOR_1_MASK |
> > > > POST_CURSOR_2_MASK |
> > > > +			 CURSOR_COEFF_MASK);
> > > > +		val |= ddi_translations[level].dw4_scaling;
> > > > +		I915_WRITE(ICL_PORT_TX_DW4_LN(port, ln), val);
> > > > +	}
> > > > +}
> > > > +
> > > > +static void icl_combo_phy_ddi_vswing_sequence(struct
> > > > intel_encoder
> > > > *encoder, u32 level)
> > > > +{
> > > > +	struct drm_i915_private *dev_priv = to_i915(encoder-
> > > > > base.dev);
> > > > 
> > > > +	enum port port = encoder->port;
> > > > +	int type = encoder->type;
> > > > +	int width = 0;
> > > > +	int rate = 0;
> > > > +	u32 val;
> > > > +	int ln = 0;
> > > > +
> > > > +	if (type == INTEL_OUTPUT_HDMI) {
> > > > +		width = 4;
> > > > +		/* Rate is always < than 6GHz for HDMI */
> > > > +	} else {
> > > > +		struct intel_dp *intel_dp =
> > > > enc_to_intel_dp(&encoder->base);
> > > > +
> > > > +		width = intel_dp->lane_count;
> > > > +		rate = intel_dp->link_rate;
> > > > +	}
> > > > +
> > > > +	/*
> > > > +	 * 1. If port type is eDP or DP,
> > > > +	 * set PORT_PCS_DW1 cmnkeeper_enable to 1b,
> > > > +	 * else clear to 0b.
> > > > +	 */
> > > > +	val = I915_READ(ICL_PORT_PCS_DW1_LN0(port));
> > > > +	if (type == INTEL_OUTPUT_HDMI)
> > > > +		val &= ~COMMON_KEEPER_EN;
> > > > +	else
> > > > +		val |= COMMON_KEEPER_EN;
> > > > +	I915_WRITE(ICL_PORT_PCS_DW1_GRP(port), val);
> > > > +
> > > > +	/* 2. Program loadgen select */
> > > > +	/*
> > > > +	 * Program PORT_TX_DW4_LN depending on Bit rate and
> > > > used
> > > > lanes
> > > > +	 * <= 6 GHz and 4 lanes (LN0=0, LN1=1, LN2=1, LN3=1)
> > > > +	 * <= 6 GHz and 1,2 lanes (LN0=0, LN1=1, LN2=1, LN3=0)
> > > > +	 * > 6 GHz (LN0=0, LN1=0, LN2=0, LN3=0)
> > > > +	 */
> > > > +	for (ln = 0; ln <= 3; ln++) {
> > > > +		val = I915_READ(ICL_PORT_TX_DW4_LN(port, ln));
> > > > +		val &= ~LOADGEN_SELECT;
> > > > +
> > > > +		if ((rate <= 600000 && width == 4 && ln >= 1)
> > > > ||
> > > > +		    (rate <= 600000 && width < 4 && (ln == 1
> > > > || ln
> > > > == 2))) {
> > > > +			val |= LOADGEN_SELECT;
> > > > +		}
> > > > +		I915_WRITE(ICL_PORT_TX_DW4_LN(port, ln), val);
> > > > +	}
> > > > +
> > > > +	/* 3. Set PORT_CL_DW5 SUS Clock Config to 11b */
> > > > +	val = I915_READ(ICL_PORT_CL_DW5(port));
> > > > +	val |= SUS_CLOCK_CONFIG;
> > > > +	I915_WRITE(ICL_PORT_CL_DW5(port), val);
> > > > +
> > > > +	/* 4. Clear training enable to change swing values */
> > > > +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> > > > +	val &= ~TX_TRAINING_EN;
> > > > +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> > > > +
> > > > +	/* 5. Program swing and de-emphasis */
> > > > +	icl_ddi_combo_vswing_program(dev_priv, level, port,
> > > > type);
> > > > +
> > > > +	/* 6. Set training enable to trigger update */
> > > > +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> > > > +	val |= TX_TRAINING_EN;
> > > > +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> > > > +}
> > > > +
> > > > +static void icl_ddi_vswing_sequence(struct intel_encoder
> > > > *encoder,
> > > > u32 level)
> > > > +{
> > > > +	enum port port = encoder->port;
> > > > +
> > > > +	if (port == PORT_A || port == PORT_B)
> > > > +		icl_combo_phy_ddi_vswing_sequence(encoder,
> > > > level);
> > > > +	else
> > > > +		/* Not Implemented Yet */
> > > > +		WARN_ON(1);
> > > > +}
> > > > +
> > > >  static uint32_t translate_signal_level(int signal_levels)
> > > >  {
> > > >  	int i;
> > > > @@ -2209,7 +2386,9 @@ u32 bxt_signal_levels(struct intel_dp
> > > > *intel_dp)
> > > >  	struct intel_encoder *encoder = &dport->base;
> > > >  	int level = intel_ddi_dp_level(intel_dp);
> > > >  
> > > > -	if (IS_CANNONLAKE(dev_priv))
> > > > +	if (IS_ICELAKE(dev_priv))
> > > > +		icl_ddi_vswing_sequence(encoder, level);
> > > > +	else if (IS_CANNONLAKE(dev_priv))
> > > >  		cnl_ddi_vswing_sequence(encoder, level,
> > > > encoder-
> > > > > type);
> > > > 
> > > >  	else
> > > >  		bxt_ddi_vswing_sequence(encoder, level,
> > > > encoder-
> > > > > type);
> > > > 
> > > > @@ -2389,7 +2568,9 @@ static void
> > > > intel_ddi_pre_enable_dp(struct
> > > > intel_encoder *encoder,
> > > >  
> > > >  	intel_display_power_get(dev_priv, dig_port-
> > > > > ddi_io_power_domain);
> > > > 
> > > >  
> > > > -	if (IS_CANNONLAKE(dev_priv))
> > > > +	if (IS_ICELAKE(dev_priv))
> > > > +		icl_ddi_vswing_sequence(encoder, level);
> > > > +	else if (IS_CANNONLAKE(dev_priv))
> > > >  		cnl_ddi_vswing_sequence(encoder, level,
> > > > encoder-
> > > > > type);
> > > > 
> > > >  	else if (IS_GEN9_LP(dev_priv))
> > > >  		bxt_ddi_vswing_sequence(encoder, level,
> > > > encoder-
> > > > > type);
> > > > 
> > > > @@ -2420,7 +2601,9 @@ static void
> > > > intel_ddi_pre_enable_hdmi(struct
> > > > intel_encoder *encoder,
> > > >  
> > > >  	intel_display_power_get(dev_priv, dig_port-
> > > > > ddi_io_power_domain);
> > > > 
> > > >  
> > > > -	if (IS_CANNONLAKE(dev_priv))
> > > > +	if (IS_ICELAKE(dev_priv))
> > > > +		icl_ddi_vswing_sequence(encoder, level);
> > > > +	else if (IS_CANNONLAKE(dev_priv))
> > > >  		cnl_ddi_vswing_sequence(encoder, level,
> > > > INTEL_OUTPUT_HDMI);
> > > >  	else if (IS_GEN9_LP(dev_priv))
> > > >  		bxt_ddi_vswing_sequence(encoder, level,
> > > > INTEL_OUTPUT_HDMI);
> > > > -- 
> > > > 2.14.3
> > > > 
> > > > _______________________________________________
> > > > 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
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 08/17] drm/i915/icl: Implement voltage swing programming sequence for Combo PHY DDI
  2018-03-23  0:10   ` Paulo Zanoni
@ 2018-04-28  0:28     ` Rodrigo Vivi
  0 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Vivi @ 2018-04-28  0:28 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx

On Thu, Mar 22, 2018 at 05:10:22PM -0700, Paulo Zanoni wrote:
> From: Manasi Navare <manasi.d.navare@intel.com>
> 
> This is an important part of the DDI initalization as well as
> for changing the voltage during DisplayPort link training.
> 
> The Voltage swing seqeuence is similar to Cannonlake.
> However it has different register definitions and hence
> it makes sense to create a separate vswing sequence and
> program functions for ICL to leave room for more changes
> in case the Bspec changes later and deviates from CNL sequence.
> 
> v2:
> Use ~TAP3_DISABLE for enbaling that bit (Jani Nikula)
> 
> v3:
> * Use dw4_scaling column for PORT_TX_DW4 values (Rodrigo)
> 
> v4:
> * Call it combo_vswing, use switch statement (Paulo)
> 
> v5 (from Paulo):
> * Fix a typo.
> * s/rate < 600000/rate <= 600000/.
> * Don't remove blank lines that should be there.
> 
> v6:
> * Rebased by Rodrigo on top of Cannonlake changes
>   where non vswing sequences are not aligned with iboost
>   anymore.
> 
> v7: Another rebase after an upstream rework.
> 
> v8 (from Paulo):
> * Adjust the code to the upstream output type changes.
> * Squash the patch that moved some functions up.
> * Merge both get_combo_buf_trans functions in order to simplify the
>   code.
> * Change the changelog format.
> 
> v9 (from Paulo):
> * Use RTERM_SELECT instead of SCALING_MODE_SEL.
> * Adjust the output type handling according to how the other platforms
>   do it now.
> 
> Cc: Jani Nikula <jani.nikula@linux.intel.com>
> Cc: James Ausmus <james.ausmus@intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 191 ++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 188 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 355dd4729ae8..15bafc850907 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -850,6 +850,45 @@ cnl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
>  	}
>  }
>  
> +static const struct icl_combo_phy_ddi_buf_trans *
> +icl_get_combo_buf_trans(struct drm_i915_private *dev_priv, enum port port,
> +			int type, int *n_entries)
> +{
> +	u32 voltage = I915_READ(ICL_PORT_COMP_DW3(port)) & VOLTAGE_INFO_MASK;
> +
> +	if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.low_vswing) {
> +		switch (voltage) {
> +		case VOLTAGE_INFO_0_85V:
> +			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_85V);
> +			return icl_combo_phy_ddi_translations_edp_0_85V;
> +		case VOLTAGE_INFO_0_95V:
> +			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_0_95V);
> +			return icl_combo_phy_ddi_translations_edp_0_95V;
> +		case VOLTAGE_INFO_1_05V:
> +			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_1_05V);
> +			return icl_combo_phy_ddi_translations_edp_1_05V;
> +		default:
> +			MISSING_CASE(voltage);
> +			return NULL;
> +		}
> +	} else {
> +		switch (voltage) {
> +		case VOLTAGE_INFO_0_85V:
> +			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_85V);
> +			return icl_combo_phy_ddi_translations_dp_hdmi_0_85V;
> +		case VOLTAGE_INFO_0_95V:
> +			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_0_95V);
> +			return icl_combo_phy_ddi_translations_dp_hdmi_0_95V;
> +		case VOLTAGE_INFO_1_05V:
> +			*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hdmi_1_05V);
> +			return icl_combo_phy_ddi_translations_dp_hdmi_1_05V;
> +		default:
> +			MISSING_CASE(voltage);
> +			return NULL;
> +		}
> +	}
> +}
> +
>  static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port port)
>  {
>  	int n_entries, level, default_entry;
> @@ -2179,6 +2218,146 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
>  	I915_WRITE(CNL_PORT_TX_DW5_GRP(port), val);
>  }
>  
> +static void icl_ddi_combo_vswing_program(struct drm_i915_private *dev_priv,
> +					 u32 level, enum port port, int type)
> +{
> +	const struct icl_combo_phy_ddi_buf_trans *ddi_translations = NULL;
> +	u32 n_entries, val;
> +	int ln;
> +
> +	ddi_translations = icl_get_combo_buf_trans(dev_priv, port, type,
> +						   &n_entries);
> +	if (!ddi_translations)
> +		return;
> +
> +	if (level >= n_entries) {
> +		DRM_DEBUG_KMS("DDI translation not found for level %d. Using %d instead.", level, n_entries - 1);
> +		level = n_entries - 1;
> +	}
> +
> +	/* Set PORT_TX_DW5 Scaling Mode Sel to 110b. */

Please fix the comment to reflect the change.
s/Scaling Mode/Rterm/g

Sorry for having missed this.

With comment fixed:

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>



> +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> +	val &= ~RTERM_SELECT_MASK;
> +	val |= RTERM_SELECT(0x6);
> +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> +
> +	/* Program PORT_TX_DW5 */
> +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> +	/* Set DisableTap2 and DisableTap3 if MIPI DSI
> +	 * Clear DisableTap2 and DisableTap3 for all other Ports
> +	 */
> +	if (type == INTEL_OUTPUT_DSI) {
> +		val |= TAP2_DISABLE;
> +		val |= TAP3_DISABLE;
> +	} else {
> +		val &= ~TAP2_DISABLE;
> +		val &= ~TAP3_DISABLE;
> +	}
> +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> +
> +	/* Program PORT_TX_DW2 */
> +	val = I915_READ(ICL_PORT_TX_DW2_LN0(port));
> +	val &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
> +		 RCOMP_SCALAR_MASK);
> +	val |= SWING_SEL_UPPER(ddi_translations[level].dw2_swing_select);
> +	val |= SWING_SEL_LOWER(ddi_translations[level].dw2_swing_select);
> +	/* Program Rcomp scalar for every table entry */
> +	val |= RCOMP_SCALAR(ddi_translations[level].dw2_swing_scalar);
> +	I915_WRITE(ICL_PORT_TX_DW2_GRP(port), val);
> +
> +	/* Program PORT_TX_DW4 */
> +	/* We cannot write to GRP. It would overwrite individual loadgen. */
> +	for (ln = 0; ln <= 3; ln++) {
> +		val = I915_READ(ICL_PORT_TX_DW4_LN(port, ln));
> +		val &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
> +			 CURSOR_COEFF_MASK);
> +		val |= ddi_translations[level].dw4_scaling;
> +		I915_WRITE(ICL_PORT_TX_DW4_LN(port, ln), val);
> +	}
> +}
> +
> +static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
> +					      u32 level,
> +					      enum intel_output_type type)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	enum port port = encoder->port;
> +	int width = 0;
> +	int rate = 0;
> +	u32 val;
> +	int ln = 0;
> +
> +	if (type == INTEL_OUTPUT_HDMI) {
> +		width = 4;
> +		/* Rate is always < than 6GHz for HDMI */
> +	} else {
> +		struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
> +
> +		width = intel_dp->lane_count;
> +		rate = intel_dp->link_rate;
> +	}
> +
> +	/*
> +	 * 1. If port type is eDP or DP,
> +	 * set PORT_PCS_DW1 cmnkeeper_enable to 1b,
> +	 * else clear to 0b.
> +	 */
> +	val = I915_READ(ICL_PORT_PCS_DW1_LN0(port));
> +	if (type == INTEL_OUTPUT_HDMI)
> +		val &= ~COMMON_KEEPER_EN;
> +	else
> +		val |= COMMON_KEEPER_EN;
> +	I915_WRITE(ICL_PORT_PCS_DW1_GRP(port), val);
> +
> +	/* 2. Program loadgen select */
> +	/*
> +	 * Program PORT_TX_DW4_LN depending on Bit rate and used lanes
> +	 * <= 6 GHz and 4 lanes (LN0=0, LN1=1, LN2=1, LN3=1)
> +	 * <= 6 GHz and 1,2 lanes (LN0=0, LN1=1, LN2=1, LN3=0)
> +	 * > 6 GHz (LN0=0, LN1=0, LN2=0, LN3=0)
> +	 */
> +	for (ln = 0; ln <= 3; ln++) {
> +		val = I915_READ(ICL_PORT_TX_DW4_LN(port, ln));
> +		val &= ~LOADGEN_SELECT;
> +
> +		if ((rate <= 600000 && width == 4 && ln >= 1) ||
> +		    (rate <= 600000 && width < 4 && (ln == 1 || ln == 2))) {
> +			val |= LOADGEN_SELECT;
> +		}
> +		I915_WRITE(ICL_PORT_TX_DW4_LN(port, ln), val);
> +	}
> +
> +	/* 3. Set PORT_CL_DW5 SUS Clock Config to 11b */
> +	val = I915_READ(ICL_PORT_CL_DW5(port));
> +	val |= SUS_CLOCK_CONFIG;
> +	I915_WRITE(ICL_PORT_CL_DW5(port), val);
> +
> +	/* 4. Clear training enable to change swing values */
> +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> +	val &= ~TX_TRAINING_EN;
> +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> +
> +	/* 5. Program swing and de-emphasis */
> +	icl_ddi_combo_vswing_program(dev_priv, level, port, type);
> +
> +	/* 6. Set training enable to trigger update */
> +	val = I915_READ(ICL_PORT_TX_DW5_LN0(port));
> +	val |= TX_TRAINING_EN;
> +	I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val);
> +}
> +
> +static void icl_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level,
> +				    enum intel_output_type type)
> +{
> +	enum port port = encoder->port;
> +
> +	if (port == PORT_A || port == PORT_B)
> +		icl_combo_phy_ddi_vswing_sequence(encoder, level, type);
> +	else
> +		/* Not Implemented Yet */
> +		WARN_ON(1);
> +}
> +
>  static uint32_t translate_signal_level(int signal_levels)
>  {
>  	int i;
> @@ -2210,7 +2389,9 @@ u32 bxt_signal_levels(struct intel_dp *intel_dp)
>  	struct intel_encoder *encoder = &dport->base;
>  	int level = intel_ddi_dp_level(intel_dp);
>  
> -	if (IS_CANNONLAKE(dev_priv))
> +	if (IS_ICELAKE(dev_priv))
> +		icl_ddi_vswing_sequence(encoder, level, encoder->type);
> +	else if (IS_CANNONLAKE(dev_priv))
>  		cnl_ddi_vswing_sequence(encoder, level, encoder->type);
>  	else
>  		bxt_ddi_vswing_sequence(encoder, level, encoder->type);
> @@ -2384,7 +2565,9 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
>  
>  	intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain);
>  
> -	if (IS_CANNONLAKE(dev_priv))
> +	if (IS_ICELAKE(dev_priv))
> +		icl_ddi_vswing_sequence(encoder, level, encoder->type);
> +	else if (IS_CANNONLAKE(dev_priv))
>  		cnl_ddi_vswing_sequence(encoder, level, encoder->type);
>  	else if (IS_GEN9_LP(dev_priv))
>  		bxt_ddi_vswing_sequence(encoder, level, encoder->type);
> @@ -2414,7 +2597,9 @@ static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
>  
>  	intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain);
>  
> -	if (IS_CANNONLAKE(dev_priv))
> +	if (IS_ICELAKE(dev_priv))
> +		icl_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
> +	else if (IS_CANNONLAKE(dev_priv))
>  		cnl_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
>  	else if (IS_GEN9_LP(dev_priv))
>  		bxt_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
> -- 
> 2.14.3
> 
> _______________________________________________
> 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] 41+ messages in thread

end of thread, other threads:[~2018-04-28  0:28 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-22  3:55 [PATCH 00/17] ICL PLLs, DP/HDMI and misc display Paulo Zanoni
2018-02-22  3:55 ` [PATCH 01/17] drm/i915/icl: add definitions for the ICL PLL registers Paulo Zanoni
2018-02-27 22:22   ` James Ausmus
2018-03-21 21:34     ` Paulo Zanoni
2018-03-23  0:07   ` Paulo Zanoni
2018-03-23  0:08   ` [PATCH 02/17] drm/i915/icl: add basic support for the ICL clocks Paulo Zanoni
2018-02-22  3:55 ` Paulo Zanoni
2018-02-28  0:40   ` James Ausmus
2018-02-22  3:55 ` [PATCH 03/17] drm/i915/icl: compute the combo PHY (DPLL) HDMI registers Paulo Zanoni
2018-02-28 19:59   ` James Ausmus
2018-02-22  3:55 ` [PATCH 04/17] drm/i915/icl: compute the combo PHY (DPLL) DP registers Paulo Zanoni
2018-02-28 20:12   ` James Ausmus
2018-02-22  3:55 ` [PATCH 05/17] drm/i915/icl: compute the MG PLL registers Paulo Zanoni
2018-03-01 23:35   ` Manasi Navare
2018-02-22  3:55 ` [PATCH 06/17] drm/i915/icl: Add register definitions for Combo PHY vswing sequences Paulo Zanoni
2018-02-22  3:55 ` [PATCH 07/17] drm/i915/icl: Add Combo PHY DDI Buffer translation tables for Icelake Paulo Zanoni
2018-02-22  3:55 ` [PATCH 08/17] drm/i915/icl: Implement voltage swing programming sequence for Combo PHY DDI Paulo Zanoni
2018-03-22 22:23   ` Paulo Zanoni
2018-03-23  0:10   ` Paulo Zanoni
2018-04-28  0:28     ` Rodrigo Vivi
2018-04-06  0:20   ` Rodrigo Vivi
2018-04-25  0:34     ` Paulo Zanoni
2018-04-25 18:01       ` Rodrigo Vivi
2018-04-25 23:33         ` Paulo Zanoni
2018-02-22  3:55 ` [PATCH 09/17] drm/i915/icl: Add register defs for voltage swing sequences for MG " Paulo Zanoni
2018-02-22  3:55 ` [PATCH 10/17] drm/i915/icl: Add Voltage swing table for MG PHY DDI Buffer Paulo Zanoni
2018-02-22  3:55 ` [PATCH 11/17] drm/i915/icl: Implement voltage swing programming sequence for MG PHY DDI Paulo Zanoni
2018-03-22 22:58   ` Paulo Zanoni
2018-02-22  3:55 ` [PATCH 12/17] drm/i915/icl: HPD pin for port F Paulo Zanoni
2018-02-22 20:16   ` Rodrigo Vivi
2018-02-22  3:55 ` [PATCH 13/17] drm/i915/icl: Added 5k source scaling support for Gen11 platform Paulo Zanoni
2018-02-22  3:55 ` [PATCH 14/17] drm/i915/icl: Calculate link clock using the new registers Paulo Zanoni
2018-03-22 23:20   ` Paulo Zanoni
2018-02-22  3:55 ` [PATCH 15/17] drm/i915/icl: Don't set pipe CSC/Gamma in PLANE_COLOR_CTL Paulo Zanoni
2018-02-22  3:55 ` [PATCH 16/17] drm/i915/gen11: all the DDI ports on gen 11 support 4 lanes Paulo Zanoni
2018-02-22  3:55 ` [PATCH 17/17] drm/i915/icl: Fix the DP Max Voltage for ICL Paulo Zanoni
2018-03-23  0:03   ` Rodrigo Vivi
2018-02-22  4:09 ` ✗ Fi.CI.CHECKPATCH: warning for ICL PLLs, DP/HDMI and misc display Patchwork
2018-02-22  4:24 ` ✗ Fi.CI.BAT: " Patchwork
2018-03-23  0:05 ` [PATCH 00/17] " Paulo Zanoni
2018-03-23  1:00 ` ✗ Fi.CI.BAT: failure for ICL PLLs, DP/HDMI and misc display (rev4) Patchwork

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.