[Intel-gfx] [PATCH 6/7] drm/i915: handle backlight through chip specific functions

Jani Nikula jani.nikula at intel.com
Thu Oct 31 17:55:53 CET 2013


The backlight code has grown rather hairy, not least because the
hardware registers and bits have repeatedly been shuffled around. And
this isn't expected to get any easier with new hardware. Make things
easier for our (read: my) poor brains, and split the code up into chip
specific functions.

There should be no functional changes.

Signed-off-by: Jani Nikula <jani.nikula at intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |    7 +
 drivers/gpu/drm/i915/intel_display.c |    2 +
 drivers/gpu/drm/i915/intel_drv.h     |    1 +
 drivers/gpu/drm/i915/intel_panel.c   |  442 ++++++++++++++++++++++------------
 4 files changed, 297 insertions(+), 155 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 16b93a6..0753e7c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -409,6 +409,13 @@ struct drm_i915_display_funcs {
 	/* render clock increase/decrease */
 	/* display clock increase/decrease */
 	/* pll clock increase/decrease */
+
+	uint32_t (*get_max_backlight)(struct drm_device *dev, enum pipe pipe);
+	uint32_t (*get_backlight)(struct drm_device *dev, enum pipe pipe);
+	void (*set_backlight)(struct drm_device *dev, enum pipe pipe,
+			      uint32_t level);
+	void (*disable_backlight)(struct drm_device *dev, enum pipe pipe);
+	void (*enable_backlight)(struct drm_device *dev, enum pipe pipe);
 };
 
 struct intel_uncore_funcs {
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 774407d..d25d23c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10355,6 +10355,8 @@ static void intel_init_display(struct drm_device *dev)
 		dev_priv->display.queue_flip = intel_gen7_queue_flip;
 		break;
 	}
+
+	intel_panel_init_backlight_funcs(dev);
 }
 
 /*
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 9460e54..b367f2f 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -816,6 +816,7 @@ int intel_panel_setup_backlight(struct drm_connector *connector);
 void intel_panel_enable_backlight(struct intel_connector *connector);
 void intel_panel_disable_backlight(struct intel_connector *connector);
 void intel_panel_destroy_backlight(struct drm_connector *connector);
+void intel_panel_init_backlight_funcs(struct drm_device *dev);
 enum drm_connector_status intel_panel_detect(struct drm_device *dev);
 
 
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 0a4aeaf..03e806f 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -338,79 +338,105 @@ static int is_backlight_combination_mode(struct drm_device *dev)
 	return 0;
 }
 
-/* XXX: query mode clock or hardware clock and program max PWM appropriately
- * when it's 0.
- */
-static u32 i915_read_blc_pwm_ctl(struct drm_device *dev, enum pipe pipe)
+static u32 pch_get_max_backlight(struct drm_device *dev, enum pipe pipe)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 val;
 
-	WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight_lock));
+	val = I915_READ(BLC_PWM_PCH_CTL2);
+	if (dev_priv->regfile.saveBLC_PWM_CTL2 == 0) {
+		dev_priv->regfile.saveBLC_PWM_CTL2 = val;
+	} else if (val == 0) {
+		val = dev_priv->regfile.saveBLC_PWM_CTL2;
+		I915_WRITE(BLC_PWM_PCH_CTL2, val);
+	}
 
-	/* Restore the CTL value if it lost, e.g. GPU reset */
+	val >>= 16;
 
-	if (HAS_PCH_SPLIT(dev_priv->dev)) {
-		val = I915_READ(BLC_PWM_PCH_CTL2);
-		if (dev_priv->regfile.saveBLC_PWM_CTL2 == 0) {
-			dev_priv->regfile.saveBLC_PWM_CTL2 = val;
-		} else if (val == 0) {
-			val = dev_priv->regfile.saveBLC_PWM_CTL2;
-			I915_WRITE(BLC_PWM_PCH_CTL2, val);
-		}
-	} else if (IS_VALLEYVIEW(dev)) {
-		val = I915_READ(VLV_BLC_PWM_CTL(pipe));
-		if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
-			dev_priv->regfile.saveBLC_PWM_CTL = val;
-			dev_priv->regfile.saveBLC_PWM_CTL2 =
-				I915_READ(VLV_BLC_PWM_CTL2(pipe));
-		} else if (val == 0) {
-			val = dev_priv->regfile.saveBLC_PWM_CTL;
-			I915_WRITE(VLV_BLC_PWM_CTL(pipe), val);
-			I915_WRITE(VLV_BLC_PWM_CTL2(pipe),
-				   dev_priv->regfile.saveBLC_PWM_CTL2);
-		}
+	return val;
+}
 
-		if (!val)
-			val = 0x0f42ffff;
-	} else {
-		val = I915_READ(BLC_PWM_CTL);
-		if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
-			dev_priv->regfile.saveBLC_PWM_CTL = val;
-			if (INTEL_INFO(dev)->gen >= 4)
-				dev_priv->regfile.saveBLC_PWM_CTL2 =
-					I915_READ(BLC_PWM_CTL2);
-		} else if (val == 0) {
-			val = dev_priv->regfile.saveBLC_PWM_CTL;
-			I915_WRITE(BLC_PWM_CTL, val);
-			if (INTEL_INFO(dev)->gen >= 4)
-				I915_WRITE(BLC_PWM_CTL2,
-					   dev_priv->regfile.saveBLC_PWM_CTL2);
-		}
+static u32 i9xx_get_max_backlight(struct drm_device *dev, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val;
+
+	val = I915_READ(BLC_PWM_CTL);
+	if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
+		dev_priv->regfile.saveBLC_PWM_CTL = val;
+	} else if (val == 0) {
+		val = dev_priv->regfile.saveBLC_PWM_CTL;
+		I915_WRITE(BLC_PWM_CTL, val);
 	}
 
+	val >>= 17;
+
+	if (is_backlight_combination_mode(dev))
+		val *= 0xff;
+
 	return val;
 }
 
-static u32 intel_panel_get_max_backlight(struct drm_device *dev,
-					 enum pipe pipe)
+static u32 i965_get_max_backlight(struct drm_device *dev, enum pipe pipe)
 {
-	u32 max;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val;
 
-	max = i915_read_blc_pwm_ctl(dev, pipe);
+	val = I915_READ(BLC_PWM_CTL);
+	if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
+		dev_priv->regfile.saveBLC_PWM_CTL = val;
+		dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
+	} else if (val == 0) {
+		val = dev_priv->regfile.saveBLC_PWM_CTL;
+		I915_WRITE(BLC_PWM_CTL, val);
+		I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
+	}
 
-	if (HAS_PCH_SPLIT(dev)) {
-		max >>= 16;
-	} else {
-		if (INTEL_INFO(dev)->gen < 4)
-			max >>= 17;
-		else
-			max >>= 16;
+	val >>= 16;
+
+	if (is_backlight_combination_mode(dev))
+		val *= 0xff;
+
+	return val;
+}
+
+static u32 vlv_get_max_backlight(struct drm_device *dev, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val;
 
-		if (is_backlight_combination_mode(dev))
-			max *= 0xff;
+	val = I915_READ(VLV_BLC_PWM_CTL(pipe));
+	if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
+		dev_priv->regfile.saveBLC_PWM_CTL = val;
+		dev_priv->regfile.saveBLC_PWM_CTL2 =
+			I915_READ(VLV_BLC_PWM_CTL2(pipe));
+	} else if (val == 0) {
+		val = dev_priv->regfile.saveBLC_PWM_CTL;
+		I915_WRITE(VLV_BLC_PWM_CTL(pipe), val);
+		I915_WRITE(VLV_BLC_PWM_CTL2(pipe),
+			   dev_priv->regfile.saveBLC_PWM_CTL2);
 	}
 
+	if (!val)
+		val = 0x0f42ffff;
+
+	val >>= 16;
+
+	return val;
+}
+
+/* XXX: query mode clock or hardware clock and program max PWM appropriately
+ * when it's 0.
+ */
+static u32 intel_panel_get_max_backlight(struct drm_device *dev, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 max;
+
+	WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight_lock));
+
+	max = dev_priv->display.get_max_backlight(dev, pipe);
+
 	DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max);
 
 	return max;
@@ -441,36 +467,48 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev,
 	return val;
 }
 
-static u32 intel_panel_get_backlight(struct drm_device *dev,
-				     enum pipe pipe)
+static u32 pch_get_backlight(struct drm_device *dev, enum pipe pipe)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 val;
-	unsigned long flags;
-	int reg;
 
-	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
+	return I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
+}
 
-	if (HAS_PCH_SPLIT(dev)) {
-		val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
-	} else {
-		if (IS_VALLEYVIEW(dev))
-			reg = VLV_BLC_PWM_CTL(pipe);
-		else
-			reg = BLC_PWM_CTL;
+static u32 i9xx_get_backlight(struct drm_device *dev, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val;
 
-		val = I915_READ(reg) & BACKLIGHT_DUTY_CYCLE_MASK;
-		if (INTEL_INFO(dev)->gen < 4)
-			val >>= 1;
+	val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
+	if (INTEL_INFO(dev)->gen < 4)
+		val >>= 1;
 
-		if (is_backlight_combination_mode(dev)) {
-			u8 lbpc;
+	if (is_backlight_combination_mode(dev)) {
+		u8 lbpc;
 
-			pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
-			val *= lbpc;
-		}
+		pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
+		val *= lbpc;
 	}
 
+	return val;
+}
+
+static u32 vlv_get_backlight(struct drm_device *dev, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	return I915_READ(VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK;
+}
+
+static u32 intel_panel_get_backlight(struct drm_device *dev, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
+
+	val = dev_priv->display.get_backlight(dev, pipe);
 	val = intel_panel_compute_brightness(dev, pipe, val);
 
 	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
@@ -479,25 +517,20 @@ static u32 intel_panel_get_backlight(struct drm_device *dev,
 	return val;
 }
 
-static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level)
+static void pch_set_backlight(struct drm_device *dev, enum pipe pipe, 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 tmp;
+
+	tmp = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+	I915_WRITE(BLC_PWM_CPU_CTL, tmp | level);
 }
 
-static void intel_panel_actually_set_backlight(struct drm_device *dev,
-					       enum pipe pipe, u32 level)
+static void i9xx_set_backlight(struct drm_device *dev, enum pipe pipe,
+			       u32 level)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 tmp;
-	int reg;
-
-	DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
-	level = intel_panel_compute_brightness(dev, pipe, level);
-
-	if (HAS_PCH_SPLIT(dev))
-		return intel_pch_panel_set_backlight(dev, level);
 
 	if (is_backlight_combination_mode(dev)) {
 		u32 max = intel_panel_get_max_backlight(dev, pipe);
@@ -512,16 +545,31 @@ static void intel_panel_actually_set_backlight(struct drm_device *dev,
 		pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
 	}
 
-	if (IS_VALLEYVIEW(dev))
-		reg = VLV_BLC_PWM_CTL(pipe);
-	else
-		reg = BLC_PWM_CTL;
-
-	tmp = I915_READ(reg);
 	if (INTEL_INFO(dev)->gen < 4)
 		level <<= 1;
-	tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK;
-	I915_WRITE(reg, tmp | level);
+
+	tmp = I915_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+	I915_WRITE(BLC_PWM_CTL, tmp | level);
+}
+
+static void vlv_set_backlight(struct drm_device *dev, enum pipe pipe, u32 level)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 tmp;
+
+	tmp = I915_READ(VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+	I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level);
+}
+
+static void intel_panel_actually_set_backlight(struct drm_device *dev,
+					       enum pipe pipe, u32 level)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
+
+	level = intel_panel_compute_brightness(dev, pipe, level);
+	dev_priv->display.set_backlight(dev, pipe, level);
 }
 
 /* set backlight brightness to level in range [0..max] */
@@ -562,6 +610,36 @@ out:
 	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
 }
 
