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 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 40 union acpi_object params[PMC_IPCS_PARAM_COUNT] = { 41 {.type = ACPI_TYPE_INTEGER,}, 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 }; 49 struct acpi_object_list arg_list = { PMC_IPCS_PARAM_COUNT, params }; 50 union acpi_object *obj; 51 int status; 52 53 if (!ipc_cmd || !rbuf) 54 return -EINVAL; 55 56 /* 57 * 0: IPC Command 58 * 1: IPC Sub Command 59 * 2: Size 60 * 3-6: Write Buffer for offset 61 */ 62 params[0].integer.value = ipc_cmd->cmd; 63 params[1].integer.value = ipc_cmd->sub_cmd; 64 params[2].integer.value = ipc_cmd->size; 65 params[3].integer.value = ipc_cmd->wbuf[0]; 66 params[4].integer.value = ipc_cmd->wbuf[1]; 67 params[5].integer.value = ipc_cmd->wbuf[2]; 68 params[6].integer.value = ipc_cmd->wbuf[3]; 69 70 status = acpi_evaluate_object(NULL, "\\IPCS", &arg_list, &buffer); 71 if (ACPI_FAILURE(status)) 72 return -ENODEV; 73 74 obj = buffer.pointer; 75 76 if (obj && obj->type == ACPI_TYPE_PACKAGE && 77 obj->package.count == VALID_IPC_RESPONSE) { 78 const union acpi_object *objs = obj->package.elements; 79 80 if ((u8)objs[0].integer.value != 0) 81 return -EINVAL; 82 83 rbuf->buf[0] = objs[1].integer.value; 84 rbuf->buf[1] = objs[2].integer.value; 85 rbuf->buf[2] = objs[3].integer.value; 86 rbuf->buf[3] = objs[4].integer.value; 87 } else { 88 return -EINVAL; 89 } 90 91 return 0; 92 } 93 94 #endif /* INTEL_PMC_IPC_H */ 95