Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1652d19e authored by Ville Syrjälä's avatar Ville Syrjälä Committed by Daniel Vetter
Browse files

drm/i915: Convert the ddi cdclk code to get_display_clock_speed



Unify the HSW/BDW/SKL cdclk extraction code to conform to the same
.get_display_clock_speed() mold that all the other platforms
use.

v2: Update due to SKL code getting added

v3: Rebase on top of -nightly (introduction of intel_audio.c) (Mika Kahola)

Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarMika Kahola <mika.kahola@intel.com>
Reviewed-by: default avatarDamien Lespiau <damien.lespiau@intel.com>
[danvet: Add v3 note as suggested by Damien.]
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 469d4b2a
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -485,7 +485,8 @@ static int i915_audio_component_get_cdclk_freq(struct device *dev)
		return -ENODEV;

	intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
	ret = intel_ddi_get_cdclk_freq(dev_priv);
	ret = dev_priv->display.get_display_clock_speed(dev_priv->dev);

	intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);

	return ret;
+1 −100
Original line number Diff line number Diff line
@@ -1689,105 +1689,6 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)
	}
}

static int skl_get_cdclk_freq(struct drm_i915_private *dev_priv)
{
	uint32_t lcpll1 = I915_READ(LCPLL1_CTL);
	uint32_t cdctl = I915_READ(CDCLK_CTL);
	uint32_t linkrate;

	if (!(lcpll1 & LCPLL_PLL_ENABLE)) {
		WARN(1, "LCPLL1 not enabled\n");
		return 24000; /* 24MHz is the cd freq with NSSC ref */
	}

	if ((cdctl & CDCLK_FREQ_SEL_MASK) == CDCLK_FREQ_540)
		return 540000;

	linkrate = (I915_READ(DPLL_CTRL1) &
		    DPLL_CRTL1_LINK_RATE_MASK(SKL_DPLL0)) >> 1;

	if (linkrate == DPLL_CRTL1_LINK_RATE_2160 ||
	    linkrate == DPLL_CRTL1_LINK_RATE_1080) {
		/* vco 8640 */
		switch (cdctl & CDCLK_FREQ_SEL_MASK) {
		case CDCLK_FREQ_450_432:
			return 432000;
		case CDCLK_FREQ_337_308:
			return 308570;
		case CDCLK_FREQ_675_617:
			return 617140;
		default:
			WARN(1, "Unknown cd freq selection\n");
		}
	} else {
		/* vco 8100 */
		switch (cdctl & CDCLK_FREQ_SEL_MASK) {
		case CDCLK_FREQ_450_432:
			return 450000;
		case CDCLK_FREQ_337_308:
			return 337500;
		case CDCLK_FREQ_675_617:
			return 675000;
		default:
			WARN(1, "Unknown cd freq selection\n");
		}
	}

	/* error case, do as if DPLL0 isn't enabled */
	return 24000;
}

static int bdw_get_cdclk_freq(struct drm_i915_private *dev_priv)
{
	uint32_t lcpll = I915_READ(LCPLL_CTL);
	uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK;

	if (lcpll & LCPLL_CD_SOURCE_FCLK)
		return 800000;
	else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
		return 450000;
	else if (freq == LCPLL_CLK_FREQ_450)
		return 450000;
	else if (freq == LCPLL_CLK_FREQ_54O_BDW)
		return 540000;
	else if (freq == LCPLL_CLK_FREQ_337_5_BDW)
		return 337500;
	else
		return 675000;
}

static int hsw_get_cdclk_freq(struct drm_i915_private *dev_priv)
{
	struct drm_device *dev = dev_priv->dev;
	uint32_t lcpll = I915_READ(LCPLL_CTL);
	uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK;

	if (lcpll & LCPLL_CD_SOURCE_FCLK)
		return 800000;
	else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
		return 450000;
	else if (freq == LCPLL_CLK_FREQ_450)
		return 450000;
	else if (IS_HSW_ULT(dev))
		return 337500;
	else
		return 540000;
}

int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
{
	struct drm_device *dev = dev_priv->dev;

	if (IS_SKYLAKE(dev))
		return skl_get_cdclk_freq(dev_priv);

	if (IS_BROADWELL(dev))
		return bdw_get_cdclk_freq(dev_priv);

	/* Haswell */
	return hsw_get_cdclk_freq(dev_priv);
}

static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
			       struct intel_shared_dpll *pll)
{
@@ -1974,7 +1875,7 @@ void intel_ddi_pll_init(struct drm_device *dev)
		hsw_shared_dplls_init(dev_priv);

