Message ID | 20180619164115.7835-1-imre.deak@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
> -----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 --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);