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