Line data Source code
1 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 1 : struct espi_saf_cfg {
104 0 : uint8_t nflash_devices;
105 0 : struct espi_saf_hw_cfg hwcfg;
106 0 : struct espi_saf_flash_cfg *flash_cfgs;
107 : };
108 :
109 : /**
110 : * @brief eSPI SAF transaction packet format
111 : */
112 1 : struct espi_saf_packet {
113 0 : uint32_t flash_addr;
114 0 : uint8_t *buf;
115 0 : 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 1 : __syscall int espi_saf_config(const struct device *dev,
220 : const struct espi_saf_cfg *cfg);
221 :
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 1 : __syscall int espi_saf_set_protection_regions(
246 : const struct device *dev,
247 : const struct espi_saf_protection *pr);
248 :
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 1 : __syscall int espi_saf_activate(const struct device *dev);
272 :
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 1 : __syscall bool espi_saf_get_channel_status(const struct device *dev);
292 :
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 1 : __syscall int espi_saf_flash_read(const struct device *dev,
316 : struct espi_saf_packet *pckt);
317 :
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 1 : __syscall int espi_saf_flash_write(const struct device *dev,
345 : struct espi_saf_packet *pckt);
346 :
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 1 : __syscall int espi_saf_flash_erase(const struct device *dev,
374 : struct espi_saf_packet *pckt);
375 :
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 1 : __syscall int espi_saf_flash_unsuccess(const struct device *dev,
403 : struct espi_saf_packet *pckt);
404 :
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 : */
488 1 : 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 : */
511 1 : 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 : */
540 1 : 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 <zephyr/syscalls/espi_saf.h>
561 : #endif /* ZEPHYR_INCLUDE_ESPI_SAF_H_ */
|