| /* |
| * Copyright (c) 2019 Intel Corporation. |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| /** |
| * @file |
| * @brief Public APIs for eSPI driver |
| */ |
| |
| #ifndef ZEPHYR_INCLUDE_ESPI_SAF_H_ |
| #define ZEPHYR_INCLUDE_ESPI_SAF_H_ |
| |
| #include <sys/__assert.h> |
| #include <zephyr/types.h> |
| #include <device.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /** |
| * @brief eSPI SAF Driver APIs |
| * @defgroup espi_interface ESPI Driver APIs |
| * @ingroup io_interfaces |
| * @{ |
| */ |
| |
| |
| /** |
| *+----------------------------------------------------------------------+ |
| *| | |
| *| eSPI host +-------------+ | |
| *| +-----------+ | Power | +----------+ | |
| *| |Out of band| | management | | GPIO | | |
| *| ------------ |processor | | controller | | sources | | |
| *| +-----------+ +-------------+ +----------+ | |
| *| | | | | |
| *| ------------ | | | | |
| *| +--------+ +---------------+ | |
| *| | | | |
| *| -----+ +--------+ +----------+ +----v-----+ | |
| *| | | LPC | | Tunneled | | Tunneled | | |
| *| | | bridge | | SMBus | | GPIO | | |
| *| | +--------+ +----------+ +----------+ | |
| *| | | | | | |
| *| | ------+ | | | |
| *| | | | | | |
| *| +------v-----+ +---v-------v-------------v----+ | |
| *| | eSPI Flash | | eSPI protocol block | | |
| *| | access +--->+ | | |
| *| +------------+ +------------------------------+ | |
| *| | | |
| *| ----------- | | |
| *| v | |
| *| XXXXXXXXXXXXXXXXXXXXXXX | |
| *| XXXXXXXXXXXXXXXXXXXXX | |
| *| XXXXXXXXXXXXXXXXXXX | |
| *+----------------------------------------------------------------------+ |
| * | |
| * +-----------------+ |
| * --------- | | | | | | |
| * | | | | | | |
| * --------- | + + + + | eSPI bus |
| * | CH0 CH1 CH2 CH3 | (logical channels) |
| * | + + + + | |
| * | | | | | | |
| * +-----------------+ |
| * | |
| *+-----------------------------------------------------------------------+ |
| *| eSPI slave | |
| *| | |
| *| CH0 | CH1 | CH2 | CH3 | |
| *| eSPI endpoint | VWIRE | OOB | Flash | |
| *+-----------------------------------------------------------------------+ |
| * | | |
| * v | |
| * +---------+ | |
| * | Flash | Slave Attached Flash | |
| * +---------+ | |
| * | |
| */ |
| |
| |
| /** |
| * @cond INTERNAL_HIDDEN |
| * |
| */ |
| |
| |
| /** @endcond */ |
| |
| struct espi_saf_hw_cfg; |
| struct espi_saf_flash_cfg; |
| struct espi_saf_pr; |
| |
| /** |
| * @brief eSPI SAF configuration parameters |
| */ |
| struct espi_saf_cfg { |
| uint8_t nflash_devices; |
| struct espi_saf_hw_cfg hwcfg; |
| struct espi_saf_flash_cfg *flash_cfgs; |
| }; |
| |
| /** |
| * @brief eSPI SAF transaction packet format |
| */ |
| struct espi_saf_packet { |
| uint32_t flash_addr; |
| uint8_t *buf; |
| uint32_t len; |
| }; |
| |
| /* |
| *defined in espi.h |
| * struct espi_callback |
| * typedef void (*espi_callback_handler_t)() |
| */ |
| |
| /** |
| * @cond INTERNAL_HIDDEN |
| * |
| * eSPI driver API definition and system call entry points |
| * |
| * (Internal use only.) |
| */ |
| typedef int (*espi_saf_api_config)(const struct device *dev, |
| const struct espi_saf_cfg *cfg); |
| |
| typedef int (*espi_saf_api_set_protection_regions)( |
| const struct device *dev, |
| const struct espi_saf_protection *pr); |
| |
| typedef int (*espi_saf_api_activate)(const struct device *dev); |
| |
| typedef bool (*espi_saf_api_get_channel_status)(const struct device *dev); |
| |
| typedef int (*espi_saf_api_flash_read)(const struct device *dev, |
| struct espi_saf_packet *pckt); |
| typedef int (*espi_saf_api_flash_write)(const struct device *dev, |
| struct espi_saf_packet *pckt); |
| typedef int (*espi_saf_api_flash_erase)(const struct device *dev, |
| struct espi_saf_packet *pckt); |
| /* Callbacks and traffic intercept */ |
| typedef int (*espi_saf_api_manage_callback)(const struct device *dev, |
| struct espi_callback *callback, |
| bool set); |
| |
| __subsystem struct espi_saf_driver_api { |
| espi_saf_api_config config; |
| espi_saf_api_set_protection_regions set_protection_regions; |
| espi_saf_api_activate activate; |
| espi_saf_api_get_channel_status get_channel_status; |
| espi_saf_api_flash_read flash_read; |
| espi_saf_api_flash_write flash_write; |
| espi_saf_api_flash_erase flash_erase; |
| espi_saf_api_manage_callback manage_callback; |
| }; |
| |
| /** |
| * @endcond |
| */ |
| |
| /** |
| * @brief Configure operation of a eSPI controller. |
| * |
| * This routine provides a generic interface to override eSPI controller |
| * capabilities. |
| * |
| * If this eSPI controller is acting as slave, the values set here |
| * will be discovered as part through the GET_CONFIGURATION command |
| * issued by the eSPI master during initialization. |
| * |
| * If this eSPI controller is acting as master, the values set here |
| * will be used by eSPI master to determine minimum common capabilities with |
| * eSPI slave then send via SET_CONFIGURATION command. |
| * |
| * +--------+ +---------+ +------+ +---------+ +---------+ |
| * | eSPI | | eSPI | | eSPI | | eSPI | | eSPI | |
| * | slave | | driver | | bus | | driver | | host | |
| * +--------+ +---------+ +------+ +---------+ +---------+ |
| * | | | | | |
| * | espi_config | Set eSPI | Set eSPI | espi_config | |
| * +--------------+ ctrl regs | cap ctrl reg| +-----------+ |
| * | +-------+ | +--------+ | |
| * | |<------+ | +------->| | |
| * | | | | | |
| * | | | | | |
| * | | | GET_CONFIGURATION | | |
| * | | +<------------------+ | |
| * | |<-----------| | | |
| * | | eSPI caps | | | |
| * | |----------->+ response | | |
| * | | |------------------>+ | |
| * | | | | | |
| * | | | SET_CONFIGURATION | | |
| * | | +<------------------+ | |
| * | | | accept | | |
| * | | +------------------>+ | |
| * + + + + + |
| * |
| * @param dev Pointer to the device structure for the driver instance. |
| * @param cfg the device runtime configuration for the eSPI controller. |
| * |
| * @retval 0 If successful. |
| * @retval -EIO General input / output error, failed to configure device. |
| * @retval -EINVAL invalid capabilities, failed to configure device. |
| * @retval -ENOTSUP capability not supported by eSPI slave. |
| */ |
| __syscall int espi_saf_config(const struct device *dev, |
| const struct espi_saf_cfg *cfg); |
| |
| static inline int z_impl_espi_saf_config(const struct device *dev, |
| const struct espi_saf_cfg *cfg) |
| { |
| const struct espi_saf_driver_api *api = |
| (const struct espi_saf_driver_api *)dev->api; |
| |
| return api->config(dev, cfg); |
| } |
| |
| /** |
| * @brief Set one or more SAF protection regions |
| * |
| * This routine provides an interface to override the default flash |
| * protection regions of the SAF controller. |
| * |
| * @param dev Pointer to the device structure for the driver instance. |
| * @param pr Pointer to the SAF protection region structure. |
| * |
| * @retval 0 If successful. |
| * @retval -EIO General input / output error, failed to configure device. |
| * @retval -EINVAL invalid capabilities, failed to configure device. |
| * @retval -ENOTSUP capability not supported by eSPI slave. |
| */ |
| __syscall int espi_saf_set_protection_regions( |
| const struct device *dev, |
| const struct espi_saf_protection *pr); |
| |
| static inline int z_impl_espi_saf_set_protection_regions( |
| const struct device *dev, |
| const struct espi_saf_protection *pr) |
| { |
| const struct espi_saf_driver_api *api = |
| (const struct espi_saf_driver_api *)dev->api; |
| |
| return api->set_protection_regions(dev, pr); |
| } |
| |
| /** |
| * @brief Activate SAF block |
| * |
| * This routine activates the SAF block and should only be |
| * called after SAF has been configured and the eSPI Master |
| * has enabled the Flash Channel. |
| * |
| * @param dev Pointer to the device structure for the driver instance. |
| * |
| * @retval 0 If successful |
| * @retval -EINVAL if failed to activate SAF. |
| */ |
| __syscall int espi_saf_activate(const struct device *dev); |
| |
| static inline int z_impl_espi_saf_activate(const struct device *dev) |
| { |
| const struct espi_saf_driver_api *api = |
| (const struct espi_saf_driver_api *)dev->api; |
| |
| return api->activate(dev); |
| } |
| |
| /** |
| * @brief Query to see if SAF is ready |
| * |
| * This routine allows to check if SAF is ready before use. |
| * |
| * @param dev Pointer to the device structure for the driver instance. |
| * |
| * @retval true If eSPI SAF is ready. |
| * @retval false otherwise. |
| */ |
| __syscall bool espi_saf_get_channel_status(const struct device *dev); |
| |
| static inline bool z_impl_espi_saf_get_channel_status( |
| const struct device *dev) |
| { |
| const struct espi_saf_driver_api *api = |
| (const struct espi_saf_driver_api *)dev->api; |
| |
| return api->get_channel_status(dev); |
| } |
| |
| /** |
| * @brief Sends a read request packet for slave attached flash. |
| * |
| * This routines provides an interface to send a request to read the flash |
| * component shared between the eSPI master and eSPI slaves. |
| * |
| * @param dev Pointer to the device structure for the driver instance. |
| * @param pckt Adddress of the representation of read flash transaction. |
| * |
| * @retval -ENOTSUP eSPI flash logical channel transactions not supported. |
| * @retval -EBUSY eSPI flash channel is not ready or disabled by master. |
| * @retval -EIO General input / output error, failed request to master. |
| */ |
| __syscall int espi_saf_flash_read(const struct device *dev, |
| struct espi_saf_packet *pckt); |
| |
| static inline int z_impl_espi_saf_flash_read(const struct device *dev, |
| struct espi_saf_packet *pckt) |
| { |
| const struct espi_saf_driver_api *api = |
| (const struct espi_saf_driver_api *)dev->api; |
| |
| if (!api->flash_read) { |
| return -ENOTSUP; |
| } |
| |
| return api->flash_read(dev, pckt); |
| } |
| |
| /** |
| * @brief Sends a write request packet for slave attached flash. |
| * |
| * This routines provides an interface to send a request to write to the flash |
| * components shared between the eSPI master and eSPI slaves. |
| * |
| * @param dev Pointer to the device structure for the driver instance. |
| * @param pckt Address of the representation of write flash transaction. |
| * |
| * @retval -ENOTSUP eSPI flash logical channel transactions not supported. |
| * @retval -EBUSY eSPI flash channel is not ready or disabled by master. |
| * @retval -EIO General input / output error, failed request to master. |
| */ |
| __syscall int espi_saf_flash_write(const struct device *dev, |
| struct espi_saf_packet *pckt); |
| |
| static inline int z_impl_espi_saf_flash_write(const struct device *dev, |
| struct espi_saf_packet *pckt) |
| { |
| const struct espi_saf_driver_api *api = |
| (const struct espi_saf_driver_api *)dev->api; |
| |
| if (!api->flash_write) { |
| return -ENOTSUP; |
| } |
| |
| return api->flash_write(dev, pckt); |
| } |
| |
| /** |
| * @brief Sends a write request packet for slave attached flash. |
| * |
| * This routines provides an interface to send a request to write to the flash |
| * components shared between the eSPI master and eSPI slaves. |
| * |
| * @param dev Pointer to the device structure for the driver instance. |
| * @param pckt Address of the representation of erase flash transaction. |
| * |
| * @retval -ENOTSUP eSPI flash logical channel transactions not supported. |
| * @retval -EBUSY eSPI flash channel is not ready or disabled by master. |
| * @retval -EIO General input / output error, failed request to master. |
| */ |
| __syscall int espi_saf_flash_erase(const struct device *dev, |
| struct espi_saf_packet *pckt); |
| |
| static inline int z_impl_espi_saf_flash_erase(const struct device *dev, |
| struct espi_saf_packet *pckt) |
| { |
| const struct espi_saf_driver_api *api = |
| (const struct espi_saf_driver_api *)dev->api; |
| |
| if (!api->flash_erase) { |
| return -ENOTSUP; |
| } |
| |
| return api->flash_erase(dev, pckt); |
| } |
| |
| /** |
| * Callback model |
| * |
| *+-------+ +-------------+ +------+ +---------+ |
| *| App | | eSPI driver | | HW | |eSPI Host| |
| *+---+---+ +-------+-----+ +---+--+ +----+----+ |
| * | | | | |
| * | espi_init_callback | | | |
| * +----------------------------> | | | |
| * | espi_add_callback | | |
| * +----------------------------->+ | |
| * | | | eSPI reset | eSPI host |
| * | | IRQ +<------------+ resets the |
| * | | <-----------+ | bus |
| * | | | | |
| * | | Processed | | |
| * | | within the | | |
| * | | driver | | |
| * | | | | |
| |
| * | | | VW CH ready| eSPI host |
| * | | IRQ +<------------+ enables VW |
| * | | <-----------+ | channel |
| * | | | | |
| * | | Processed | | |
| * | | within the | | |
| * | | driver | | |
| * | | | | |
| * | | | Memory I/O | Peripheral |
| * | | <-------------+ event |
| * | +<------------+ | |
| * +<-----------------------------+ callback | | |
| * | Report peripheral event | | | |
| * | and data for the event | | | |
| * | | | | |
| * | | | SLP_S5 | eSPI host |
| * | | <-------------+ send VWire |
| * | +<------------+ | |
| * +<-----------------------------+ callback | | |
| * | App enables/configures | | | |
| * | discrete regulator | | | |
| * | | | | |
| * | espi_send_vwire_signal | | | |
| * +------------------------------>------------>|------------>| |
| * | | | | |
| * | | | HOST_RST | eSPI host |
| * | | <-------------+ send VWire |
| * | +<------------+ | |
| * +<-----------------------------+ callback | | |
| * | App reset host-related | | | |
| * | data structures | | | |
| * | | | | |
| * | | | C10 | eSPI host |
| * | | +<------------+ send VWire |
| * | <-------------+ | |
| * <------------------------------+ | | |
| * | App executes | | | |
| * + power mgmt policy | | | |
| */ |
| |
| /** |
| * @brief Helper to initialize a struct espi_callback properly. |
| * |
| * @param callback A valid Application's callback structure pointer. |
| * @param handler A valid handler function pointer. |
| * @param evt_type indicates the eSPI event relevant for the handler. |
| * for VWIRE_RECEIVED event the data will indicate the new level asserted |
| */ |
| static inline void espi_saf_init_callback(struct espi_callback *callback, |
| espi_callback_handler_t handler, |
| enum espi_bus_event evt_type) |
| { |
| __ASSERT(callback, "Callback pointer should not be NULL"); |
| __ASSERT(handler, "Callback handler pointer should not be NULL"); |
| |
| callback->handler = handler; |
| callback->evt_type = evt_type; |
| } |
| |
| /** |
| * @brief Add an application callback. |
| * @param dev Pointer to the device structure for the driver instance. |
| * @param callback A valid Application's callback structure pointer. |
| * @return 0 if successful, negative errno code on failure. |
| * |
| * @note Callbacks may be added to the device from within a callback |
| * handler invocation, but whether they are invoked for the current |
| * eSPI event is not specified. |
| * |
| * Note: enables to add as many callback as needed on the same device. |
| */ |
| static inline int espi_saf_add_callback(const struct device *dev, |
| struct espi_callback *callback) |
| { |
| const struct espi_saf_driver_api *api = |
| (const struct espi_saf_driver_api *)dev->api; |
| |
| if (!api->manage_callback) { |
| return -ENOTSUP; |
| } |
| |
| return api->manage_callback(dev, callback, true); |
| } |
| |
| /** |
| * @brief Remove an application callback. |
| * @param dev Pointer to the device structure for the driver instance. |
| * @param callback A valid application's callback structure pointer. |
| * @return 0 if successful, negative errno code on failure. |
| * |
| * @warning It is explicitly permitted, within a callback handler, to |
| * remove the registration for the callback that is running, i.e. @p |
| * callback. Attempts to remove other registrations on the same |
| * device may result in undefined behavior, including failure to |
| * invoke callbacks that remain registered and unintended invocation |
| * of removed callbacks. |
| * |
| * Note: enables to remove as many callbacks as added through |
| * espi_add_callback(). |
| */ |
| static inline int espi_saf_remove_callback(const struct device *dev, |
| struct espi_callback *callback) |
| { |
| const struct espi_saf_driver_api *api = |
| (const struct espi_saf_driver_api *)dev->api; |
| |
| if (!api->manage_callback) { |
| return -ENOTSUP; |
| } |
| |
| return api->manage_callback(dev, callback, false); |
| } |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| /** |
| * @} |
| */ |
| #include <syscalls/espi_saf.h> |
| #endif /* ZEPHYR_INCLUDE_ESPI_SAF_H_ */ |