On Wed, Dec 14, 2022 at 09:15:07PM +0200, Srivatsa, Anusha wrote:
> 
> 
> > -----Original Message-----
> > From: Lisovskiy, Stanislav <[email protected]>
> > Sent: Wednesday, December 14, 2022 2:31 AM
> > To: Srivatsa, Anusha <[email protected]>
> > Cc: [email protected]; Nikula, Jani <[email protected]>
> > Subject: Re: [Intel-gfx] [PATCH 1/1] drm/i915: Implement workaround for
> > CDCLK PLL disable/enable
> > 
> > On Tue, Nov 29, 2022 at 09:19:40PM +0200, Srivatsa, Anusha wrote:
> > >
> > >
> > > > -----Original Message-----
> > > > From: Intel-gfx <[email protected]> On Behalf
> > > > Of Stanislav Lisovskiy
> > > > Sent: Thursday, November 24, 2022 2:36 AM
> > > > To: [email protected]
> > > > Cc: Nikula, Jani <[email protected]>
> > > > Subject: [Intel-gfx] [PATCH 1/1] drm/i915: Implement workaround for
> > > > CDCLK PLL disable/enable
> > > >
> > > > It was reported that we might get a hung and loss of register access
> > > > in some cases when CDCLK PLL is disabled and then enabled, while
> > > > squashing is enabled.
> > > > As a workaround it was proposed by HW team that SW should disable
> > > > squashing when CDCLK PLL is being reenabled.
> > > >
> > > > Signed-off-by: Stanislav Lisovskiy <[email protected]>
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_cdclk.c | 14 ++++++++++++--
> > > >  1 file changed, 12 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c
> > > > b/drivers/gpu/drm/i915/display/intel_cdclk.c
> > > > index 0c107a38f9d0..e338f288c9ac 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_cdclk.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
> > > > @@ -1801,6 +1801,13 @@ static bool
> > > > cdclk_compute_crawl_and_squash_midpoint(struct drm_i915_private
> > *i91
> > > >         return true;
> > > >  }
> > > >
> > > > +static bool pll_enable_wa_needed(struct drm_i915_private *dev_priv)
> > {
> > > > +       return ((IS_DG2(dev_priv) || IS_METEORLAKE(dev_priv))
> > > > +               && dev_priv->display.cdclk.hw.vco > 0
> > > > +               && HAS_CDCLK_SQUASH(dev_priv));
> > > Redundant check. If it is MTL or DG2, then it will have
> > HAS_CDCLK_SQUASH set to true always. Shouldn't vco be 0 instead of > 0.
> > The commit message says the hang can be observed when moving from 0 to
> > > 0 vco.
> > >
> > > Anusha
> > 
> > Idea was that we probably should bind more to the feature rather than
> > platform, I agree checking both "IS_DG2" and if platform has squashing is
> > redundant, because then we would have to add each new platform
> > manually, so I would leave HAS_CDCLK_SQUASH and then at some point
> > just cut off using some INTEL_GEN or other check all the new platforms
> > where this is fixed in HW.
> > 
> > Regarding vco, the icl_cdclk_pll_update func works as follows:
> > 
> > if (i915->display.cdclk.hw.vco != 0 &&
> >     i915->display.cdclk.hw.vco != vco)
> >     icl_cdclk_pll_disable(i915);
> > 
> > if (i915->display.cdclk.hw.vco != vco)
> >     icl_cdclk_pll_enable(i915, vco);
> > 
> > 1) if vco changes from zero value(i915->display.cdclk.hw.vco) to non-zero
> > value(vco), that means
> >    currently squashing is anyway disabled(if vco == 0, cdclk is set to 
> > "bypass"
> > and squash waveform
> >    is 0), so the W/A is not needed.
> > 
> > 2) if vco changes from non-zero value in i915->display.cdclk.hw.vco to zero
> > value(vco), we are not
> >    going to call icl_cdclk_pll_enable anyway so W/A is also not needed.
> > 
> > 3) if vco changes from some non-zero value in i915->display.cdclk.hw.vco to
> > other non-zero value(vco),
> >    which can happen if CDCLK changes, then icl_cdclk_pll_disable(hw vco!=0
> > and vco!=0) and then
> >    icl_cdclk_pll_enable would be called(hw vco is still not equal to vco)
> >    So that disabling enabling in between is what we are interested and
> > where we should make sure
> >    squashing is disabled.
> >    BTW I have another question - is this code even correct? Shouldn't we
> > avoid disabling/enabling PLL if we have
> >    squashing/crawling? As I understood the whole point of having
> > swuashing/crawling is avoiding swithing the PLL
> >    on and off.
> > 
> Squashing works when we don't need to change the PLL ratio. We fix the PLL 
> ratio to say 307 (this can change from platform to platform). Then squashing 
> can be used to vary frequencies below this. So we set squasher to ffff it 
> will mean highest. We can use squasher to change frequency with squash 
> waveform, max being ffff and any value lower will take lower frequencies. 
> Cdclk Crawling is used when the PLL has to be changed. Eg higher than 307 
> then we need to update PLL. In that case we first program squashing to 
> ffff(this will take to 307) n then use crawling to go up to the desired 
> frequency.

