patch merged to dinq. On Thu, Jul 6, 2017 at 1:52 PM, Rodrigo Vivi <rodrigo.vivi@xxxxxxxxx> wrote: > PLLs are the source clocks for the DDIs so in order > to determine the ddi clock we need to check the PLL > configuration. > > v2: Mika pointed out that 24 was hardcoded while it > should consider ref clock that can be either 24KHz > or 19.2KHz on CNL. > > Reviewed-by: Mika Kahola <mika.kahola@xxxxxxxxx> > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@xxxxxxxxx> > --- > drivers/gpu/drm/i915/i915_reg.h | 2 + > drivers/gpu/drm/i915/intel_ddi.c | 111 +++++++++++++++++++++++++++++++++++++++ > 2 files changed, 113 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 64cc674..d6b537e 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -8343,6 +8343,7 @@ enum { > #define DPLL_CFGCR0_LINK_RATE_3240 (6 << 25) > #define DPLL_CFGCR0_LINK_RATE_4050 (7 << 25) > #define DPLL_CFGCR0_DCO_FRACTION_MASK (0x7fff << 10) > +#define DPLL_CFGCR0_DCO_FRAC_SHIFT (10) > #define DPLL_CFGCR0_DCO_FRACTION(x) ((x) << 10) > #define DPLL_CFGCR0_DCO_INTEGER_MASK (0x3ff) > #define CNL_DPLL_CFGCR0(pll) _MMIO_PLL(pll, _CNL_DPLL0_CFGCR0, _CNL_DPLL1_CFGCR0) > @@ -8350,6 +8351,7 @@ enum { > #define _CNL_DPLL0_CFGCR1 0x6C004 > #define _CNL_DPLL1_CFGCR1 0x6C084 > #define DPLL_CFGCR1_QDIV_RATIO_MASK (0xff << 10) > +#define DPLL_CFGCR1_QDIV_RATIO_SHIFT (10) > #define DPLL_CFGCR1_QDIV_RATIO(x) ((x) << 10) > #define DPLL_CFGCR1_QDIV_MODE(x) ((x) << 9) > #define DPLL_CFGCR1_KDIV_MASK (7 << 6) > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c > index 80e96f1..241decf 100644 > --- a/drivers/gpu/drm/i915/intel_ddi.c > +++ b/drivers/gpu/drm/i915/intel_ddi.c > @@ -1103,6 +1103,62 @@ static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv, > return dco_freq / (p0 * p1 * p2 * 5); > } > > +static int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv, > + uint32_t pll_id) > +{ > + 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)); > + > + p0 = cfgcr1 & DPLL_CFGCR1_PDIV_MASK; > + p2 = cfgcr1 & DPLL_CFGCR1_KDIV_MASK; > + > + if (cfgcr1 & DPLL_CFGCR1_QDIV_MODE(1)) > + p1 = (cfgcr1 & DPLL_CFGCR1_QDIV_RATIO_MASK) >> > + DPLL_CFGCR1_QDIV_RATIO_SHIFT; > + else > + p1 = 1; > + > + > + switch (p0) { > + case DPLL_CFGCR1_PDIV_2: > + p0 = 2; > + break; > + case DPLL_CFGCR1_PDIV_3: > + p0 = 3; > + break; > + case DPLL_CFGCR1_PDIV_5: > + p0 = 5; > + break; > + case DPLL_CFGCR1_PDIV_7: > + p0 = 7; > + break; > + } > + > + switch (p2) { > + case DPLL_CFGCR1_KDIV_1: > + p2 = 1; > + break; > + case DPLL_CFGCR1_KDIV_2: > + p2 = 2; > + break; > + case DPLL_CFGCR1_KDIV_4: > + p2 = 4; > + break; > + } > + > + ref_clock = dev_priv->cdclk.hw.ref; > + > + dco_freq = (cfgcr0 & DPLL_CFGCR0_DCO_INTEGER_MASK) * ref_clock; > + > + dco_freq += (((cfgcr0 & DPLL_CFGCR0_DCO_FRACTION_MASK) >> > + DPLL_CFGCR0_DCO_FRAC_SHIFT) * ref_clock) / 0x8000; > + > + return dco_freq / (p0 * p1 * p2 * 5); > +} > + > static void ddi_dotclock_get(struct intel_crtc_state *pipe_config) > { > int dotclock; > @@ -1124,6 +1180,59 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config) > pipe_config->base.adjusted_mode.crtc_clock = dotclock; > } > > +static void cnl_ddi_clock_get(struct intel_encoder *encoder, > + struct intel_crtc_state *pipe_config) > +{ > + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > + int link_clock = 0; > + uint32_t cfgcr0, pll_id; > + > + pll_id = intel_get_shared_dpll_id(dev_priv, pipe_config->shared_dpll); > + > + cfgcr0 = I915_READ(CNL_DPLL_CFGCR0(pll_id)); > + > + if (cfgcr0 & DPLL_CFGCR0_HDMI_MODE) { > + link_clock = cnl_calc_wrpll_link(dev_priv, pll_id); > + } else { > + link_clock = cfgcr0 & DPLL_CFGCR0_LINK_RATE_MASK; > + > + switch (link_clock) { > + case DPLL_CFGCR0_LINK_RATE_810: > + link_clock = 81000; > + break; > + case DPLL_CFGCR0_LINK_RATE_1080: > + link_clock = 108000; > + break; > + case DPLL_CFGCR0_LINK_RATE_1350: > + link_clock = 135000; > + break; > + case DPLL_CFGCR0_LINK_RATE_1620: > + link_clock = 162000; > + break; > + case DPLL_CFGCR0_LINK_RATE_2160: > + link_clock = 216000; > + break; > + case DPLL_CFGCR0_LINK_RATE_2700: > + link_clock = 270000; > + break; > + case DPLL_CFGCR0_LINK_RATE_3240: > + link_clock = 324000; > + break; > + case DPLL_CFGCR0_LINK_RATE_4050: > + link_clock = 405000; > + break; > + default: > + WARN(1, "Unsupported link rate\n"); > + break; > + } > + link_clock *= 2; > + } > + > + pipe_config->port_clock = link_clock; > + > + ddi_dotclock_get(pipe_config); > +} > + > static void skl_ddi_clock_get(struct intel_encoder *encoder, > struct intel_crtc_state *pipe_config) > { > @@ -1267,6 +1376,8 @@ void intel_ddi_clock_get(struct intel_encoder *encoder, > skl_ddi_clock_get(encoder, pipe_config); > else if (IS_GEN9_LP(dev_priv)) > bxt_ddi_clock_get(encoder, pipe_config); > + else if (IS_CANNONLAKE(dev_priv)) > + cnl_ddi_clock_get(encoder, pipe_config); > } > > void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state) > -- > 1.9.1 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Rodrigo Vivi Blog: http://blog.vivi.eng.br _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx