coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
ec_dptf_helpers.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <acpi/acpigen.h>
4 #include <acpi/acpigen_dptf.h>
6 
7 /*
8  * The Chrome EC is typically in charge of many system functions, including battery charging and
9  * fan PWM control. This places it in the middle of a DPTF implementation and therefore, many of
10  * the "helper" ACPI Methods themselves call EC Methods. Because of that, the responsibility for
11  * producing the corresponding AML lies here.
12  */
13 
14 /* DPTF Event types */
15 enum {
17  THERMAL_EVENT = 0x90,
18 };
19 
20 /* EC constants */
21 enum {
23 };
24 
25 static void write_charger_PPPC(const struct device *ec)
26 {
28 
29  /*
30  * Convert size of PPSS table to index
31  *
32  * Store (SizeOf (PPSS), Local0)
33  * Decrement (Local0)
34  */
41 
42  /*
43  * Check if charging is disabled (AC removed)
44  *
45  * If (\_SB.PCI0.LPCB.EC0.ACEX () = Zero) {
46  * Return (Local0)
47  * }
48  */
54  acpigen_pop_len(); /* If */
55 
56  /* Return highest power state (index 0) */
58 
59  acpigen_pop_len(); /* Method */
60 }
61 
62 static void write_charger_SPPC(const struct device *ec)
63 {
64  /*
65  * SPPC - Set charger current limit
66  * Method(SPPC, 1) {
67  * Store (DeRefOf (Index (DeRefOf (Index
68  * (PPSS, ToInteger (Arg0))), 4)), Local0)
69  * \_SB.PCI0.LPCB.EC0.CHGS (Local0)
70  * }
71  */
72 
74 
75  /* Retrieve Control (index 4) for specified PPSS level */
83  acpigen_emit_byte(ZERO_OP); /* 3rd arg to Index */
84  acpigen_write_integer(4); /* Index */
85  acpigen_emit_byte(ZERO_OP); /* 3rd arg to Index */
87 
88  /* Pass Control value to EC to limit charging */
91  acpigen_pop_len(); /* Method */
92 }
93 
94 static void write_fan_fst(const struct device *ec)
95 {
96  /* TFST is a package that is used to store data from FAND */
97  acpigen_write_name("TFST");
99  acpigen_write_integer(0); /* Revision */
100  acpigen_write_integer(0); /* Control */
101  acpigen_write_integer(0); /* Speed */
102  acpigen_pop_len(); /* Package */
103 
104  /* _FST */
109  acpigen_emit_namestring("TFST");
111  acpigen_emit_byte(ZERO_OP); /* 3rd arg to Index */
113  acpigen_emit_namestring("TFST");
114  acpigen_pop_len(); /* Method _FST */
115 }
116 
117 static void write_fan_fsl(const struct device *ec)
118 {
119  /* _FSL */
124  acpigen_pop_len(); /* Method _FSL */
125 }
126 
127 /*
128  * Emit code to execute if the policy is enabled after this function is called, and also
129  * remember to manually add a acpigen_pop_len() afterwards!
130  */
131 static void write_is_policy_enabled(bool enabled)
132 {
133  /*
134  * Local0 = SizeOf (IDSP)
135  * Local1 = 0
136  * Local2 = 0
137  *
138  * While (Local1 < Local0) {
139  * If (IDSP[Local1] == Arg0 && Arg1 == enabled) {
140  * Local2 = 1
141  * }
142  * Local1++
143  * }
144  *
145  * If (Local2 == 1) {
146  * ..........
147  */
148 
149  /* Local0 = SizeOf (IDSP) */
152  acpigen_emit_namestring("IDSP");
154 
155  /* Local1 = 0 (index variable) */
159 
160  /* Local2 = 0 (out variable, 1=found, 0=not found) */
164 
165  /*
166  * While (Local1 < Local0) {
167  */
173 
174  /* If (IDSP[Local1] == Arg0 && Arg1 == 1) { */
180  acpigen_emit_namestring("IDSP");
182  acpigen_emit_byte(ZERO_OP); /* 3rd arg of index - unused */
183  acpigen_emit_byte(ARG0_OP); /* end lequal */
186  acpigen_write_integer(enabled ? 1 : 0);
187 
188  /* { Local2 = 1 } */
192  acpigen_pop_len(); /* If */
193 
194  /*
195  * Local1++
196  * } # End of While
197  */
200  acpigen_pop_len(); /* While */
201 
202  /*
203  * If (Local2 == 1)
204  */
209 
210  /* caller must insert acpigen_pop_len() ! */
211 }
212 
213 static void write_dptf_OSC(const struct device *ec)
214 {
215  char name[16];
216  int i;
217 
218  /*
219  * Arg0: Buffer containing UUID
220  * Arg1: "Integer containing Revision ID of buffer format", but Linux passes whether
221  * it is enabling (1) or disabling (0) the policy in Arg1.
222  * Arg2: Integer containing count of entries in Arg3
223  * Arg3: Buffer containing list of DWORD capabilities
224  * Return: Buffer containing list of DWORD capabilities
225  */
227 
228  /*
229  * If the Passive Policy is enabled:
230  * 1) Disable temperature sensor trip points in the EC (replaces TINI)
231  * 2) Disable the charge limit in the EC (replaces TCHG.INIT)
232  */
234  for (i = 0; i < DPTF_MAX_TSR; ++i) {
235  snprintf(name, sizeof(name), "^TSR%1d.PATD", i);
237  }
238 
240  acpigen_pop_len(); /* If (from write_is_policy_enabled) */
241 
242  /* If the Active Policy is disabled, disable DPTF fan control in the EC */
247  acpigen_pop_len(); /* If (from write_is_policy_enabled) */
248 
250  acpigen_pop_len(); /* Method _OSC */
251 }
252 
253 static void write_dppm_methods(const struct device *ec)
254 {
255  enum dptf_participant p;
256  char name[16];
257  int i;
258 
259  acpigen_write_scope("\\_SB.DPTF");
260  write_dptf_OSC(ec);
261 
262  /* TEVT */
263  if (CONFIG(EC_SUPPORTS_DPTF_TEVT)) {
264  acpigen_write_method("TEVT", 1);
265 
266  /* Local0 = ToInteger(Arg0) */
268  for (p = DPTF_TEMP_SENSOR_0, i = 0; p <= DPTF_TEMP_SENSOR_4; ++p, ++i) {
269  snprintf(name, sizeof(name), "^TSR%1d", i);
272  acpigen_pop_len(); /* If */
273  }
274 
275  acpigen_pop_len(); /* Method */
276  }
277 
278  /* TPET */
279  acpigen_write_method("TPET", 0);
280  for (p = DPTF_TEMP_SENSOR_0, i = 0; p <= DPTF_TEMP_SENSOR_4; ++p, ++i) {
281  snprintf(name, sizeof(name), "^TSR%1d", i);
283  }
284 
285  acpigen_pop_len(); /* Method */
286  acpigen_pop_len(); /* Scope */
287 }
288 
289 static void write_charger_methods(const struct device *ec)
290 {
292  write_charger_PPPC(ec);
293  write_charger_SPPC(ec);
294  acpigen_pop_len(); /* Scope */
295 }
296 
297 static void write_fan_methods(const struct device *ec)
298 {
300  write_fan_fsl(ec);
301  write_fan_fst(ec);
302  acpigen_pop_len(); /* Scope */
303 }
304 
305 static void write_thermal_methods(const struct device *ec, enum dptf_participant participant,
306  int tsr_index)
307 {
308  dptf_write_scope(participant);
309 
310  /*
311  * GTSH - Amount of hysteresis inherent in temperature reading (2 degrees, in units of
312  * 1/10th degree K)
313  */
314  acpigen_write_name_integer("GTSH", 20);
315 
316  /* _TMP - read temperature from EC */
320  acpigen_write_integer(tsr_index);
321  acpigen_pop_len(); /* Method _TMP */
322 
323  /* PATC - Aux trip point count */
324  acpigen_write_name_integer("PATC", 2);
325 
326  /* PAT0 - Set Aux trip point 0 */
329  acpigen_write_integer(tsr_index);
331  acpigen_pop_len(); /* Method PAT0 */
332 
333  /* PAT1 - Set Aux trip point 1 */
336  acpigen_write_integer(tsr_index);
338  acpigen_pop_len(); /* Method PAT0 */
339 
340  /* PATD - Disable Aux trip point */
343  acpigen_write_integer(tsr_index);
344  acpigen_pop_len(); /* Method PAT0 */
345 
346  acpigen_pop_len(); /* Scope */
347 }
348 
349 void ec_fill_dptf_helpers(const struct device *ec)
350 {
351  enum dptf_participant p;
352  int i;
353 
354  write_dppm_methods(ec);
356  write_fan_methods(ec);
357 
358  for (p = DPTF_TEMP_SENSOR_0, i = 0; p <= DPTF_TEMP_SENSOR_4; ++p, ++i)
359  write_thermal_methods(ec, p, i);
360 }
const char * acpi_device_path_join(const struct device *dev, const char *name)
Definition: device.c:172
void acpigen_write_len_f(void)
Definition: acpigen.c:28
void acpigen_write_if(void)
Definition: acpigen.c:1437
void acpigen_emit_namestring(const char *namepath)
Definition: acpigen.c:275
void acpigen_write_store(void)
Definition: acpigen.c:1333
void acpigen_write_integer(uint64_t data)
Definition: acpigen.c:136
void acpigen_pop_len(void)
Definition: acpigen.c:37
void acpigen_write_scope(const char *name)
Definition: acpigen.c:326
void acpigen_write_zero(void)
Definition: acpigen.c:121
void acpigen_write_one(void)
Definition: acpigen.c:126
void acpigen_write_if_lequal_op_int(uint8_t op, uint64_t val)
Definition: acpigen.c:1472
void acpigen_write_method_serialized(const char *name, int nargs)
Definition: acpigen.c:764
char * acpigen_write_package(int nr_el)
Definition: acpigen.c:86
void acpigen_write_name_integer(const char *name, uint64_t val)
Definition: acpigen.c:170
void acpigen_emit_byte(unsigned char b)
Definition: acpigen.c:61
void acpigen_write_to_integer(uint8_t src, uint8_t dst)
Definition: acpigen.c:1532
void acpigen_write_method(const char *name, int nargs)
Definition: acpigen.c:758
void acpigen_write_return_op(uint8_t arg)
Definition: acpigen.c:1571
void acpigen_notify(const char *namestr, int value)
Definition: acpigen.c:2154
void acpigen_write_name(const char *name)
Definition: acpigen.c:320
void dptf_write_scope(enum dptf_participant participant)
Definition: acpigen_dptf.c:114
@ DPTF_MAX_TSR
Definition: acpigen_dptf.h:50
dptf_participant
Definition: acpigen_dptf.h:18
@ DPTF_TEMP_SENSOR_0
Definition: acpigen_dptf.h:23
@ DPTF_TEMP_SENSOR_4
Definition: acpigen_dptf.h:27
@ DPTF_CHARGER
Definition: acpigen_dptf.h:21
@ DPTF_FAN
Definition: acpigen_dptf.h:22
const char * name
Definition: mmu.c:92
@ CONFIG
Definition: dsi_common.h:201
static void write_fan_fst(const struct device *ec)
static void write_dppm_methods(const struct device *ec)
static void write_dptf_OSC(const struct device *ec)
@ EC_FAN_DUTY_AUTO
static void write_charger_methods(const struct device *ec)
static void write_thermal_methods(const struct device *ec, enum dptf_participant participant, int tsr_index)
void ec_fill_dptf_helpers(const struct device *ec)
static void write_is_policy_enabled(bool enabled)
static void write_fan_methods(const struct device *ec)
static void write_fan_fsl(const struct device *ec)
@ THERMAL_EVENT
@ TRIP_POINTS_CHANGED_EVENT
static void write_charger_PPPC(const struct device *ec)
static void write_charger_SPPC(const struct device *ec)
@ ARG0_OP
Definition: acpigen.h:89
@ ARG1_OP
Definition: acpigen.h:90
@ LLESS_OP
Definition: acpigen.h:133
@ INDEX_OP
Definition: acpigen.h:120
@ LOCAL1_OP
Definition: acpigen.h:82
@ ARG3_OP
Definition: acpigen.h:92
@ LOCAL0_OP
Definition: acpigen.h:81
@ WHILE_OP
Definition: acpigen.h:144
@ LOCAL2_OP
Definition: acpigen.h:83
@ DECREMENT_OP
Definition: acpigen.h:102
@ RETURN_OP
Definition: acpigen.h:146
@ ZERO_OP
Definition: acpigen.h:30
@ DEREF_OP
Definition: acpigen.h:115
@ LEQUAL_OP
Definition: acpigen.h:131
@ SIZEOF_OP
Definition: acpigen.h:119
@ INCREMENT_OP
Definition: acpigen.h:101
@ LAND_OP
Definition: acpigen.h:128
@ STORE_OP
Definition: acpigen.h:96
Definition: device.h:107
int snprintf(char *buf, size_t size, const char *fmt,...)
Note: This file is only for POSIX compatibility, and is meant to be chain-included via string....
Definition: vsprintf.c:35