xref: /aosp_15_r20/external/coreboot/src/soc/intel/common/block/include/intelblocks/pmc_ipc.h (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #ifndef SOC_INTEL_COMMON_BLOCK_PMC_IPC_H
4 #define SOC_INTEL_COMMON_BLOCK_PMC_IPC_H
5 
6 #include <types.h>
7 
8 #define PMC_IPC_BUF_COUNT		4
9 
10 #define PMC_IPC_CMD_COMMAND_SHIFT	0
11 #define PMC_IPC_CMD_COMMAND_MASK	0xff
12 #define PMC_IPC_CMD_MSI_SHIFT		8
13 #define PMC_IPC_CMD_MSI_MASK		0x01
14 #define PMC_IPC_CMD_SUB_COMMAND_SHIFT	12
15 #define PMC_IPC_CMD_SUB_COMMAND_MASK	0x0f
16 #define PMC_IPC_CMD_SIZE_SHIFT		16
17 #define PMC_IPC_CMD_SIZE_MASK		0xff
18 
19 /* IPC command to control FIVR Configuration */
20 #define PMC_IPC_CMD_COMMAND_FIVR	0xA3
21 /* IPC subcommand to read FIVR Register */
22 #define PMC_IPC_CMD_CMD_ID_FIVR_READ	0x00
23 /* IPC subcommand to write FIVR Register */
24 #define PMC_IPC_CMD_CMD_ID_FIVR_WRITE	0x01
25 /* IPC subcommand to control RFI Control 0 register logic write */
26 #define PMC_IPC_SUBCMD_RFI_CTRL0_LOGIC	0
27 /* IPC subcommand to control RFI Control 4 register logic write */
28 #define PMC_IPC_SUBCMD_RFI_CTRL4_LOGIC	1
29 /* IPC subcommand to control EMI Control 0 register logic write */
30 #define PMC_IPC_SUBCMD_EMI_CTRL0_LOGIC	2
31 /* IPC subcommand to control FFFC_FAULT_STATUS register logic read */
32 #define PMC_IPC_SUBCMD_FFFC_FAULT_STATUS	3
33 /* IPC subcommand to control FFFC_RFI_STATUS register logic read */
34 #define PMC_IPC_SUBCMD_FFFC_RFI_STATUS	4
35 
36 #define PMC_IPC_CMD_FIELD(name, val) \
37 	((((val) & PMC_IPC_CMD_##name##_MASK) << PMC_IPC_CMD_##name##_SHIFT))
38 
39 #define PMC_IPC_CMD_NO_MSI		0
40 
41 /* IPC command for reading PMC registers */
42 #define PMC_IPC_CMD_RD_PMC_REG		0xA0
43 #define PMC_IPC_CMD_SUBCMD_RD_PMC_REG	0x02
44 
45 /* IPC command to enable/disable PCIe SRCCLK */
46 #define PMC_IPC_CMD_ID_SET_PCIE_CLOCK	0xAC
47 
48 /* IPC return values */
49 #define PMC_IPC_SUCCESS			0
50 #define PMC_IPC_ERROR			1
51 #define PMC_IPC_TIMEOUT			2
52 
53 /*
54  * Create the IPC CMD to send to PMC
55  */
pmc_make_ipc_cmd(uint32_t cmd,uint32_t subcmd,uint32_t size)56 static inline uint32_t pmc_make_ipc_cmd(uint32_t cmd, uint32_t subcmd,
57 					uint32_t size)
58 {
59 	return PMC_IPC_CMD_FIELD(COMMAND, cmd) |
60 		PMC_IPC_CMD_FIELD(SUB_COMMAND, subcmd) |
61 		PMC_IPC_CMD_FIELD(MSI, PMC_IPC_CMD_NO_MSI) |
62 		PMC_IPC_CMD_FIELD(SIZE, size);
63 }
64 
65 /*
66  * Buffer for holding write and read buffers of IPC commands
67  */
68 struct pmc_ipc_buffer {
69 	uint32_t buf[PMC_IPC_BUF_COUNT];
70 };
71 
72 /*
73  * Send PMC IPC command
74  */
75 enum cb_err pmc_send_ipc_cmd(uint32_t cmd, const struct pmc_ipc_buffer *wbuf,
76 			     struct pmc_ipc_buffer *rbuf);
77 
78 /*
79  * Provides an ACPI method in the SSDT to read/write to the IPC mailbox which is
80  * defined in the PMC device MMIO address space.
81  *
82  * One possible use of this method is to enable/disable the clock for a
83  * particular PCIe root port at runtime when the device is in D3 state.
84  *
85  * The ACPI method takes 7 arguments:
86  *  IPCW (COMMAND, SUB_ID, SIZE, DATA0, DATA1, DATA2, DATA3)
87  *
88  * And will return a package with 5 elements:
89  *  0    = Return code
90  *         PMC_IPC_SUCCESS
91  *         PMC_IPC_ERROR
92  *         PMC_IPC_TIMEOUT
93  *  1..4 = Data read from IPC if return code is PMC_IPC_SUCCESS
94  */
95 void pmc_ipc_acpi_fill_ssdt(void);
96 
97 /*
98  * Call the ACPI method to write to the IPC mailbox and enable/disable the
99  * specified clock pin connected to the specified PCIe root port.
100  */
101 void pmc_ipc_acpi_set_pci_clock(unsigned int pcie_rp, unsigned int clock_pin, bool enable);
102 
103 #endif /* SOC_INTEL_COMMON_BLOCK_PMC_IPC_H */
104