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