summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_panel.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2010-10-06 10:11:56 +1000
committerDave Airlie <airlied@redhat.com>2010-10-06 10:11:56 +1000
commit9a170caed6fce89da77852575a7eee7dbadee332 (patch)
tree489082522869cb382a2dc464ccbd474846693a37 /drivers/gpu/drm/i915/intel_panel.c
parent45ff46c54a31bf8924b61e3e3411654410a3b5c3 (diff)
parent7b4f3990a22fbe800945f12001bc30db374d0af5 (diff)
Merge remote branch 'intel/drm-intel-next' of ../drm-next into drm-core-next
* 'intel/drm-intel-next' of ../drm-next: (266 commits) drm/i915: Avoid circular locking from intel_fbdev_fini() drm/i915: mark display port DPMS state as 'ON' when enabling output drm/i915: Skip pread/pwrite if size to copy is 0. drm/i915: avoid struct mutex output_poll mutex lock loop on unload drm/i915: Rephrase pwrite bounds checking to avoid any potential overflow drm/i915: Sanity check pread/pwrite drm/i915: Use pipe state to tell when pipe is off drm/i915: vblank status not valid while training display port drivers/gpu/drm/i915/i915_gem.c: Add missing error handling code drm/i915: Don't mask the return code whilst relocating. drm/i915: If the GPU hangs twice within 5 seconds, declare it wedged. drm/i915: Only print 'generating error event' if we actually are drm/i915: Try to reset gen2 devices. drm/i915: Clear fence registers on GPU reset drm/i915: Force the domain to CPU on unbinding whilst wedged. drm: Move the GTT accounting to i915 drm/i915: Fix refleak during eviction. i915: Added function to initialize VBT settings drm/i915: Remove redundant deletion of obj->gpu_write_list drm/i915: Make get/put pages static ...
Diffstat (limited to 'drivers/gpu/drm/i915/intel_panel.c')
-rw-r--r--drivers/gpu/drm/i915/intel_panel.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index e7f5299d9d5..92ff8f38527 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -30,6 +30,8 @@
#include "intel_drv.h"
+#define PCI_LBPC 0xf4 /* legacy/combination backlight modes */
+
void
intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
struct drm_display_mode *adjusted_mode)
@@ -109,3 +111,110 @@ done:
dev_priv->pch_pf_pos = (x << 16) | y;
dev_priv->pch_pf_size = (width << 16) | height;
}
+
+static int is_backlight_combination_mode(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (INTEL_INFO(dev)->gen >= 4)
+ return I915_READ(BLC_PWM_CTL2) & BLM_COMBINATION_MODE;
+
+ if (IS_GEN2(dev))
+ return I915_READ(BLC_PWM_CTL) & BLM_LEGACY_MODE;
+
+ return 0;
+}
+
+u32 intel_panel_get_max_backlight(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 max;
+
+ if (HAS_PCH_SPLIT(dev)) {
+ max = I915_READ(BLC_PWM_PCH_CTL2) >> 16;
+ } else {
+ max = I915_READ(BLC_PWM_CTL);
+ if (IS_PINEVIEW(dev)) {
+ max >>= 17;
+ } else {
+ max >>= 16;
+ if (INTEL_INFO(dev)->gen < 4)
+ max &= ~1;
+ }
+
+ if (is_backlight_combination_mode(dev))
+ max *= 0xff;
+ }
+
+ if (max == 0) {
+ /* XXX add code here to query mode clock or hardware clock
+ * and program max PWM appropriately.
+ */
+ DRM_ERROR("fixme: max PWM is zero.\n");
+ max = 1;
+ }
+
+ DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max);
+ return max;
+}
+
+u32 intel_panel_get_backlight(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 val;
+
+ if (HAS_PCH_SPLIT(dev)) {
+ val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
+ } else {
+ val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
+ if (IS_PINEVIEW(dev))
+ val >>= 1;
+
+ if (is_backlight_combination_mode(dev)){
+ u8 lbpc;
+
+ val &= ~1;
+ pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
+ val *= lbpc;
+ val >>= 1;
+ }
+ }
+
+ DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val);
+ return val;
+}
+
+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);
+}
+
+void intel_panel_set_backlight(struct drm_device *dev, u32 level)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 tmp;
+
+ DRM_DEBUG_DRIVER("set backlight PWM = %d\n", 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);
+ u8 lpbc;
+
+ lpbc = level * 0xfe / max + 1;
+ level /= lpbc;
+ pci_write_config_byte(dev->pdev, PCI_LBPC, lpbc);
+ }
+
+ tmp = I915_READ(BLC_PWM_CTL);
+ if (IS_PINEVIEW(dev)) {
+ tmp &= ~(BACKLIGHT_DUTY_CYCLE_MASK - 1);
+ level <<= 1;
+ } else
+ tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK;
+ I915_WRITE(BLC_PWM_CTL, tmp | level);
+}