xref: /linux/include/linux/platform_data/x86/intel_pmc_ipc.h (revision 8499899816fd79aefdfa923ed3fb5a15b0a62757)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Intel Core SoC Power Management Controller Header File
4  *
5  * Copyright (c) 2025, Intel Corporation.
6  * All Rights Reserved.
7  *
8  */
9 #ifndef INTEL_PMC_IPC_H
10 #define INTEL_PMC_IPC_H
11 #include <linux/acpi.h>
12 
13 #define IPC_SOC_REGISTER_ACCESS			0xAA
14 #define IPC_SOC_SUB_CMD_READ			0x00
15 #define IPC_SOC_SUB_CMD_WRITE			0x01
16 #define PMC_IPCS_PARAM_COUNT			7
17 #define VALID_IPC_RESPONSE			5
18 
19 struct pmc_ipc_cmd {
20 	u32 cmd;
21 	u32 sub_cmd;
22 	u32 size;
23 	u32 wbuf[4];
24 };
25 
26 struct pmc_ipc_rbuf {
27 	u32 buf[4];
28 };
29 
30 /**
31  * intel_pmc_ipc() - PMC IPC Mailbox accessor
32  * @ipc_cmd:  Prepared input command to send
33  * @rbuf:     Allocated array for returned IPC data
34  *
35  * Return: 0 on success. Non-zero on mailbox error
36  */
intel_pmc_ipc(struct pmc_ipc_cmd * ipc_cmd,struct pmc_ipc_rbuf * rbuf)37 static inline int intel_pmc_ipc(struct pmc_ipc_cmd *ipc_cmd, struct pmc_ipc_rbuf *rbuf)
38 {
39 #ifdef CONFIG_ACPI
40 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
41 	union acpi_object params[PMC_IPCS_PARAM_COUNT] = {
42 		{.type = ACPI_TYPE_INTEGER,},
43 		{.type = ACPI_TYPE_INTEGER,},
44 		{.type = ACPI_TYPE_INTEGER,},
45 		{.type = ACPI_TYPE_INTEGER,},
46 		{.type = ACPI_TYPE_INTEGER,},
47 		{.type = ACPI_TYPE_INTEGER,},
48 		{.type = ACPI_TYPE_INTEGER,},
49 	};
50 	struct acpi_object_list arg_list = { PMC_IPCS_PARAM_COUNT, params };
51 	union acpi_object *obj;
52 	int status;
53 
54 	if (!ipc_cmd || !rbuf)
55 		return -EINVAL;
56 
57 	/*
58 	 * 0: IPC Command
59 	 * 1: IPC Sub Command
60 	 * 2: Size
61 	 * 3-6: Write Buffer for offset
62 	 */
63 	params[0].integer.value = ipc_cmd->cmd;
64 	params[1].integer.value = ipc_cmd->sub_cmd;
65 	params[2].integer.value = ipc_cmd->size;
66 	params[3].integer.value = ipc_cmd->wbuf[0];
67 	params[4].integer.value = ipc_cmd->wbuf[1];
68 	params[5].integer.value = ipc_cmd->wbuf[2];
69 	params[6].integer.value = ipc_cmd->wbuf[3];
70 
71 	status = acpi_evaluate_object(NULL, "\\IPCS", &arg_list, &buffer);
72 	if (ACPI_FAILURE(status))
73 		return -ENODEV;
74 
75 	obj = buffer.pointer;
76 
77 	if (obj && obj->type == ACPI_TYPE_PACKAGE &&
78 	    obj->package.count == VALID_IPC_RESPONSE) {
79 		const union acpi_object *objs = obj->package.elements;
80 
81 		if ((u8)objs[0].integer.value != 0)
82 			return -EINVAL;
83 
84 		rbuf->buf[0] = objs[1].integer.value;
85 		rbuf->buf[1] = objs[2].integer.value;
86 		rbuf->buf[2] = objs[3].integer.value;
87 		rbuf->buf[3] = objs[4].integer.value;
88 	} else {
89 		return -EINVAL;
90 	}
91 
92 	return 0;
93 #else
94 	return -ENODEV;
95 #endif /* CONFIG_ACPI */
96 }
97 
98 #endif /* INTEL_PMC_IPC_H */
99