Skip to content

Commit c27e917

Browse files
committed
drm/i915/icl: add basic support for the ICL clocks
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) v5: - Rebase after the pll struct changes. v6: - Properly make the unmap function based on encoders_post_disable() with regarding to checks and iterators. - Address checkpatch comment on "min = max = x()". Cc: James Ausmus <james.ausmus@intel.com> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: James Ausmus <james.ausmus@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20180427231436.9353-1-paulo.r.zanoni@intel.com
1 parent 13e1592 commit c27e917

File tree

6 files changed

+491
-5
lines changed

6 files changed

+491
-5
lines changed

drivers/gpu/drm/i915/i915_debugfs.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3368,6 +3368,28 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused)
33683368
seq_printf(m, " fp0: 0x%08x\n", pll->state.hw_state.fp0);
33693369
seq_printf(m, " fp1: 0x%08x\n", pll->state.hw_state.fp1);
33703370
seq_printf(m, " wrpll: 0x%08x\n", pll->state.hw_state.wrpll);
3371+
seq_printf(m, " cfgcr0: 0x%08x\n", pll->state.hw_state.cfgcr0);
3372+
seq_printf(m, " cfgcr1: 0x%08x\n", pll->state.hw_state.cfgcr1);
3373+
seq_printf(m, " mg_refclkin_ctl: 0x%08x\n",
3374+
pll->state.hw_state.mg_refclkin_ctl);
3375+
seq_printf(m, " mg_clktop2_coreclkctl1: 0x%08x\n",
3376+
pll->state.hw_state.mg_clktop2_coreclkctl1);
3377+
seq_printf(m, " mg_clktop2_hsclkctl: 0x%08x\n",
3378+
pll->state.hw_state.mg_clktop2_hsclkctl);
3379+
seq_printf(m, " mg_pll_div0: 0x%08x\n",
3380+
pll->state.hw_state.mg_pll_div0);
3381+
seq_printf(m, " mg_pll_div1: 0x%08x\n",
3382+
pll->state.hw_state.mg_pll_div1);
3383+
seq_printf(m, " mg_pll_lf: 0x%08x\n",
3384+
pll->state.hw_state.mg_pll_lf);
3385+
seq_printf(m, " mg_pll_frac_lock: 0x%08x\n",
3386+
pll->state.hw_state.mg_pll_frac_lock);
3387+
seq_printf(m, " mg_pll_ssc: 0x%08x\n",
3388+
pll->state.hw_state.mg_pll_ssc);
3389+
seq_printf(m, " mg_pll_bias: 0x%08x\n",
3390+
pll->state.hw_state.mg_pll_bias);
3391+
seq_printf(m, " mg_pll_tdc_coldst_bias: 0x%08x\n",
3392+
pll->state.hw_state.mg_pll_tdc_coldst_bias);
33713393
}
33723394
drm_modeset_unlock_all(dev);
33733395

drivers/gpu/drm/i915/intel_ddi.c

Lines changed: 94 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,25 @@ static uint32_t hsw_pll_to_ddi_pll_sel(const struct intel_shared_dpll *pll)
10521052
}
10531053
}
10541054

