WFU

[ 精選文章 ]

自行車 入門 Escape 3 , Snap 21 , Revel

最近周末想運動 , 平日想通勤 , 想買台自行車 , 把自己找的資料跟大家分享 , 如果你是玩家級的 就不用看了 這是給跟我一樣的新新新手 參考的 騎車半年後的補充: 如果你有把握你是真的有時間有興趣會一直騎,建議還是存點錢買好一點的彎把公路車, 或是可以考慮買2手的自...

2015年11月12日 星期四

Windows 亮度調整 ACPI

如果 BCL 沒被跑到 , 先檢查 VBIOS Seting 
-> Panel #x -> BackLight Control Parameters->Inverter Type 必須選為 None/External

 WDDM 的架構上是 monitor.sys會去問 WDDM video driver, 如果不 support 的話就會走標準的 ACPI standard: _BCM, _BCL, _BQC. 

在 XP或Linux等其他沒有 WDDM video driver 就會走 ACPI 標準 interface

Brightness Control in WDDM
https://msdn.microsoft.com/en-us/library/windows/hardware/Dn653987.aspx

Figure 1. WDDM Brightness Control Architecture in Windows Vista



Brightness Support Initialization
The monitor driver queries the WDDM driver for the Brightness Query Interface and device driver interface (DDI) support during initialization.
1. If the WDDM driver supports the necessary DDI, then the monitor driver uses the driver interface to control the panel brightness levels.
2. If the WDDM driver does not support the Brightness DDI, the monitor driver then checks for the System BIOS ACPI Brightness support. If the required BIOS methods have been implemented, then the monitor driver uses ACPI methods to control panel brightness.

The monitor driver uses the selected interface to query for the supported brightness levels and caches them. If neither the WDDM driver nor the BIOS support the Brightness notifications, then the monitor driver cannot support brightness.
If brightness levels are supported, the monitor driver registers for ACPI notifications of shortcut keys for brightness control.

=========================
Implementation Requirements and Guidelines - Implementation of Brightness Controls
Either the display miniport driver or the ACPI methods that the system BIOS exposes can support changing the brightness of an integrated display panel. For the first video target that is marked as having output technology that connects internally in a computer (D3DKMDT_VOT_INTERNAL), the monitor driver calls the display miniport driver's DxgkDdiQueryInterface function to query for the brightness control interface that is identified by GUID_DEVINTERFACE_BRIGHTNESS and DXGK_BRIGHTNESS_INTERFACE_VERSION_1.
If the WDDM miniport driver does not support the brightness control interface, the monitor driver uses ACPI to query for the _BCL, _BCM, and _BQC methods on the child device. For more information about these methods, see the ACPI specification.

ACPI spec

B.5.3 _BCM (Set the Brightness Level)
   This method allows OSPM to set the brightness level of a built-in display output device.
   The OS will only set levels that were reported via the _BCL method. This method is required if          _BCL is implemented.
