Last active
December 21, 2015 13:48
-
-
Save aaronlu/6314920 to your computer and use it in GitHub Desktop.
Intel operation region and _BQC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
A typical ASL code for the backlight control method _BCM with Intel | |
graphics card is as follows: | |
Method (_BCM, 1, NotSerialized) | |
{ | |
If (BRNC) | |
{ | |
AINT (One, Arg0) | |
} | |
Else | |
{ | |
^^^LPCB.EC0.STBR () | |
} | |
} | |
_BCM method takes one param: the target brightness level in the range | |
of 0-100. The BRNC variable is set if bit2 of _DOS's param is set, | |
which we do for Win8 systems now, so AINT will be executed. | |
And the simplified ASL code for AINT on backlight control is: | |
Method (AINT, 2, Serialized) | |
{ | |
If (LEqual (Arg0, One)) | |
{ | |
Store (Divide (Multiply (Arg1, 0xFF), 0x64, ), BCLP) | |
Or (BCLP, 0x80000000, BCLP) | |
Store (0x02, ASLC) | |
} | |
} | |
The ASLC/BCLP are variables declared in IGD operation region. BCLP is | |
used to store the target brightness level in the range of 0-255. Due to | |
the mismatch of the level range in _BCM and BCLP, a convert is done here | |
for BCLP. The setting of the ASLC variable will trigger interrupt of the | |
graphics card and the GPU driver will find out this is due to IGD operation | |
region and will handle the irq accordingly. In backlight case, it will | |
set backlight level in the GPU driver according to the value of BCLP. | |
So the setting of backlight is actually done in GPU driver, even though | |
it is triggered through firmware's interface. A side note is, there are | |
ASL implementations that would trigger the SMI handler on backlight | |
control and that would also result in GPU driver's irq handler and GPU | |
driver will handle backlight setting then. | |
So this is how to make use of IGD operation region to do the backlight | |
brightness level control. | |
There is a problem related to _BQC though on some firmware implementation. | |
_BQC is a control method provided by firmware to tell which backlight | |
level the firmware thinks the device is in. The broken implementation is: | |
Method (_BQC, 0, NotSerialized) // _BQC: Brightness Query Current | |
{ | |
If (LGreaterEqual (MSOS (), OSW8)) | |
{ | |
And (CBLV, 0x7FFFFFFF, Local0) | |
Return (Local0) | |
} | |
} | |
CBLV is a variable in IGD operation region, used to represent the | |
current brightness level in the range of 0-100 and is updated by | |
GPU driver everytime it is asked to set the backlight level. | |
Say user wants to set target level to 8, then 8 will be converted to | |
20(8 * 255 / 100) for BCLP in AINT, then in GPU driver, 20 will be | |
converted again to 7(20 * 100 / 255) for CBLV, so _BQC will return 7 | |
afterwards though user actually sets 8 in _BCM. But this doesn't happen | |
for every level set through _BCM, for those values that do not lose | |
precisions during the conversion back and forth like 20 are not affected. | |
This needs to be remembered when enhancing the quirk logic of _BQC, | |
unless we can somehow fix the problem. | |
Some firmware doesn't have this problem as they simply store the target | |
level user has requested in _BCM in a variable and then return that | |
variable in _BQC, but then we probably do not need to evaluate _BQC at | |
all since we also know what level the device should be in too in ACPI | |
video module. | |
PS: The above example ASL code is taken from a ASUS NV5Z system. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment