From: Imre Deak <imre.deak@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [Intel-gfx] [PATCH 2/5] drm/i915: Factor out skl_wrpll_calc_freq()
Date: Tue, 29 Sep 2020 03:29:26 +0300 [thread overview]
Message-ID: <20200929002929.783620-3-imre.deak@intel.com> (raw)
In-Reply-To: <20200929002929.783620-1-imre.deak@intel.com>
The WRPLL parameter -> frequency formula is the same for all platforms
starting with SKL. Factor out the helper for this for clarity and so
that we can use the same formula when selecting the ICL WRPLL dividers
for DP mode in an upcoming patch (to cross-check the frequency
calculated using the formula wrt. hard-coded freq values in the ICL DP
PLL tables).
While at it add the MISSING_CASE() for incorrect divider encodings.
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 160 +++++++++++-------
drivers/gpu/drm/i915/i915_reg.h | 3 +
2 files changed, 101 insertions(+), 62 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
index 095b53fe3a21..e3370c8dccc8 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
@@ -1576,31 +1576,31 @@ static bool skl_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state)
return true;
}
-static int skl_ddi_wrpll_get_freq(struct drm_i915_private *i915,
- const struct intel_shared_dpll *pll)
+static int skl_wrpll_calc_freq(int ref_clock,
+ u32 dco_integer, u32 dco_fraction,
+ u32 pdiv, u32 qdiv, u32 kdiv)
{
- const struct intel_dpll_hw_state *pll_state = &pll->state.hw_state;
- int ref_clock = i915->dpll.ref_clks.nssc;
- u32 p0, p1, p2, dco_freq;
+ u32 dco_freq;
- p0 = pll_state->cfgcr2 & DPLL_CFGCR2_PDIV_MASK;
- p2 = pll_state->cfgcr2 & DPLL_CFGCR2_KDIV_MASK;
+ dco_freq = ref_clock * dco_integer;
+ dco_freq += dco_fraction * ref_clock / 0x8000;
- if (pll_state->cfgcr2 & DPLL_CFGCR2_QDIV_MODE(1))
- p1 = (pll_state->cfgcr2 & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
- else
- p1 = 1;
+ return dco_freq / (pdiv * qdiv * kdiv * 5);
+}
-
- switch (p0) {
+static void skl_wrpll_decode_divs(struct drm_i915_private *i915,
+ const struct skl_wrpll_params *wrpll_params,
+ u32 *pdiv, u32 *qdiv, u32 *kdiv)
+{
+ switch (DPLL_CFGCR2_PDIV(wrpll_params->pdiv)) {
case DPLL_CFGCR2_PDIV_1:
- p0 = 1;
+ *pdiv = 1;
break;
case DPLL_CFGCR2_PDIV_2:
- p0 = 2;
+ *pdiv = 2;
break;
case DPLL_CFGCR2_PDIV_3:
- p0 = 3;
+ *pdiv = 3;
break;
case DPLL_CFGCR2_PDIV_7 | (1 << DPLL_CFGCR2_PDIV_SHIFT):
/*
@@ -1608,38 +1608,63 @@ static int skl_ddi_wrpll_get_freq(struct drm_i915_private *i915,
* handling it the same way as PDIV_7.
*/
drm_err(&i915->drm, "Invalid WRPLL PDIV divider value, fixing it.\n");
- p0 = 7;
+ *pdiv = 7;
break;
+ default:
+ MISSING_CASE(wrpll_params->pdiv);
+ fallthrough;
case DPLL_CFGCR2_PDIV_7:
- p0 = 7;
+ *pdiv = 7;
break;
}
- switch (p2) {
+ *qdiv = wrpll_params->qdiv_mode ? wrpll_params->qdiv_ratio : 1;
+
+ switch (DPLL_CFGCR2_KDIV(wrpll_params->kdiv)) {
+ default:
+ MISSING_CASE(wrpll_params->kdiv);
+ fallthrough;
case DPLL_CFGCR2_KDIV_5:
- p2 = 5;
+ *kdiv = 5;
break;
case DPLL_CFGCR2_KDIV_2:
- p2 = 2;
+ *kdiv = 2;
break;
case DPLL_CFGCR2_KDIV_3:
- p2 = 3;
+ *kdiv = 3;
break;
case DPLL_CFGCR2_KDIV_1:
- p2 = 1;
+ *kdiv = 1;
break;
}
+}
- dco_freq = (pll_state->cfgcr1 & DPLL_CFGCR1_DCO_INTEGER_MASK) *
- ref_clock;
+static int skl_ddi_wrpll_get_freq(struct drm_i915_private *i915,
+ const struct intel_shared_dpll *pll)
+{
+ const struct intel_dpll_hw_state *pll_state = &pll->state.hw_state;
+ struct skl_wrpll_params wrpll_params = { };
+ int ref_clock = i915->dpll.ref_clks.nssc;
+ u32 pdiv;
+ u32 qdiv;
+ u32 kdiv;
+ u32 dco_integer;
+ u32 dco_fraction;
- dco_freq += ((pll_state->cfgcr1 & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) *
- ref_clock / 0x8000;
+ wrpll_params.pdiv = (pll_state->cfgcr2 & DPLL_CFGCR2_PDIV_MASK) >> DPLL_CFGCR2_PDIV_SHIFT;
+ wrpll_params.kdiv = (pll_state->cfgcr2 & DPLL_CFGCR2_KDIV_MASK) >> DPLL_CFGCR2_KDIV_SHIFT;
- if (drm_WARN_ON(&i915->drm, p0 == 0 || p1 == 0 || p2 == 0))
- return 0;
+ wrpll_params.qdiv_mode = !!(pll_state->cfgcr2 & DPLL_CFGCR2_QDIV_MODE(1));
+ wrpll_params.qdiv_ratio = (pll_state->cfgcr2 & DPLL_CFGCR2_QDIV_RATIO_MASK) >>
+ DPLL_CFGCR2_QDIV_RATIO_SHIFT;
- return dco_freq / (p0 * p1 * p2 * 5);
+ skl_wrpll_decode_divs(i915, &wrpll_params, &pdiv, &qdiv, &kdiv);
+
+ dco_integer = pll_state->cfgcr1 & DPLL_CFGCR1_DCO_INTEGER_MASK;
+ dco_fraction = (pll_state->cfgcr1 & DPLL_CFGCR1_DCO_FRACTION_MASK) >>
+ DPLL_CFGCR1_DCO_FRACTION_SHIFT;
+
+ return skl_wrpll_calc_freq(ref_clock, dco_integer, dco_fraction, pdiv, qdiv, kdiv);
}
static bool
@@ -2630,60 +2655,71 @@ static bool cnl_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state)
return true;
}
-static int __cnl_ddi_wrpll_get_freq(struct drm_i915_private *dev_priv,
- const struct intel_shared_dpll *pll,
- int ref_clock)
+static void cnl_wrpll_decode_divs(const struct skl_wrpll_params *wrpll_params,
+ u32 *pdiv, u32 *qdiv, u32 *kdiv)
{
- const struct intel_dpll_hw_state *pll_state = &pll->state.hw_state;
- u32 p0, p1, p2, dco_freq;
-
- p0 = pll_state->cfgcr1 & DPLL_CFGCR1_PDIV_MASK;
- p2 = pll_state->cfgcr1 & DPLL_CFGCR1_KDIV_MASK;
-
- if (pll_state->cfgcr1 & DPLL_CFGCR1_QDIV_MODE(1))
- p1 = (pll_state->cfgcr1 & DPLL_CFGCR1_QDIV_RATIO_MASK) >>
- DPLL_CFGCR1_QDIV_RATIO_SHIFT;
- else
- p1 = 1;
-
-
- switch (p0) {
+ switch (DPLL_CFGCR1_PDIV(wrpll_params->pdiv)) {
case DPLL_CFGCR1_PDIV_2:
- p0 = 2;
+ *pdiv = 2;
break;
case DPLL_CFGCR1_PDIV_3:
- p0 = 3;
+ *pdiv = 3;
break;
case DPLL_CFGCR1_PDIV_5:
- p0 = 5;
+ *pdiv = 5;
break;
+ default:
+ MISSING_CASE(wrpll_params->pdiv);
+ fallthrough;
case DPLL_CFGCR1_PDIV_7:
- p0 = 7;
+ *pdiv = 7;
break;
}
- switch (p2) {
+ *qdiv = wrpll_params->qdiv_mode ? wrpll_params->qdiv_ratio : 1;
+
+ switch (DPLL_CFGCR1_KDIV(wrpll_params->kdiv)) {
case DPLL_CFGCR1_KDIV_1:
- p2 = 1;
+ *kdiv = 1;
break;
case DPLL_CFGCR1_KDIV_2:
- p2 = 2;
+ *kdiv = 2;
break;
+ default:
+ MISSING_CASE(wrpll_params->kdiv);
+ fallthrough;
case DPLL_CFGCR1_KDIV_3:
- p2 = 3;
+ *kdiv = 3;
break;
}
+}
- dco_freq = (pll_state->cfgcr0 & DPLL_CFGCR0_DCO_INTEGER_MASK) *
- ref_clock;
+static int __cnl_ddi_wrpll_get_freq(struct drm_i915_private *dev_priv,
+ const struct intel_shared_dpll *pll,
+ int ref_clock)
+{
+ const struct intel_dpll_hw_state *pll_state = &pll->state.hw_state;
+ struct skl_wrpll_params wrpll_params = { };
+ u32 pdiv;
+ u32 qdiv;
+ u32 kdiv;
+ u32 dco_integer;
+ u32 dco_fraction;
- dco_freq += (((pll_state->cfgcr0 & DPLL_CFGCR0_DCO_FRACTION_MASK) >>
- DPLL_CFGCR0_DCO_FRACTION_SHIFT) * ref_clock) / 0x8000;
+ wrpll_params.pdiv = (pll_state->cfgcr1 & DPLL_CFGCR1_PDIV_MASK) >> DPLL_CFGCR1_PDIV_SHIFT;
+ wrpll_params.kdiv = (pll_state->cfgcr1 & DPLL_CFGCR1_KDIV_MASK) >> DPLL_CFGCR1_KDIV_SHIFT;
- if (drm_WARN_ON(&dev_priv->drm, p0 == 0 || p1 == 0 || p2 == 0))
- return 0;
+ wrpll_params.qdiv_mode = !!(pll_state->cfgcr1 & DPLL_CFGCR1_QDIV_MODE(1));
+ wrpll_params.qdiv_ratio = (pll_state->cfgcr1 & DPLL_CFGCR1_QDIV_RATIO_MASK) >>
+ DPLL_CFGCR1_QDIV_RATIO_SHIFT;
- return dco_freq / (p0 * p1 * p2 * 5);
+ cnl_wrpll_decode_divs(&wrpll_params, &pdiv, &qdiv, &kdiv);
+
+ dco_integer = pll_state->cfgcr0 & DPLL_CFGCR0_DCO_INTEGER_MASK;
+ dco_fraction = (pll_state->cfgcr0 & DPLL_CFGCR0_DCO_FRACTION_MASK) >>
+ DPLL_CFGCR0_DCO_FRACTION_SHIFT;
+
+ return skl_wrpll_calc_freq(ref_clock, dco_integer, dco_fraction, pdiv, qdiv, kdiv);
}
static int cnl_ddi_wrpll_get_freq(struct drm_i915_private *i915,
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index f70e45bd3810..4409c712030c 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -10237,6 +10237,7 @@ enum skl_power_gate {
#define _DPLL3_CFGCR1 0x6C050
#define DPLL_CFGCR1_FREQ_ENABLE (1 << 31)
#define DPLL_CFGCR1_DCO_FRACTION_MASK (0x7fff << 9)
+#define DPLL_CFGCR1_DCO_FRACTION_SHIFT 9
#define DPLL_CFGCR1_DCO_FRACTION(x) ((x) << 9)
#define DPLL_CFGCR1_DCO_INTEGER_MASK (0x1ff)
@@ -10244,9 +10245,11 @@ enum skl_power_gate {
#define _DPLL2_CFGCR2 0x6C04C
#define _DPLL3_CFGCR2 0x6C054
#define DPLL_CFGCR2_QDIV_RATIO_MASK (0xff << 8)
+#define DPLL_CFGCR2_QDIV_RATIO_SHIFT 8
#define DPLL_CFGCR2_QDIV_RATIO(x) ((x) << 8)
#define DPLL_CFGCR2_QDIV_MODE(x) ((x) << 7)
#define DPLL_CFGCR2_KDIV_MASK (3 << 5)
+#define DPLL_CFGCR2_KDIV_SHIFT 5
#define DPLL_CFGCR2_KDIV(x) ((x) << 5)
#define DPLL_CFGCR2_KDIV_5 (0 << 5)
#define DPLL_CFGCR2_KDIV_2 (1 << 5)
--
2.25.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2020-09-29 0:29 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-29 0:29 [Intel-gfx] [PATCH 0/5] drm/i915/tgl: Fix Combo PHY DPLL fractional divider for 38.4MHz ref clock Imre Deak
2020-09-29 0:29 ` [Intel-gfx] [PATCH 1/5] drm/i915/skl: Work around incorrect BIOS WRPLL PDIV programming Imre Deak
2020-10-01 16:41 ` Ville Syrjälä
2020-10-01 16:53 ` Imre Deak
2020-09-29 0:29 ` Imre Deak [this message]
2020-09-29 0:29 ` [Intel-gfx] [PATCH 3/5] drm/i915/icl: Cross check the combo PLL WRPLL parameters wrt. hard-coded PLL freqs Imre Deak
2020-10-01 16:44 ` Ville Syrjälä
2020-10-01 17:00 ` Ville Syrjälä
2020-10-01 17:31 ` Imre Deak
2020-09-29 0:29 ` [Intel-gfx] [PATCH 4/5] drm/i915/tgl: Fix Combo PHY DPLL fractional divider for 38.4MHz ref clock Imre Deak
2020-10-01 16:45 ` Ville Syrjälä
2020-09-29 0:29 ` [Intel-gfx] [PATCH 5/5] drm/i915/tgl: Add workaround for incorrect BIOS combo PHY DPLL programming Imre Deak
2020-09-29 1:51 ` [Intel-gfx] ✗ Fi.CI.SPARSE: warning for drm/i915/tgl: Fix Combo PHY DPLL fractional divider for 38.4MHz ref clock Patchwork
2020-09-29 2:11 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200929002929.783620-3-imre.deak@intel.com \
--to=imre.deak@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox