Add Intel ACPI IGD OpRegion support
Subsystems (4)
PATCH 1/1 Add Intel ACPI IGD OpRegion support
This adds the support necessary for allowing ACPI backlight control to work on some newer Intel-based graphics systems. Tested on Thinkpad T61 and HP 2510p hardware.
---
drivers/gpu/drm/i915/Makefile +1 -1
@@ -3,7 +3,7 @@ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. ccflags-y := -Iinclude/drm -i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o +i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_opregion.o i915-$(CONFIG_COMPAT) += i915_ioc32.o
drivers/gpu/drm/i915/i915_dma.c +4 -0
@@ -810,6 +810,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)if (!IS_I945G (dev) && !IS_I945GM (dev))pci_enable_msi (dev->pdev); +intel_opregion_init (dev); +spin_lock_init (&dev_priv->user_irq_lock);return ret;
@@ -827,6 +829,8 @@ int i915_driver_unload(struct drm_device *dev)if (dev_priv->mmio_map)drm_rmmap (dev, dev_priv->mmio_map); +intel_opregion_free (dev); +drm_free (dev->dev_private,sizeof (drm_i915_private_t),DRM_MEM_DRIVER );
drivers/gpu/drm/i915/i915_drv.c +4 -0
@@ -371,6 +371,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)i915_save_vga (dev); +intel_opregion_free (dev); +if (state.event ==PM_EVENT_SUSPEND ) {/* Shut down the device */ pci_disable_device (dev->pdev);
@@ -532,6 +534,8 @@ static int i915_resume(struct drm_device *dev)i915_restore_vga (dev); +intel_opregion_init (dev); +return 0 ; }
drivers/gpu/drm/i915/i915_drv.h +17 -0
@@ -82,6 +82,14 @@ typedef struct _drm_i915_vbl_swap {unsigned int sequence; } drm_i915_vbl_swap_t; +struct intel_opregion { +struct opregion_header *header; +struct opregion_acpi *acpi; +struct opregion_swsci *swsci; +struct opregion_asle *asle; +int enabled; +}; + typedef struct drm_i915_private { drm_local_map_t *sarea; drm_local_map_t *mmio_map;
@@ -122,6 +130,8 @@ typedef struct drm_i915_private {drm_i915_vbl_swap_t vbl_swaps;unsigned int swaps_pending; +struct intel_opregion opregion; +/* Register state */ u8 saveLBB;u32 saveDSPACNTR;
@@ -244,6 +254,7 @@ extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, struct drm_file *file_priv);extern int i915_vblank_swap (struct drm_device *dev,void *data,struct drm_file *file_priv); +extern void i915_enable_irq (drm_i915_private_t *dev_priv,u32 mask);/* i915_mem.c */ extern int i915_mem_alloc(struct drm_device *dev, void *data,
@@ -258,6 +269,12 @@ extern void i915_mem_takedown(struct mem_block **heap);extern void i915_mem_release (struct drm_device * dev,struct drm_file *file_priv,struct mem_block *heap); +/* i915_opregion.c */ +extern int intel_opregion_init (struct drm_device *dev); +extern void intel_opregion_free (struct drm_device *dev); +extern void opregion_asle_intr (struct drm_device *dev); +extern void opregion_enable_asle (struct drm_device *dev); +#define I915_READ (reg) DRM_READ32(dev_priv->mmio_map, (reg))#define I915_WRITE (reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))#define I915_READ16 (reg) DRM_READ16(dev_priv->mmio_map, (reg))
drivers/gpu/drm/i915/i915_irq.c +17 -8
@@ -36,9 +36,11 @@/** These are the interrupts used by the driver */ #define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \ I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | \ - I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) + I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT | \ + I915_ASLE_INTERRUPT | \ + I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) -static inline void +void i915_enable_irq (drm_i915_private_t *dev_priv,u32 mask) {if ((dev_priv->irq_mask_reg & mask) !=0 ) {
@@ -274,6 +276,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)return IRQ_NONE ; } +I915_WRITE (PIPEASTAT , pipea_stats); +I915_WRITE (PIPEBSTAT , pipeb_stats); +I915_WRITE (IIR , iir);if (dev->pdev->msi_enabled)I915_WRITE (IMR , dev_priv->irq_mask_reg);
@@ -306,14 +311,14 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)if (dev_priv->swaps_pending >0 )drm_locked_tasklet (dev, i915_vblank_tasklet); -I915_WRITE (PIPEASTAT , - pipea_stats|I915_VBLANK_INTERRUPT_ENABLE | -PIPE_VBLANK_INTERRUPT_STATUS ); -I915_WRITE (PIPEBSTAT , - pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE | -PIPE_VBLANK_INTERRUPT_STATUS ); } +if (iir &I915_ASLE_INTERRUPT ) +opregion_asle_intr (dev); + +if (iir &I915_DISPLAY_PIPE_B_EVENT_INTERRUPT ) +opregion_asle_intr (dev); +return IRQ_HANDLED ; }
@@ -661,10 +666,14 @@ void i915_driver_irq_postinstall(struct drm_device * dev)if (dev_priv->vblank_pipe &DRM_I915_VBLANK_PIPE_B ) dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT ; + dev_priv->irq_mask_reg &=I915_INTERRUPT_ENABLE_MASK ; +I915_WRITE (IMR , dev_priv->irq_mask_reg);I915_WRITE (IER ,I915_INTERRUPT_ENABLE_MASK ); (void )I915_READ (IER ); +opregion_enable_asle (dev); +DRM_INIT_WAITQUEUE (&dev_priv->irq_queue); }
drivers/gpu/drm/i915/i915_opregion.c new file +371 -0
371 lines not on this page · raw message
drivers/gpu/drm/i915/i915_reg.h +1 -0
@@ -740,6 +740,7 @@#define BLC_PWM_CTL 0x61254#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)#define BLC_PWM_CTL2 0x61250/* 965+ only */ +#define BLM_COMBINATION_MODE (1 << 30)/* * This is the most significant 15 bits of the number of backlight cycles in a * complete cycle of the modulated backlight control.
Signature · 1 line
Matthew Garrett | [email protected]
Quoted 5 lines · Matthew Garrett
This adds the support necessary for allowing ACPI backlight control to
work on some newer Intel-based graphics systems. Tested on Thinkpad T61
and HP 2510p hardware.
Ok, I managed to apply it against drm-2.6/drm-next but it won't apply against linux-acpi-2.6/test and I'm not sure how hard it is to cherry pick the needed stuff from drm to acpi.
I'll try to build the drm-2.6/drm-next + patch but I guess it won't be enough to test brightness keys?
Cheersm
Signature · 1 line
Yves-Alexis
Quoted 7 lines · Yves-Alexis Perez
Quoted 5 lines · Matthew Garrett
This adds the support necessary for allowing ACPI backlight control to
work on some newer Intel-based graphics systems. Tested on Thinkpad T61
and HP 2510p hardware.
Quoted 6 lines
Ok, I managed to apply it against drm-2.6/drm-next but it won't apply against linux-acpi-2.6/test and I'm not sure how hard it is to cherry pick the needed stuff from drm to acpi.
I'll try to build the drm-2.6/drm-next + patch but I guess it won't be enough to test brightness keys?
Ok, I checked out drm-2.6/drm-next, created a local branch drm-next and applied OpRegion.
Then I checked out linux-acpi-2.6/test, created a local branched, and merged then my local drm-next into it.
Built fine, rebooted into single user (without using acpi_backlight=). In single user, brightness keys still don't work.
In booted into X (with hal, powersaved, dbus etc. running), and then, tada, brightness keys work. There is a 750ms (I guess) delay, and I don't know who is really responsible, I guess X is. (and thus I guess the opregion is the one needed, and X manages the brightness. If the kernel was, it would be working even in single user)
Hope that can help understand the issues. Feel free to ask more info.
Cheers,
Signature · 1 line
Yves-Alexis
Quoted 5 lines · Yves-Alexis Perez
In booted into X (with hal, powersaved, dbus etc. running), and then, tada, brightness keys work. There is a 750ms (I guess) delay, and I don't know who is really responsible, I guess X is. (and thus I guess the opregion is the one needed, and X manages the brightness. If the kernel was, it would be working even in single user)
The 750ms delay is from thinkpad-acpi. I sent a patch to Henrique which makes it go away, but I'm not entirely sure what the ACPI method concerned is supposed to be doing. The opregion code won't currently run until X is started because the drm layer requires X to be the foreground vt before handling IRQs.
Signature · 1 line
Matthew Garrett | [email protected]
Quoted 7 lines · Matthew Garrett
Quoted 5 lines · Yves-Alexis Perez
In booted into X (with hal, powersaved, dbus etc. running), and then, tada, brightness keys work. There is a 750ms (I guess) delay, and I don't know who is really responsible, I guess X is. (and thus I guess the opregion is the one needed, and X manages the brightness. If the kernel was, it would be working even in single user)
Quoted 5 lines
The 750ms delay is from thinkpad-acpi. I sent a patch to Henrique which makes it go away, but I'm not entirely sure what the ACPI method concerned is supposed to be doing. The opregion code won't currently run until X is started because the drm layer requires X to be the foreground vt before handling IRQs.
Well, for what is it worth, thinkpad-acpi has a knob (brightness_mode) which can be used. Set it to CMOS mode (see docs). From what I recall, it should do what your patch does.
Signature · 4 lines
"One disk to rule them all, One disk to find them. One disk to bring them all and in the darkness grind them. In the Land of Redmond where the shadows lie." -- The Silicon Valley Tarot Henrique Holschuh
Quoted 5 lines · Henrique de Moraes Holschuh
Well, for what is it worth, thinkpad-acpi has a knob (
brightness_mode) which
can be used. Set it to CMOS mode (see docs). From what I recall, it should
do what your patch does.
It's worth noting that I get the 750 ms delay even when I reload thinkpad-acpi with brightness_mode=2 it got it (but maybe I should reboot before to be sure no one messed with EC).
What's strange too is that brightness keys work fine when thinkpad-acpi isn't loaded, so everything seems done in video.ko.
Cheers,
Signature · 1 line
Yves-Alexis
Quoted 10 lines · Henrique de Moraes Holschuh
Quoted 5 lines · Matthew Garrett
The 750ms delay is from thinkpad-acpi. I sent a patch to Henrique which makes it go away, but I'm not entirely sure what the ACPI method concerned is supposed to be doing. The opregion code won't currently run until X is started because the drm layer requires X to be the foreground vt before handling IRQs.
Well, for what is it worth, thinkpad-acpi has a knob (
brightness_mode) which can be used. Set it to CMOS mode (see docs). From what I recall, it should do what your patch does.
It doesn't seem to, no. I should have been clearer - the delay is in the DSDT (not thinkpad-acpi itself), but there's a Thinkpad-specific ACPI call that seems to be needed in order to delay it. Here's the patch again.
drivers/misc/thinkpad_acpi.c +3 -0
@@ -899,6 +899,9 @@ static int __init tpacpi_check_std_acpi_brightness_support(void)if (ACPI_SUCCESS (status) && bcl_levels >2 ) { tp_features.bright_acpimode =1 ; +/* Set ACPI mode */ +if (!acpi_evalf (hkey_handle,NULL ,"PWMS" ,"vd" ,0 )) +printk (TPACPI_INFO "Failed to claim backlight\n" );return (bcl_levels -2 ); }
Signature · 1 line
Matthew Garrett | [email protected]
Quoted 5 lines · Matthew Garrett
It doesn't seem to, no. I should have been clearer - the delay is in the
DSDT (not thinkpad-acpi itself), but there's a Thinkpad-specific ACPI call that seems to be needed in order to delay it. Here's the patch again.
Woah, it works perfectly fine here. Thanks :)
Cheers,
Signature · 1 line
Yves-Alexis
Hi Matthew!
Quoted 22 lines · Matthew Garrett
Quoted 10 lines · Henrique de Moraes Holschuh
Quoted 5 lines · Matthew Garrett
The 750ms delay is from thinkpad-acpi. I sent a patch to Henrique which makes it go away, but I'm not entirely sure what the ACPI method concerned is supposed to be doing. The opregion code won't currently run until X is started because the drm layer requires X to be the foreground vt before handling IRQs.
Well, for what is it worth, thinkpad-acpi has a knob (
brightness_mode) which can be used. Set it to CMOS mode (see docs). From what I recall, it should do what your patch does.It doesn't seem to, no. I should have been clearer - the delay is in the DSDT (not thinkpad-acpi itself), but there's a Thinkpad-specific ACPI call that seems to be needed in order to delay it. Here's the patch again.
drivers/misc/thinkpad_acpi.c +0
-0
drivers/misc/thinkpad_acpi.c static int __init tpacpi_check_std_acpi_brightness_support(void) · line 906
Quoted 8 lines
drivers/misc/thinkpad_acpi.c +3
-0@@ -899,6 +899,9 @@ static int __init tpacpi_check_std_acpi_brightness_support(void)if (ACPI_SUCCESS (status) && bcl_levels >2 ) { tp_features.bright_acpimode =1 ; +/* Set ACPI mode */ +if (!acpi_evalf (hkey_handle,NULL ,"PWMS" ,"vd" ,0 )) +printk (TPACPI_INFO "Failed to claim backlight\n" );return (bcl_levels -2 ); }
Ah, THIS patch. Yes, a more intelligent version of it (that doesn't scream blood murder on thinkpads without PWMS) needs to go into thinkpad-acpi along with your patch.
Signature · 4 lines
"One disk to rule them all, One disk to find them. One disk to bring them all and in the darkness grind them. In the Land of Redmond where the shadows lie." -- The Silicon Valley Tarot Henrique Holschuh