Arguments: (1)
Arg0 – An Integer containing the new brightness level
Return Value:
None
Example:

  • Method (_BCM, 1) { // Set the requested level }

The method will be called in response to a power source change or at the specific request of the end user, for example, when the user presses a function key that represents brightness control.

=======================================================================
Figure 1

As in Figure 1, OS queries the list of supported brightness levels from _BCL when it starts (1). This list can be used in UI or by OS kernel when it intends to adjust the brightness. OS also read current brightness from _BQC (2). Together with (1), OS can display how brightness the LCD is in a slider or in a OSD to users.
When a user want to adjust the brightness via a slider or hotkeys (more in next blog), OS will call _BCM which calls to EC or to VGA that eventually changes the panel brightness. However, it is worthwhile to note whether to call _BCM is OS- and driver-dependent. At the time of writing, Windows 8 does not call _BCM and Windows 7 may or may not call _BCM depending on VGA, while normal Linux distribution always uses _BCM. A separate blog will discuss how Ubuntu Linux controls brightness.

Sample Code and Common Errors


_BCL


Method (_BCL, 0) {
     // List of supported brightness levels
     Return (Package(7){
          80, // level when machine has full power
          50, // level when machine is on batteries
          20, 40, 60, 80, 100 // other supported levels:
          }
}

The above is an example of _BCL in ACPI. One of the most common errors is the first two elements are left-out. Meaning OS no longer knows what brightness levels should be used when the AC adapter is plugged and unplugged.

_BCM


Method (_BCM, 1) {
     Store (Arg0, \_SB.PCI0.LPC.EC.BRLV)
}

The above is a very simple _BCM implementation. It simply passes the brightness level, from OS, to an EC registers (assuming brightness is controlled by EC). Please note Arg0 will be one of the values in _BCL such as 20, 40, 60 and so on in the _BCL example.

Common errors of _BCM are:
  • _BCM is present but it does not control brightness
    • Some Windows VGA drivers do not use _BCM; however, Linux requires _BCM to work correctly.
  • Lowest brightness level blacks out the screen
    • This may or may not be a bug depending on OEMs.

_BQC


Method (_BQC, 0) {
     Return (\_SB.PCI0.LPC.EC.BRLV)
}

The above example simply returns brightness set from _BCM in the above example.

Common errors of _BQC are:
  • _BQC is not implemented in BIOS AML
  • _BQC returns value not in _BCL
    • _BQC needs to report the value of the brightness, the order of the brightness.
  • _BQC returns zero at boot time

Overview of Brightness Hotkeys


When a brightness up or down hotkey is pressed, the screen shows a OSD and panel brightness is changed accordingly. A simple action results a simple output, but what happens underneath is a lot of magic.


Figure 1 shows a overview from software perspectives. When a hotkey is pressed, ACPI events are generates that triggers a series of actions specific to OS which eventually changes panel brightness. More information can be found in "ACPI Brightness Control (1) - Control Methods".

BIOS ASL for Brightness Up and Down


How does BIOS tell OS to change brightness? ACPI Appendix B.6 (Notifications Specific to Output Devices) defines five types of notification; however two of them are most commonly used:
  • Notify(LCD, 0x86) – increase brightness
  • Notify(LCD, 0x87) – decrease brightness
where LCD is a devices with _BCL, _BQC and _BCM as the below example:

Device (_SB.PCI0.GFX0.LCD) {
     ...
     Method (_BCL, 0) {
          ...
     }
     Method (_BQC, 0) {
          ...
     }
     Method (_BCM, 1) {
          ...
     }
}

The below is an ASL example of an EC handing Q events for brightness hotkeys:

Device (_SB.PCI0.LPC.EC) {
     Method (_Q12, 0) {
          Notify (_SB.PCI0.GFX0.LCD, 0x86)
     }

     Method (_Q13, 0) {
          Notify (_SB.PCI0.GFX0.LCD, 0x87)
     }
}

When Hotkeys Fail


Most of them, brightness hotkeys fail for two reasons: 

1) No events are triggered: 
On Ubuntu or many other Linux distro, running "acpi_listen" and pressing hotkeys shows standard ACPI events. If you don't see anything with hotkey presses, the system BIOS fails to issue events

2) _BCM fails to work
As Windows 8 no longer uses, many BIOS engineers never check whether _BCM works (please remember ACPI requires _BCM to present in order to support brightness controls). In Linux, you can and write to /sys/class/backlight/acpi_video0/brightness to verify whether _BCM works.

========================================
1. OS will get brightness level from _BCL

Method(_BCL, 0, NotSerialized)
{
Return(Package(){100, // AC Default Level 16
33, // DC Default Level 5
13, // Level 1
18, // Level 2
23, // Level 3
28, // Level 4
33, // Level 5
38, // Level 6
43, // Level 7
48, // Level 8
54, // Level 9
60, // Level 10
66, // Level 11
72, // Level 12
78, // Level 13
84, // Level 14
90, // Level 15
100 // Level 16
})
}

2. OS will set brightness from _BCM

Method(_BCM, 1, NotSerialized)
{
if (LEqual(\_SB.PCI0.VGA.AF7E, 0x80000001)) // Brightness control by driver
{
// Using the equation (Arg0*3+19)/20 to convert the "0 to 100%" BCL levels
// to "0 to 15" based.
Divide(Add(Multiply(Arg0, 3), 19), 20, Local1, Local0)
Store (DeRefOf(Index(BLVL, Local0)), Local3) // Get 0-255 range level from buffer
\_SB.PCI0.AFN7(Local3)
}
}

=============================================
REF : http://alexhungdmz.blogspot.tw/2013/06/acpi-brightness-control-1-control.html

2 則留言:

  1. 想請教一下,我的inverter type已經設為None/External,但還是不會走_BCM的方式去調整背光,另外WDDM裡提到會不會走ACPI的路徑是取決於Driver有沒有提供gkfxDDI的介面,那VBIOS中的inverter type就是WDDM判斷的依據嗎?
    目前_BCM那些都有定義在PCI0.GFX0.DD1F下,inverter type None,另外我也關了VBIOS中的DxgkDDI Brightness Control Method這項,還有沒有需要調整的?

    謝謝

    回覆刪除
  2. 感謝樓主分享,我的面板終於能動了

    回覆刪除