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