blob: c6ead0f6ed7761a42189f70c51e019a03fe9d975 [file] [log] [blame]
Tim Wawrzynczak103bd5e2020-05-29 13:11:00 -06001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <acpi/acpigen.h>
Tim Wawrzynczakd40a4c22021-02-25 13:14:49 -07004#include <acpi/acpigen_pci.h>
Tim Wawrzynczak103bd5e2020-05-29 13:11:00 -06005#include <console/console.h>
6#include <device/device.h>
Sumeet Pawnikara91d9312021-08-30 23:19:38 +05307#include <intelblocks/pmc_ipc.h>
Sumeet Pawnikare0bff812021-09-23 21:49:29 +05308#include <soc/pci_devs.h>
Tim Wawrzynczak103bd5e2020-05-29 13:11:00 -06009#include "chip.h"
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -060010#include "dptf.h"
Tim Wawrzynczak103bd5e2020-05-29 13:11:00 -060011
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -060012/* Generic DPTF participants have a PTYP field to distinguish them */
13enum dptf_generic_participant_type {
14 DPTF_GENERIC_PARTICIPANT_TYPE_TSR = 0x3,
Sumeet Pawnikare0bff812021-09-23 21:49:29 +053015 DPTF_GENERIC_PARTICIPANT_TYPE_TPCH = 0x5,
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -060016 DPTF_GENERIC_PARTICIPANT_TYPE_CHARGER = 0xB,
17};
18
19#define DEFAULT_CHARGER_STR "Battery Charger"
Sumeet Pawnikare0bff812021-09-23 21:49:29 +053020#define DEFAULT_TPCH_STR "Intel PCH FIVR Participant"
21
22#define PMC_IPC_COMMAND_FIVR_SIZE 0x8
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -060023
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -060024/*
25 * Helper method to determine if a device is "used" (called out anywhere as a source or a target
26 * of any policies, and therefore should be included in the ACPI tables.
27 */
28static bool is_participant_used(const struct drivers_intel_dptf_config *config,
29 enum dptf_participant participant)
30{
Tim Wawrzynczakc41f7f12020-05-29 13:56:37 -060031 int i;
32
33 /* Active? */
34 for (i = 0; i < DPTF_MAX_ACTIVE_POLICIES; ++i)
35 if (config->policies.active[i].target == participant)
36 return true;
37
Tim Wawrzynczak7eb11362020-05-29 14:10:53 -060038 /* Passive? */
39 for (i = 0; i < DPTF_MAX_PASSIVE_POLICIES; ++i)
40 if (config->policies.passive[i].source == participant ||
41 config->policies.passive[i].target == participant)
42 return true;
43
Tim Wawrzynczak3a9cde92020-05-29 14:19:15 -060044 /* Critical? */
45 for (i = 0; i < DPTF_MAX_CRITICAL_POLICIES; ++i)
46 if (config->policies.critical[i].source == participant)
47 return true;
48
Tim Wawrzynczakc41f7f12020-05-29 13:56:37 -060049 /* Check fan as well (its use is implicit in the Active policy) */
50 if (participant == DPTF_FAN && config->policies.active[0].target != DPTF_NONE)
51 return true;
52
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -060053 return false;
54}
55
Tim Wawrzynczak103bd5e2020-05-29 13:11:00 -060056static const char *dptf_acpi_name(const struct device *dev)
57{
58 return "DPTF";
59}
60
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -060061static int get_STA_value(const struct drivers_intel_dptf_config *config,
62 enum dptf_participant participant)
63{
64 return is_participant_used(config, participant) ?
65 ACPI_STATUS_DEVICE_ALL_ON :
66 ACPI_STATUS_DEVICE_ALL_OFF;
67}
68
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -060069static void dptf_write_hid(bool is_eisa, const char *hid)
70{
71 if (is_eisa)
72 acpigen_emit_eisaid(hid);
73 else
74 acpigen_write_string(hid);
75}
76
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -060077/* Devices with GENERIC _HID (distinguished by PTYP) */
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -060078static void dptf_write_generic_participant(const char *name,
79 enum dptf_generic_participant_type ptype,
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -060080 const char *str, int sta_val,
81 const struct dptf_platform_info *platform_info)
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -060082{
83 /* Auto-incrementing UID for generic participants */
84 static int generic_uid = 0;
85
86 acpigen_write_device(name);
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -060087 acpigen_write_name("_HID");
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -060088 dptf_write_hid(platform_info->use_eisa_hids, platform_info->generic_hid);
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -060089
90 acpigen_write_name_integer("_UID", generic_uid++);
91 acpigen_write_STA(sta_val);
92
93 if (str)
94 acpigen_write_name_string("_STR", str);
95
96 acpigen_write_name_integer("PTYP", ptype);
97
98 acpigen_pop_len(); /* Device */
99}
100
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600101/* \_SB.PCI0.TCPU */
102static void write_tcpu(const struct device *pci_dev,
103 const struct drivers_intel_dptf_config *config)
Tim Wawrzynczak103bd5e2020-05-29 13:11:00 -0600104{
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600105 /* DPTF CPU device - \_SB.PCI0.TCPU */
106 acpigen_write_scope(TCPU_SCOPE);
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -0600107 acpigen_write_device("TCPU");
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600108 acpigen_write_ADR_pci_device(pci_dev);
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -0600109 acpigen_write_STA(get_STA_value(config, DPTF_CPU));
110 acpigen_pop_len(); /* Device */
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600111 acpigen_pop_len(); /* TCPU Scope */
112}
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -0600113
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600114/* \_SB.DPTF.TFN1 */
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -0600115static void write_fan(const struct drivers_intel_dptf_config *config,
116 const struct dptf_platform_info *platform_info)
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600117{
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -0600118 acpigen_write_device("TFN1");
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600119 acpigen_write_name("_HID");
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -0600120 dptf_write_hid(platform_info->use_eisa_hids, platform_info->fan_hid);
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -0600121 acpigen_write_name_integer("_UID", 0);
122 acpigen_write_STA(get_STA_value(config, DPTF_FAN));
123 acpigen_pop_len(); /* Device */
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600124}
125
Sumeet R Pawnikar36571872021-05-11 20:05:20 +0530126/* \_SB.DPTF */
Sumeet Pawnikarf96aa7a2021-07-05 21:09:53 +0530127static void write_imok(void)
128{
129 acpigen_write_method("IMOK", 1);
130 /* Return (Arg0) */
131 acpigen_emit_byte(RETURN_OP);
132 acpigen_emit_byte(ARG0_OP);
133 acpigen_write_method_end();
134}
135/* \_SB.DPTF */
Sumeet R Pawnikar36571872021-05-11 20:05:20 +0530136static void write_oem_variables(const struct drivers_intel_dptf_config *config)
137{
138 int i;
139
140 acpigen_write_name("ODVX");
141 acpigen_write_package(DPTF_OEM_VARIABLE_COUNT);
142 for (i = 0; i < DPTF_OEM_VARIABLE_COUNT; i++)
143 acpigen_write_dword(config->oem_data.oem_variables[i]);
144 acpigen_write_package_end();
145
146 /*
147 * Method (ODUP, 2)
148 * Arg0 = Index of ODVX to update
149 * Arg1 = Value to place in ODVX[Arg0]
150 */
151 acpigen_write_method_serialized("ODUP", 2);
152 /* ODVX[Arg0] = Arg1 */
153 acpigen_write_store();
154 acpigen_emit_byte(ARG1_OP);
155 acpigen_emit_byte(INDEX_OP);
156 acpigen_emit_namestring("ODVX");
157 acpigen_emit_byte(ARG0_OP);
158 acpigen_emit_byte(ZERO_OP); /* Ignore Index() Destination */
159 acpigen_write_method_end();
160
161 /*
162 * Method (ODGT, 1)
163 * Arg0 = Index of ODVX to get
164 */
165 acpigen_write_method_serialized("ODGT", 1);
166 /* Return (ODVX[Arg0]) */
167 acpigen_emit_byte(RETURN_OP);
168 acpigen_emit_byte(DEREF_OP);
169 acpigen_emit_byte(INDEX_OP);
170 acpigen_emit_namestring("ODVX");
171 acpigen_emit_byte(ARG0_OP);
172 acpigen_emit_byte(ZERO_OP); /* Ignore Index() Destination */
173 acpigen_write_method_end();
174
175 /* Method (ODVP) { Return (ODVX) } */
176 acpigen_write_method_serialized("ODVP", 0);
177 acpigen_emit_byte(RETURN_OP);
178 acpigen_emit_namestring("ODVX");
179 acpigen_write_method_end();
180}
181
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600182/* \_SB.DPTF.xxxx */
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -0600183static void write_generic_devices(const struct drivers_intel_dptf_config *config,
184 const struct dptf_platform_info *platform_info)
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600185{
186 enum dptf_participant participant;
187 char name[ACPI_NAME_BUFFER_SIZE];
188 int i;
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -0600189
190 dptf_write_generic_participant("TCHG", DPTF_GENERIC_PARTICIPANT_TYPE_CHARGER,
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -0600191 DEFAULT_CHARGER_STR,
192 get_STA_value(config, DPTF_CHARGER),
193 platform_info);
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -0600194
195 for (i = 0, participant = DPTF_TEMP_SENSOR_0; i < 4; ++i, ++participant) {
196 snprintf(name, sizeof(name), "TSR%1d", i);
197 dptf_write_generic_participant(name, DPTF_GENERIC_PARTICIPANT_TYPE_TSR,
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -0600198 NULL, get_STA_value(config, participant),
199 platform_info);
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -0600200 }
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600201}
Tim Wawrzynczak103bd5e2020-05-29 13:11:00 -0600202
Sumeet Pawnikare0bff812021-09-23 21:49:29 +0530203static const char *get_pmc_ipcs_method(void)
204{
205 const char *method = acpi_device_path_join(
206 pcidev_path_on_root(PCH_DEVFN_PMC), "IPCS");
207 if (!method) {
208 printk(BIOS_ERR, "%s: Unable to find PMC device IPCS method\n", __func__);
209 return NULL;
210 }
211 return method;
212}
213
214static void write_tpch_write_method(const char *tpch_write_method_name,
Sumeet Pawnikara91d9312021-08-30 23:19:38 +0530215 unsigned int ipc_subcmd_ctrl_value)
216{
Sumeet Pawnikare0bff812021-09-23 21:49:29 +0530217 /* Get IPCS method from the PMC device */
218 const char *ipcs = get_pmc_ipcs_method();
219 acpigen_write_method_serialized(tpch_write_method_name, 1);
220 acpigen_emit_namestring(ipcs);
Sumeet Pawnikara91d9312021-08-30 23:19:38 +0530221 acpigen_write_integer(PMC_IPC_CMD_COMMAND_FIVR);
222 acpigen_write_integer(PMC_IPC_CMD_CMD_ID_FIVR_WRITE);
Sumeet Pawnikare0bff812021-09-23 21:49:29 +0530223 acpigen_write_integer(PMC_IPC_COMMAND_FIVR_SIZE);
Sumeet Pawnikara91d9312021-08-30 23:19:38 +0530224 acpigen_write_integer(ipc_subcmd_ctrl_value);
225 acpigen_emit_byte(ARG0_OP);
Sumeet Pawnikare0bff812021-09-23 21:49:29 +0530226 acpigen_write_zero();
227 acpigen_write_zero();
Sumeet Pawnikara91d9312021-08-30 23:19:38 +0530228 /* The reason for returning a value here is a W/A for the ESIF shell */
229 acpigen_emit_byte(RETURN_OP);
Sumeet Pawnikar7c1ce192021-10-07 18:00:57 +0530230 acpigen_write_package(1);
231 acpigen_write_zero();
Sumeet Pawnikara91d9312021-08-30 23:19:38 +0530232 acpigen_write_package_end();
233 acpigen_write_method_end();
234}
235
Sumeet Pawnikare0bff812021-09-23 21:49:29 +0530236static void write_ppkg_package(const uint8_t i)
237{
238 acpigen_write_store();
239 acpigen_emit_byte(DEREF_OP);
240 acpigen_emit_byte(INDEX_OP);
241 acpigen_emit_byte(ARG0_OP);
242 acpigen_write_integer(i);
243 acpigen_emit_byte(ZERO_OP);
244 acpigen_emit_byte(INDEX_OP);
245 acpigen_emit_namestring("PPKG");
246 acpigen_write_integer(i);
247 acpigen_emit_byte(ZERO_OP);
248}
249
250/*
251 * Truncate Package received from IPC
252 * Arguments:
253 * Arg0: Package returned from the IPCS read call from the Pmc
254 * Return Value:
255 * Return Package with just the Status and ReadBuf0
256 * Status returns 0 for success and 2 for device error
257 */
258static void write_pkgc_method(void)
259{
260 acpigen_write_method_serialized("PKGC", 1);
261 acpigen_write_name("PPKG");
262 acpigen_write_package(2);
263 acpigen_write_zero();
264 acpigen_write_zero();
265 acpigen_write_package_end();
266
267 write_ppkg_package(0);
268 write_ppkg_package(1);
269
270 acpigen_write_return_namestr("PPKG");
271 acpigen_write_method_end();
272}
273
274static void write_tpch_read_method(const char *tpch_read_method_name,
275 unsigned int ipc_subcmd_ctrl_value)
276{
277 /* Get IPCS method from the PMC device */
278 const char *ipcs = get_pmc_ipcs_method();
279 acpigen_write_method_serialized(tpch_read_method_name, 0);
280 acpigen_write_store();
281 acpigen_emit_namestring(ipcs);
282 acpigen_write_integer(PMC_IPC_CMD_COMMAND_FIVR);
283 acpigen_write_integer(PMC_IPC_CMD_CMD_ID_FIVR_READ);
284 acpigen_write_integer(PMC_IPC_COMMAND_FIVR_SIZE);
285 acpigen_write_integer(ipc_subcmd_ctrl_value);
286 acpigen_write_zero();
287 acpigen_write_zero();
288 acpigen_write_zero();
289 acpigen_emit_byte(LOCAL0_OP);
290
291 acpigen_write_store();
292 acpigen_emit_namestring("PKGC");
293 acpigen_emit_byte(LOCAL0_OP);
294 acpigen_emit_byte(LOCAL1_OP);
295
296 acpigen_emit_byte(RETURN_OP);
297 acpigen_emit_byte(LOCAL1_OP);
298 acpigen_write_method_end();
299}
300
Sumeet Pawnikara91d9312021-08-30 23:19:38 +0530301static void write_create_tpch(const struct dptf_platform_info *platform_info)
302{
303 acpigen_write_device("TPCH");
304 acpigen_write_name("_HID");
305 dptf_write_hid(platform_info->use_eisa_hids, platform_info->tpch_device_hid);
Sumeet Pawnikare0bff812021-09-23 21:49:29 +0530306 acpigen_write_name_string("_STR", DEFAULT_TPCH_STR);
307 acpigen_write_name_integer("PTYP", DPTF_GENERIC_PARTICIPANT_TYPE_TPCH);
Sumeet Pawnikara91d9312021-08-30 23:19:38 +0530308 acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON);
309}
310
311static void write_tpch_methods(const struct dptf_platform_info *platform_info)
312{
313 write_create_tpch(platform_info);
314
Sumeet Pawnikare0bff812021-09-23 21:49:29 +0530315 const struct {
316 enum { READ, WRITE } type;
317 const char *method_name;
318 unsigned int subcommand;
319 } tpch_methods[] = {
320 { .type = WRITE,
321 .method_name =
322 platform_info->tpch_method_names.set_fivr_low_clock_method,
323 .subcommand = PMC_IPC_SUBCMD_RFI_CTRL0_LOGIC
324 },
325 { .type = WRITE,
326 .method_name =
327 platform_info->tpch_method_names.set_fivr_high_clock_method,
328 .subcommand = PMC_IPC_SUBCMD_RFI_CTRL4_LOGIC
329 },
330 { .type = READ,
331 .method_name =
332 platform_info->tpch_method_names.get_fivr_low_clock_method,
333 .subcommand = PMC_IPC_SUBCMD_RFI_CTRL0_LOGIC
334 },
335 { .type = READ,
336 .method_name =
337 platform_info->tpch_method_names.get_fivr_high_clock_method,
338 .subcommand = PMC_IPC_SUBCMD_RFI_CTRL4_LOGIC
339 },
340 { .type = READ,
341 .method_name =
342 platform_info->tpch_method_names.get_fivr_ssc_method,
343 .subcommand = PMC_IPC_SUBCMD_EMI_CTRL0_LOGIC
344 },
345 { .type = READ,
346 .method_name =
347 platform_info->tpch_method_names.get_fivr_switching_fault_status,
348 .subcommand = PMC_IPC_SUBCMD_FFFC_FAULT_STATUS
349 },
350 { .type = READ,
351 .method_name =
352 platform_info->tpch_method_names.get_fivr_switching_freq_mhz,
353 .subcommand = PMC_IPC_SUBCMD_FFFC_RFI_STATUS
354 },
355 };
356
357 write_pkgc_method();
358 for (size_t i = 0; i < ARRAY_SIZE(tpch_methods); i++) {
359 if (tpch_methods[i].type == READ) {
360 write_tpch_read_method(tpch_methods[i].method_name,
361 tpch_methods[i].subcommand);
362 } else if (tpch_methods[i].type == WRITE) {
363 write_tpch_write_method(tpch_methods[i].method_name,
364 tpch_methods[i].subcommand);
365 }
366 }
Sumeet Pawnikara91d9312021-08-30 23:19:38 +0530367
368 acpigen_write_device_end(); /* TPCH Device */
369}
370
371/* \_SB.DPTF - note: leaves the Scope open for child devices */
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -0600372static void write_open_dptf_device(const struct device *dev,
373 const struct dptf_platform_info *platform_info)
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600374{
375 acpigen_write_scope("\\_SB");
376 acpigen_write_device(acpi_device_name(dev));
377 acpigen_write_name("_HID");
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -0600378 dptf_write_hid(platform_info->use_eisa_hids, platform_info->dptf_device_hid);
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600379 acpigen_write_name_integer("_UID", 0);
380 acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON);
381}
382
383/* Add minimal definitions of DPTF devices into the SSDT */
384static void write_device_definitions(const struct device *dev)
385{
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -0600386 const struct dptf_platform_info *platform_info = get_dptf_platform_info();
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600387 const struct drivers_intel_dptf_config *config;
388 struct device *parent;
389
390 /* The CPU device gets an _ADR that matches the ACPI PCI address for 00:04.00 */
391 parent = dev && dev->bus ? dev->bus->dev : NULL;
392 if (!parent || parent->path.type != DEVICE_PATH_PCI) {
393 printk(BIOS_ERR, "%s: DPTF objects must live under 00:04.0 PCI device\n",
394 __func__);
395 return;
396 }
397
398 config = config_of(dev);
399 write_tcpu(parent, config);
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -0600400 write_open_dptf_device(dev, platform_info);
401 write_fan(config, platform_info);
Sumeet R Pawnikar36571872021-05-11 20:05:20 +0530402 write_oem_variables(config);
Sumeet Pawnikarf96aa7a2021-07-05 21:09:53 +0530403 write_imok();
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -0600404 write_generic_devices(config, platform_info);
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600405
Sumeet Pawnikara91d9312021-08-30 23:19:38 +0530406 if (CONFIG(DRIVERS_INTEL_DPTF_SUPPORTS_TPCH))
407 write_tpch_methods(platform_info);
408
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600409 acpigen_pop_len(); /* DPTF Device (write_open_dptf_device) */
Tim Wawrzynczak103bd5e2020-05-29 13:11:00 -0600410 acpigen_pop_len(); /* Scope */
411}
412
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600413/* Emites policy definitions for each policy type */
414static void write_policies(const struct drivers_intel_dptf_config *config)
415{
416 dptf_write_enabled_policies(config->policies.active, DPTF_MAX_ACTIVE_POLICIES,
417 config->policies.passive, DPTF_MAX_PASSIVE_POLICIES,
418 config->policies.critical, DPTF_MAX_CRITICAL_POLICIES);
419
420 dptf_write_active_policies(config->policies.active,
421 DPTF_MAX_ACTIVE_POLICIES);
422
423 dptf_write_passive_policies(config->policies.passive,
424 DPTF_MAX_PASSIVE_POLICIES);
425
426 dptf_write_critical_policies(config->policies.critical,
427 DPTF_MAX_CRITICAL_POLICIES);
428}
429
430/* Writes other static tables that are used by DPTF */
431static void write_controls(const struct drivers_intel_dptf_config *config)
432{
433 dptf_write_charger_perf(config->controls.charger_perf, DPTF_MAX_CHARGER_PERF_STATES);
434 dptf_write_fan_perf(config->controls.fan_perf, DPTF_MAX_FAN_PERF_STATES);
435 dptf_write_power_limits(&config->controls.power_limits);
436}
437
438/* Options to control the behavior of devices */
439static void write_options(const struct drivers_intel_dptf_config *config)
440{
441 enum dptf_participant p;
442 int i;
443
444 /* Fan options */
Tim Wawrzynczak3a658ad2020-07-24 18:58:24 -0600445 dptf_write_scope(DPTF_FAN);
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600446 dptf_write_fan_options(config->options.fan.fine_grained_control,
447 config->options.fan.step_size,
448 config->options.fan.low_speed_notify);
Tim Wawrzynczak3a658ad2020-07-24 18:58:24 -0600449 acpigen_pop_len(); /* Scope */
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600450
451 /* TSR options */
452 for (p = DPTF_TEMP_SENSOR_0, i = 0; p <= DPTF_TEMP_SENSOR_3; ++p, ++i) {
Tim Wawrzynczakc6a593b2020-07-14 13:19:03 -0600453 if (is_participant_used(config, p) && (config->options.tsr[i].hysteresis ||
454 config->options.tsr[i].desc)) {
455 dptf_write_scope(p);
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600456 dptf_write_tsr_hysteresis(config->options.tsr[i].hysteresis);
457 dptf_write_STR(config->options.tsr[i].desc);
Tim Wawrzynczakc6a593b2020-07-14 13:19:03 -0600458 acpigen_pop_len(); /* Scope */
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600459 }
460 }
461}
462
463/* Add custom tables and methods to SSDT */
464static void dptf_fill_ssdt(const struct device *dev)
465{
466 struct drivers_intel_dptf_config *config = config_of(dev);
467
468 write_device_definitions(dev);
469 write_policies(config);
470 write_controls(config);
471 write_options(config);
472
473 printk(BIOS_INFO, DPTF_DEVICE_PATH ": %s at %s\n", dev->chip_ops->name, dev_path(dev));
474}
475
Tim Wawrzynczak103bd5e2020-05-29 13:11:00 -0600476static struct device_operations dptf_ops = {
477 .read_resources = noop_read_resources,
478 .set_resources = noop_set_resources,
479 .acpi_name = dptf_acpi_name,
480 .acpi_fill_ssdt = dptf_fill_ssdt,
Tim Wawrzynczak103bd5e2020-05-29 13:11:00 -0600481};
482
483static void dptf_enable_dev(struct device *dev)
484{
485 dev->ops = &dptf_ops;
486}
487
488struct chip_operations drivers_intel_dptf_ops = {
489 CHIP_NAME("Intel DPTF")
490 .enable_dev = dptf_enable_dev,
491};