+static void pch_disable_backlight(struct drm_device *dev, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 tmp;
+
+	tmp = I915_READ(BLC_PWM_CPU_CTL2);
+	I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
+
+	tmp = I915_READ(BLC_PWM_PCH_CTL1);
+	I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
+}
+
+static void i965_disable_backlight(struct drm_device *dev, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 tmp;
+
+	tmp = I915_READ(BLC_PWM_CTL2);
+	I915_WRITE(BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE);
+}
+
+static void vlv_disable_backlight(struct drm_device *dev, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 tmp;
+
+	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
+	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE);
+}
+
 void intel_panel_disable_backlight(struct intel_connector *connector)
 {
 	struct drm_device *dev = connector->base.dev;
@@ -589,26 +667,92 @@ void intel_panel_disable_backlight(struct intel_connector *connector)
 	panel->backlight.enabled = false;
 	intel_panel_actually_set_backlight(dev, pipe, 0);
 
-	if (INTEL_INFO(dev)->gen >= 4) {
-		uint32_t reg, tmp;
+	if (dev_priv->display.disable_backlight)
+		dev_priv->display.disable_backlight(dev, pipe);
 
-		if (HAS_PCH_SPLIT(dev))
-			reg = BLC_PWM_CPU_CTL2;
-		else if (IS_VALLEYVIEW(dev))
-			reg = VLV_BLC_PWM_CTL2(pipe);
-		else
-			reg = BLC_PWM_CTL2;
+	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
+}
 
-		I915_WRITE(reg, I915_READ(reg) & ~BLM_PWM_ENABLE);
+static void pch_enable_backlight(struct drm_device *dev, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum transcoder cpu_transcoder =
+		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
+	u32 tmp;
 
-		if (HAS_PCH_SPLIT(dev)) {
-			tmp = I915_READ(BLC_PWM_PCH_CTL1);
-			tmp &= ~BLM_PCH_PWM_ENABLE;
-			I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
-		}
+	tmp = I915_READ(BLC_PWM_CPU_CTL2);
+
+	/* Note that this can also get called through dpms changes. And
+	 * we don't track the backlight dpms state, hence check whether
+	 * we have to do anything first. */
+	if (tmp & BLM_PWM_ENABLE)
+		return;
+
+	if (INTEL_INFO(dev)->num_pipes == 3)
+		tmp &= ~BLM_PIPE_SELECT_IVB;
+	else
+		tmp &= ~BLM_PIPE_SELECT;
+
+	if (cpu_transcoder == TRANSCODER_EDP)
+		tmp |= BLM_TRANSCODER_EDP;
+	else
+		tmp |= BLM_PIPE(cpu_transcoder);
+	tmp &= ~BLM_PWM_ENABLE;
+
+	I915_WRITE(BLC_PWM_CPU_CTL2, tmp);
+	POSTING_READ(BLC_PWM_CPU_CTL2);
+	I915_WRITE(BLC_PWM_CPU_CTL2, tmp | BLM_PWM_ENABLE);
+
+	if (!(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) {
+		tmp = I915_READ(BLC_PWM_PCH_CTL1);
+		tmp |= BLM_PCH_PWM_ENABLE;
+		tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
+		I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
 	}
+}
 
-	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
+static void i965_enable_backlight(struct drm_device *dev, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 tmp;
+
+	tmp = I915_READ(BLC_PWM_CTL2);
+
+	/* Note that this can also get called through dpms changes. And
+	 * we don't track the backlight dpms state, hence check whether
+	 * we have to do anything first. */
+	if (tmp & BLM_PWM_ENABLE)
+		return;
+
+	tmp &= ~BLM_PIPE_SELECT;
+	tmp |= BLM_PIPE(pipe);
+	tmp &= ~BLM_PWM_ENABLE;
+
+	I915_WRITE(BLC_PWM_CTL2, tmp);
+	POSTING_READ(BLC_PWM_CTL2);
+	I915_WRITE(BLC_PWM_CTL2, tmp | BLM_PWM_ENABLE);
+}
+
+static void vlv_enable_backlight(struct drm_device *dev, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 tmp;
+
+	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
+
+	/* Note that this can also get called through dpms changes. And
+	 * we don't track the backlight dpms state, hence check whether
+	 * we have to do anything first. */
+	if (tmp & BLM_PWM_ENABLE)
+		return;
+
+	tmp &= ~BLM_PIPE_SELECT;
+	tmp |= BLM_PIPE(pipe);
+	tmp &= ~BLM_PWM_ENABLE;
+
+	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp);
+	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
+	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp | BLM_PWM_ENABLE);
 }
 
 void intel_panel_enable_backlight(struct intel_connector *connector)
