blob: 886093e26d4399549e93be0184e41614b5ab9ffa [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>
Subrata Banikaf206282022-12-19 21:56:35 +05308#include <soc/dptf.h>
Sumeet Pawnikare0bff812021-09-23 21:49:29 +05309#include <soc/pci_devs.h>
Tim Wawrzynczak103bd5e2020-05-29 13:11:00 -060010#include "chip.h"
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -060011#include "dptf.h"
Tim Wawrzynczak103bd5e2020-05-29 13:11:00 -060012
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -060013/* Generic DPTF participants have a PTYP field to distinguish them */
14enum dptf_generic_participant_type {
15 DPTF_GENERIC_PARTICIPANT_TYPE_TSR = 0x3,
Sumeet Pawnikare0bff812021-09-23 21:49:29 +053016 DPTF_GENERIC_PARTICIPANT_TYPE_TPCH = 0x5,
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -060017 DPTF_GENERIC_PARTICIPANT_TYPE_CHARGER = 0xB,
Varshit B Pandya170a76c2022-04-02 15:11:36 +053018 DPTF_GENERIC_PARTICIPANT_TYPE_BATTERY = 0xC,
Varshit B Pandyae7d3a1a2022-03-20 20:39:51 +053019 DPTF_GENERIC_PARTICIPANT_TYPE_POWER = 0x11,
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -060020};
21
22#define DEFAULT_CHARGER_STR "Battery Charger"
Sumeet Pawnikare0bff812021-09-23 21:49:29 +053023#define DEFAULT_TPCH_STR "Intel PCH FIVR Participant"
Varshit B Pandyae7d3a1a2022-03-20 20:39:51 +053024#define DEFAULT_POWER_STR "Power Participant"
Varshit B Pandya170a76c2022-04-02 15:11:36 +053025#define DEFAULT_BATTERY_STR "Battery Participant"
Sumeet Pawnikare0bff812021-09-23 21:49:29 +053026
27#define PMC_IPC_COMMAND_FIVR_SIZE 0x8
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -060028
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -060029/*
30 * Helper method to determine if a device is "used" (called out anywhere as a source or a target
31 * of any policies, and therefore should be included in the ACPI tables.
32 */
33static bool is_participant_used(const struct drivers_intel_dptf_config *config,
34 enum dptf_participant participant)
35{
Tim Wawrzynczakc41f7f12020-05-29 13:56:37 -060036 int i;
37
38 /* Active? */
39 for (i = 0; i < DPTF_MAX_ACTIVE_POLICIES; ++i)
40 if (config->policies.active[i].target == participant)
41 return true;
42
Tim Wawrzynczak7eb11362020-05-29 14:10:53 -060043 /* Passive? */
44 for (i = 0; i < DPTF_MAX_PASSIVE_POLICIES; ++i)
45 if (config->policies.passive[i].source == participant ||
46 config->policies.passive[i].target == participant)
47 return true;
48
Tim Wawrzynczak3a9cde92020-05-29 14:19:15 -060049 /* Critical? */
50 for (i = 0; i < DPTF_MAX_CRITICAL_POLICIES; ++i)
51 if (config->policies.critical[i].source == participant)
52 return true;
53
Tim Wawrzynczakc41f7f12020-05-29 13:56:37 -060054 /* Check fan as well (its use is implicit in the Active policy) */
Sumeet Pawnikar4dba71f2022-10-19 15:15:54 +053055 if (participant == DPTF_FAN && config->policies.active[0].target != DPTF_NONE)
Tim Wawrzynczakc41f7f12020-05-29 13:56:37 -060056 return true;
57
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -060058 return false;
59}
60
Tim Wawrzynczak103bd5e2020-05-29 13:11:00 -060061static const char *dptf_acpi_name(const struct device *dev)
62{
63 return "DPTF";
64}
65
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -060066static int get_STA_value(const struct drivers_intel_dptf_config *config,
67 enum dptf_participant participant)
68{
69 return is_participant_used(config, participant) ?
70 ACPI_STATUS_DEVICE_ALL_ON :
71 ACPI_STATUS_DEVICE_ALL_OFF;
72}
73
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -060074static void dptf_write_hid(bool is_eisa, const char *hid)
75{
76 if (is_eisa)
77 acpigen_emit_eisaid(hid);
78 else
79 acpigen_write_string(hid);
80}
81
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -060082/* Devices with GENERIC _HID (distinguished by PTYP) */
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -060083static void dptf_write_generic_participant(const char *name,
84 enum dptf_generic_participant_type ptype,
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -060085 const char *str, int sta_val,
86 const struct dptf_platform_info *platform_info)
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -060087{
88 /* Auto-incrementing UID for generic participants */
89 static int generic_uid = 0;
90
91 acpigen_write_device(name);
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -060092 acpigen_write_name("_HID");
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -060093 dptf_write_hid(platform_info->use_eisa_hids, platform_info->generic_hid);
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -060094
95 acpigen_write_name_integer("_UID", generic_uid++);
96 acpigen_write_STA(sta_val);
97
98 if (str)
99 acpigen_write_name_string("_STR", str);
100
101 acpigen_write_name_integer("PTYP", ptype);
102
103 acpigen_pop_len(); /* Device */
104}
105
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600106/* \_SB.PCI0.TCPU */
107static void write_tcpu(const struct device *pci_dev,
108 const struct drivers_intel_dptf_config *config)
Tim Wawrzynczak103bd5e2020-05-29 13:11:00 -0600109{
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600110 /* DPTF CPU device - \_SB.PCI0.TCPU */
111 acpigen_write_scope(TCPU_SCOPE);
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -0600112 acpigen_write_device("TCPU");
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600113 acpigen_write_ADR_pci_device(pci_dev);
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -0600114 acpigen_write_STA(get_STA_value(config, DPTF_CPU));
115 acpigen_pop_len(); /* Device */
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600116 acpigen_pop_len(); /* TCPU Scope */
117}
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -0600118
Sumeet Pawnikar4dba71f2022-10-19 15:15:54 +0530119/* \_SB.DPTF.TFN1 */
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -0600120static void write_fan(const struct drivers_intel_dptf_config *config,
Sumeet Pawnikar4dba71f2022-10-19 15:15:54 +0530121 const struct dptf_platform_info *platform_info)
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600122{
Sumeet Pawnikar4dba71f2022-10-19 15:15:54 +0530123 acpigen_write_device("TFN1");
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600124 acpigen_write_name("_HID");
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -0600125 dptf_write_hid(platform_info->use_eisa_hids, platform_info->fan_hid);
Sumeet Pawnikar4dba71f2022-10-19 15:15:54 +0530126 acpigen_write_name_integer("_UID", 0);
127 acpigen_write_STA(get_STA_value(config, DPTF_FAN));
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -0600128 acpigen_pop_len(); /* Device */
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600129}
130
Sumeet R Pawnikar36571872021-05-11 20:05:20 +0530131/* \_SB.DPTF */
Sumeet Pawnikarf96aa7a2021-07-05 21:09:53 +0530132static void write_imok(void)
133{
134 acpigen_write_method("IMOK", 1);
135 /* Return (Arg0) */
136 acpigen_emit_byte(RETURN_OP);
137 acpigen_emit_byte(ARG0_OP);
138 acpigen_write_method_end();
139}
140/* \_SB.DPTF */
Sumeet R Pawnikar36571872021-05-11 20:05:20 +0530141static void write_oem_variables(const struct drivers_intel_dptf_config *config)
142{
143 int i;
144
145 acpigen_write_name("ODVX");
146 acpigen_write_package(DPTF_OEM_VARIABLE_COUNT);
147 for (i = 0; i < DPTF_OEM_VARIABLE_COUNT; i++)
148 acpigen_write_dword(config->oem_data.oem_variables[i]);
149 acpigen_write_package_end();
150
151 /*
152 * Method (ODUP, 2)
153 * Arg0 = Index of ODVX to update
154 * Arg1 = Value to place in ODVX[Arg0]
155 */
156 acpigen_write_method_serialized("ODUP", 2);
157 /* ODVX[Arg0] = Arg1 */
158 acpigen_write_store();
159 acpigen_emit_byte(ARG1_OP);
160 acpigen_emit_byte(INDEX_OP);
161 acpigen_emit_namestring("ODVX");
162 acpigen_emit_byte(ARG0_OP);
163 acpigen_emit_byte(ZERO_OP); /* Ignore Index() Destination */
164 acpigen_write_method_end();
165
166 /*
167 * Method (ODGT, 1)
168 * Arg0 = Index of ODVX to get
169 */
170 acpigen_write_method_serialized("ODGT", 1);
171 /* Return (ODVX[Arg0]) */
172 acpigen_emit_byte(RETURN_OP);
173 acpigen_emit_byte(DEREF_OP);
174 acpigen_emit_byte(INDEX_OP);
175 acpigen_emit_namestring("ODVX");
176 acpigen_emit_byte(ARG0_OP);
177 acpigen_emit_byte(ZERO_OP); /* Ignore Index() Destination */
178 acpigen_write_method_end();
179
180 /* Method (ODVP) { Return (ODVX) } */
181 acpigen_write_method_serialized("ODVP", 0);
182 acpigen_emit_byte(RETURN_OP);
183 acpigen_emit_namestring("ODVX");
184 acpigen_write_method_end();
185}
186
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600187/* \_SB.DPTF.xxxx */
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -0600188static void write_generic_devices(const struct drivers_intel_dptf_config *config,
189 const struct dptf_platform_info *platform_info)
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600190{
191 enum dptf_participant participant;
192 char name[ACPI_NAME_BUFFER_SIZE];
193 int i;
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -0600194
195 dptf_write_generic_participant("TCHG", DPTF_GENERIC_PARTICIPANT_TYPE_CHARGER,
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -0600196 DEFAULT_CHARGER_STR,
197 get_STA_value(config, DPTF_CHARGER),
198 platform_info);
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -0600199
Tim Wawrzynczak40713aa2021-11-24 09:18:44 -0700200 for (i = 0, participant = DPTF_TEMP_SENSOR_0; i < DPTF_MAX_TSR; ++i, ++participant) {
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -0600201 snprintf(name, sizeof(name), "TSR%1d", i);
202 dptf_write_generic_participant(name, DPTF_GENERIC_PARTICIPANT_TYPE_TSR,
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -0600203 NULL, get_STA_value(config, participant),
204 platform_info);
Tim Wawrzynczakff2f6b22020-05-29 13:24:03 -0600205 }
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600206}
Tim Wawrzynczak103bd5e2020-05-29 13:11:00 -0600207
Sumeet Pawnikare0bff812021-09-23 21:49:29 +0530208static const char *get_pmc_ipcs_method(void)
209{
210 const char *method = acpi_device_path_join(
211 pcidev_path_on_root(PCH_DEVFN_PMC), "IPCS");
212 if (!method) {
213 printk(BIOS_ERR, "%s: Unable to find PMC device IPCS method\n", __func__);
214 return NULL;
215 }
216 return method;
217}
218
219static void write_tpch_write_method(const char *tpch_write_method_name,
Sumeet Pawnikara91d9312021-08-30 23:19:38 +0530220 unsigned int ipc_subcmd_ctrl_value)
221{
Sumeet Pawnikare0bff812021-09-23 21:49:29 +0530222 /* Get IPCS method from the PMC device */
223 const char *ipcs = get_pmc_ipcs_method();
224 acpigen_write_method_serialized(tpch_write_method_name, 1);
225 acpigen_emit_namestring(ipcs);
Sumeet Pawnikara91d9312021-08-30 23:19:38 +0530226 acpigen_write_integer(PMC_IPC_CMD_COMMAND_FIVR);
227 acpigen_write_integer(PMC_IPC_CMD_CMD_ID_FIVR_WRITE);
Sumeet Pawnikare0bff812021-09-23 21:49:29 +0530228 acpigen_write_integer(PMC_IPC_COMMAND_FIVR_SIZE);
Sumeet Pawnikara91d9312021-08-30 23:19:38 +0530229 acpigen_write_integer(ipc_subcmd_ctrl_value);
230 acpigen_emit_byte(ARG0_OP);
Sumeet Pawnikare0bff812021-09-23 21:49:29 +0530231 acpigen_write_zero();
232 acpigen_write_zero();
Sumeet Pawnikara91d9312021-08-30 23:19:38 +0530233 /* The reason for returning a value here is a W/A for the ESIF shell */
234 acpigen_emit_byte(RETURN_OP);
Sumeet Pawnikar7c1ce192021-10-07 18:00:57 +0530235 acpigen_write_package(1);
236 acpigen_write_zero();
Sumeet Pawnikara91d9312021-08-30 23:19:38 +0530237 acpigen_write_package_end();
238 acpigen_write_method_end();
239}
240
Sumeet Pawnikare0bff812021-09-23 21:49:29 +0530241static void write_ppkg_package(const uint8_t i)
242{
243 acpigen_write_store();
244 acpigen_emit_byte(DEREF_OP);
245 acpigen_emit_byte(INDEX_OP);
246 acpigen_emit_byte(ARG0_OP);
247 acpigen_write_integer(i);
248 acpigen_emit_byte(ZERO_OP);
249 acpigen_emit_byte(INDEX_OP);
250 acpigen_emit_namestring("PPKG");
251 acpigen_write_integer(i);
252 acpigen_emit_byte(ZERO_OP);
253}
254
255/*
256 * Truncate Package received from IPC
257 * Arguments:
258 * Arg0: Package returned from the IPCS read call from the Pmc
259 * Return Value:
260 * Return Package with just the Status and ReadBuf0
261 * Status returns 0 for success and 2 for device error
262 */
263static void write_pkgc_method(void)
264{
265 acpigen_write_method_serialized("PKGC", 1);
266 acpigen_write_name("PPKG");
267 acpigen_write_package(2);
268 acpigen_write_zero();
269 acpigen_write_zero();
270 acpigen_write_package_end();
271
272 write_ppkg_package(0);
273 write_ppkg_package(1);
274
275 acpigen_write_return_namestr("PPKG");
276 acpigen_write_method_end();
277}
278
279static void write_tpch_read_method(const char *tpch_read_method_name,
280 unsigned int ipc_subcmd_ctrl_value)
281{
282 /* Get IPCS method from the PMC device */
283 const char *ipcs = get_pmc_ipcs_method();
284 acpigen_write_method_serialized(tpch_read_method_name, 0);
285 acpigen_write_store();
286 acpigen_emit_namestring(ipcs);
287 acpigen_write_integer(PMC_IPC_CMD_COMMAND_FIVR);
288 acpigen_write_integer(PMC_IPC_CMD_CMD_ID_FIVR_READ);
289 acpigen_write_integer(PMC_IPC_COMMAND_FIVR_SIZE);
290 acpigen_write_integer(ipc_subcmd_ctrl_value);
291 acpigen_write_zero();
292 acpigen_write_zero();
293 acpigen_write_zero();
294 acpigen_emit_byte(LOCAL0_OP);
295
296 acpigen_write_store();
297 acpigen_emit_namestring("PKGC");
298 acpigen_emit_byte(LOCAL0_OP);
299 acpigen_emit_byte(LOCAL1_OP);
300
301 acpigen_emit_byte(RETURN_OP);
302 acpigen_emit_byte(LOCAL1_OP);
303 acpigen_write_method_end();
304}
305
Sumeet Pawnikara91d9312021-08-30 23:19:38 +0530306static void write_create_tpch(const struct dptf_platform_info *platform_info)
307{
308 acpigen_write_device("TPCH");
309 acpigen_write_name("_HID");
310 dptf_write_hid(platform_info->use_eisa_hids, platform_info->tpch_device_hid);
Sumeet Pawnikare0bff812021-09-23 21:49:29 +0530311 acpigen_write_name_string("_STR", DEFAULT_TPCH_STR);
312 acpigen_write_name_integer("PTYP", DPTF_GENERIC_PARTICIPANT_TYPE_TPCH);
Sumeet Pawnikara91d9312021-08-30 23:19:38 +0530313 acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON);
314}
315
316static void write_tpch_methods(const struct dptf_platform_info *platform_info)
317{
318 write_create_tpch(platform_info);
319
Sumeet Pawnikare0bff812021-09-23 21:49:29 +0530320 const struct {
321 enum { READ, WRITE } type;
322 const char *method_name;
323 unsigned int subcommand;
324 } tpch_methods[] = {
325 { .type = WRITE,
326 .method_name =
327 platform_info->tpch_method_names.set_fivr_low_clock_method,
328 .subcommand = PMC_IPC_SUBCMD_RFI_CTRL0_LOGIC
329 },
330 { .type = WRITE,
331 .method_name =
332 platform_info->tpch_method_names.set_fivr_high_clock_method,
333 .subcommand = PMC_IPC_SUBCMD_RFI_CTRL4_LOGIC
334 },
335 { .type = READ,
336 .method_name =
337 platform_info->tpch_method_names.get_fivr_low_clock_method,
338 .subcommand = PMC_IPC_SUBCMD_RFI_CTRL0_LOGIC
339 },
340 { .type = READ,
341 .method_name =
342 platform_info->tpch_method_names.get_fivr_high_clock_method,
343 .subcommand = PMC_IPC_SUBCMD_RFI_CTRL4_LOGIC
344 },
345 { .type = READ,
346 .method_name =
347 platform_info->tpch_method_names.get_fivr_ssc_method,
348 .subcommand = PMC_IPC_SUBCMD_EMI_CTRL0_LOGIC
349 },
350 { .type = READ,
351 .method_name =
352 platform_info->tpch_method_names.get_fivr_switching_fault_status,
353 .subcommand = PMC_IPC_SUBCMD_FFFC_FAULT_STATUS
354 },
355 { .type = READ,
356 .method_name =
357 platform_info->tpch_method_names.get_fivr_switching_freq_mhz,
358 .subcommand = PMC_IPC_SUBCMD_FFFC_RFI_STATUS
359 },
360 };
361
362 write_pkgc_method();
363 for (size_t i = 0; i < ARRAY_SIZE(tpch_methods); i++) {
364 if (tpch_methods[i].type == READ) {
365 write_tpch_read_method(tpch_methods[i].method_name,
366 tpch_methods[i].subcommand);
367 } else if (tpch_methods[i].type == WRITE) {
368 write_tpch_write_method(tpch_methods[i].method_name,
369 tpch_methods[i].subcommand);
370 }
371 }
Sumeet Pawnikara91d9312021-08-30 23:19:38 +0530372
373 acpigen_write_device_end(); /* TPCH Device */
374}
375
Varshit B Pandya282b3b62022-04-18 14:50:30 +0530376static void write_create_tpwr(const struct drivers_intel_dptf_config *config,
377 const struct dptf_platform_info *platform_info)
Varshit B Pandyae7d3a1a2022-03-20 20:39:51 +0530378{
379 acpigen_write_device("TPWR");
380 acpigen_write_name("_HID");
381 if (platform_info->tpwr_device_hid != NULL)
382 dptf_write_hid(platform_info->use_eisa_hids, platform_info->tpwr_device_hid);
383 acpigen_write_name_string("_UID", "TPWR");
384 acpigen_write_name_string("_STR", DEFAULT_POWER_STR);
385 acpigen_write_name_integer("PTYP", DPTF_GENERIC_PARTICIPANT_TYPE_POWER);
386 acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON);
Varshit B Pandya282b3b62022-04-18 14:50:30 +0530387
388 /* PROP method */
389 if(config->prop != 0) {
390 acpigen_write_method_serialized("PROP", 0);
391 acpigen_emit_byte(RETURN_OP);
392 acpigen_write_integer(config->prop);
393 acpigen_pop_len(); /* Method PROP */
394 }
Varshit B Pandyae7d3a1a2022-03-20 20:39:51 +0530395 acpigen_write_device_end(); /* TPWR Power Participant Device */
396}
397
Varshit B Pandya282b3b62022-04-18 14:50:30 +0530398static void write_tpwr_methods(const struct drivers_intel_dptf_config *config,
399 const struct dptf_platform_info *platform_info)
Varshit B Pandyae7d3a1a2022-03-20 20:39:51 +0530400{
Varshit B Pandya282b3b62022-04-18 14:50:30 +0530401 write_create_tpwr(config, platform_info);
Varshit B Pandyae7d3a1a2022-03-20 20:39:51 +0530402}
403
Varshit B Pandya170a76c2022-04-02 15:11:36 +0530404static void write_create_tbat(const struct dptf_platform_info *platform_info)
405{
406 acpigen_write_device("TBAT");
407 acpigen_write_name("_HID");
408 if (platform_info->tbat_device_hid != NULL)
409 dptf_write_hid(platform_info->use_eisa_hids, platform_info->tbat_device_hid);
Varshit B Pandya4060df42022-07-01 17:57:43 +0530410 acpigen_write_name_string("_UID", "1");
Varshit B Pandya170a76c2022-04-02 15:11:36 +0530411 acpigen_write_name_string("_STR", DEFAULT_BATTERY_STR);
412 acpigen_write_name_integer("PTYP", DPTF_GENERIC_PARTICIPANT_TYPE_BATTERY);
413 acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON);
414 acpigen_write_device_end(); /* TBAT Battery Participant Device */
415}
416
417
418static void write_tbat_methods(const struct dptf_platform_info *platform_info)
419{
420 write_create_tbat(platform_info);
421}
422
423
Sumeet Pawnikara91d9312021-08-30 23:19:38 +0530424/* \_SB.DPTF - note: leaves the Scope open for child devices */
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -0600425static void write_open_dptf_device(const struct device *dev,
426 const struct dptf_platform_info *platform_info)
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600427{
428 acpigen_write_scope("\\_SB");
429 acpigen_write_device(acpi_device_name(dev));
430 acpigen_write_name("_HID");
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -0600431 dptf_write_hid(platform_info->use_eisa_hids, platform_info->dptf_device_hid);
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600432 acpigen_write_name_integer("_UID", 0);
433 acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON);
434}
435
Subrata Banikaf206282022-12-19 21:56:35 +0530436static const struct dptf_platform_info generic_dptf_platform_info = {
437 .use_eisa_hids = CONFIG(DPTF_USE_EISA_HID),
438 /* _HID for the toplevel DPTF device, typically \_SB.DPTF */
439 .dptf_device_hid = DPTF_DPTF_DEVICE,
440 /* _HID for Intel DPTF Generic Device (these require PTYP as well) */
441 .generic_hid = DPTF_GEN_DEVICE,
442 /* _HID for Intel DPTF Fan Device */
443 .fan_hid = DPTF_FAN_DEVICE,
444
445#if CONFIG(DRIVERS_INTEL_DPTF_SUPPORTS_TPWR)
446 /* _HID for the toplevel TPWR device, typically \_SB.DPTF.TPWR */
447 .tpwr_device_hid = DPTF_TPWR_DEVICE,
448#endif
449
450#if CONFIG(DRIVERS_INTEL_DPTF_SUPPORTS_TBAT)
451 /* _HID for the toplevel BAT1 device, typically \_SB.DPTF.BAT1 */
452 .tbat_device_hid = DPTF_BAT1_DEVICE,
453#endif
454
455#if CONFIG(DRIVERS_INTEL_DPTF_SUPPORTS_TPCH)
456 /* _HID for the toplevel TPCH device, typically \_SB.TPCH */
457 .tpch_device_hid = DPTF_TPCH_DEVICE,
458
459 .tpch_method_names = {
460 .set_fivr_low_clock_method = "RFC0",
461 .set_fivr_high_clock_method = "RFC1",
462 .get_fivr_low_clock_method = "GFC0",
463 .get_fivr_high_clock_method = "GFC1",
464 .get_fivr_ssc_method = "GEMI",
465 .get_fivr_switching_fault_status = "GFFS",
466 .get_fivr_switching_freq_mhz = "GFCS",
467 },
468#endif
469};
470
471static const struct dptf_platform_info *get_dptf_platform_info(void)
472{
473 return &generic_dptf_platform_info;
474}
475
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600476/* Add minimal definitions of DPTF devices into the SSDT */
477static void write_device_definitions(const struct device *dev)
478{
Subrata Banikaf206282022-12-19 21:56:35 +0530479 const struct dptf_platform_info *platform_info = get_dptf_platform_info();
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600480 const struct drivers_intel_dptf_config *config;
481 struct device *parent;
482
483 /* The CPU device gets an _ADR that matches the ACPI PCI address for 00:04.00 */
484 parent = dev && dev->bus ? dev->bus->dev : NULL;
485 if (!parent || parent->path.type != DEVICE_PATH_PCI) {
486 printk(BIOS_ERR, "%s: DPTF objects must live under 00:04.0 PCI device\n",
487 __func__);
488 return;
489 }
490
491 config = config_of(dev);
492 write_tcpu(parent, config);
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -0600493 write_open_dptf_device(dev, platform_info);
Sumeet Pawnikar4dba71f2022-10-19 15:15:54 +0530494 write_fan(config, platform_info);
Sumeet R Pawnikar36571872021-05-11 20:05:20 +0530495 write_oem_variables(config);
Sumeet Pawnikarf96aa7a2021-07-05 21:09:53 +0530496 write_imok();
Tim Wawrzynczak7f7c3882021-04-09 12:15:21 -0600497 write_generic_devices(config, platform_info);
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600498
Sumeet Pawnikara91d9312021-08-30 23:19:38 +0530499 if (CONFIG(DRIVERS_INTEL_DPTF_SUPPORTS_TPCH))
500 write_tpch_methods(platform_info);
501
Varshit B Pandyae7d3a1a2022-03-20 20:39:51 +0530502 if (CONFIG(DRIVERS_INTEL_DPTF_SUPPORTS_TPWR))
Varshit B Pandya282b3b62022-04-18 14:50:30 +0530503 write_tpwr_methods(config, platform_info);
Varshit B Pandyae7d3a1a2022-03-20 20:39:51 +0530504
Varshit B Pandya170a76c2022-04-02 15:11:36 +0530505 if (CONFIG(DRIVERS_INTEL_DPTF_SUPPORTS_TBAT))
506 write_tbat_methods(platform_info);
507
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600508 acpigen_pop_len(); /* DPTF Device (write_open_dptf_device) */
Tim Wawrzynczak103bd5e2020-05-29 13:11:00 -0600509 acpigen_pop_len(); /* Scope */
510}
511
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600512/* Emites policy definitions for each policy type */
513static void write_policies(const struct drivers_intel_dptf_config *config)
514{
515 dptf_write_enabled_policies(config->policies.active, DPTF_MAX_ACTIVE_POLICIES,
516 config->policies.passive, DPTF_MAX_PASSIVE_POLICIES,
517 config->policies.critical, DPTF_MAX_CRITICAL_POLICIES);
518
519 dptf_write_active_policies(config->policies.active,
Sumeet Pawnikar4dba71f2022-10-19 15:15:54 +0530520 DPTF_MAX_ACTIVE_POLICIES);
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600521
522 dptf_write_passive_policies(config->policies.passive,
523 DPTF_MAX_PASSIVE_POLICIES);
524
525 dptf_write_critical_policies(config->policies.critical,
526 DPTF_MAX_CRITICAL_POLICIES);
527}
528
529/* Writes other static tables that are used by DPTF */
530static void write_controls(const struct drivers_intel_dptf_config *config)
531{
532 dptf_write_charger_perf(config->controls.charger_perf, DPTF_MAX_CHARGER_PERF_STATES);
Sumeet Pawnikar4dba71f2022-10-19 15:15:54 +0530533 dptf_write_fan_perf(config->controls.fan_perf, DPTF_MAX_FAN_PERF_STATES);
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600534 dptf_write_power_limits(&config->controls.power_limits);
535}
536
537/* Options to control the behavior of devices */
538static void write_options(const struct drivers_intel_dptf_config *config)
539{
540 enum dptf_participant p;
Sumeet Pawnikar4dba71f2022-10-19 15:15:54 +0530541 int i;
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600542
Sumeet Pawnikar4dba71f2022-10-19 15:15:54 +0530543 /* Fan options */
544 dptf_write_scope(DPTF_FAN);
545 dptf_write_fan_options(config->options.fan.fine_grained_control,
546 config->options.fan.step_size,
547 config->options.fan.low_speed_notify);
548 acpigen_pop_len(); /* Scope */
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600549
550 /* TSR options */
Tim Wawrzynczak40713aa2021-11-24 09:18:44 -0700551 for (p = DPTF_TEMP_SENSOR_0, i = 0; p <= DPTF_TEMP_SENSOR_4; ++p, ++i) {
Tim Wawrzynczakc6a593b2020-07-14 13:19:03 -0600552 if (is_participant_used(config, p) && (config->options.tsr[i].hysteresis ||
553 config->options.tsr[i].desc)) {
554 dptf_write_scope(p);
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600555 dptf_write_tsr_hysteresis(config->options.tsr[i].hysteresis);
556 dptf_write_STR(config->options.tsr[i].desc);
Tim Wawrzynczakc6a593b2020-07-14 13:19:03 -0600557 acpigen_pop_len(); /* Scope */
Tim Wawrzynczak5212ece62020-07-16 11:54:04 -0600558 }
559 }
560}
561
562/* Add custom tables and methods to SSDT */
563static void dptf_fill_ssdt(const struct device *dev)
564{
565 struct drivers_intel_dptf_config *config = config_of(dev);
566
567 write_device_definitions(dev);
568 write_policies(config);
569 write_controls(config);
570 write_options(config);
571
572 printk(BIOS_INFO, DPTF_DEVICE_PATH ": %s at %s\n", dev->chip_ops->name, dev_path(dev));
573}
574
Tim Wawrzynczak103bd5e2020-05-29 13:11:00 -0600575static struct device_operations dptf_ops = {
576 .read_resources = noop_read_resources,
577 .set_resources = noop_set_resources,
578 .acpi_name = dptf_acpi_name,
579 .acpi_fill_ssdt = dptf_fill_ssdt,
Tim Wawrzynczak103bd5e2020-05-29 13:11:00 -0600580};
581
582static void dptf_enable_dev(struct device *dev)
583{
584 dev->ops = &dptf_ops;
585}
586
587struct chip_operations drivers_intel_dptf_ops = {
588 CHIP_NAME("Intel DPTF")
589 .enable_dev = dptf_enable_dev,
590};