blob: dfd878cb2651bbdc8efb9587b26a887faf07745b [file] [log] [blame]
Patrick Rudolph6838aae2018-07-29 10:53:01 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2015 Nico Huber <nico.huber@secunet.com>
Nico Huber58344fc2018-08-23 21:52:05 +02005 * Copyright (C) 2018 Nico Huber <nico.h@gmx.de>
Patrick Rudolph6838aae2018-07-29 10:53:01 +02006 * Copyright (C) 2018 Patrick Rudolph
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18 /*
19 * Pseudo device that contains methods to modify Opregion
20 * "Mailbox 3 BIOS to Driver Notification"
21 * The BIOS to Driver Notification mailbox is intended to support
22 * BIOS to Driver event notification or data storage for BIOS to
23 * Driver data synchronization purpose.
24 */
25 Device (BOX3)
26 {
27 Name (_ADR, 0)
28
29 OperationRegion (OPRG, SystemMemory, ASLS, 0x2000)
30 Field (OPRG, DWordAcc, NoLock, Preserve)
31 {
32 // OpRegion Header
33 Offset (0x58),
34 MBOX, 32,
35
36 // Mailbox 3
37 Offset (0x300),
38 ARDY, 1, /* Offset 0 Driver readiness */
39 , 31,
40 ASLC, 32, /* Offset 4 ASLE interrupt command / status */
41 TCHE, 32, /* Offset 8 Technology enabled indicator */
42 ALSI, 32, /* Offset 12 Current ALS illuminance reading */
43 BCLP, 32, /* Offset 16 Backlight britness to set */
44 PFIT, 32, /* Offset 20 Panel fitting Request */
45 CBLV, 32, /* Offset 24 Brightness Current State */
46 }
47
48 /*
49 * Request back-light brightness change through mailbox 3
50 *
51 * @param Arg0 The brightness level to set in percent
52 * @Return Zero on success, Ones on failure
53 * Errors: * ASLS is zero
54 * * Mailbox 3 support not advertised
55 * * Driver not loaded or not ready
56 * * Driver reported an error during ASLE IRQ
57 */
58 Method (XBCM, 1, NotSerialized)
59 {
60 If (LEqual(ASLS, Zero))
61 {
62 Return (Ones)
63 }
64 If (LEqual(And(MBOX, 0x4), Zero))
65 {
66 Return (Ones)
67 }
Patrick Rudolph6838aae2018-07-29 10:53:01 +020068
Nico Huber58344fc2018-08-23 21:52:05 +020069 /* Always keep BCLP up to date, even if driver is not ready.
70 It requires a full 8-bit brightness value. 255 = 100% */
Alexander Couzens661907c2018-08-23 16:40:55 +020071 Store (Divide (Multiply (Arg0, 255), 100), Local1)
72 If (LGreater(Local1, 255)) {
73 Store (255, Local1)
74 }
Nico Huber58344fc2018-08-23 21:52:05 +020075 /* also set valid bit */
Alexander Couzens661907c2018-08-23 16:40:55 +020076 Store (Or (Local1, 0x80000000), BCLP)
77
Nico Huber58344fc2018-08-23 21:52:05 +020078 If (LEqual(ARDY, Zero))
79 {
80 Return (Ones)
81 }
82
Patrick Rudolph6838aae2018-07-29 10:53:01 +020083 /* Request back-light change */
84 Store (0x2, ASLC)
85 /* Trigger IRQ */
86 Store (0x1, ASLE)
87
88 Store (0x20, Local0)
89 While (LGreater(Local0, Zero))
90 {
91 Sleep (1)
92 If (LEqual(And(ShiftRight(ASLC, 12), 0x3), Zero))
93 {
94 Return (Zero)
95 }
96 Decrement (Local0)
97 }
98
99 Return (Ones)
100 }
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200101 }
102
103 /*
104 * Pseudo device that contains methods to operate on GTT memory
105 */
106 Device (LEGA)
107 {
108 Name (_ADR, 0)
109
Nico Huberf26a7c72018-08-23 22:14:01 +0200110 /* Divide round closest */
111 Method (DRCL, 2)
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200112 {
Nico Huberf26a7c72018-08-23 22:14:01 +0200113 Return (Divide (Add (Arg0, Divide (Arg1, 2)), Arg1))
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200114 }
115
Nico Huberf26a7c72018-08-23 22:14:01 +0200116 Method (XBCM, 1, NotSerialized)
117 {
118 Store (DRCL (Multiply (Arg0, BCLM), 100), BCLV)
119 }
120
121 /* Find value closest to BCLV in BRIG (which must be ordered) */
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200122 Method (XBQC, 0, NotSerialized)
123 {
Nico Huberf26a7c72018-08-23 22:14:01 +0200124 /* Local0: current percentage */
125 Store (DRCL (Multiply (BCLV, 100), BCLM), Local0)
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200126
Nico Huberf26a7c72018-08-23 22:14:01 +0200127 /* Local1: loop index (selectable values start at 2 in BRIG) */
128 Store (2, Local1)
129 While (LLess (Local1, Subtract (SizeOf (BRIG), 1))) {
130 /* Local[23]: adjacent values in BRIG */
131 Store (DeRefOf (Index (BRIG, Local1)), Local2)
132 Store (DeRefOf (Index (BRIG, Add (Local1, 1))), Local3)
133
134 If (LLess (Local0, Local3)) {
135 If (LOr (LLess (Local0, Local2),
136 LLess (Subtract (Local0, Local2),
137 Subtract (Local3, Local0)))) {
138 Return (Local2)
139 } Else {
140 Return (Local3)
141 }
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200142 }
Nico Huberf26a7c72018-08-23 22:14:01 +0200143
144 Increment (Local1)
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200145 }
Nico Huberf26a7c72018-08-23 22:14:01 +0200146
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200147 /* Didn't find greater/equal value: use the last */
Nico Huberf26a7c72018-08-23 22:14:01 +0200148 Return (Local3)
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200149 }
150 }
151
Nico Huberd5842f52015-09-24 17:45:45 +0200152 Method (XBCM, 1, NotSerialized)
153 {
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200154 If (LEqual(^BOX3.XBCM (Arg0), Ones))
155 {
156 ^LEGA.XBCM (Arg0)
157 }
Nico Huberd5842f52015-09-24 17:45:45 +0200158 }
159
160 Method (XBQC, 0, NotSerialized)
161 {
Nico Huberf26a7c72018-08-23 22:14:01 +0200162 /*
163 * Always query the hardware directly. Not all OS drivers
164 * keep CBLV up to date (one is Linux' i915). Some years
165 * after that is fixed we can probably use CBLV?
166 */
167 Return (^LEGA.XBQC ())
Nico Huberd5842f52015-09-24 17:45:45 +0200168 }