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;

Reply via email to