On Thu, Feb 09, 2017 at 06:39:13PM -0600, joshua stein wrote:
> I have no idea why there are chickens involved, but this fixes the
> problem on at least the MacBookAir7,1 (Broadwell) where upon S3
> resume, the backlight value is treated as 0 or 100 despite reporting
> intermediate values, so if the backlight value was anything other
> than 100 at suspend time, the screen will stay off upon resume.

Chicken bits are overrides for functions like clock gating, if it turns
out there is a hardware bug in a particular feature these bits are used
to disable them.

This diff seems reasonable but it would be nice to get some tests
on non-apple broadwell hardware.

> 
> This is backported from Linux commits
> 32b421e79e6b546da1d469f1229403ac9142d695 and
> e29aff05f239f8dd24e9ee7816fd96726e20105a which were noted in
> freedesktop.org bug 67454.
> 
> This and the previous ACPI diff get suspend and resume working on
> the MacBook Air.
> 
> 
> Index: sys/dev/pci/drm/i915/i915_reg.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/i915/i915_reg.h,v
> retrieving revision 1.11
> diff -u -p -u -p -r1.11 i915_reg.h
> --- sys/dev/pci/drm/i915/i915_reg.h   25 Sep 2015 16:15:19 -0000      1.11
> +++ sys/dev/pci/drm/i915/i915_reg.h   10 Feb 2017 00:39:02 -0000
> @@ -4540,9 +4540,11 @@
>  #define  FDI_PHASE_SYNC_OVR(pipe) (1<<(FDIA_PHASE_SYNC_SHIFT_OVR - ((pipe) * 
> 2)))
>  #define  FDI_PHASE_SYNC_EN(pipe) (1<<(FDIA_PHASE_SYNC_SHIFT_EN - ((pipe) * 
> 2)))
>  #define  FDI_BC_BIFURCATION_SELECT   (1 << 12)
> +#define  SPT_PWM_GRANULARITY         (1<<0)
>  #define SOUTH_CHICKEN2               0xc2004
>  #define  FDI_MPHY_IOSFSB_RESET_STATUS        (1<<13)
>  #define  FDI_MPHY_IOSFSB_RESET_CTL   (1<<12)
> +#define  LPT_PWM_GRANULARITY         (1<<5)
>  #define  DPLS_EDP_PPS_FIX_DIS                (1<<0)
>  
>  #define _FDI_RXA_CHICKEN         0xc200c
> Index: sys/dev/pci/drm/i915/intel_drv.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/i915/intel_drv.h,v
> retrieving revision 1.9
> diff -u -p -u -p -r1.9 intel_drv.h
> --- sys/dev/pci/drm/i915/intel_drv.h  9 Dec 2015 05:17:44 -0000       1.9
> +++ sys/dev/pci/drm/i915/intel_drv.h  10 Feb 2017 00:39:02 -0000
> @@ -168,6 +168,7 @@ struct intel_panel {
>               bool enabled;
>               bool combination_mode;  /* gen 2/4 only */
>               bool active_low_pwm;
> +             bool alternate_pwm_increment;   /* lpt+ */
>               struct backlight_device *device;
>       } backlight;
>  };
> Index: sys/dev/pci/drm/i915/intel_panel.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/i915/intel_panel.c,v
> retrieving revision 1.11
> diff -u -p -u -p -r1.11 intel_panel.c
> --- sys/dev/pci/drm/i915/intel_panel.c        23 Sep 2015 23:12:12 -0000      
> 1.11
> +++ sys/dev/pci/drm/i915/intel_panel.c        10 Feb 2017 00:39:02 -0000
> @@ -611,7 +611,7 @@ static void bdw_enable_backlight(struct 
>       struct drm_device *dev = connector->base.dev;
>       struct drm_i915_private *dev_priv = dev->dev_private;
>       struct intel_panel *panel = &connector->panel;
> -     u32 pch_ctl1, pch_ctl2;
> +     u32 pch_ctl1, pch_ctl2, schicken;
>  
>       pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
>       if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
> @@ -620,6 +620,22 @@ static void bdw_enable_backlight(struct 
>               I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
>       }
>  
> +     if (HAS_PCH_LPT(dev)) {
> +             schicken = I915_READ(SOUTH_CHICKEN2);
> +             if (panel->backlight.alternate_pwm_increment)
> +                     schicken |= LPT_PWM_GRANULARITY;
> +             else
> +                     schicken &= ~LPT_PWM_GRANULARITY;
> +             I915_WRITE(SOUTH_CHICKEN2, schicken);
> +     } else {
> +             schicken = I915_READ(SOUTH_CHICKEN1);
> +             if (panel->backlight.alternate_pwm_increment)
> +                     schicken |= SPT_PWM_GRANULARITY;
> +             else
> +                     schicken &= ~SPT_PWM_GRANULARITY;
> +             I915_WRITE(SOUTH_CHICKEN1, schicken);
> +     }
> +
>       pch_ctl2 = panel->backlight.max << 16;
>       I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
>  
> @@ -956,6 +972,13 @@ static int bdw_setup_backlight(struct in
>       struct drm_i915_private *dev_priv = dev->dev_private;
>       struct intel_panel *panel = &connector->panel;
>       u32 pch_ctl1, pch_ctl2, val;
> +     bool alt;
> +
> +     if (HAS_PCH_LPT(dev))
> +             alt = I915_READ(SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY;
> +     else
> +             alt = I915_READ(SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY;
> +     panel->backlight.alternate_pwm_increment = alt;
>  
>       pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
>       panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
> 

Reply via email to