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