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;
>