diff mbox

[v3,2/2] drm/i915/icl: Do read-modify-write as needed during MG PLL programming

Message ID 20180619164115.7835-1-imre.deak@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Imre Deak June 19, 2018, 4:41 p.m. UTC
Some MG PLL registers have fields that need to be preserved at their HW
default or BIOS programmed values. So make sure we preserve them.

v2:
- Add comment to icl_mg_pll_write() explaining the need for register
  masks. (Vandita)
- Fix patchwork checkpatch warning.

v3:
- Rebase on drm-tip.

Cc: Vandita Kulkarni <vandita.kulkarni@intel.com>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: James Ausmus <james.ausmus@intel.com> (v1)
---
 drivers/gpu/drm/i915/i915_reg.h       | 13 ++++++++++++
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 39 +++++++++++++++++++++++++++++++----
 2 files changed, 48 insertions(+), 4 deletions(-)

Comments

Kulkarni, Vandita June 20, 2018, 1:31 p.m. UTC | #1
> -----Original Message-----
> From: Deak, Imre
> Sent: Tuesday, June 19, 2018 10:11 PM
> To: intel-gfx@lists.freedesktop.org
> Cc: Kulkarni, Vandita <vandita.kulkarni@intel.com>; Zanoni, Paulo R
> <paulo.r.zanoni@intel.com>; Ausmus, James <james.ausmus@intel.com>
> Subject: [PATCH v3 2/2] drm/i915/icl: Do read-modify-write as needed
> during MG PLL programming
> 
> Some MG PLL registers have fields that need to be preserved at their HW
> default or BIOS programmed values. So make sure we preserve them.
> 
> v2:
> - Add comment to icl_mg_pll_write() explaining the need for register
>   masks. (Vandita)
> - Fix patchwork checkpatch warning.
> 
> v3:
> - Rebase on drm-tip.
> 
> Cc: Vandita Kulkarni <vandita.kulkarni@intel.com>
> Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
> Cc: James Ausmus <james.ausmus@intel.com>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> Reviewed-by: James Ausmus <james.ausmus@intel.com> (v1)

Looks good to me.
Reviewed-by: Vandita Kulkarni <vandita.kulkarni@intel.com>

