diff options
author | Dave Airlie <airlied@redhat.com> | 2010-10-06 10:11:56 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-10-06 10:11:56 +1000 |
commit | 9a170caed6fce89da77852575a7eee7dbadee332 (patch) | |
tree | 489082522869cb382a2dc464ccbd474846693a37 /drivers/gpu/drm/i915/intel_panel.c | |
parent | 45ff46c54a31bf8924b61e3e3411654410a3b5c3 (diff) | |
parent | 7b4f3990a22fbe800945f12001bc30db374d0af5 (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.c | 109 |
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); +} |