@@ -617,8 +761,6 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_panel *panel = &connector->panel;
 	enum pipe pipe = intel_get_pipe_from_connector(connector);
-	enum transcoder cpu_transcoder =
-		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
 	unsigned long flags;
 
 	if (pipe == INVALID_PIPE)
@@ -636,49 +778,9 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
 				panel->backlight.level;
 	}
 
-	if (INTEL_INFO(dev)->gen >= 4) {
-		uint32_t reg, tmp;
-
-		if (HAS_PCH_SPLIT(dev))
-			reg = BLC_PWM_CPU_CTL2;
-		else if (IS_VALLEYVIEW(dev))
-			reg = VLV_BLC_PWM_CTL2(pipe);
-		else
-			reg = BLC_PWM_CTL2;
-
-		tmp = I915_READ(reg);
-
-		/* Note that this can also get called through dpms changes. And
-		 * we don't track the backlight dpms state, hence check whether
-		 * we have to do anything first. */
-		if (tmp & BLM_PWM_ENABLE)
-			goto set_level;
-
-		if (INTEL_INFO(dev)->num_pipes == 3)
-			tmp &= ~BLM_PIPE_SELECT_IVB;
-		else
-			tmp &= ~BLM_PIPE_SELECT;
-
-		if (cpu_transcoder == TRANSCODER_EDP)
-			tmp |= BLM_TRANSCODER_EDP;
-		else
-			tmp |= BLM_PIPE(cpu_transcoder);
-		tmp &= ~BLM_PWM_ENABLE;
-
-		I915_WRITE(reg, tmp);
-		POSTING_READ(reg);
-		I915_WRITE(reg, tmp | BLM_PWM_ENABLE);
-
-		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;
-			tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
-			I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
-		}
-	}
+	if (dev_priv->display.enable_backlight)
+		dev_priv->display.enable_backlight(dev, pipe);
 
-set_level:
 	/* Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1.
 	 * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
 	 * registers are set.
@@ -854,6 +956,36 @@ void intel_panel_destroy_backlight(struct drm_connector *connector)
 	intel_backlight_device_unregister(intel_connector);
 }
 
+/* Set up chip specific backlight functions */
+void intel_panel_init_backlight_funcs(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (HAS_PCH_SPLIT(dev)) {
+		dev_priv->display.enable_backlight = pch_enable_backlight;
+		dev_priv->display.disable_backlight = pch_disable_backlight;
+		dev_priv->display.set_backlight = pch_set_backlight;
+		dev_priv->display.get_backlight = pch_get_backlight;
+		dev_priv->display.get_max_backlight = pch_get_max_backlight;
+	} else if (IS_VALLEYVIEW(dev)) {
+		dev_priv->display.enable_backlight = vlv_enable_backlight;
+		dev_priv->display.disable_backlight = vlv_disable_backlight;
+		dev_priv->display.set_backlight = vlv_set_backlight;
+		dev_priv->display.get_backlight = vlv_get_backlight;
+		dev_priv->display.get_max_backlight = vlv_get_max_backlight;
+	} else if (IS_GEN4(dev)) {
+		dev_priv->display.enable_backlight = i965_enable_backlight;
+		dev_priv->display.disable_backlight = i965_disable_backlight;
+		dev_priv->display.set_backlight = i9xx_set_backlight;
+		dev_priv->display.get_backlight = i9xx_get_backlight;
+		dev_priv->display.get_max_backlight = i965_get_max_backlight;
+	} else {
+		dev_priv->display.set_backlight = i9xx_set_backlight;
+		dev_priv->display.get_backlight = i9xx_get_backlight;
+		dev_priv->display.get_max_backlight = i9xx_get_max_backlight;
+	}
+}
+
 int intel_panel_init(struct intel_panel *panel,
 		     struct drm_display_mode *fixed_mode)
 {
-- 
1.7.10.4




More information about the Intel-gfx mailing list