[Intel-gfx] [PATCH 2/2] drm/i915: Add the support of ACPI opregion on Ironlake

yakui.zhao at intel.com yakui.zhao at intel.com
Mon Oct 26 07:13:14 CET 2009


From: Zhao Yakui <yakui.zhao at intel.com>

Add the support of ACPI opregion on Ironlake so that the backlight brightness
can be adjusted by using ACPI interface
   >/sys/class/backlight/acpi_video0/brightness

Signed-off-by: Zhao Yakui <yakui.zhao at intel.com>
---
 drivers/gpu/drm/i915/i915_dma.c      |    8 +--
 drivers/gpu/drm/i915/i915_drv.h      |    2 +
 drivers/gpu/drm/i915/i915_irq.c      |    3 +
 drivers/gpu/drm/i915/i915_opregion.c |   82 ++++++++++++++++++++++++++++++++--
 4 files changed, 86 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 794ded2..fcf5c95 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1492,9 +1492,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 	}
 
 	/* Must be done after probing outputs */
-	/* FIXME: verify on IGDNG */
-	if (!IS_IGDNG(dev))
-		intel_opregion_init(dev, 0);
+	/* enable the Opregion on ironlake */
+	intel_opregion_init(dev, 0);
 
 	setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed,
 		    (unsigned long) dev);
@@ -1538,8 +1537,7 @@ int i915_driver_unload(struct drm_device *dev)
 	if (dev_priv->regs != NULL)
 		iounmap(dev_priv->regs);
 
-	if (!IS_IGDNG(dev))
-		intel_opregion_free(dev, 0);
+	intel_opregion_free(dev, 0);
 
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
 		intel_modeset_cleanup(dev);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ddfd906..a75afd2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -832,11 +832,13 @@ extern int i915_restore_state(struct drm_device *dev);
 extern int intel_opregion_init(struct drm_device *dev, int resume);
 extern void intel_opregion_free(struct drm_device *dev, int suspend);
 extern void opregion_asle_intr(struct drm_device *dev);
+extern void igdng_opregion_gse_intr(struct drm_device *dev);
 extern void opregion_enable_asle(struct drm_device *dev);
 #else
 static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; }
 static inline void intel_opregion_free(struct drm_device *dev, int suspend) { return; }
 static inline void opregion_asle_intr(struct drm_device *dev) { return; }
+static inline void igdng_opregion_gse_intr(struct drm_device *dev) { return; }
 static inline void opregion_enable_asle(struct drm_device *dev) { return; }
 #endif
 
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index e8031b8..35c90e4 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -300,6 +300,9 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
 			DRM_WAKEUP(&dev_priv->irq_queue);
 		}
 
+		if (de_iir && DE_GSE)
+			igdng_opregion_gse_intr(dev);
+
 		de_iir = new_de_iir;
 		gt_iir = new_gt_iir;
 	}
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
index 9032bda..7652e24 100644
--- a/drivers/gpu/drm/i915/i915_opregion.c
+++ b/drivers/gpu/drm/i915/i915_opregion.c
@@ -118,6 +118,10 @@ struct opregion_asle {
 #define ASLE_BACKLIGHT_FAIL    (2<<12)
 #define ASLE_PFIT_FAIL         (2<<14)
 #define ASLE_PWM_FREQ_FAIL     (2<<16)
+#define ASLE_ALS_ILLUM_FAILED	(1<<10)
+#define ASLE_BACKLIGHT_FAILED	(1<<12)
+#define ASLE_PFIT_FAILED	(1<<14)
+#define ASLE_PWM_FREQ_FAILED	(1<<16)
 
 /* ASLE backlight brightness to set */
 #define ASLE_BCLP_VALID                (1<<31)
@@ -243,6 +247,73 @@ void opregion_asle_intr(struct drm_device *dev)
 	asle->aslc = asle_stat;
 }
 
+static u32 asle_set_backlight_igdng(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 igdng_opregion_gse_intr(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct opregion_asle *asle = dev_priv->opregion.asle;
+	u32 asle_stat = 0;
+	u32 asle_req;
+
+	if (!asle)
+		return;
+
+	asle_req = asle->aslc & ASLE_REQ_MSK;
+
+	if (!asle_req) {
+		DRM_DEBUG_DRIVER("non asle set request??\n");
+		return;
+	}
+
+	if (asle_req & ASLE_SET_ALS_ILLUM) {
+		DRM_DEBUG_DRIVER("Illum is not supported\n");
+		asle_stat |= ASLE_ALS_ILLUM_FAILED;
+	}
+
+	if (asle_req & ASLE_SET_BACKLIGHT)
+		asle_stat |= asle_set_backlight_igdng(dev, asle->bclp);
+
+	if (asle_req & ASLE_SET_PFIT) {
+		DRM_DEBUG_DRIVER("Pfit is not supported\n");
+		asle_stat |= ASLE_PFIT_FAILED;
+	}
+
+	if (asle_req & ASLE_SET_PWM_FREQ) {
+		DRM_DEBUG_DRIVER("PWM freq is not supported\n");
+		asle_stat |= ASLE_PWM_FREQ_FAILED;
+	}
+
+	asle->aslc = asle_stat;
+}
 #define ASLE_ALS_EN    (1<<0)
 #define ASLE_BLC_EN    (1<<1)
 #define ASLE_PFIT_EN   (1<<2)
@@ -254,15 +325,18 @@ void opregion_enable_asle(struct drm_device *dev)
 	struct opregion_asle *asle = dev_priv->opregion.asle;
 
 	if (asle) {
-		if (IS_MOBILE(dev)) {
-			unsigned long irqflags;
-
+		unsigned long irqflags = 0;
+		if (IS_MOBILE(dev) || IS_IGDNG(dev))
 			spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
+		if (IS_IGDNG(dev))
+			igdng_enable_display_irq(dev_priv, DE_GSE);
+		else if (IS_MOBILE(dev))
 			i915_enable_pipestat(dev_priv, 1,
 					     I915_LEGACY_BLC_EVENT_ENABLE);
+
+		if (IS_MOBILE(dev) || IS_IGDNG(dev))
 			spin_unlock_irqrestore(&dev_priv->user_irq_lock,
 					       irqflags);
-		}
 
 		asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN |
 			ASLE_PFMB_EN;
-- 
1.5.4.5




More information about the Intel-gfx mailing list