> ---
>  drivers/gpu/drm/i915/i915_reg.h       | 13 ++++++++++++
>  drivers/gpu/drm/i915/intel_dpll_mgr.c | 39
> +++++++++++++++++++++++++++++++----
>  2 files changed, 48 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h
> b/drivers/gpu/drm/i915/i915_reg.h index 4bfd7a9bd75f..65b222287ee4
> 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -9047,6 +9047,7 @@ enum skl_power_gate {
>  #define _MG_REFCLKIN_CTL_PORT3				0x16A92C
>  #define _MG_REFCLKIN_CTL_PORT4				0x16B92C
>  #define   MG_REFCLKIN_CTL_OD_2_MUX(x)			((x) << 8)
> +#define   MG_REFCLKIN_CTL_OD_2_MUX_MASK			(0x7
> << 8)
>  #define MG_REFCLKIN_CTL(port) _MMIO_PORT((port) - PORT_C, \
>  					 _MG_REFCLKIN_CTL_PORT1, \
>  					 _MG_REFCLKIN_CTL_PORT2)
> @@ -9056,7 +9057,9 @@ enum skl_power_gate {
>  #define _MG_CLKTOP2_CORECLKCTL1_PORT3
> 	0x16A8D8
>  #define _MG_CLKTOP2_CORECLKCTL1_PORT4
> 	0x16B8D8
>  #define   MG_CLKTOP2_CORECLKCTL1_B_DIVRATIO(x)		((x)
> << 16)
> +#define   MG_CLKTOP2_CORECLKCTL1_B_DIVRATIO_MASK	(0xff << 16)
>  #define   MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO(x)		((x)
> << 8)
> +#define   MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK	(0xff << 8)
>  #define MG_CLKTOP2_CORECLKCTL1(port) _MMIO_PORT((port) - PORT_C,
> \
> 
> 	_MG_CLKTOP2_CORECLKCTL1_PORT1, \
> 
> 	_MG_CLKTOP2_CORECLKCTL1_PORT2)
> @@ -9066,9 +9069,13 @@ enum skl_power_gate {
>  #define _MG_CLKTOP2_HSCLKCTL_PORT3			0x16A8D4
>  #define _MG_CLKTOP2_HSCLKCTL_PORT4			0x16B8D4
>  #define   MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL(x)		((x)
> << 16)
> +#define   MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK	(0x1 << 16)
>  #define   MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL(x)	((x) << 14)
> +#define   MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK	(0x3
> << 14)
>  #define   MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO(x)		((x) << 12)
> +#define   MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK		(0x3
> << 12)
>  #define   MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO(x)		((x) << 8)
> +#define   MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK		(0xf
> << 8)
>  #define MG_CLKTOP2_HSCLKCTL(port) _MMIO_PORT((port) - PORT_C, \
> 
> _MG_CLKTOP2_HSCLKCTL_PORT1, \
> 
> _MG_CLKTOP2_HSCLKCTL_PORT2)
> @@ -9142,12 +9149,18 @@ enum skl_power_gate {
>  #define _MG_PLL_BIAS_PORT3				0x16AA14
>  #define _MG_PLL_BIAS_PORT4				0x16BA14
>  #define   MG_PLL_BIAS_BIAS_GB_SEL(x)			((x) << 30)
> +#define   MG_PLL_BIAS_BIAS_GB_SEL_MASK			(0x3
> << 30)
>  #define   MG_PLL_BIAS_INIT_DCOAMP(x)			((x) << 24)
> +#define   MG_PLL_BIAS_INIT_DCOAMP_MASK			(0x3f
> << 24)
>  #define   MG_PLL_BIAS_BIAS_BONUS(x)			((x) << 16)
> +#define   MG_PLL_BIAS_BIAS_BONUS_MASK			(0xff << 16)
>  #define   MG_PLL_BIAS_BIASCAL_EN			(1 << 15)
>  #define   MG_PLL_BIAS_CTRIM(x)				((x) << 8)
> +#define   MG_PLL_BIAS_CTRIM_MASK			(0x1f << 8)
>  #define   MG_PLL_BIAS_VREF_RDAC(x)			((x) << 5)
> +#define   MG_PLL_BIAS_VREF_RDAC_MASK			(0x7 << 5)
>  #define   MG_PLL_BIAS_IREFTRIM(x)			((x) << 0)
> +#define   MG_PLL_BIAS_IREFTRIM_MASK			(0x1f << 0)
>  #define MG_PLL_BIAS(port) _MMIO_PORT((port) - PORT_C,
> _MG_PLL_BIAS_PORT1, \
>  				     _MG_PLL_BIAS_PORT2)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c
> b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> index d4c7bacbe83e..57342364fd30 100644
> --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
> +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> @@ -2945,10 +2945,21 @@ static bool icl_pll_get_hw_state(struct
> drm_i915_private *dev_priv,
>  	case DPLL_ID_ICL_MGPLL4:
>  		port = icl_mg_pll_id_to_port(id);
>  		hw_state->mg_refclkin_ctl =
> I915_READ(MG_REFCLKIN_CTL(port));
> +		hw_state->mg_refclkin_ctl &=
> MG_REFCLKIN_CTL_OD_2_MUX_MASK;
> +
>  		hw_state->mg_clktop2_coreclkctl1 =
>  			I915_READ(MG_CLKTOP2_CORECLKCTL1(port));
> +		hw_state->mg_clktop2_coreclkctl1 &=
> +			MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
> +
>  		hw_state->mg_clktop2_hsclkctl =
>  			I915_READ(MG_CLKTOP2_HSCLKCTL(port));
> +		hw_state->mg_clktop2_hsclkctl &=
> +			MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK
> |
> +			MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
> +			MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
> +			MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK;
> +
>  		hw_state->mg_pll_div0 = I915_READ(MG_PLL_DIV0(port));
>  		hw_state->mg_pll_div1 = I915_READ(MG_PLL_DIV1(port));
>  		hw_state->mg_pll_lf = I915_READ(MG_PLL_LF(port)); @@ -
> 2998,10 +3009,30 @@ static void icl_mg_pll_write(struct
> drm_i915_private *dev_priv,
>  	enum port port = icl_mg_pll_id_to_port(pll->info->id);
>  	u32 val;
> 
> -	I915_WRITE(MG_REFCLKIN_CTL(port), hw_state->mg_refclkin_ctl);
> -	I915_WRITE(MG_CLKTOP2_CORECLKCTL1(port),
> -		   hw_state->mg_clktop2_coreclkctl1);
> -	I915_WRITE(MG_CLKTOP2_HSCLKCTL(port), hw_state-
> >mg_clktop2_hsclkctl);
> +	/*
> +	 * Some of the following registers have reserved fields, so program
> +	 * these with RMW based on a mask. The mask can be fixed or
> generated
> +	 * during the calc/readout phase if the mask depends on some
> other HW
> +	 * state like refclk, see icl_calc_mg_pll_state().
> +	 */
> +	val = I915_READ(MG_REFCLKIN_CTL(port));
> +	val &= ~MG_REFCLKIN_CTL_OD_2_MUX_MASK;
> +	val |= hw_state->mg_refclkin_ctl;
> +	I915_WRITE(MG_REFCLKIN_CTL(port), val);
> +
> +	val = I915_READ(MG_CLKTOP2_CORECLKCTL1(port));
> +	val &= ~MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
> +	val |= hw_state->mg_clktop2_coreclkctl1;
> +	I915_WRITE(MG_CLKTOP2_CORECLKCTL1(port), val);
> +
> +	val = I915_READ(MG_CLKTOP2_HSCLKCTL(port));
> +	val &= ~(MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
> +		 MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
> +		 MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
> +		 MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK);
> +	val |= hw_state->mg_clktop2_hsclkctl;
> +	I915_WRITE(MG_CLKTOP2_HSCLKCTL(port), val);
> +
>  	I915_WRITE(MG_PLL_DIV0(port), hw_state->mg_pll_div0);
>  	I915_WRITE(MG_PLL_DIV1(port), hw_state->mg_pll_div1);
>  	I915_WRITE(MG_PLL_LF(port), hw_state->mg_pll_lf);
> --
> 2.13.2
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 4bfd7a9bd75f..65b222287ee4 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -9047,6 +9047,7 @@  enum skl_power_gate {
 #define _MG_REFCLKIN_CTL_PORT3				0x16A92C
 #define _MG_REFCLKIN_CTL_PORT4				0x16B92C
 #define   MG_REFCLKIN_CTL_OD_2_MUX(x)			((x) << 8)
+#define   MG_REFCLKIN_CTL_OD_2_MUX_MASK			(0x7 << 8)
 #define MG_REFCLKIN_CTL(port) _MMIO_PORT((port) - PORT_C, \
 					 _MG_REFCLKIN_CTL_PORT1, \
 					 _MG_REFCLKIN_CTL_PORT2)
@@ -9056,7 +9057,9 @@  enum skl_power_gate {
 #define _MG_CLKTOP2_CORECLKCTL1_PORT3			0x16A8D8
 #define _MG_CLKTOP2_CORECLKCTL1_PORT4			0x16B8D8
 #define   MG_CLKTOP2_CORECLKCTL1_B_DIVRATIO(x)		((x) << 16)
+#define   MG_CLKTOP2_CORECLKCTL1_B_DIVRATIO_MASK	(0xff << 16)
 #define   MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO(x)		((x) << 8)
+#define   MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK	(0xff << 8)
 #define MG_CLKTOP2_CORECLKCTL1(port) _MMIO_PORT((port) - PORT_C, \
 						_MG_CLKTOP2_CORECLKCTL1_PORT1, \
 						_MG_CLKTOP2_CORECLKCTL1_PORT2)
@@ -9066,9 +9069,13 @@  enum skl_power_gate {
 #define _MG_CLKTOP2_HSCLKCTL_PORT3			0x16A8D4
 #define _MG_CLKTOP2_HSCLKCTL_PORT4			0x16B8D4
 #define   MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL(x)		((x) << 16)
+#define   MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK	(0x1 << 16)
 #define   MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL(x)	((x) << 14)
+#define   MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK	(0x3 << 14)
 #define   MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO(x)		((x) << 12)
+#define   MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK		(0x3 << 12)
 #define   MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO(x)		((x) << 8)
+#define   MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK		(0xf << 8)
 #define MG_CLKTOP2_HSCLKCTL(port) _MMIO_PORT((port) - PORT_C, \
 					     _MG_CLKTOP2_HSCLKCTL_PORT1, \
 					     _MG_CLKTOP2_HSCLKCTL_PORT2)
@@ -9142,12 +9149,18 @@  enum skl_power_gate {
 #define _MG_PLL_BIAS_PORT3				0x16AA14
 #define _MG_PLL_BIAS_PORT4				0x16BA14
 #define   MG_PLL_BIAS_BIAS_GB_SEL(x)			((x) << 30)
+#define   MG_PLL_BIAS_BIAS_GB_SEL_MASK			(0x3 << 30)
 #define   MG_PLL_BIAS_INIT_DCOAMP(x)			((x) << 24)
+#define   MG_PLL_BIAS_INIT_DCOAMP_MASK			(0x3f << 24)
 #define   MG_PLL_BIAS_BIAS_BONUS(x)			((x) << 16)
+#define   MG_PLL_BIAS_BIAS_BONUS_MASK			(0xff << 16)
 #define   MG_PLL_BIAS_BIASCAL_EN			(1 << 15)
 #define   MG_PLL_BIAS_CTRIM(x)				((x) << 8)
+#define   MG_PLL_BIAS_CTRIM_MASK			(0x1f << 8)
 #define   MG_PLL_BIAS_VREF_RDAC(x)			((x) << 5)
+#define   MG_PLL_BIAS_VREF_RDAC_MASK			(0x7 << 5)
 #define   MG_PLL_BIAS_IREFTRIM(x)			((x) << 0)
+#define   MG_PLL_BIAS_IREFTRIM_MASK			(0x1f << 0)
 #define MG_PLL_BIAS(port) _MMIO_PORT((port) - PORT_C, _MG_PLL_BIAS_PORT1, \
 				     _MG_PLL_BIAS_PORT2)
 
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index d4c7bacbe83e..57342364fd30 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -2945,10 +2945,21 @@  static bool icl_pll_get_hw_state(struct drm_i915_private *dev_priv,
 	case DPLL_ID_ICL_MGPLL4:
 		port = icl_mg_pll_id_to_port(id);
 		hw_state->mg_refclkin_ctl = I915_READ(MG_REFCLKIN_CTL(port));
+		hw_state->mg_refclkin_ctl &= MG_REFCLKIN_CTL_OD_2_MUX_MASK;
+
 		hw_state->mg_clktop2_coreclkctl1 =
 			I915_READ(MG_CLKTOP2_CORECLKCTL1(port));
+		hw_state->mg_clktop2_coreclkctl1 &=
+			MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
+
 		hw_state->mg_clktop2_hsclkctl =
 			I915_READ(MG_CLKTOP2_HSCLKCTL(port));
+		hw_state->mg_clktop2_hsclkctl &=
+			MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
+			MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
+			MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
+			MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK;
+
 		hw_state->mg_pll_div0 = I915_READ(MG_PLL_DIV0(port));
 		hw_state->mg_pll_div1 = I915_READ(MG_PLL_DIV1(port));
 		hw_state->mg_pll_lf = I915_READ(MG_PLL_LF(port));
@@ -2998,10 +3009,30 @@  static void icl_mg_pll_write(struct drm_i915_private *dev_priv,
 	enum port port = icl_mg_pll_id_to_port(pll->info->id);
 	u32 val;
 
-	I915_WRITE(MG_REFCLKIN_CTL(port), hw_state->mg_refclkin_ctl);
-	I915_WRITE(MG_CLKTOP2_CORECLKCTL1(port),
-		   hw_state->mg_clktop2_coreclkctl1);
-	I915_WRITE(MG_CLKTOP2_HSCLKCTL(port), hw_state->mg_clktop2_hsclkctl);
+	/*
+	 * Some of the following registers have reserved fields, so program
+	 * these with RMW based on a mask. The mask can be fixed or generated
+	 * during the calc/readout phase if the mask depends on some other HW
+	 * state like refclk, see icl_calc_mg_pll_state().
+	 */
+	val = I915_READ(MG_REFCLKIN_CTL(port));
+	val &= ~MG_REFCLKIN_CTL_OD_2_MUX_MASK;
+	val |= hw_state->mg_refclkin_ctl;
+	I915_WRITE(MG_REFCLKIN_CTL(port), val);
+
+	val = I915_READ(MG_CLKTOP2_CORECLKCTL1(port));
+	val &= ~MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
+	val |= hw_state->mg_clktop2_coreclkctl1;
+	I915_WRITE(MG_CLKTOP2_CORECLKCTL1(port), val);
+
+	val = I915_READ(MG_CLKTOP2_HSCLKCTL(port));
+	val &= ~(MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
+		 MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
+		 MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
+		 MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK);
+	val |= hw_state->mg_clktop2_hsclkctl;
+	I915_WRITE(MG_CLKTOP2_HSCLKCTL(port), val);
+
 	I915_WRITE(MG_PLL_DIV0(port), hw_state->mg_pll_div0);
 	I915_WRITE(MG_PLL_DIV1(port), hw_state->mg_pll_div1);
 	I915_WRITE(MG_PLL_LF(port), hw_state->mg_pll_lf);