Not all systems expose a firmware or platform mechanism for changing the
backlight intensity on i915, so add native driver support.
Signed-off-by: Matthew Garrett m...@redhat.com
Cc: intel-gfx intel-gfx@lists.freedesktop.org
---
drivers/gpu/drm/i915/i915_drv.h |3 +
drivers/gpu/drm/i915/i915_opregion.c | 60 +---
drivers/gpu/drm/i915/intel_drv.h |3 +
drivers/gpu/drm/i915/intel_lvds.c| 177 ++
4 files changed, 170 insertions(+), 73 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index af4a263..36c4b407 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -34,6 +34,7 @@
#include intel_bios.h
#include intel_ringbuffer.h
#include linux/io-mapping.h
+#include linux/backlight.h
/* General customization:
*/
@@ -663,6 +664,8 @@ typedef struct drm_i915_private {
/* list of fbdev register on this device */
struct intel_fbdev *fbdev;
+
+ struct backlight_device *backlight;
} drm_i915_private_t;
/** driver private structure attached to each drm_gem_object */
diff --git a/drivers/gpu/drm/i915/i915_opregion.c
b/drivers/gpu/drm/i915/i915_opregion.c
index ea5d3fe..de199dd 100644
--- a/drivers/gpu/drm/i915/i915_opregion.c
+++ b/drivers/gpu/drm/i915/i915_opregion.c
@@ -31,9 +31,9 @@
#include drmP.h
#include i915_drm.h
#include i915_drv.h
+#include intel_drv.h
#define PCI_ASLE 0xe4
-#define PCI_LBPC 0xf4
#define PCI_ASLS 0xfc
#define OPREGION_SZ(8*1024)
@@ -147,8 +147,7 @@ static u32 asle_set_backlight(struct drm_device *dev, u32
bclp)
{
struct drm_i915_private *dev_priv = dev-dev_private;
struct opregion_asle *asle = dev_priv-opregion.asle;
- u32 blc_pwm_ctl, blc_pwm_ctl2;
- u32 max_backlight, level, shift;
+ u32 max = intel_lvds_get_max_backlight(dev);
if (!(bclp ASLE_BCLP_VALID))
return ASLE_BACKLIGHT_FAILED;
@@ -157,27 +156,8 @@ static u32 asle_set_backlight(struct drm_device *dev, u32
bclp)
if (bclp 0 || bclp 255)
return ASLE_BACKLIGHT_FAILED;
- blc_pwm_ctl = I915_READ(BLC_PWM_CTL);
- blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2);
-
- if (IS_I965G(dev) (blc_pwm_ctl2 BLM_COMBINATION_MODE))
- pci_write_config_dword(dev-pdev, PCI_LBPC, bclp);
- else {
- if (IS_PINEVIEW(dev)) {
- blc_pwm_ctl = ~(BACKLIGHT_DUTY_CYCLE_MASK - 1);
- max_backlight = (blc_pwm_ctl
BACKLIGHT_MODULATION_FREQ_MASK)
- BACKLIGHT_MODULATION_FREQ_SHIFT;
- shift = BACKLIGHT_DUTY_CYCLE_SHIFT + 1;
- } else {
- blc_pwm_ctl = ~BACKLIGHT_DUTY_CYCLE_MASK;
- max_backlight = ((blc_pwm_ctl
BACKLIGHT_MODULATION_FREQ_MASK)
- BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
- shift = BACKLIGHT_DUTY_CYCLE_SHIFT;
- }
- level = (bclp * max_backlight) / 255;
- I915_WRITE(BLC_PWM_CTL, blc_pwm_ctl | (level shift));
- }
- asle-cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID;
+ asle-cblv = (bclp * 100 / 255) | ASLE_CBLV_VALID;
+ intel_lvds_set_backlight(dev, max * bclp / 255);
return 0;
}
@@ -243,36 +223,6 @@ void opregion_asle_intr(struct drm_device *dev)
asle-aslc = asle_stat;
}
-static u32 asle_set_backlight_ironlake(struct drm_device *dev, u32 bclp)
-{
- struct drm_i915_private *dev_priv = dev-dev_private;
- struct opregion_asle *asle = dev_priv-opregion.asle;
- u32 cpu_pwm_ctl, pch_pwm_ctl2;
- u32 max_backlight, level;
-
- if (!(bclp ASLE_BCLP_VALID))
- return ASLE_BACKLIGHT_FAILED;
-
- bclp = ASLE_BCLP_MSK;
- if (bclp 0 || bclp 255)
- return ASLE_BACKLIGHT_FAILED;
-
- cpu_pwm_ctl = I915_READ(BLC_PWM_CPU_CTL);
- pch_pwm_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
- /* get the max PWM frequency */
- max_backlight = (pch_pwm_ctl2 16) BACKLIGHT_DUTY_CYCLE_MASK;
- /* calculate the expected PMW frequency */
- level = (bclp * max_backlight) / 255;
- /* reserve the high 16 bits */
- cpu_pwm_ctl = ~(BACKLIGHT_DUTY_CYCLE_MASK);
- /* write the updated PWM frequency */
- I915_WRITE(BLC_PWM_CPU_CTL, cpu_pwm_ctl | level);
-
- asle-cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID;
-
- return 0;
-}
-
void ironlake_opregion_gse_intr(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev-dev_private;
@@ -296,7 +246,7 @@ void ironlake_opregion_gse_intr(struct drm_device *dev)
}
if (asle_req ASLE_SET_BACKLIGHT)
- asle_stat |= asle_set_backlight_ironlake(dev, asle-bclp);
+ asle_stat |= asle_set_backlight(dev, asle-bclp);
if (asle_req ASLE_SET_PFIT)