[PATCH 15/21] drm/i915/bdw: GEN8 backlight support

Ben Widawsky
2013-11-08T07:13:31Z

Prior to Haswell the CPU control register for backlight
(BLC_PWM_CPU_CTL) toggled the PCH baclight pin for us. This made some
sense as there was no pin on the CPU. With Haswell came the introduction
of a CPU backlight pin, but the interface was still controlled by
software with the same mechnism. Behind the scenes, hardware did all the
dirty work for us.

Broadwell no longer provides this for free. If we want to use the PCH
backlight pin [1] then we have to set the override bit BLC_PWM_PCH_CTL1
and program BLC_PWM_PCH_CTL2 for the PWM values.

This patch implements that. This patch is compile tested only, and given
that I rarely if ever touch this code, careful review is welcome.

[1] According to Art, we know of no devices that exist which use the CPU
pin (and remember it has existed already on HSW). If such a device does
exist, we'll have to handle it properly - this is left as TODO until
then.

CC: Art Runyan <arthur.j.runyan@intel.com>
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
drivers/gpu/drm/i915/intel_panel.c | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index e8a749a..8ecd14a 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -435,7 +435,9 @@ static u32 intel_panel_get_backlight(struct drm_device *dev)

spin_lock_irqsave(&dev_priv->backlight.lock, flags);

- if (HAS_PCH_SPLIT(dev))
+ if (IS_BROADWELL(dev))
+ reg = BLC_PWM_PCH_CTL2;
+ else if (HAS_PCH_SPLIT(dev))
reg = BLC_PWM_CPU_CTL;
else
reg = BLC_PWM_CTL;
@@ -462,8 +464,15 @@ static u32 intel_panel_get_backlight(struct drm_device *dev)
static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- u32 val = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
- I915_WRITE(BLC_PWM_CPU_CTL, val | level);
+ u32 reg, val;
+
+ if (IS_BROADWELL(dev))
+ reg = BLC_PWM_PCH_CTL2;
+ else
+ reg = BLC_PWM_CPU_CTL;
+
+ val = I915_READ(reg) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+ I915_WRITE(reg, val | level);
}

static void intel_panel_actually_set_backlight(struct drm_device *dev,
@@ -615,7 +624,15 @@ void intel_panel_enable_backlight(struct drm_device *dev,
POSTING_READ(reg);
I915_WRITE(reg, tmp | BLM_PWM_ENABLE);

- if (HAS_PCH_SPLIT(dev) &&
+ if (IS_BROADWELL(dev) &&
+ !(WARN_ON(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE))) {
+ /* Broadwell requires PCH override to drive the PCH
+ * backlight pin. The above will configure the CPU
+ * backlight pin, which we don't plan to use */
+ tmp = I915_READ(BLC_PWM_PCH_CTL1);
+ tmp |= BLM_PCH_OVERRIDE_ENABLE | BLM_PCH_PWM_ENABLE;
+ I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
+ } else if (HAS_PCH_SPLIT(dev) &&
!(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) {
tmp = I915_READ(BLC_PWM_PCH_CTL1);
tmp |= BLM_PCH_PWM_ENABLE;
--
1.8.4.2