1 /*
2  * Copyright (c) 2019 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief Public APIs for eSPI driver
10  */
11 
12 #ifndef ZEPHYR_INCLUDE_ESPI_SAF_H_
13 #define ZEPHYR_INCLUDE_ESPI_SAF_H_
14 
15 #include <zephyr/sys/__assert.h>
16 #include <zephyr/types.h>
17 #include <zephyr/device.h>
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 /**
24  * @brief eSPI SAF Driver APIs
25  * @defgroup espi_interface ESPI Driver APIs
26  * @ingroup io_interfaces
27  * @{
28  */
29 
30 
31 /**
32  * @code
33  *+----------------------------------------------------------------------+
34  *|                                                                      |
35  *|  eSPI host                           +-------------+                 |
36  *|                      +-----------+   |    Power    |   +----------+  |
37  *|                      |Out of band|   |  management |   |   GPIO   |  |
38  *|   ------------       |processor  |   |  controller |   |  sources |  |
39  *|                      +-----------+   +-------------+   +----------+  |
40  *|                            |                |               |        |
41  *|   ------------             |                |               |        |
42  *|                            +--------+       +---------------+        |
43  *|                                     |               |                |
44  *|            -----+   +--------+   +----------+  +----v-----+          |
45  *|                 |   |  LPC   |   | Tunneled |  | Tunneled |          |
46  *|                 |   | bridge |   |  SMBus   |  |   GPIO   |          |
47  *|                 |   +--------+   +----------+  +----------+          |
48  *|                 |        |             |             |               |
49  *|                 |        ------+       |             |               |
50  *|                 |              |       |             |               |
51  *|          +------v-----+    +---v-------v-------------v----+          |
52  *|          | eSPI Flash |    |    eSPI protocol block       |          |
53  *|          |   access   +--->+                              |          |
54  *|          +------------+    +------------------------------+          |
55  *|                                    |                                 |
56  *|       -----------                  |                                 |
57  *|                                    v                                 |
58  *|               XXXXXXXXXXXXXXXXXXXXXXX                                |
59  *|                XXXXXXXXXXXXXXXXXXXXX                                 |
60  *|                 XXXXXXXXXXXXXXXXXXX                                  |
61  *+----------------------------------------------------------------------+
62  *                          |
63  *                 +-----------------+
64  *  ---------      |  |   |   |   |  |
65  *                 |  |   |   |   |  |
66  *  ---------      |  +   +   +   +  |    eSPI bus
67  *                 | CH0 CH1 CH2 CH3 |    (logical channels)
68  *                 |  +   +   +   +  |
69  *                 |  |   |   |   |  |
70  *                 +-----------------+
71  *                          |
72  *+-----------------------------------------------------------------------+
73  *|  eSPI slave                                                           |
74  *|                                                                       |
75  *|       CH0         |     CH1      |      CH2      |    CH3             |
76  *|   eSPI endpoint   |    VWIRE     |      OOB      |   Flash            |
77  *+-----------------------------------------------------------------------+
78  *   |                                 |
79  *   v                                 |
80  * +---------+                         |
81  * |  Flash  |  Slave Attached Flash   |
82  * +---------+                         |
83  *                                     |
84  * @endcode
85  */
86 
87 
88 /**
89  * @cond INTERNAL_HIDDEN
90  *
91  */
92 
93 
94 /** @endcond */
95 
96 struct espi_saf_hw_cfg;
97 struct espi_saf_flash_cfg;
98 struct espi_saf_pr;
99 
100 /**
101  * @brief eSPI SAF configuration parameters
102  */
103 struct espi_saf_cfg {
104 	uint8_t nflash_devices;
105 	struct espi_saf_hw_cfg hwcfg;
106 	struct espi_saf_flash_cfg *flash_cfgs;
107 };
108 
109 /**
110  * @brief eSPI SAF transaction packet format
111  */
112 struct espi_saf_packet {
113 	uint32_t flash_addr;
114 	uint8_t *buf;
115 	uint32_t len;
116 };
117 
118 /*
119  *defined in espi.h
120  * struct espi_callback
121  * typedef void (*espi_callback_handler_t)()
122  */
123 
124 /**
125  * @cond INTERNAL_HIDDEN
126  *
127  * eSPI driver API definition and system call entry points
128  *
129  * (Internal use only.)
130  */
131 typedef int (*espi_saf_api_config)(const struct device *dev,
132 				   const struct espi_saf_cfg *cfg);
133 
134 typedef int (*espi_saf_api_set_protection_regions)(
135 				const struct device *dev,
136 				const struct espi_saf_protection *pr);
137 
138 typedef int (*espi_saf_api_activate)(const struct device *dev);
139 
140 typedef bool (*espi_saf_api_get_channel_status)(const struct device *dev);
141 
142 typedef int (*espi_saf_api_flash_read)(const struct device *dev,
143 				       struct espi_saf_packet *pckt);
144 typedef int (*espi_saf_api_flash_write)(const struct device *dev,
145 					struct espi_saf_packet *pckt);
146 typedef int (*espi_saf_api_flash_erase)(const struct device *dev,
147 					struct espi_saf_packet *pckt);
148 typedef int (*espi_saf_api_flash_unsuccess)(const struct device *dev,
149 					struct espi_saf_packet *pckt);
150 /* Callbacks and traffic intercept */
151 typedef int (*espi_saf_api_manage_callback)(const struct device *dev,
152 					    struct espi_callback *callback,
153 					    bool set);
154 
155 __subsystem struct espi_saf_driver_api {
156 	espi_saf_api_config config;
157 	espi_saf_api_set_protection_regions set_protection_regions;
158 	espi_saf_api_activate activate;
159 	espi_saf_api_get_channel_status get_channel_status;
160 	espi_saf_api_flash_read flash_read;
161 	espi_saf_api_flash_write flash_write;
162 	espi_saf_api_flash_erase flash_erase;
163 	espi_saf_api_flash_unsuccess flash_unsuccess;
164 	espi_saf_api_manage_callback manage_callback;
165 };
166 
167 /**
168  * @endcond
169  */
170 
171 /**
172  * @brief Configure operation of a eSPI controller.
173  *
174  * This routine provides a generic interface to override eSPI controller
175  * capabilities.
176  *
177  * If this eSPI controller is acting as slave, the values set here
178  * will be discovered as part through the GET_CONFIGURATION command
179  * issued by the eSPI master during initialization.
180  *
181  * If this eSPI controller is acting as master, the values set here
182  * will be used by eSPI master to determine minimum common capabilities with
183  * eSPI slave then send via SET_CONFIGURATION command.
184  *
185  * @code
186  * +--------+   +---------+     +------+          +---------+   +---------+
187  * |  eSPI  |   |  eSPI   |     | eSPI |          |  eSPI   |   |  eSPI   |
188  * |  slave |   | driver  |     |  bus |          |  driver |   |  host   |
189  * +--------+   +---------+     +------+          +---------+   +---------+
190  *     |              |            |                   |             |
191  *     | espi_config  | Set eSPI   |       Set eSPI    | espi_config |
192  *     +--------------+ ctrl regs  |       cap ctrl reg| +-----------+
193  *     |              +-------+    |          +--------+             |
194  *     |              |<------+    |          +------->|             |
195  *     |              |            |                   |             |
196  *     |              |            |                   |             |
197  *     |              |            | GET_CONFIGURATION |             |
198  *     |              |            +<------------------+             |
199  *     |              |<-----------|                   |             |
200  *     |              | eSPI caps  |                   |             |
201  *     |              |----------->+    response       |             |
202  *     |              |            |------------------>+             |
203  *     |              |            |                   |             |
204  *     |              |            | SET_CONFIGURATION |             |
205  *     |              |            +<------------------+             |
206  *     |              |            |  accept           |             |
207  *     |              |            +------------------>+             |
208  *     +              +            +                   +             +
209  * @endcode
210  *
211  * @param dev Pointer to the device structure for the driver instance.
212  * @param cfg the device runtime configuration for the eSPI controller.
213  *
214  * @retval 0 If successful.
215  * @retval -EIO General input / output error, failed to configure device.
216  * @retval -EINVAL invalid capabilities, failed to configure device.
217  * @retval -ENOTSUP capability not supported by eSPI slave.
218  */
219 __syscall int espi_saf_config(const struct device *dev,
220 			      const struct espi_saf_cfg *cfg);
221 
z_impl_espi_saf_config(const struct device * dev,const struct espi_saf_cfg * cfg)222 static inline int z_impl_espi_saf_config(const struct device *dev,
223 					 const struct espi_saf_cfg *cfg)
224 {
225 	const struct espi_saf_driver_api *api =
226 		(const struct espi_saf_driver_api *)dev->api;
227 
228 	return api->config(dev, cfg);
229 }
230 
231 /**
232  * @brief Set one or more SAF protection regions
233  *
234  * This routine provides an interface to override the default flash
235  * protection regions of the SAF controller.
236  *
237  * @param dev Pointer to the device structure for the driver instance.
238  * @param pr Pointer to the SAF protection region structure.
239  *
240  * @retval 0 If successful.
241  * @retval -EIO General input / output error, failed to configure device.
242  * @retval -EINVAL invalid capabilities, failed to configure device.
243  * @retval -ENOTSUP capability not supported by eSPI slave.
244  */
245 __syscall int espi_saf_set_protection_regions(
246 				const struct device *dev,
247 				const struct espi_saf_protection *pr);
248 
z_impl_espi_saf_set_protection_regions(const struct device * dev,const struct espi_saf_protection * pr)249 static inline int z_impl_espi_saf_set_protection_regions(
250 					const struct device *dev,
251 					const struct espi_saf_protection *pr)
252 {
253 	const struct espi_saf_driver_api *api =
254 		(const struct espi_saf_driver_api *)dev->api;
255 
256 	return api->set_protection_regions(dev, pr);
257 }
258 
259 /**
260  * @brief Activate SAF block
261  *
262  * This routine activates the SAF block and should only be
263  * called after SAF has been configured and the eSPI Master
264  * has enabled the Flash Channel.
265  *
266  * @param dev Pointer to the device structure for the driver instance.
267  *
268  * @retval 0 If successful
269  * @retval -EINVAL if failed to activate SAF.
270  */
271 __syscall int espi_saf_activate(const struct device *dev);
272 
z_impl_espi_saf_activate(const struct device * dev)273 static inline int z_impl_espi_saf_activate(const struct device *dev)
274 {
275 	const struct espi_saf_driver_api *api =
276 		(const struct espi_saf_driver_api *)dev->api;
277 
278 	return api->activate(dev);
279 }
280 
281 /**
282  * @brief Query to see if SAF is ready
283  *
284  * This routine allows to check if SAF is ready before use.
285  *
286  * @param dev Pointer to the device structure for the driver instance.
287  *
288  * @retval true If eSPI SAF is ready.
289  * @retval false otherwise.
290  */
291 __syscall bool espi_saf_get_channel_status(const struct device *dev);
292 
z_impl_espi_saf_get_channel_status(const struct device * dev)293 static inline bool z_impl_espi_saf_get_channel_status(
294 					const struct device *dev)
295 {
296 	const struct espi_saf_driver_api *api =
297 		(const struct espi_saf_driver_api *)dev->api;
298 
299 	return api->get_channel_status(dev);
300 }
301 
302 /**
303  * @brief Sends a read request packet for slave attached flash.
304  *
305  * This routines provides an interface to send a request to read the flash
306  * component shared between the eSPI master and eSPI slaves.
307  *
308  * @param dev Pointer to the device structure for the driver instance.
309  * @param pckt Address of the representation of read flash transaction.
310  *
311  * @retval -ENOTSUP eSPI flash logical channel transactions not supported.
312  * @retval -EBUSY eSPI flash channel is not ready or disabled by master.
313  * @retval -EIO General input / output error, failed request to master.
314  */
315 __syscall int espi_saf_flash_read(const struct device *dev,
316 				  struct espi_saf_packet *pckt);
317 
z_impl_espi_saf_flash_read(const struct device * dev,struct espi_saf_packet * pckt)318 static inline int z_impl_espi_saf_flash_read(const struct device *dev,
319 					     struct espi_saf_packet *pckt)
320 {
321 	const struct espi_saf_driver_api *api =
322 		(const struct espi_saf_driver_api *)dev->api;
323 
324 	if (!api->flash_read) {
325 		return -ENOTSUP;
326 	}
327 
328 	return api->flash_read(dev, pckt);
329 }
330 
331 /**
332  * @brief Sends a write request packet for slave attached flash.
333  *
334  * This routines provides an interface to send a request to write to the flash
335  * components shared between the eSPI master and eSPI slaves.
336  *
337  * @param dev Pointer to the device structure for the driver instance.
338  * @param pckt Address of the representation of write flash transaction.
339  *
340  * @retval -ENOTSUP eSPI flash logical channel transactions not supported.
341  * @retval -EBUSY eSPI flash channel is not ready or disabled by master.
342  * @retval -EIO General input / output error, failed request to master.
343  */
344 __syscall int espi_saf_flash_write(const struct device *dev,
345 				   struct espi_saf_packet *pckt);
346 
z_impl_espi_saf_flash_write(const struct device * dev,struct espi_saf_packet * pckt)347 static inline int z_impl_espi_saf_flash_write(const struct device *dev,
348 					      struct espi_saf_packet *pckt)
349 {
350 	const struct espi_saf_driver_api *api =
351 		(const struct espi_saf_driver_api *)dev->api;
352 
353 	if (!api->flash_write) {
354 		return -ENOTSUP;
355 	}
356 
357 	return api->flash_write(dev, pckt);
358 }
359 
360 /**
361  * @brief Sends a write request packet for slave attached flash.
362  *
363  * This routines provides an interface to send a request to write to the flash
364  * components shared between the eSPI master and eSPI slaves.
365  *
366  * @param dev Pointer to the device structure for the driver instance.
367  * @param pckt Address of the representation of erase flash transaction.
368  *
369  * @retval -ENOTSUP eSPI flash logical channel transactions not supported.
370  * @retval -EBUSY eSPI flash channel is not ready or disabled by master.
371  * @retval -EIO General input / output error, failed request to master.
372  */
373 __syscall int espi_saf_flash_erase(const struct device *dev,
374 				   struct espi_saf_packet *pckt);
375 
z_impl_espi_saf_flash_erase(const struct device * dev,struct espi_saf_packet * pckt)376 static inline int z_impl_espi_saf_flash_erase(const struct device *dev,
377 					      struct espi_saf_packet *pckt)
378 {
379 	const struct espi_saf_driver_api *api =
380 		(const struct espi_saf_driver_api *)dev->api;
381 
382 	if (!api->flash_erase) {
383 		return -ENOTSUP;
384 	}
385 
386 	return api->flash_erase(dev, pckt);
387 }
388 
389 /**
390  * @brief Response unsuccessful completion for slave attached flash.
391  *
392  * This routines provides an interface to response that transaction is
393  * invalid and return unsuccessful completion from target to controller.
394  *
395  * @param dev Pointer to the device structure for the driver instance.
396  * @param pckt Address of the representation of flash transaction.
397  *
398  * @retval -ENOTSUP eSPI flash logical channel transactions not supported.
399  * @retval -EBUSY eSPI flash channel is not ready or disabled by master.
400  * @retval -EIO General input / output error, failed request to master.
401  */
402 __syscall int espi_saf_flash_unsuccess(const struct device *dev,
403 				       struct espi_saf_packet *pckt);
404 
z_impl_espi_saf_flash_unsuccess(const struct device * dev,struct espi_saf_packet * pckt)405 static inline int z_impl_espi_saf_flash_unsuccess(const struct device *dev,
406 						  struct espi_saf_packet *pckt)
407 {
408 	const struct espi_saf_driver_api *api =
409 		(const struct espi_saf_driver_api *)dev->api;
410 
411 	if (!api->flash_unsuccess) {
412 		return -ENOTSUP;
413 	}
414 
415 	return api->flash_unsuccess(dev, pckt);
416 }
417 
418 /**
419  * Callback model
420  *
421  * @code
422  *+-------+                  +-------------+   +------+     +---------+
423  *|  App  |                  | eSPI driver |   |  HW  |     |eSPI Host|
424  *+---+---+                  +-------+-----+   +---+--+     +----+----+
425  *    |                              |             |             |
426  *    |   espi_init_callback         |             |             |
427  *    +----------------------------> |             |             |
428  *    |   espi_add_callback          |             |
429  *    +----------------------------->+             |
430  *    |                              |             |  eSPI reset |  eSPI host
431  *    |                              |    IRQ      +<------------+  resets the
432  *    |                              | <-----------+             |  bus
433  *    |                              |             |             |
434  *    |                              | Processed   |             |
435  *    |                              | within the  |             |
436  *    |                              | driver      |             |
437  *    |                              |             |             |
438 
439  *    |                              |             |  VW CH ready|  eSPI host
440  *    |                              |    IRQ      +<------------+  enables VW
441  *    |                              | <-----------+             |  channel
442  *    |                              |             |             |
443  *    |                              | Processed   |             |
444  *    |                              | within the  |             |
445  *    |                              | driver      |             |
446  *    |                              |             |             |
447  *    |                              |             | Memory I/O  |  Peripheral
448  *    |                              |             <-------------+  event
449  *    |                              +<------------+             |
450  *    +<-----------------------------+ callback    |             |
451  *    | Report peripheral event      |             |             |
452  *    | and data for the event       |             |             |
453  *    |                              |             |             |
454  *    |                              |             | SLP_S5      |  eSPI host
455  *    |                              |             <-------------+  send VWire
456  *    |                              +<------------+             |
457  *    +<-----------------------------+ callback    |             |
458  *    | App enables/configures       |             |             |
459  *    | discrete regulator           |             |             |
460  *    |                              |             |             |
461  *    |   espi_send_vwire_signal     |             |             |
462  *    +------------------------------>------------>|------------>|
463  *    |                              |             |             |
464  *    |                              |             | HOST_RST    |  eSPI host
465  *    |                              |             <-------------+  send VWire
466  *    |                              +<------------+             |
467  *    +<-----------------------------+ callback    |             |
468  *    | App reset host-related       |             |             |
469  *    | data structures              |             |             |
470  *    |                              |             |             |
471  *    |                              |             |   C10       |  eSPI host
472  *    |                              |             +<------------+  send VWire
473  *    |                              <-------------+             |
474  *    <------------------------------+             |             |
475  *    | App executes                 |             |             |
476  *    + power mgmt policy            |             |             |
477  * @endcode
478  */
479 
480 /**
481  * @brief Helper to initialize a struct espi_callback properly.
482  *
483  * @param callback A valid Application's callback structure pointer.
484  * @param handler A valid handler function pointer.
485  * @param evt_type indicates the eSPI event relevant for the handler.
486  * for VWIRE_RECEIVED event the data will indicate the new level asserted
487  */
espi_saf_init_callback(struct espi_callback * callback,espi_callback_handler_t handler,enum espi_bus_event evt_type)488 static inline void espi_saf_init_callback(struct espi_callback *callback,
489 					  espi_callback_handler_t handler,
490 					  enum espi_bus_event evt_type)
491 {
492 	__ASSERT(callback, "Callback pointer should not be NULL");
493 	__ASSERT(handler, "Callback handler pointer should not be NULL");
494 
495 	callback->handler = handler;
496 	callback->evt_type = evt_type;
497 }
498 
499 /**
500  * @brief Add an application callback.
501  * @param dev Pointer to the device structure for the driver instance.
502  * @param callback A valid Application's callback structure pointer.
503  * @return 0 if successful, negative errno code on failure.
504  *
505  * @note Callbacks may be added to the device from within a callback
506  * handler invocation, but whether they are invoked for the current
507  * eSPI event is not specified.
508  *
509  * Note: enables to add as many callback as needed on the same device.
510  */
espi_saf_add_callback(const struct device * dev,struct espi_callback * callback)511 static inline int espi_saf_add_callback(const struct device *dev,
512 					struct espi_callback *callback)
513 {
514 	const struct espi_saf_driver_api *api =
515 		(const struct espi_saf_driver_api *)dev->api;
516 
517 	if (!api->manage_callback) {
518 		return -ENOTSUP;
519 	}
520 
521 	return api->manage_callback(dev, callback, true);
522 }
523 
524 /**
525  * @brief Remove an application callback.
526  * @param dev Pointer to the device structure for the driver instance.
527  * @param callback A valid application's callback structure pointer.
528  * @return 0 if successful, negative errno code on failure.
529  *
530  * @warning It is explicitly permitted, within a callback handler, to
531  * remove the registration for the callback that is running, i.e. @p
532  * callback.  Attempts to remove other registrations on the same
533  * device may result in undefined behavior, including failure to
534  * invoke callbacks that remain registered and unintended invocation
535  * of removed callbacks.
536  *
537  * Note: enables to remove as many callbacks as added through
538  *       espi_add_callback().
539  */
espi_saf_remove_callback(const struct device * dev,struct espi_callback * callback)540 static inline int espi_saf_remove_callback(const struct device *dev,
541 					   struct espi_callback *callback)
542 {
543 	const struct espi_saf_driver_api *api =
544 		(const struct espi_saf_driver_api *)dev->api;
545 
546 	if (!api->manage_callback) {
547 		return -ENOTSUP;
548 	}
549 
550 	return api->manage_callback(dev, callback, false);
551 }
552 
553 #ifdef __cplusplus
554 }
555 #endif
556 
557 /**
558  * @}
559  */
560 #include <syscalls/espi_saf.h>
561 #endif /* ZEPHYR_INCLUDE_ESPI_SAF_H_ */
562