LCOV - code coverage report
Current view: top level - zephyr/drivers/pcie/endpoint - pcie_ep.h Coverage Total Hit
Test: new.info Lines: 47.8 % 23 11
Test Date: 2025-09-05 20:47:19

            Line data    Source code
       1            1 : /**
       2              :  * @file
       3              :  *
       4              :  * @brief Public APIs for the PCIe EP drivers.
       5              :  */
       6              : 
       7              : /*
       8              :  * SPDX-License-Identifier: Apache-2.0
       9              :  *
      10              :  * Copyright 2020 Broadcom
      11              :  *
      12              :  */
      13              : #ifndef ZEPHYR_INCLUDE_DRIVERS_PCIE_EP_H_
      14              : #define ZEPHYR_INCLUDE_DRIVERS_PCIE_EP_H_
      15              : 
      16              : #include <zephyr/device.h>
      17              : #include <zephyr/init.h>
      18              : #include <zephyr/kernel.h>
      19              : #include <stdint.h>
      20              : 
      21            0 : enum pcie_ob_mem_type {
      22              :         PCIE_OB_ANYMEM,  /**< PCIe OB window within any address range */
      23              :         PCIE_OB_LOWMEM,  /**< PCIe OB window within 32-bit address range */
      24              :         PCIE_OB_HIGHMEM, /**< PCIe OB window above 32-bit address range */
      25              : };
      26              : 
      27            0 : enum pci_ep_irq_type {
      28              :         PCIE_EP_IRQ_LEGACY,     /**< Raise Legacy interrupt */
      29              :         PCIE_EP_IRQ_MSI,        /**< Raise MSI interrupt */
      30              :         PCIE_EP_IRQ_MSIX,       /**< Raise MSIX interrupt */
      31              : };
      32              : 
      33            0 : enum xfer_direction {
      34              :         HOST_TO_DEVICE,         /**< Read from Host */
      35              :         DEVICE_TO_HOST,         /**< Write to Host */
      36              : };
      37              : 
      38            0 : enum pcie_reset {
      39              :         PCIE_PERST,     /**< Cold reset */
      40              :         PCIE_PERST_INB, /**< Inband hot reset */
      41              :         PCIE_FLR,       /**< Functional Level Reset */
      42              :         PCIE_RESET_MAX
      43              : };
      44              : 
      45              : /**
      46              :  * @typedef pcie_ep_reset_callback_t
      47              :  * @brief Callback API for PCIe reset interrupts
      48              :  *
      49              :  * These callbacks execute in interrupt context. Therefore, use only
      50              :  * interrupt-safe APIS. Registration of callbacks is done via
      51              :  * @a pcie_ep_register_reset_cb
      52              :  *
      53              :  * @param arg Pointer provided at registration time, later to be
      54              :  *        passed back as argument to callback function
      55              :  */
      56              : 
      57            1 : typedef void (*pcie_ep_reset_callback_t)(void *arg);
      58              : 
      59            0 : __subsystem struct pcie_ep_driver_api {
      60            0 :         int (*conf_read)(const struct device *dev, uint32_t offset,
      61              :                          uint32_t *data);
      62            0 :         void (*conf_write)(const struct device *dev, uint32_t offset,
      63              :                            uint32_t data);
      64            0 :         int (*map_addr)(const struct device *dev, uint64_t pcie_addr,
      65              :                         uint64_t *mapped_addr, uint32_t size,
      66              :                         enum pcie_ob_mem_type ob_mem_type);
      67            0 :         void (*unmap_addr)(const struct device *dev, uint64_t mapped_addr);
      68            0 :         int (*raise_irq)(const struct device *dev,
      69              :                          enum pci_ep_irq_type irq_type,
      70              :                          uint32_t irq_num);
      71            0 :         int (*register_reset_cb)(const struct device *dev,
      72              :                                  enum pcie_reset reset,
      73              :                                  pcie_ep_reset_callback_t cb, void *arg);
      74            0 :         int (*dma_xfer)(const struct device *dev, uint64_t mapped_addr,
      75              :                         uintptr_t local_addr, uint32_t size,
      76              :                         enum xfer_direction dir);
      77              : };
      78              : 
      79              : /**
      80              :  * @brief Read PCIe EP configuration space
      81              :  *
      82              :  * @details This API reads EP's own configuration space
      83              :  *
      84              :  * @param dev    Pointer to the device structure for the driver instance
      85              :  * @param offset Offset within configuration space
      86              :  * @param data   Pointer to data read from the offset
      87              :  *
      88              :  * @return 0 if successful, negative errno code if failure.
      89              :  */
      90              : 
      91            1 : static inline int pcie_ep_conf_read(const struct device *dev,
      92              :                                     uint32_t offset, uint32_t *data)
      93              : {
      94              :         const struct pcie_ep_driver_api *api =
      95              :                         (const struct pcie_ep_driver_api *)dev->api;
      96              : 
      97              :         return api->conf_read(dev, offset, data);
      98              : }
      99              : 
     100              : /**
     101              :  * @brief Write PCIe EP configuration space
     102              :  *
     103              :  * @details This API writes EP's own configuration space
     104              :  *
     105              :  * @param dev    Pointer to the device structure for the driver instance
     106              :  * @param offset Offset within configuration space
     107              :  * @param data   Data to be written at the offset
     108              :  */
     109              : 
     110            1 : static inline void pcie_ep_conf_write(const struct device *dev,
     111              :                                       uint32_t offset, uint32_t data)
     112              : {
     113              :         const struct pcie_ep_driver_api *api =
     114              :                         (const struct pcie_ep_driver_api *)dev->api;
     115              : 
     116              :         api->conf_write(dev, offset, data);
     117              : }
     118              : 
     119              : /**
     120              :  * @brief Map a host memory buffer to PCIe outbound region
     121              :  *
     122              :  * @details This API maps a host memory buffer to PCIe outbound region,
     123              :  *          It is left to EP driver to manage multiple mappings through
     124              :  *          multiple PCIe outbound regions if supported by SoC
     125              :  *
     126              :  * @param dev         Pointer to the device structure for the driver instance
     127              :  * @param pcie_addr   Host memory buffer address to be mapped
     128              :  * @param mapped_addr Mapped PCIe outbound region address
     129              :  * @param size        Host memory buffer size (bytes)
     130              :  * @param ob_mem_type Hint if lowmem/highmem outbound region has to be used,
     131              :  *                    this is useful in cases where bus master cannot generate
     132              :  *                    more than 32-bit address; it becomes essential to use
     133              :  *                    lowmem outbound region
     134              :  *
     135              :  * @return Mapped size : If mapped size is less than requested size,
     136              :  *         then requester has to call the same API again to map
     137              :  *         the unmapped host buffer after data transfer is done with
     138              :  *         mapped size. This situation may arise because of the
     139              :  *         mapping alignment requirements.
     140              :  *
     141              :  * @return Negative errno code if failure.
     142              :  */
     143              : 
     144            1 : static inline int pcie_ep_map_addr(const struct device *dev,
     145              :                                    uint64_t pcie_addr,
     146              :                                    uint64_t *mapped_addr, uint32_t size,
     147              :                                    enum pcie_ob_mem_type ob_mem_type)
     148              : {
     149              :         const struct pcie_ep_driver_api *api =
     150              :                         (const struct pcie_ep_driver_api *)dev->api;
     151              : 
     152              :         return api->map_addr(dev, pcie_addr, mapped_addr, size, ob_mem_type);
     153              : }
     154              : 
     155              : /**
     156              :  * @brief Remove mapping to PCIe outbound region
     157              :  *
     158              :  * @details This API removes mapping to PCIe outbound region.
     159              :  *          Mapped PCIe outbound region address is given as argument
     160              :  *          to figure out the outbound region to be unmapped
     161              :  *
     162              :  * @param dev         Pointer to the device structure for the driver instance
     163              :  * @param mapped_addr PCIe outbound region address
     164              :  */
     165              : 
     166            1 : static inline void pcie_ep_unmap_addr(const struct device *dev,
     167              :                                       uint64_t mapped_addr)
     168              : {
     169              :         const struct pcie_ep_driver_api *api =
     170              :                         (const struct pcie_ep_driver_api *)dev->api;
     171              : 
     172              :         api->unmap_addr(dev, mapped_addr);
     173              : }
     174              : 
     175              : /**
     176              :  * @brief Raise interrupt to Host
     177              :  *
     178              :  * @details This API raises interrupt to Host
     179              :  *
     180              :  * @param   dev      Pointer to the device structure for the driver instance
     181              :  * @param   irq_type Type of Interrupt be raised (legacy, MSI or MSI-X)
     182              :  * @param   irq_num  MSI or MSI-X interrupt number
     183              :  *
     184              :  * @return 0 if successful, negative errno code if failure.
     185              :  */
     186              : 
     187            1 : static inline int pcie_ep_raise_irq(const struct device *dev,
     188              :                                     enum pci_ep_irq_type irq_type,
     189              :                                     uint32_t irq_num)
     190              : {
     191              :         const struct pcie_ep_driver_api *api =
     192              :                         (const struct pcie_ep_driver_api *)dev->api;
     193              :         return api->raise_irq(dev, irq_type, irq_num);
     194              : }
     195              : 
     196              : /**
     197              :  * @brief Register callback function for reset interrupts
     198              :  *
     199              :  * @details If reset interrupts are handled by device, this API can be
     200              :  *          used to register callback function, which will be
     201              :  *          executed part of corresponding PCIe reset handler
     202              :  *
     203              :  * @param   dev   Pointer to the device structure for the driver instance
     204              :  * @param   reset Reset interrupt type
     205              :  * @param   cb    Callback function being registered
     206              :  * @param   arg   Argument to be passed back to callback function
     207              :  *
     208              :  * @return 0 if successful, negative errno code if failure.
     209              :  */
     210              : 
     211            1 : static inline int pcie_ep_register_reset_cb(const struct device *dev,
     212              :                                             enum pcie_reset reset,
     213              :                                             pcie_ep_reset_callback_t cb,
     214              :                                             void *arg)
     215              : {
     216              :         const struct pcie_ep_driver_api *api =
     217              :                         (const struct pcie_ep_driver_api *)dev->api;
     218              : 
     219              :         if (api->register_reset_cb) {
     220              :                 return api->register_reset_cb(dev, reset, cb, arg);
     221              :         }
     222              : 
     223              :         return -ENOTSUP;
     224              : }
     225              : 
     226              : /**
     227              :  * @brief Data transfer between mapped Host memory and device memory with
     228              :  *        "System DMA". The term "System DMA" is used to clarify that we
     229              :  *        are not talking about dedicated "PCIe DMA"; rather the one
     230              :  *        which does not understand PCIe address directly, and
     231              :  *        uses the mapped Host memory.
     232              :  *
     233              :  * @details If DMA controller is available in the EP device, this API can be
     234              :  *          used to achieve data transfer between mapped Host memory,
     235              :  *          i.e. outbound memory and EP device's local memory with DMA
     236              :  *
     237              :  * @param   dev         Pointer to the device structure for the driver instance
     238              :  * @param   mapped_addr Mapped Host memory address
     239              :  * @param   local_addr  Device memory address
     240              :  * @param   size        DMA transfer length (bytes)
     241              :  * @param   dir         Direction of DMA transfer
     242              :  *
     243              :  * @return 0 if successful, negative errno code if failure.
     244              :  */
     245              : 
     246            1 : static inline int pcie_ep_dma_xfer(const struct device *dev,
     247              :                                    uint64_t mapped_addr,
     248              :                                    uintptr_t local_addr, uint32_t size,
     249              :                                    const enum xfer_direction dir)
     250              : {
     251              :         const struct pcie_ep_driver_api *api =
     252              :                         (const struct pcie_ep_driver_api *)dev->api;
     253              : 
     254              :         if (api->dma_xfer) {
     255              :                 return api->dma_xfer(dev, mapped_addr, local_addr, size, dir);
     256              :         }
     257              : 
     258              :         return -ENOTSUP;
     259              : }
     260              : 
     261              : /**
     262              :  * @brief Data transfer using memcpy
     263              :  *
     264              :  * @details Helper API to achieve data transfer with memcpy
     265              :  *          through PCIe outbound memory
     266              :  *
     267              :  * @param dev         Pointer to the device structure for the driver instance
     268              :  * @param pcie_addr   Host memory buffer address
     269              :  * @param local_addr  Local memory buffer address
     270              :  * @param size        Data transfer size (bytes)
     271              :  * @param ob_mem_type Hint if lowmem/highmem outbound region has to be used
     272              :  *                    (PCIE_OB_LOWMEM / PCIE_OB_HIGHMEM / PCIE_OB_ANYMEM),
     273              :  *                    should be PCIE_OB_LOWMEM if bus master cannot generate
     274              :  *                    more than 32-bit address
     275              :  * @param dir         Data transfer direction (HOST_TO_DEVICE / DEVICE_TO_HOST)
     276              :  *
     277              :  * @return 0 if successful, negative errno code if failure.
     278              :  */
     279            1 : int pcie_ep_xfer_data_memcpy(const struct device *dev, uint64_t pcie_addr,
     280              :                              uintptr_t *local_addr, uint32_t size,
     281              :                              enum pcie_ob_mem_type ob_mem_type,
     282              :                              enum xfer_direction dir);
     283              : 
     284              : /**
     285              :  * @brief Data transfer using system DMA
     286              :  *
     287              :  * @details Helper API to achieve data transfer with system DMA through PCIe
     288              :  *          outbound memory, this API is based off pcie_ep_xfer_data_memcpy,
     289              :  *          here we use "system dma" instead of memcpy
     290              :  *
     291              :  * @param dev         Pointer to the device structure for the driver instance
     292              :  * @param pcie_addr   Host memory buffer address
     293              :  * @param local_addr  Local memory buffer address
     294              :  * @param size        Data transfer size (bytes)
     295              :  * @param ob_mem_type Hint if lowmem/highmem outbound region has to be used
     296              :  *                    (PCIE_OB_LOWMEM / PCIE_OB_HIGHMEM / PCIE_OB_ANYMEM)
     297              :  * @param dir         Data transfer direction (HOST_TO_DEVICE / DEVICE_TO_HOST)
     298              :  *
     299              :  * @return 0 if successful, negative errno code if failure.
     300              :  */
     301            1 : int pcie_ep_xfer_data_dma(const struct device *dev, uint64_t pcie_addr,
     302              :                           uintptr_t *local_addr, uint32_t size,
     303              :                           enum pcie_ob_mem_type ob_mem_type,
     304              :                           enum xfer_direction dir);
     305              : 
     306              : #endif /* ZEPHYR_INCLUDE_DRIVERS_PCIE_EP_H_ */
        

Generated by: LCOV version 2.0-1