Commit 51c83cfa authored by Manasi Navare's avatar Manasi Navare Committed by Paulo Zanoni

drm/i915/icl: Get DDI clock for ICL based on PLLs.

PLLs are the source clocks for the DDIs so in order
to determine the ddi clock we need to check the PLL
configuration.

This gets a little tricky for ICL since there is
no register bit that maps directly to the link clock.
So this patch creates a separate function in intel_dpll_mgr.c
to obtain the write array PLL Params and compares the set
pll_params with the table to get the corresponding link
clock.

v2:
  - Fix the encoder type check (DK).
  - Improve our error checking, return a sane value (Mika, Paulo).
  - Fix table entries (Paulo).

Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Reviewed-by: default avatarMika Kahola <mika.kahola@intel.com>
Signed-off-by: default avatarManasi Navare <manasi.d.navare@intel.com>
Signed-off-by: default avatarLucas De Marchi <lucas.demarchi@intel.com>
[Paulo: implement v2]
Signed-off-by: default avatarPaulo Zanoni <paulo.r.zanoni@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180523224444.19017-1-paulo.r.zanoni@intel.com
parent f17ca501
...@@ -9127,13 +9127,16 @@ enum skl_power_gate { ...@@ -9127,13 +9127,16 @@ enum skl_power_gate {
#define DPLL_CFGCR1_QDIV_RATIO_MASK (0xff << 10) #define DPLL_CFGCR1_QDIV_RATIO_MASK (0xff << 10)
#define DPLL_CFGCR1_QDIV_RATIO_SHIFT (10) #define DPLL_CFGCR1_QDIV_RATIO_SHIFT (10)
#define DPLL_CFGCR1_QDIV_RATIO(x) ((x) << 10) #define DPLL_CFGCR1_QDIV_RATIO(x) ((x) << 10)
#define DPLL_CFGCR1_QDIV_MODE_SHIFT (9)
#define DPLL_CFGCR1_QDIV_MODE(x) ((x) << 9) #define DPLL_CFGCR1_QDIV_MODE(x) ((x) << 9)
#define DPLL_CFGCR1_KDIV_MASK (7 << 6) #define DPLL_CFGCR1_KDIV_MASK (7 << 6)
#define DPLL_CFGCR1_KDIV_SHIFT (6)
#define DPLL_CFGCR1_KDIV(x) ((x) << 6) #define DPLL_CFGCR1_KDIV(x) ((x) << 6)
#define DPLL_CFGCR1_KDIV_1 (1 << 6) #define DPLL_CFGCR1_KDIV_1 (1 << 6)
#define DPLL_CFGCR1_KDIV_2 (2 << 6) #define DPLL_CFGCR1_KDIV_2 (2 << 6)
#define DPLL_CFGCR1_KDIV_4 (4 << 6) #define DPLL_CFGCR1_KDIV_4 (4 << 6)
#define DPLL_CFGCR1_PDIV_MASK (0xf << 2) #define DPLL_CFGCR1_PDIV_MASK (0xf << 2)
#define DPLL_CFGCR1_PDIV_SHIFT (2)
#define DPLL_CFGCR1_PDIV(x) ((x) << 2) #define DPLL_CFGCR1_PDIV(x) ((x) << 2)
#define DPLL_CFGCR1_PDIV_2 (1 << 2) #define DPLL_CFGCR1_PDIV_2 (1 << 2)
#define DPLL_CFGCR1_PDIV_3 (2 << 2) #define DPLL_CFGCR1_PDIV_3 (2 << 2)
......
...@@ -1422,6 +1422,30 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config) ...@@ -1422,6 +1422,30 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
pipe_config->base.adjusted_mode.crtc_clock = dotclock; pipe_config->base.adjusted_mode.crtc_clock = dotclock;
} }
static void icl_ddi_clock_get(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum port port = encoder->port;
int link_clock = 0;
uint32_t pll_id;
pll_id = intel_get_shared_dpll_id(dev_priv, pipe_config->shared_dpll);
if (port == PORT_A || port == PORT_B) {
if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI))
link_clock = cnl_calc_wrpll_link(dev_priv, pll_id);
else
link_clock = icl_calc_dp_combo_pll_link(dev_priv,
pll_id);
} else {
/* FIXME - Add for MG PLL */
WARN(1, "MG PLL clock_get code not implemented yet\n");
}
pipe_config->port_clock = link_clock;
ddi_dotclock_get(pipe_config);
}
static void cnl_ddi_clock_get(struct intel_encoder *encoder, static void cnl_ddi_clock_get(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config) struct intel_crtc_state *pipe_config)
{ {
...@@ -1615,6 +1639,8 @@ static void intel_ddi_clock_get(struct intel_encoder *encoder, ...@@ -1615,6 +1639,8 @@ static void intel_ddi_clock_get(struct intel_encoder *encoder,
bxt_ddi_clock_get(encoder, pipe_config); bxt_ddi_clock_get(encoder, pipe_config);
else if (IS_CANNONLAKE(dev_priv)) else if (IS_CANNONLAKE(dev_priv))
cnl_ddi_clock_get(encoder, pipe_config); cnl_ddi_clock_get(encoder, pipe_config);
else if (IS_ICELAKE(dev_priv))
icl_ddi_clock_get(encoder, pipe_config);
} }
void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state) void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state)
......
...@@ -2525,6 +2525,76 @@ static bool icl_calc_dpll_state(struct intel_crtc_state *crtc_state, ...@@ -2525,6 +2525,76 @@ static bool icl_calc_dpll_state(struct intel_crtc_state *crtc_state,
return true; return true;
} }
int icl_calc_dp_combo_pll_link(struct drm_i915_private *dev_priv,
uint32_t pll_id)
{
uint32_t cfgcr0, cfgcr1;
uint32_t pdiv, kdiv, qdiv_mode, qdiv_ratio, dco_integer, dco_fraction;
const struct skl_wrpll_params *params;
int index, n_entries, link_clock;
/* Read back values from DPLL CFGCR registers */
cfgcr0 = I915_READ(ICL_DPLL_CFGCR0(pll_id));
cfgcr1 = I915_READ(ICL_DPLL_CFGCR1(pll_id));
dco_integer = cfgcr0 & DPLL_CFGCR0_DCO_INTEGER_MASK;
dco_fraction = (cfgcr0 & DPLL_CFGCR0_DCO_FRACTION_MASK) >>
DPLL_CFGCR0_DCO_FRACTION_SHIFT;
pdiv = (cfgcr1 & DPLL_CFGCR1_PDIV_MASK) >> DPLL_CFGCR1_PDIV_SHIFT;
kdiv = (cfgcr1 & DPLL_CFGCR1_KDIV_MASK) >> DPLL_CFGCR1_KDIV_SHIFT;
qdiv_mode = (cfgcr1 & DPLL_CFGCR1_QDIV_MODE(1)) >>
DPLL_CFGCR1_QDIV_MODE_SHIFT;
qdiv_ratio = (cfgcr1 & DPLL_CFGCR1_QDIV_RATIO_MASK) >>
DPLL_CFGCR1_QDIV_RATIO_SHIFT;
params = dev_priv->cdclk.hw.ref == 24000 ?
icl_dp_combo_pll_24MHz_values :
icl_dp_combo_pll_19_2MHz_values;
n_entries = ARRAY_SIZE(icl_dp_combo_pll_24MHz_values);
for (index = 0; index < n_entries; index++) {
if (dco_integer == params[index].dco_integer &&
dco_fraction == params[index].dco_fraction &&
pdiv == params[index].pdiv &&
kdiv == params[index].kdiv &&
qdiv_mode == params[index].qdiv_mode &&
qdiv_ratio == params[index].qdiv_ratio)
break;
}
/* Map PLL Index to Link Clock */
switch (index) {
default:
MISSING_CASE(index);
case 0:
link_clock = 540000;
break;
case 1:
link_clock = 270000;
break;
case 2:
link_clock = 162000;
break;
case 3:
link_clock = 324000;
break;
case 4:
link_clock = 216000;
break;
case 5:
link_clock = 432000;
break;
case 6:
link_clock = 648000;
break;
case 7:
link_clock = 810000;
break;
}
return link_clock;
}
static enum port icl_mg_pll_id_to_port(enum intel_dpll_id id) static enum port icl_mg_pll_id_to_port(enum intel_dpll_id id)
{ {
return id - DPLL_ID_ICL_MGPLL1 + PORT_C; return id - DPLL_ID_ICL_MGPLL1 + PORT_C;
......
...@@ -336,5 +336,7 @@ void intel_shared_dpll_init(struct drm_device *dev); ...@@ -336,5 +336,7 @@ void intel_shared_dpll_init(struct drm_device *dev);
void intel_dpll_dump_hw_state(struct drm_i915_private *dev_priv, void intel_dpll_dump_hw_state(struct drm_i915_private *dev_priv,
struct intel_dpll_hw_state *hw_state); struct intel_dpll_hw_state *hw_state);
int icl_calc_dp_combo_pll_link(struct drm_i915_private *dev_priv,
uint32_t pll_id);
#endif /* _INTEL_DPLL_MGR_H_ */ #endif /* _INTEL_DPLL_MGR_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment