[Intel-gfx] BACKLIGHT_CONTROL and xrandr
Sergio Monteiro Basto
sergio at sergiomb.no-ip.org
Mon Apr 12 21:45:11 CEST 2010
On Mon, 2010-04-12 at 18:36 +0100, Matthew Garrett wrote:
> On Mon, Apr 12, 2010 at 06:19:20PM +0100, Matthew Garrett wrote:
> > Can you give this patch a try? It's not ready for upstream yet, but
> > ought to work.
>
> It would, of course, be more useful if I included the patch.
Hum can't apply on fedora kernel 2.6.32.11-99.fc12.i686
Patch12: Add_native_backlight_control.patch
+ case "$patch" in
+ patch -p1 -F1 -s
1 out of 2 hunks FAILED -- saving rejects to file
drivers/gpu/drm/i915/i915_drv.h.rej
3 out of 4 hunks FAILED -- saving rejects to file
drivers/gpu/drm/i915/i915_opregion.c.rej
1 out of 6 hunks FAILED -- saving rejects to file
drivers/gpu/drm/i915/intel_lvds.c.rej
I'd like use this kernel because I have been use this kernel and the
test will be more conclusive.
>
> commit bd599ffa48a679679434109ead29fcdf108ccc77
> Author: Matthew Garrett <mjg at redhat.com>
> Date: Wed Mar 31 16:36:00 2010 -0400
>
> intel: Add native backlight control
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index aba8260..40f6684 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -33,6 +33,7 @@
> #include "i915_reg.h"
> #include "intel_bios.h"
> #include <linux/io-mapping.h>
> +#include <linux/backlight.h>
>
> /* General customization:
> */
> @@ -628,6 +629,8 @@ typedef struct drm_i915_private {
> u8 max_delay;
>
> enum no_fbc_reason no_fbc_reason;
> +
> + struct backlight_device *backlight;
> } drm_i915_private_t;
>
> /** driver private structure attached to each drm_gem_object */
> diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
> index 7cc8410..ea71e65 100644
> --- a/drivers/gpu/drm/i915/i915_opregion.c
> +++ b/drivers/gpu/drm/i915/i915_opregion.c
> @@ -31,9 +31,9 @@
> #include "drmP.h"
> #include "i915_drm.h"
> #include "i915_drv.h"
> +#include "intel_drv.h"
>
> #define PCI_ASLE 0xe4
> -#define PCI_LBPC 0xf4
> #define PCI_ASLS 0xfc
>
> #define OPREGION_SZ (8*1024)
> @@ -151,37 +151,10 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
> {
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct opregion_asle *asle = dev_priv->opregion.asle;
> - u32 blc_pwm_ctl, blc_pwm_ctl2;
> - u32 max_backlight, level, shift;
> -
> - if (!(bclp & ASLE_BCLP_VALID))
> - return ASLE_BACKLIGHT_FAIL;
> -
> - bclp &= ASLE_BCLP_MSK;
> - if (bclp < 0 || bclp > 255)
> - return ASLE_BACKLIGHT_FAIL;
> -
> - blc_pwm_ctl = I915_READ(BLC_PWM_CTL);
> - blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2);
> -
> - if (IS_I965G(dev) && (blc_pwm_ctl2 & BLM_COMBINATION_MODE))
> - pci_write_config_dword(dev->pdev, PCI_LBPC, bclp);
> - else {
> - if (IS_PINEVIEW(dev)) {
> - blc_pwm_ctl &= ~(BACKLIGHT_DUTY_CYCLE_MASK - 1);
> - max_backlight = (blc_pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >>
> - BACKLIGHT_MODULATION_FREQ_SHIFT;
> - shift = BACKLIGHT_DUTY_CYCLE_SHIFT + 1;
> - } else {
> - blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
> - max_backlight = ((blc_pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >>
> - BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
> - shift = BACKLIGHT_DUTY_CYCLE_SHIFT;
> - }
> - level = (bclp * max_backlight) / 255;
> - I915_WRITE(BLC_PWM_CTL, blc_pwm_ctl | (level << shift));
> - }
> - asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID;
> + u32 max = intel_lvds_get_max_backlight(dev);
> +
> + asle->cblv = (bclp * 100 / 255) | ASLE_CBLV_VALID;
> + intel_lvds_set_backlight(dev, max * bclp / 255);
>
> return 0;
> }
> @@ -247,36 +220,6 @@ void opregion_asle_intr(struct drm_device *dev)
> asle->aslc = asle_stat;
> }
>
> -static u32 asle_set_backlight_ironlake(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 ironlake_opregion_gse_intr(struct drm_device *dev)
> {
> struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -300,7 +243,7 @@ void ironlake_opregion_gse_intr(struct drm_device *dev)
> }
>
> if (asle_req & ASLE_SET_BACKLIGHT)
> - asle_stat |= asle_set_backlight_ironlake(dev, asle->bclp);
> + asle_stat |= asle_set_backlight(dev, asle->bclp);
>
> if (asle_req & ASLE_SET_PFIT) {
> DRM_DEBUG_DRIVER("Pfit is not supported\n");
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 3a467ca..1c35f67 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -171,6 +171,9 @@ extern void intel_dvo_init(struct drm_device *dev);
> extern void intel_tv_init(struct drm_device *dev);
> extern void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj);
> extern void intel_lvds_init(struct drm_device *dev);
> +extern u32 intel_lvds_get_max_backlight(struct drm_device *dev);
> +extern u32 intel_lvds_get_backlight(struct drm_device *dev);
> +extern void intel_lvds_set_backlight(struct drm_device *dev, int level);
> extern void intel_dp_init(struct drm_device *dev, int dp_reg);
> void
> intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
> diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
> index 2b3fa7a..ee2a06f 100644
> --- a/drivers/gpu/drm/i915/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/intel_lvds.c
> @@ -38,6 +38,7 @@
> #include "i915_drm.h"
> #include "i915_drv.h"
> #include <linux/acpi.h>
> +#include <linux/backlight.h>
>
> /* Private structure for the integrated LVDS support */
> struct intel_lvds_priv {
> @@ -47,43 +48,174 @@ struct intel_lvds_priv {
> };
>
> /**
> - * Sets the backlight level.
> - *
> - * \param level backlight level, from 0 to intel_lvds_get_max_backlight().
> + * Returns the maximum level of the backlight duty cycle field.
> */
> -static void intel_lvds_set_backlight(struct drm_device *dev, int level)
> +u32 intel_lvds_get_max_backlight(struct drm_device *dev)
> {
> struct drm_i915_private *dev_priv = dev->dev_private;
> - u32 blc_pwm_ctl, reg;
> + u32 reg;
> + int value;
> + bool combo;
>
> - if (HAS_PCH_SPLIT(dev))
> - reg = BLC_PWM_CPU_CTL;
> + if (IS_I965G(dev))
> + combo = I915_READ(BLC_PWM_CTL2) & BLM_COMBINATION_MODE;
> + else
> + combo = I915_READ(BLC_PWM_CTL) & BLM_LEGACY_MODE;
> +
> + if (IS_IRONLAKE(dev))
> + reg = BLC_PWM_PCH_CTL2;
> else
> reg = BLC_PWM_CTL;
>
> - blc_pwm_ctl = I915_READ(reg) & ~BACKLIGHT_DUTY_CYCLE_MASK;
> - I915_WRITE(reg, (blc_pwm_ctl |
> - (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
> + value = ((I915_READ(reg) & BACKLIGHT_MODULATION_FREQ_MASK) >>
> + BACKLIGHT_MODULATION_FREQ_SHIFT);
> +
> + if (!IS_PINEVIEW(dev))
> + value *= 2;
> +
> + if (combo) {
> + value *= 0xff;
> + value /= 2;
> + }
> +
> + return value;
> }
>
> /**
> - * Returns the maximum level of the backlight duty cycle field.
> + * Returns the level of the backlight duty cycle field.
> */
> -static u32 intel_lvds_get_max_backlight(struct drm_device *dev)
> +u32 intel_lvds_get_backlight(struct drm_device *dev)
> {
> struct drm_i915_private *dev_priv = dev->dev_private;
> u32 reg;
> + u8 lbpc;
> + int value;
> + bool combo;
>
> - if (HAS_PCH_SPLIT(dev))
> - reg = BLC_PWM_PCH_CTL2;
> + if (IS_I965G(dev))
> + combo = I915_READ(BLC_PWM_CTL2) & BLM_COMBINATION_MODE;
> + else
> + combo = I915_READ(BLC_PWM_CTL) & BLM_LEGACY_MODE;
> +
> + if (IS_IRONLAKE(dev))
> + reg = BLC_PWM_CPU_CTL;
> else
> reg = BLC_PWM_CTL;
>
> - return ((I915_READ(reg) & BACKLIGHT_MODULATION_FREQ_MASK) >>
> - BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
> + value = I915_READ(reg) & BACKLIGHT_DUTY_CYCLE_MASK;
> +
> + if (IS_PINEVIEW(dev))
> + value /= 2;
> +
> + if (combo) {
> + value &= ~0x1;
> + pci_read_config_byte(dev->pdev, LBB, &lbpc);
> + value *= lbpc;
> + value /= 2;
> + }
> +
> + return value;
> }
>
> /**
> + * Sets the backlight level.
> + *
> + * \param level backlight level, from 0 to intel_lvds_get_max_backlight().
> + */
> +void intel_lvds_set_backlight(struct drm_device *dev, int level)
> +{
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + u32 blc_pwm_ctl, reg;
> + bool combo;
> + u8 lbpc;
> +
> + if (IS_I965G(dev))
> + combo = I915_READ(BLC_PWM_CTL2) & BLM_COMBINATION_MODE;
> + else
> + combo = I915_READ(BLC_PWM_CTL) & BLM_LEGACY_MODE;
> +
> + if (IS_IRONLAKE(dev))
> + reg = BLC_PWM_CPU_CTL;
> + else
> + reg = BLC_PWM_CTL;
> +
> + if (combo) {
> + int maximum = intel_lvds_get_max_backlight(dev);
> + lbpc = level * 0xfe / maximum;
> + lbpc += 1;
> + pci_write_config_byte(dev->pdev, LBB, lbpc);
> + level /= lbpc;
> + level <<= 1;
> + }
> +
> + if (IS_PINEVIEW(dev)) {
> + blc_pwm_ctl = I915_READ(reg) & ~(BACKLIGHT_DUTY_CYCLE_MASK - 1);
> + I915_WRITE(reg, (blc_pwm_ctl |
> + (level << (BACKLIGHT_DUTY_CYCLE_SHIFT + 1))));
> + } else {
> + blc_pwm_ctl = I915_READ(reg) & ~BACKLIGHT_DUTY_CYCLE_MASK;
> + I915_WRITE(reg, blc_pwm_ctl |
> + (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
> + }
> +}
> +
> +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
> +static int intel_lvds_update_status(struct backlight_device *bd)
> +{
> + struct drm_device *dev = bl_get_data(bd);
> + intel_lvds_set_backlight(dev, bd->props.brightness);
> + return 0;
> +}
> +
> +static int intel_lvds_get_brightness(struct backlight_device *bd)
> +{
> + struct drm_device *dev = bl_get_data(bd);
> + return intel_lvds_get_backlight(dev);
> +}
> +
> +static const struct backlight_ops intel_lvds_bl_ops = {
> + .update_status = intel_lvds_update_status,
> + .get_brightness = intel_lvds_get_brightness,
> +};
> +
> +static int intel_lvds_backlight_setup(struct drm_device *dev)
> +{
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + struct backlight_properties props;
> +
> + props.max_brightness = intel_lvds_get_max_backlight(dev);
> + dev_priv->backlight = backlight_device_register("intel_backlight",
> + &dev->pdev->dev, dev,
> + &intel_lvds_bl_ops,
> + &props);
> + if (IS_ERR(dev_priv->backlight)) {
> + DRM_ERROR("Failed to register backlight: %ld\n",
> + PTR_ERR(dev_priv->backlight));
> + dev_priv->backlight = NULL;
> + return -ENODEV;
> + }
> + dev_priv->backlight->props.brightness = intel_lvds_get_backlight(dev);
> + return 0;
> +}
> +
> +static void intel_lvds_backlight_destroy(struct drm_device *dev) {
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + if (dev_priv->backlight)
> + backlight_device_unregister(dev_priv->backlight);
> +}
> +#else
> +static int intel_lvds_backlight_setup(struct drm_device *dev)
> +{
> + return 0;
> +}
> +
> +static void intel_lvds_backlight_destroy(struct drm_device *dev)
> +{
> + return;
> +}
> +#endif
> +
> +/**
> * Sets the power state for the panel.
> */
> static void intel_lvds_set_power(struct drm_device *dev, bool on)
> @@ -164,8 +296,7 @@ static void intel_lvds_save(struct drm_connector *connector)
> dev_priv->savePP_CONTROL = I915_READ(pp_ctl_reg);
> dev_priv->savePP_DIVISOR = I915_READ(pp_div_reg);
> dev_priv->saveBLC_PWM_CTL = I915_READ(pwm_ctl_reg);
> - dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
> - BACKLIGHT_DUTY_CYCLE_MASK);
> + dev_priv->backlight_duty_cycle = intel_lvds_get_backlight(dev);
>
> /*
> * If the light is off at server startup, just make it full brightness
> @@ -562,8 +693,7 @@ static void intel_lvds_prepare(struct drm_encoder *encoder)
> reg = BLC_PWM_CTL;
>
> dev_priv->saveBLC_PWM_CTL = I915_READ(reg);
> - dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
> - BACKLIGHT_DUTY_CYCLE_MASK);
> + dev_priv->backlight_duty_cycle = intel_lvds_get_backlight(dev);
>
> intel_lvds_set_power(dev, false);
> }
> @@ -717,6 +847,8 @@ static void intel_lvds_destroy(struct drm_connector *connector)
> struct intel_output *intel_output = to_intel_output(connector);
> struct drm_i915_private *dev_priv = dev->dev_private;
>
> + intel_lvds_backlight_destroy(dev);
> +
> if (intel_output->ddc_bus)
> intel_i2c_destroy(intel_output->ddc_bus);
> if (dev_priv->lid_notifier.notifier_call)
> @@ -1128,6 +1260,9 @@ out:
> /* keep the LVDS connector */
> dev_priv->int_lvds_connector = connector;
> drm_sysfs_connector_add(connector);
> +
> + intel_lvds_backlight_setup(dev);
> +
> return;
>
> failed:
>
--
Sérgio M. B.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 3159 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20100412/ed38ae98/attachment.bin>
More information about the Intel-gfx
mailing list