1055+
static uint32_t icl_pll_to_ddi_pll_sel(struct intel_encoder *encoder,
1056+
const struct intel_shared_dpll *pll)
1057+
{
1058+
const enum intel_dpll_id id = pll->info->id;
1059+
1060+
switch (id) {
1061+
default:
1062+
MISSING_CASE(id);
1063+
case DPLL_ID_ICL_DPLL0:
1064+
case DPLL_ID_ICL_DPLL1:
1065+
return DDI_CLK_SEL_NONE;
1066+
case DPLL_ID_ICL_MGPLL1:
1067+
case DPLL_ID_ICL_MGPLL2:
1068+
case DPLL_ID_ICL_MGPLL3:
1069+
case DPLL_ID_ICL_MGPLL4:
1070+
return DDI_CLK_SEL_MG;
1071+
}
1072+
}
1073+
10551074
/* Starting with Haswell, different DDI ports can work in FDI mode for
10561075
* connection to the PCH-located connectors. For this, it is necessary to train
10571076
* both the DDI port and PCH receiver for the desired DDI buffer settings.
@@ -2421,6 +2440,69 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
24212440
return DDI_BUF_TRANS_SELECT(level);
24222441
}
24232442

2443+
void icl_map_plls_to_ports(struct drm_crtc *crtc,
2444+
struct intel_crtc_state *crtc_state,
2445+
struct drm_atomic_state *old_state)
2446+
{
2447+
struct intel_shared_dpll *pll = crtc_state->shared_dpll;
2448+
struct drm_i915_private *dev_priv = to_i915(crtc->dev);
2449+
struct drm_connector_state *conn_state;
2450+
struct drm_connector *conn;
2451+
int i;
2452+
2453+
for_each_new_connector_in_state(old_state, conn, conn_state, i) {
2454+
struct intel_encoder *encoder =
2455+
to_intel_encoder(conn_state->best_encoder);
2456+
enum port port = encoder->port;
2457+
uint32_t val;
2458+
2459+
if (conn_state->crtc != crtc)
2460+
continue;
2461+
2462+
mutex_lock(&dev_priv->dpll_lock);
2463+
2464+
val = I915_READ(DPCLKA_CFGCR0_ICL);
2465+
WARN_ON((val & DPCLKA_CFGCR0_DDI_CLK_OFF(port)) == 0);
2466+
2467+
if (port == PORT_A || port == PORT_B) {
2468+
val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port);
2469+
val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, port);
2470+
I915_WRITE(DPCLKA_CFGCR0_ICL, val);
2471+
POSTING_READ(DPCLKA_CFGCR0_ICL);
2472+
}
2473+
2474+
val &= ~DPCLKA_CFGCR0_DDI_CLK_OFF(port);
2475+
I915_WRITE(DPCLKA_CFGCR0_ICL, val);
2476+
2477+
mutex_unlock(&dev_priv->dpll_lock);
2478+
}
2479+
}
2480+
2481+
void icl_unmap_plls_to_ports(struct drm_crtc *crtc,
2482+
struct intel_crtc_state *crtc_state,
2483+
struct drm_atomic_state *old_state)
2484+
{
2485+
struct drm_i915_private *dev_priv = to_i915(crtc->dev);
2486+
struct drm_connector_state *old_conn_state;
2487+
struct drm_connector *conn;
2488+
int i;
2489+
2490+
for_each_old_connector_in_state(old_state, conn, old_conn_state, i) {
2491+
struct intel_encoder *encoder =
2492+
to_intel_encoder(old_conn_state->best_encoder);
2493+
enum port port = encoder->port;
2494+
2495+
if (old_conn_state->crtc != crtc)
2496+
continue;
2497+
2498+
mutex_lock(&dev_priv->dpll_lock);
2499+
I915_WRITE(DPCLKA_CFGCR0_ICL,
2500+
I915_READ(DPCLKA_CFGCR0_ICL) |
2501+
DPCLKA_CFGCR0_DDI_CLK_OFF(port));
2502+
mutex_unlock(&dev_priv->dpll_lock);
2503+
}
2504+
}
2505+
24242506
static void intel_ddi_clk_select(struct intel_encoder *encoder,
24252507
const struct intel_shared_dpll *pll)
24262508
{
@@ -2433,7 +2515,11 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder,
24332515

24342516
mutex_lock(&dev_priv->dpll_lock);
24352517

2436-
if (IS_CANNONLAKE(dev_priv)) {
2518+
if (IS_ICELAKE(dev_priv)) {
2519+
if (port >= PORT_C)
2520+
I915_WRITE(DDI_CLK_SEL(port),
2521+
icl_pll_to_ddi_pll_sel(encoder, pll));
2522+
} else if (IS_CANNONLAKE(dev_priv)) {
24372523
/* Configure DPCLKA_CFGCR0 to map the DPLL to the DDI. */
24382524
val = I915_READ(DPCLKA_CFGCR0);
24392525
val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port);
@@ -2471,14 +2557,18 @@ static void intel_ddi_clk_disable(struct intel_encoder *encoder)
24712557
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
24722558
enum port port = encoder->port;
24732559

2474-
if (IS_CANNONLAKE(dev_priv))
2560+
if (IS_ICELAKE(dev_priv)) {
2561+
if (port >= PORT_C)
2562+
I915_WRITE(DDI_CLK_SEL(port), DDI_CLK_SEL_NONE);
2563+
} else if (IS_CANNONLAKE(dev_priv)) {
24752564
I915_WRITE(DPCLKA_CFGCR0, I915_READ(DPCLKA_CFGCR0) |
24762565
DPCLKA_CFGCR0_DDI_CLK_OFF(port));
2477-
else if (IS_GEN9_BC(dev_priv))
2566+
} else if (IS_GEN9_BC(dev_priv)) {
24782567
I915_WRITE(DPLL_CTRL2, I915_READ(DPLL_CTRL2) |
24792568
DPLL_CTRL2_DDI_CLK_OFF(port));
2480-
else if (INTEL_GEN(dev_priv) < 9)
2569+
} else if (INTEL_GEN(dev_priv) < 9) {
24812570
I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
2571+
}
24822572
}
24832573

24842574
static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,

drivers/gpu/drm/i915/intel_display.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5559,6 +5559,9 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
55595559
if (intel_crtc->config->shared_dpll)
55605560
intel_enable_shared_dpll(intel_crtc);
55615561

5562+
if (INTEL_GEN(dev_priv) >= 11)
5563+
icl_map_plls_to_ports(crtc, pipe_config, old_state);
5564+
55625565
if (intel_crtc_has_dp_encoder(intel_crtc->config))
55635566
intel_dp_set_m_n(intel_crtc, M1_N1);
55645567

@@ -5756,6 +5759,9 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
57565759
intel_ddi_disable_pipe_clock(intel_crtc->config);
57575760

57585761
intel_encoders_post_disable(crtc, old_crtc_state, old_state);
5762+
5763+
if (INTEL_GEN(dev_priv) >= 11)
5764+
icl_unmap_plls_to_ports(crtc, old_crtc_state, old_state);
57595765
}
57605766

57615767
static void i9xx_pfit_enable(struct intel_crtc *crtc)
@@ -11386,6 +11392,16 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
1138611392
PIPE_CONF_CHECK_X(dpll_hw_state.pll9);
1138711393
PIPE_CONF_CHECK_X(dpll_hw_state.pll10);
1138811394
PIPE_CONF_CHECK_X(dpll_hw_state.pcsdw12);
11395+
PIPE_CONF_CHECK_X(dpll_hw_state.mg_refclkin_ctl);
11396+
PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_coreclkctl1);
11397+
PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_hsclkctl);
11398+
PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div0);
11399+
PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div1);
11400+
PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_lf);
11401+
PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_frac_lock);
11402+
PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_ssc);
11403+
PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_bias);
11404+
PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_tdc_coldst_bias);
1138911405

1139011406
PIPE_CONF_CHECK_X(dsi_pll.ctrl);
1139111407
PIPE_CONF_CHECK_X(dsi_pll.div);

0 commit comments

Comments
 (0)