diff mbox series

[3/5] drm/i915/tgl: Add DKL phy pll state calculations

Message ID 20190725235643.6870-4-lucas.demarchi@intel.com (mailing list archive)
State New, archived
Headers show
Series Tiger Lake: DKL phy PLLs | expand

Commit Message

Lucas De Marchi July 25, 2019, 11:56 p.m. UTC
From: Vandita Kulkarni <vandita.kulkarni@intel.com>

Reuse the existing calculate icl_calc_mg_pll_state() function.
Since the pll variables are calculated differently for DKL phy, add
support for the same.

Signed-off-by: Vandita Kulkarni <vandita.kulkarni@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 59 ++++++++++++++++---
 1 file changed, 50 insertions(+), 9 deletions(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
index 7eefd63a8b7e..3a1348ea6714 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
@@ -2625,7 +2625,8 @@  enum intel_dpll_id icl_tc_port_to_pll_id(enum tc_port tc_port)
 
 static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
 				     u32 *target_dco_khz,
-				     struct intel_dpll_hw_state *state)
+				     struct intel_dpll_hw_state *state,
+				     bool is_dkl)
 {
 	u32 dco_min_freq, dco_max_freq;
 	int div1_vals[] = {7, 5, 3, 2};
@@ -2647,8 +2648,13 @@  static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
 				continue;
 
 			if (div2 >= 2) {
-				a_divratio = is_dp ? 10 : 5;
-				tlinedrv = 2;
+				if (is_dkl) {
+					a_divratio = 5;
+					tlinedrv = 1;
+				} else {
+					a_divratio = is_dp ? 10 : 5;
+					tlinedrv = 2;
+				}
 			} else {
 				a_divratio = 5;
 				tlinedrv = 0;
@@ -2698,7 +2704,8 @@  static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
  * adapted to integer-only calculation, that's why it looks so different.
  */
 static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
-				  struct intel_dpll_hw_state *pll_state)
+				  struct intel_dpll_hw_state *pll_state,
+				  bool is_dkl)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
 	int refclk_khz = dev_priv->cdclk.hw.ref;
@@ -2715,7 +2722,7 @@  static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
 	memset(pll_state, 0, sizeof(*pll_state));
 
 	if (!icl_mg_pll_find_divisors(clock, is_dp, use_ssc, &dco_khz,
-				      pll_state)) {
+				      pll_state, is_dkl)) {
 		DRM_DEBUG_KMS("Failed to find divisors for clock %d\n", clock);
 		return false;
 	}
@@ -2723,8 +2730,11 @@  static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
 	m1div = 2;
 	m2div_int = dco_khz / (refclk_khz * m1div);
 	if (m2div_int > 255) {
-		m1div = 4;
-		m2div_int = dco_khz / (refclk_khz * m1div);
+		if (!is_dkl) {
+			m1div = 4;
+			m2div_int = dco_khz / (refclk_khz * m1div);
+		}
+
 		if (m2div_int > 255) {
 			DRM_DEBUG_KMS("Failed to find mdiv for clock %d\n",
 				      clock);
@@ -2753,6 +2763,12 @@  static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
 		iref_trim = 28;
 		iref_pulse_w = 1;
 		break;
+
+		/*
+		 * TODO: spec adds a case for ndiv = 4 when refclk > 80MHz,
+		 * however this doesn't seem possible from the input.
+		 * See Issue 17526.
+		 */
 	default:
 		MISSING_CASE(refclk_khz);
 		return false;
@@ -2805,7 +2821,31 @@  static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
 	ssc_steplog = 4;
 
 	/* write pll_state calculations */
-	{
+	if (is_dkl) {
+		pll_state->mg_pll_div0 =
+			DKL_PLL_DIV0_INTEG_COEFF(int_coeff) |
+			DKL_PLL_DIV0_PROP_COEFF(prop_coeff) |
+			DKL_PLL_DIV0_FBPREDIV(m1div) |
+			DKL_PLL_DIV0_FBDIV_INT(m2div_int);
+
+		pll_state->mg_pll_div1 =
+			DKL_PLL_DIV1_IREF_TRIM(iref_trim) |
+			DKL_PLL_DIV1_TDC_TARGET_CNT(tdc_targetcnt);
+
+		pll_state->mg_pll_ssc =
+			DKL_PLL_SSC_IREF_NDIV_RATIO(iref_ndiv) |
+			DKL_PLL_SSC_STEP_LEN(ssc_steplen) |
+			DKL_PLL_SSC_STEP_NUM(ssc_steplog) |
+			(use_ssc ? DKL_PLL_SSC_EN : 0);
+
+		pll_state->mg_pll_tdc_coldst_bias =
+			DKL_PLL_TDC_SSC_STEP_SIZE(ssc_stepsize) |
+			DKL_PLL_TDC_FEED_FWD_GAIN(feedfwgain);
+
+		pll_state->mg_pll_bias =
+			(m2div_frac > 0 ? DKL_PLL_BIAS_FRAC_EN_H : 0) |
+			DKL_PLL_BIAS_FBDIV_FRAC(m2div_frac);
+	} else {
 		pll_state->mg_pll_div0 =
 			(m2div_rem > 0 ? MG_PLL_DIV0_FRACNEN_H : 0) |
 			MG_PLL_DIV0_FBDIV_FRAC(m2div_frac) |
@@ -2963,6 +3003,7 @@  static bool icl_get_tc_phy_dplls(struct intel_atomic_state *state,
 		intel_atomic_get_new_crtc_state(state, crtc);
 	struct icl_port_dpll *port_dpll;
 	enum intel_dpll_id dpll_id;
+	bool is_dkl = INTEL_GEN(dev_priv) >= 12;
 
 	port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
 	if (!icl_calc_dpll_state(crtc_state, encoder, &port_dpll->hw_state)) {
@@ -2983,7 +3024,7 @@  static bool icl_get_tc_phy_dplls(struct intel_atomic_state *state,
 
 
 	port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_MG_PHY];
-	if (!icl_calc_mg_pll_state(crtc_state, &port_dpll->hw_state)) {
+	if (!icl_calc_mg_pll_state(crtc_state, &port_dpll->hw_state, is_dkl)) {
 		DRM_DEBUG_KMS("Could not calculate MG PHY PLL state.\n");
 		goto err_unreference_tbt_pll;
 	}