blob: aa1730cc8b9102e2b15befceb2908a93877be3d8 [file] [log] [blame]
Nico Huber53ec8c52020-03-21 19:50:26 +01001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Patrick Rudolph6838aae2018-07-29 10:53:01 +02003
4 /*
5 * Pseudo device that contains methods to modify Opregion
6 * "Mailbox 3 BIOS to Driver Notification"
7 * The BIOS to Driver Notification mailbox is intended to support
8 * BIOS to Driver event notification or data storage for BIOS to
9 * Driver data synchronization purpose.
10 */
11 Device (BOX3)
12 {
13 Name (_ADR, 0)
14
15 OperationRegion (OPRG, SystemMemory, ASLS, 0x2000)
16 Field (OPRG, DWordAcc, NoLock, Preserve)
17 {
18 // OpRegion Header
19 Offset (0x58),
20 MBOX, 32,
21
22 // Mailbox 3
23 Offset (0x300),
24 ARDY, 1, /* Offset 0 Driver readiness */
25 , 31,
26 ASLC, 32, /* Offset 4 ASLE interrupt command / status */
27 TCHE, 32, /* Offset 8 Technology enabled indicator */
28 ALSI, 32, /* Offset 12 Current ALS illuminance reading */
29 BCLP, 32, /* Offset 16 Backlight britness to set */
30 PFIT, 32, /* Offset 20 Panel fitting Request */
31 CBLV, 32, /* Offset 24 Brightness Current State */
32 }
33
34 /*
35 * Request back-light brightness change through mailbox 3
36 *
37 * @param Arg0 The brightness level to set in percent
38 * @Return Zero on success, Ones on failure
39 * Errors: * ASLS is zero
40 * * Mailbox 3 support not advertised
41 * * Driver not loaded or not ready
42 * * Driver reported an error during ASLE IRQ
43 */
Nico Huberc48d8832018-08-23 22:36:09 +020044 Method (XBCM, 1, Serialized)
Patrick Rudolph6838aae2018-07-29 10:53:01 +020045 {
46 If (LEqual(ASLS, Zero))
47 {
48 Return (Ones)
49 }
50 If (LEqual(And(MBOX, 0x4), Zero))
51 {
52 Return (Ones)
53 }
Patrick Rudolph6838aae2018-07-29 10:53:01 +020054
Nico Huber58344fc2018-08-23 21:52:05 +020055 /* Always keep BCLP up to date, even if driver is not ready.
56 It requires a full 8-bit brightness value. 255 = 100% */
Alexander Couzens661907c2018-08-23 16:40:55 +020057 Store (Divide (Multiply (Arg0, 255), 100), Local1)
58 If (LGreater(Local1, 255)) {
59 Store (255, Local1)
60 }
Nico Huber58344fc2018-08-23 21:52:05 +020061 /* also set valid bit */
Alexander Couzens661907c2018-08-23 16:40:55 +020062 Store (Or (Local1, 0x80000000), BCLP)
63
Nico Huber58344fc2018-08-23 21:52:05 +020064 If (LEqual(ARDY, Zero))
65 {
66 Return (Ones)
67 }
68
Patrick Rudolph6838aae2018-07-29 10:53:01 +020069 /* Request back-light change */
70 Store (0x2, ASLC)
71 /* Trigger IRQ */
72 Store (0x1, ASLE)
73
74 Store (0x20, Local0)
75 While (LGreater(Local0, Zero))
76 {
77 Sleep (1)
Nico Huberc48d8832018-08-23 22:36:09 +020078 If (LEqual (And (ASLC, 0x2), 0)) {
79 /* Request has been processed, check status: */
80 And (ShiftRight (ASLC, 12), 0x3, Local1)
81 If (LEqual (Local1, 0)) {
82 Return (Zero)
83 } Else {
84 Return (Ones)
85 }
Patrick Rudolph6838aae2018-07-29 10:53:01 +020086 }
87 Decrement (Local0)
88 }
89
90 Return (Ones)
91 }
Patrick Rudolph6838aae2018-07-29 10:53:01 +020092 }
93
94 /*
95 * Pseudo device that contains methods to operate on GTT memory
96 */
97 Device (LEGA)
98 {
99 Name (_ADR, 0)
100
Nico Huberf26a7c72018-08-23 22:14:01 +0200101 /* Divide round closest */
102 Method (DRCL, 2)
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200103 {
Nico Huberf26a7c72018-08-23 22:14:01 +0200104 Return (Divide (Add (Arg0, Divide (Arg1, 2)), Arg1))
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200105 }
106
Nico Huberf26a7c72018-08-23 22:14:01 +0200107 Method (XBCM, 1, NotSerialized)
108 {
109 Store (DRCL (Multiply (Arg0, BCLM), 100), BCLV)
110 }
111
112 /* Find value closest to BCLV in BRIG (which must be ordered) */
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200113 Method (XBQC, 0, NotSerialized)
114 {
Patrick Rudolph6dc488a2020-02-28 10:38:55 +0100115 /* Prevent DivideByZero if backlight control isn't enabled */
116 If (BCLM == 0)
117 {
118 Return (Zero)
119 }
Nico Huberf26a7c72018-08-23 22:14:01 +0200120 /* Local0: current percentage */
121 Store (DRCL (Multiply (BCLV, 100), BCLM), Local0)
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200122
Nico Huberf26a7c72018-08-23 22:14:01 +0200123 /* Local1: loop index (selectable values start at 2 in BRIG) */
124 Store (2, Local1)
125 While (LLess (Local1, Subtract (SizeOf (BRIG), 1))) {
126 /* Local[23]: adjacent values in BRIG */
127 Store (DeRefOf (Index (BRIG, Local1)), Local2)
128 Store (DeRefOf (Index (BRIG, Add (Local1, 1))), Local3)
129
130 If (LLess (Local0, Local3)) {
131 If (LOr (LLess (Local0, Local2),
132 LLess (Subtract (Local0, Local2),
133 Subtract (Local3, Local0)))) {
134 Return (Local2)
135 } Else {
136 Return (Local3)
137 }
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200138 }
Nico Huberf26a7c72018-08-23 22:14:01 +0200139
140 Increment (Local1)
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200141 }
Nico Huberf26a7c72018-08-23 22:14:01 +0200142
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200143 /* Didn't find greater/equal value: use the last */
Nico Huberf26a7c72018-08-23 22:14:01 +0200144 Return (Local3)
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200145 }
146 }
147
Nico Huberd5842f52015-09-24 17:45:45 +0200148 Method (XBCM, 1, NotSerialized)
149 {
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200150 If (LEqual(^BOX3.XBCM (Arg0), Ones))
151 {
152 ^LEGA.XBCM (Arg0)
153 }
Nico Huberd5842f52015-09-24 17:45:45 +0200154 }
155
156 Method (XBQC, 0, NotSerialized)
157 {
Nico Huberf26a7c72018-08-23 22:14:01 +0200158 /*
159 * Always query the hardware directly. Not all OS drivers
160 * keep CBLV up to date (one is Linux' i915). Some years
161 * after that is fixed we can probably use CBLV?
162 */
163 Return (^LEGA.XBQC ())
Nico Huberd5842f52015-09-24 17:45:45 +0200164 }