[Intel-gfx] [PATCH 7/7] drm/i915: add some assertions to hsw_disable_lcpll

Paulo Zanoni przanoni at gmail.com
Fri Jul 19 20:42:06 CEST 2013


2013/7/18 Ben Widawsky <ben at bwidawsk.net>:
> On Fri, Jul 12, 2013 at 02:19:42PM -0300, Paulo Zanoni wrote:
>> From: Paulo Zanoni <paulo.r.zanoni at intel.com>
>>
>> Most of the hardware needs to be disabled before LCPLL is disabled, so
>> let's add a function to assert some of items listed in the "Display
>> Sequences for LCPLL disabling" documentation.
>>
>> The idea is that hsw_disable_lcpll should not disable the hardware,
>> the callers need to take care of calling hsw_disable_lcpll only once
>> everything is already disabled.
>>
>> Signed-off-by: Paulo Zanoni <paulo.r.zanoni at intel.com>
>
> I don't see a reason to separate this patch from the previous one. It
> makes review easier, but it's weird bisect wise. The correct order, if
> you wanted to do them as separate patches would be to introduce the
> assertions, and then add the functionality (I think).

Originally this code was part of other function. I agree that the way
things look now, it should be on the same patch.

>
>> ---
>>  drivers/gpu/drm/i915/i915_reg.h      |  8 ++++++++
>>  drivers/gpu/drm/i915/intel_display.c | 28 ++++++++++++++++++++++++++++
>>  2 files changed, 36 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
>> index 8e5a5ec..9556dff 100644
>> --- a/drivers/gpu/drm/i915/i915_reg.h
>> +++ b/drivers/gpu/drm/i915/i915_reg.h
>> @@ -2195,6 +2195,8 @@
>>  #define BLC_PWM_CPU_CTL2     0x48250
>>  #define BLC_PWM_CPU_CTL              0x48254
>>
>> +#define HSW_BLC_PWM2_CTL     0x48350
>> +
>>  /* PCH CTL1 is totally different, all but the below bits are reserved. CTL2 is
>>   * like the normal CTL from gen4 and earlier. Hooray for confusing naming. */
>>  #define BLC_PWM_PCH_CTL1     0xc8250
>> @@ -2203,6 +2205,12 @@
>>  #define   BLM_PCH_POLARITY                   (1 << 29)
>>  #define BLC_PWM_PCH_CTL2     0xc8254
>>
>> +#define UTIL_PIN_CTL         0x48400
>> +#define   UTIL_PIN_ENABLE    (1 << 31)
>> +
>> +#define PCH_GTC_CTL          0xe7000
>> +#define   PCH_GTC_ENABLE     (1 << 31)
>> +
>>  /* TV port control */
>>  #define TV_CTL                       0x68000
>>  /** Enables the TV encoder */
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index ffb08bf..9055f60 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -5922,6 +5922,32 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
>>       return true;
>>  }
>>
>> +static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
>> +{
>> +     struct drm_device *dev = dev_priv->dev;
>> +     struct intel_ddi_plls *plls = &dev_priv->ddi_plls;
>> +     struct intel_crtc *crtc;
>> +
>> +     list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head)
>> +             WARN(crtc->base.enabled, "CRTC for pipe %c enabled\n",
>> +                  pipe_name(crtc->pipe));
>> +
>> +     WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on\n");
>> +     WARN(plls->spll_refcount, "SPLL enabled\n");
>> +     WARN(plls->wrpll1_refcount, "WRPLL1 enabled\n");
>> +     WARN(plls->wrpll2_refcount, "WRPLL2 enabled\n");
>> +     WARN(I915_READ(PCH_PP_STATUS) & PP_ON, "Panel power on\n");
>> +     WARN(I915_READ(BLC_PWM_CPU_CTL2) & BLM_PWM_ENABLE,
>> +          "CPU PWM1 enabled\n");
>> +     WARN(I915_READ(HSW_BLC_PWM2_CTL) & BLM_PWM_ENABLE,
>> +          "CPU PWM2 enabled\n");
>> +     WARN(I915_READ(BLC_PWM_PCH_CTL1) & BLM_PCH_PWM_ENABLE,
>> +          "PCH PWM1 enabled\n");
>> +     WARN(I915_READ(UTIL_PIN_CTL) & UTIL_PIN_ENABLE,
>> +          "Utility pin enabled\n");
>> +     WARN(I915_READ(PCH_GTC_CTL) & PCH_GTC_ENABLE, "PCH GTC enabled\n");
>
> Looking at probably the same list you've looked at, I don't see:
> Audio controller

The audio registers go away when we disable the power well, which is
part of the assertion.

> eDP HPD
> Other CPU/PCH interrupts

I guess these ones deserve to be part of the assertion, but checking
interrupts is dangerous and racy...I'll try to find a good solution.


>
> You've worked with this code longer than I have, so maybe you can
> explain why you've skipped them.
>
>> +}
>> +
>>  /*
>>   * This function implements pieces of two sequences from BSpec:
>>   * - Sequence for display software to disable LCPLL
>> @@ -5935,6 +5961,8 @@ void hsw_disable_lcpll(struct drm_i915_private *dev_priv,
>>  {
>>       uint32_t val;
>>
>> +     assert_can_disable_lcpll(dev_priv);
>> +
>
> Do we want to proceed if the above fails? I was sort of under the
> impression that hard hangs can occur as a result of some functions still
> being enabled when we change clocks. I'm fine with continuing on since
> we have the WARNS, just wondering if you've thought about it.

This function should should be the last thing on a big sequence that
involves disabling all the outputs, rearranging the interrupts, etc.
If we detect a problem here, we can't just return, the caller would
have to unwind everything it did. Anyway, this is really something we
don't expect and should never happen. I was kinda assuming the callers
would have to make sure they do everything before they call
hsw_diable_lcpll, and then these assertions are just double-checking.
Suggestions welcome :)


>
>>       val = I915_READ(LCPLL_CTL);
>>
>>       if (switch_to_fclk) {
>> --
>> 1.8.1.2
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> --
> Ben Widawsky, Intel Open Source Technology Center



-- 
Paulo Zanoni



More information about the Intel-gfx mailing list