* [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.