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