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 */ 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