1 /*
2 * Copyright (c) 2020 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief Public Platform Environment Control Interface driver APIs
10 */
11
12 #ifndef ZEPHYR_INCLUDE_DRIVERS_PECI_H_
13 #define ZEPHYR_INCLUDE_DRIVERS_PECI_H_
14
15 /**
16 * @brief PECI Interface 3.0
17 * @defgroup peci_interface PECI Interface
18 * @ingroup io_interfaces
19 * @{
20 */
21
22 #include <errno.h>
23 #include <zephyr/types.h>
24 #include <stddef.h>
25 #include <device.h>
26 #include <dt-bindings/pwm/pwm.h>
27
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31
32 /**
33 * @brief PECI error codes.
34 */
35 enum peci_error_code {
36 PECI_GENERAL_SENSOR_ERROR = 0x8000,
37 PECI_UNDERFLOW_SENSOR_ERROR = 0x8002,
38 PECI_OVERFLOW_SENSOR_ERROR = 0x8003,
39 };
40
41 /**
42 * @brief PECI commands.
43 */
44 enum peci_command_code {
45 PECI_CMD_PING = 0x00,
46 PECI_CMD_GET_TEMP0 = 0x01,
47 PECI_CMD_GET_TEMP1 = 0x02,
48 PECI_CMD_RD_PCI_CFG0 = 0x61,
49 PECI_CMD_RD_PCI_CFG1 = 0x62,
50 PECI_CMD_WR_PCI_CFG0 = 0x65,
51 PECI_CMD_WR_PCI_CFG1 = 0x66,
52 PECI_CMD_RD_PKG_CFG0 = 0xA1,
53 PECI_CMD_RD_PKG_CFG1 = 0xA,
54 PECI_CMD_WR_PKG_CFG0 = 0xA5,
55 PECI_CMD_WR_PKG_CFG1 = 0xA6,
56 PECI_CMD_RD_IAMSR0 = 0xB1,
57 PECI_CMD_RD_IAMSR1 = 0xB2,
58 PECI_CMD_WR_IAMSR0 = 0xB5,
59 PECI_CMD_WR_IAMSR1 = 0xB6,
60 PECI_CMD_RD_PCI_CFG_LOCAL0 = 0xE1,
61 PECI_CMD_RD_PCI_CFG_LOCAL1 = 0xE2,
62 PECI_CMD_WR_PCI_CFG_LOCAL0 = 0xE5,
63 PECI_CMD_WR_PCI_CFG_LOCAL1 = 0xE6,
64 PECI_CMD_GET_DIB = 0xF7,
65 };
66
67 /** PECI read/write supported responses */
68 #define PECI_CC_RSP_SUCCESS (0x40U)
69 #define PECI_CC_RSP_TIMEOUT (0x80U)
70 #define PECI_CC_OUT_OF_RESOURCES_TIMEOUT (0x81U)
71 #define PECI_CC_RESOURCES_LOWPWR_TIMEOUT (0x82U)
72 #define PECI_CC_ILLEGAL_REQUEST (0x90U)
73
74 /** Ping command format. */
75 #define PECI_PING_WR_LEN (0U)
76 #define PECI_PING_RD_LEN (0U)
77 #define PECI_PING_LEN (3U)
78
79 /** GetDIB command format. */
80 #define PECI_GET_DIB_WR_LEN (1U)
81 #define PECI_GET_DIB_RD_LEN (8U)
82 #define PECI_GET_DIB_CMD_LEN (4U)
83 #define PECI_GET_DIB_DEVINFO (0U)
84 #define PECI_GET_DIB_REVNUM (1U)
85 #define PECI_GET_DIB_DOMAIN_BIT_MASK (0x4U)
86 #define PECI_GET_DIB_MAJOR_REV_MASK 0xF0
87 #define PECI_GET_DIB_MINOR_REV_MASK 0x0F
88
89 /** GetTemp command format. */
90 #define PECI_GET_TEMP_WR_LEN (1U)
91 #define PECI_GET_TEMP_RD_LEN (2U)
92 #define PECI_GET_TEMP_CMD_LEN (4U)
93 #define PECI_GET_TEMP_LSB (0U)
94 #define PECI_GET_TEMP_MSB (1U)
95 #define PECI_GET_TEMP_ERR_MSB (0x80U)
96 #define PECI_GET_TEMP_ERR_LSB_GENERAL (0x0U)
97 #define PECI_GET_TEMP_ERR_LSB_RES (0x1U)
98 #define PECI_GET_TEMP_ERR_LSB_TEMP_LO (0x2U)
99 #define PECI_GET_TEMP_ERR_LSB_TEMP_HI (0x3U)
100
101 /** RdPkgConfig command format. */
102 #define PECI_RD_PKG_WR_LEN (5U)
103 #define PECI_RD_PKG_LEN_BYTE (2U)
104 #define PECI_RD_PKG_LEN_WORD (3U)
105 #define PECI_RD_PKG_LEN_DWORD (5U)
106 #define PECI_RD_PKG_CMD_LEN (8U)
107
108 /** WrPkgConfig command format */
109 #define PECI_WR_PKG_RD_LEN (1U)
110 #define PECI_WR_PKG_LEN_BYTE (7U)
111 #define PECI_WR_PKG_LEN_WORD (8U)
112 #define PECI_WR_PKG_LEN_DWORD (10U)
113 #define PECI_WR_PKG_CMD_LEN (9U)
114
115 /** RdIAMSR command format */
116 #define PECI_RD_IAMSR_WR_LEN (5U)
117 #define PECI_RD_IAMSR_LEN_BYTE (2U)
118 #define PECI_RD_IAMSR_LEN_WORD (3U)
119 #define PECI_RD_IAMSR_LEN_DWORD (5U)
120 #define PECI_RD_IAMSR_LEN_QWORD (9U)
121 #define PECI_RD_IAMSR_CMD_LEN (8U)
122
123 /** WrIAMSR command format */
124 #define PECI_WR_IAMSR_RD_LEN (1U)
125 #define PECI_WR_IAMSR_LEN_BYTE (7U)
126 #define PECI_WR_IAMSR_LEN_WORD (8U)
127 #define PECI_WR_IAMSR_LEN_DWORD (10U)
128 #define PECI_WR_IAMSR_LEN_QWORD (14U)
129 #define PECI_WR_IAMSR_CMD_LEN (9U)
130
131 /** RdPCIConfig command format */
132 #define PECI_RD_PCICFG_WR_LEN (6U)
133 #define PECI_RD_PCICFG_LEN_BYTE (2U)
134 #define PECI_RD_PCICFG_LEN_WORD (3U)
135 #define PECI_RD_PCICFG_LEN_DWORD (5U)
136 #define PECI_RD_PCICFG_CMD_LEN (9U)
137
138 /** WrPCIConfig command format */
139 #define PECI_WR_PCICFG_RD_LEN (1U)
140 #define PECI_WR_PCICFG_LEN_BYTE (8U)
141 #define PECI_WR_PCICFG_LEN_WORD (9U)
142 #define PECI_WR_PCICFG_LEN_DWORD (11U)
143 #define PECI_WR_PCICFG_CMD_LEN (10U)
144
145 /** RdPCIConfigLocal command format */
146 #define PECI_RD_PCICFGL_WR_LEN (5U)
147 #define PECI_RD_PCICFGL_RD_LEN_BYTE (2U)
148 #define PECI_RD_PCICFGL_RD_LEN_WORD (3U)
149 #define PECI_RD_PCICFGL_RD_LEN_DWORD (5U)
150 #define PECI_RD_PCICFGL_CMD_LEN (8U)
151
152 /** WrPCIConfigLocal command format */
153 #define PECI_WR_PCICFGL_RD_LEN (1U)
154 #define PECI_WR_PCICFGL_WR_LEN_BYTE (7U)
155 #define PECI_WR_PCICFGL_WR_LEN_WORD (8U)
156 #define PECI_WR_PCICFGL_WR_LEN_DWORD (10U)
157 #define PECI_WR_PCICFGL_CMD_LEN (9U)
158
159 /**
160 * @brief PECI buffer structure
161 *
162 * @param buf is a valid pointer on a data buffer, or NULL otherwise.
163 * @param len is the length of the data buffer expected to received without
164 * considering the frame check sequence byte.
165 *
166 * Note: Frame check sequence byte is added into rx buffer, need to allocate
167 * an additional byte for this in rx buffer.
168 */
169 struct peci_buf {
170 uint8_t *buf;
171 size_t len;
172 };
173
174 /**
175 * @brief PECI transaction packet format.
176 */
177 struct peci_msg {
178 /** Client address */
179 uint8_t addr;
180 /** Command code */
181 enum peci_command_code cmd_code;
182 /** Pointer to buffer of write data */
183 struct peci_buf tx_buffer;
184 /** Pointer to buffer of read data */
185 struct peci_buf rx_buffer;
186 /** PECI msg flags */
187 uint8_t flags;
188 };
189
190 /**
191 * @cond INTERNAL_HIDDEN
192 *
193 * PECI driver API definition and system call entry points
194 *
195 * (Internal use only.)
196 */
197 typedef int (*peci_config_t)(const struct device *dev, uint32_t bitrate);
198 typedef int (*peci_transfer_t)(const struct device *dev, struct peci_msg *msg);
199 typedef int (*peci_disable_t)(const struct device *dev);
200 typedef int (*peci_enable_t)(const struct device *dev);
201
202 struct peci_driver_api {
203 peci_config_t config;
204 peci_disable_t disable;
205 peci_enable_t enable;
206 peci_transfer_t transfer;
207 };
208
209 /**
210 * @endcond
211 */
212
213 /**
214 * @brief Configures the PECI interface.
215 *
216 * @param dev Pointer to the device structure for the driver instance.
217 * @param bitrate the selected expressed in Kbps.
218 * command or when an event needs to be sent to the client application.
219 *
220 * @retval 0 If successful.
221 * @retval Negative errno code if failure.
222 */
223 __syscall int peci_config(const struct device *dev, uint32_t bitrate);
224
z_impl_peci_config(const struct device * dev,uint32_t bitrate)225 static inline int z_impl_peci_config(const struct device *dev,
226 uint32_t bitrate)
227 {
228 struct peci_driver_api *api;
229
230 api = (struct peci_driver_api *)dev->api;
231 return api->config(dev, bitrate);
232 }
233
234 /**
235 * @brief Enable PECI interface.
236 *
237 * @param dev Pointer to the device structure for the driver instance.
238 *
239 * @retval 0 If successful.
240 * @retval Negative errno code if failure.
241 */
242 __syscall int peci_enable(const struct device *dev);
243
z_impl_peci_enable(const struct device * dev)244 static inline int z_impl_peci_enable(const struct device *dev)
245 {
246 struct peci_driver_api *api;
247
248 api = (struct peci_driver_api *)dev->api;
249 return api->enable(dev);
250 }
251
252 /**
253 * @brief Disable PECI interface.
254 *
255 * @param dev Pointer to the device structure for the driver instance.
256 *
257 * @retval 0 If successful.
258 * @retval Negative errno code if failure.
259 */
260 __syscall int peci_disable(const struct device *dev);
261
z_impl_peci_disable(const struct device * dev)262 static inline int z_impl_peci_disable(const struct device *dev)
263 {
264 struct peci_driver_api *api;
265
266 api = (struct peci_driver_api *)dev->api;
267 return api->disable(dev);
268 }
269
270 /**
271 * @brief Performs a PECI transaction.
272 *
273 * @param dev Pointer to the device structure for the driver instance.
274 * @param msg Structure representing a PECI transaction.
275 *
276 * @retval 0 If successful.
277 * @retval Negative errno code if failure.
278 */
279
280 __syscall int peci_transfer(const struct device *dev, struct peci_msg *msg);
281
z_impl_peci_transfer(const struct device * dev,struct peci_msg * msg)282 static inline int z_impl_peci_transfer(const struct device *dev,
283 struct peci_msg *msg)
284 {
285 struct peci_driver_api *api;
286
287 api = (struct peci_driver_api *)dev->api;
288 return api->transfer(dev, msg);
289 }
290
291
292 #ifdef __cplusplus
293 }
294 #endif
295
296 /**
297 * @}
298 */
299
300 #include <syscalls/peci.h>
301
302 #endif /* ZEPHYR_INCLUDE_DRIVERS_PECI_H_ */
303