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