	DRM_DEBUG_KMS("CDCLK running at %dKHz\n",
		      intel_ddi_get_cdclk_freq(dev_priv));
		      dev_priv->display.get_display_clock_speed(dev));

	if (IS_SKYLAKE(dev)) {
		if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
+97 −1
Original line number Diff line number Diff line
@@ -5864,6 +5864,93 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
	return 0;
}

static int skylake_get_display_clock_speed(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = to_i915(dev);
	uint32_t lcpll1 = I915_READ(LCPLL1_CTL);
	uint32_t cdctl = I915_READ(CDCLK_CTL);
	uint32_t linkrate;

	if (!(lcpll1 & LCPLL_PLL_ENABLE)) {
		WARN(1, "LCPLL1 not enabled\n");
		return 24000; /* 24MHz is the cd freq with NSSC ref */
	}

	if ((cdctl & CDCLK_FREQ_SEL_MASK) == CDCLK_FREQ_540)
		return 540000;

	linkrate = (I915_READ(DPLL_CTRL1) &
		    DPLL_CRTL1_LINK_RATE_MASK(SKL_DPLL0)) >> 1;

	if (linkrate == DPLL_CRTL1_LINK_RATE_2160 ||
	    linkrate == DPLL_CRTL1_LINK_RATE_1080) {
		/* vco 8640 */
		switch (cdctl & CDCLK_FREQ_SEL_MASK) {
		case CDCLK_FREQ_450_432:
			return 432000;
		case CDCLK_FREQ_337_308:
			return 308570;
		case CDCLK_FREQ_675_617:
			return 617140;
		default:
			WARN(1, "Unknown cd freq selection\n");
		}
	} else {
		/* vco 8100 */
		switch (cdctl & CDCLK_FREQ_SEL_MASK) {
		case CDCLK_FREQ_450_432:
			return 450000;
		case CDCLK_FREQ_337_308:
			return 337500;
		case CDCLK_FREQ_675_617:
			return 675000;
		default:
			WARN(1, "Unknown cd freq selection\n");
		}
	}

	/* error case, do as if DPLL0 isn't enabled */
	return 24000;
}

static int broadwell_get_display_clock_speed(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	uint32_t lcpll = I915_READ(LCPLL_CTL);
	uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK;

	if (lcpll & LCPLL_CD_SOURCE_FCLK)
		return 800000;
	else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
		return 450000;
	else if (freq == LCPLL_CLK_FREQ_450)
		return 450000;
	else if (freq == LCPLL_CLK_FREQ_54O_BDW)
		return 540000;
	else if (freq == LCPLL_CLK_FREQ_337_5_BDW)
		return 337500;
	else
		return 675000;
}

static int haswell_get_display_clock_speed(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	uint32_t lcpll = I915_READ(LCPLL_CTL);
	uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK;

	if (lcpll & LCPLL_CD_SOURCE_FCLK)
		return 800000;
	else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
		return 450000;
	else if (freq == LCPLL_CLK_FREQ_450)
		return 450000;
	else if (IS_HSW_ULT(dev))
		return 337500;
	else
		return 540000;
}

static int valleyview_get_display_clock_speed(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -13500,7 +13587,16 @@ static void intel_init_display(struct drm_device *dev)
	}

	/* Returns the core display clock speed */
	if (IS_VALLEYVIEW(dev))
	if (IS_SKYLAKE(dev))
		dev_priv->display.get_display_clock_speed =
			skylake_get_display_clock_speed;
	else if (IS_BROADWELL(dev))
		dev_priv->display.get_display_clock_speed =
			broadwell_get_display_clock_speed;
	else if (IS_HASWELL(dev))
		dev_priv->display.get_display_clock_speed =
			haswell_get_display_clock_speed;
	else if (IS_VALLEYVIEW(dev))
		dev_priv->display.get_display_clock_speed =
			valleyview_get_display_clock_speed;
	else if (IS_GEN5(dev))
+1 −1
Original line number Diff line number Diff line
@@ -717,7 +717,7 @@ static uint32_t hsw_get_aux_clock_divider(struct intel_dp *intel_dp, int index)
	if (intel_dig_port->port == PORT_A) {
		if (index)
			return 0;
		return DIV_ROUND_CLOSEST(intel_ddi_get_cdclk_freq(dev_priv), 2000);
		return DIV_ROUND_CLOSEST(dev_priv->display.get_display_clock_speed(dev), 2000);
	} else if (dev_priv->pch_id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
		/* Workaround for non-ULT HSW */
		switch (index) {
+0 −1
Original line number Diff line number Diff line
@@ -855,7 +855,6 @@ void hsw_fdi_link_train(struct drm_crtc *crtc);
void intel_ddi_init(struct drm_device *dev, enum port port);
enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder);
bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe);
int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv);
void intel_ddi_pll_init(struct drm_device *dev);
void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc);
void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
Loading