if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0 
&&
    !cdclk_pll_is_unknown(dev_priv->display.cdclk.hw.vco)) {
        if (dev_priv->display.cdclk.hw.vco != vco)
                adlp_cdclk_pll_crawl(dev_priv, vco);
        } else if (DISPLAY_VER(dev_priv) >= 11) {
                if (pll_enable_wa_needed(dev_priv))
                        dg2_cdclk_squash_program(dev_priv, 0);

                icl_cdclk_pll_update(dev_priv, vco);
        } else
                bxt_cdclk_pll_update(dev_priv, vco);

I think that condition above will trigger CDCLK crawl whenever vco is not ~0, 
CDCLK crawl is supported
and both hw.vco and vco are > 0 and vco has to be changed.

In bxt_set_cdclk which calls _bxt_set_cdclk we calculate the midpoint however I 
don't see
how _bxt_set_cdclk is going to distinguish between crawling and squashing.

I can see that squash waveform will be returned as 0, if CDCLK is >= 307 MHz 
for MTL for example,
or if CDCLK is equal to bypass, however the only way to skip crawling here 
seems to either have 
vco == ~0(probably after hw init) or vco == 0, but if vco == 0 we are going to 
then call 
icl_cdclk_pll_update which might disable pll, if current hw.vco is not 0.

So what am I missing here?

Stan

> 
> Anusha
> > Stan
> > 
> > 
> > > > +}
> > > > +
> > > >  static void _bxt_set_cdclk(struct drm_i915_private *dev_priv,
> > > >                            const struct intel_cdclk_config 
> > > > *cdclk_config,
> > > >                            enum pipe pipe)
> > > > @@ -1815,9 +1822,12 @@ static void _bxt_set_cdclk(struct
> > > > drm_i915_private *dev_priv,
> > > >             !cdclk_pll_is_unknown(dev_priv->display.cdclk.hw.vco)) {
> > > >                 if (dev_priv->display.cdclk.hw.vco != vco)
> > > >                         adlp_cdclk_pll_crawl(dev_priv, vco);
> > > > -       } else if (DISPLAY_VER(dev_priv) >= 11)
> > > > +       } else if (DISPLAY_VER(dev_priv) >= 11) {
> > > > +               if (pll_enable_wa_needed(dev_priv))
> > > > +                       dg2_cdclk_squash_program(dev_priv, 0);
> > > > +
> > > >                 icl_cdclk_pll_update(dev_priv, vco);
> > > > -       else
> > > > +       } else
> > > >                 bxt_cdclk_pll_update(dev_priv, vco);
> > > >
> > > >         waveform = cdclk_squash_waveform(dev_priv, cdclk);
> > > > --
> > > > 2.37.3
> > >

Reply via email to