pcie: endpoint: Add public APIs for PCIe endpoint driver
Add public APIs for PCIe endpoint driver: - EP configuration space read/write - Mapping/Unmapping of Host buffer and PCIe outbound region - Raise interrupt to Host These are minimal base APIs to make PCIe EP functional. Also, add a Kconfig and an empty CMakeLists.txt for drivers to extend. Signed-off-by: Abhishek Shah <abhishek.shah@broadcom.com>
This commit is contained in:
parent
bee0fdea1e
commit
ca17315d7f
5 changed files with 177 additions and 0 deletions
|
@ -1,3 +1,5 @@
|
|||
zephyr_sources(pcie.c)
|
||||
zephyr_sources_ifdef(CONFIG_PCIE_MSI msi.c)
|
||||
zephyr_sources_ifdef(CONFIG_PCIE_SHELL shell.c)
|
||||
|
||||
add_subdirectory_ifdef(CONFIG_PCIE_ENDPOINT endpoint)
|
||||
|
|
|
@ -24,4 +24,6 @@ config PCIE_SHELL
|
|||
help
|
||||
Enable commands for debugging PCI(e) using the built-in shell.
|
||||
|
||||
source "drivers/pcie/endpoint/Kconfig"
|
||||
|
||||
endif # PCIE
|
||||
|
|
1
drivers/pcie/endpoint/CMakeLists.txt
Normal file
1
drivers/pcie/endpoint/CMakeLists.txt
Normal file
|
@ -0,0 +1 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
9
drivers/pcie/endpoint/Kconfig
Normal file
9
drivers/pcie/endpoint/Kconfig
Normal file
|
@ -0,0 +1,9 @@
|
|||
# PCIe Endpoint configuration options
|
||||
|
||||
# Copyright 2020 Broadcom
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
menuconfig PCIE_ENDPOINT
|
||||
bool "Enable PCIe Endpoint support"
|
||||
help
|
||||
This option enables PCIe Endpoint support.
|
163
include/drivers/pcie/endpoint/pcie_ep.h
Normal file
163
include/drivers/pcie/endpoint/pcie_ep.h
Normal file
|
@ -0,0 +1,163 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief Public APIs for the PCIe EP drivers.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020 Broadcom
|
||||
*
|
||||
*/
|
||||
#ifndef ZEPHYR_INCLUDE_DRIVERS_PCIE_EP_H_
|
||||
#define ZEPHYR_INCLUDE_DRIVERS_PCIE_EP_H_
|
||||
|
||||
#include <device.h>
|
||||
#include <init.h>
|
||||
#include <kernel.h>
|
||||
#include <stdint.h>
|
||||
|
||||
enum pcie_ob_mem_type {
|
||||
PCIE_OB_ANYMEM, /**< PCIe OB window within any address range */
|
||||
PCIE_OB_LOWMEM, /**< PCIe OB window within 32-bit address range */
|
||||
PCIE_OB_HIGHMEM, /**< PCIe OB window above 32-bit address range */
|
||||
};
|
||||
|
||||
enum pci_ep_irq_type {
|
||||
PCIE_EP_IRQ_LEGACY, /**< Raise Legacy interrupt */
|
||||
PCIE_EP_IRQ_MSI, /**< Raise MSI interrupt */
|
||||
PCIE_EP_IRQ_MSIX, /**< Raise MSIX interrupt */
|
||||
};
|
||||
|
||||
struct pcie_ep_driver_api {
|
||||
int (*conf_read)(struct device *dev, uint32_t offset, uint32_t *data);
|
||||
void (*conf_write)(struct device *dev, uint32_t offset, uint32_t data);
|
||||
int (*map_addr)(struct device *dev, uint64_t pcie_addr,
|
||||
uint64_t *mapped_addr, uint32_t size,
|
||||
enum pcie_ob_mem_type ob_mem_type);
|
||||
void (*unmap_addr)(struct device *dev, uint64_t mapped_addr);
|
||||
int (*raise_irq)(struct device *dev, enum pci_ep_irq_type irq_type,
|
||||
uint32_t irq_num);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Read PCIe EP configuration space
|
||||
*
|
||||
* @details This API reads EP's own configuration space
|
||||
*
|
||||
* @param dev Pointer to the device structure for the driver instance
|
||||
* @param offset Offset within configuration space
|
||||
* @param data Pointer to data read from the offset
|
||||
*
|
||||
* @return 0 if successful, negative errno code if failure.
|
||||
*/
|
||||
|
||||
static inline int pcie_ep_conf_read(struct device *dev,
|
||||
uint32_t offset, uint32_t *data)
|
||||
{
|
||||
const struct pcie_ep_driver_api *api =
|
||||
(const struct pcie_ep_driver_api *)dev->driver_api;
|
||||
|
||||
return api->conf_read(dev, offset, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write PCIe EP configuration space
|
||||
*
|
||||
* @details This API writes EP's own configuration space
|
||||
*
|
||||
* @param dev Pointer to the device structure for the driver instance
|
||||
* @param offset Offset within configuration space
|
||||
* @param data Data to be written at the offset
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
|
||||
static inline void pcie_ep_conf_write(struct device *dev,
|
||||
uint32_t offset, uint32_t data)
|
||||
{
|
||||
const struct pcie_ep_driver_api *api =
|
||||
(const struct pcie_ep_driver_api *)dev->driver_api;
|
||||
|
||||
api->conf_write(dev, offset, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Map a host memory buffer to PCIe outbound region
|
||||
*
|
||||
* @details This API maps a host memory buffer to PCIe outbound region,
|
||||
* It is left to EP driver to manage multiple mappings through
|
||||
* multiple PCIe outbound regions if supported by SoC
|
||||
*
|
||||
* @param dev Pointer to the device structure for the driver instance
|
||||
* @param pcie_addr Host memory buffer address to be mapped
|
||||
* @param mapped_addr Mapped PCIe outbound region address
|
||||
* @param size Host memory buffer size (bytes)
|
||||
* @param ob_mem_type Hint if lowmem/highmem outbound region has to be used,
|
||||
* this is useful in cases where bus master cannot generate
|
||||
* more than 32-bit address; it becomes essential to use
|
||||
* lowmem outbound region
|
||||
*
|
||||
* @return Mapped size : If mapped size is less than requested size,
|
||||
* then requestor has to call the same API again to map
|
||||
* the unmapped host buffer after data transfer is done with
|
||||
* mapped size. This situation may arise because of the
|
||||
* mapping alignment requirements.
|
||||
*
|
||||
* @return Negative errno code if failure.
|
||||
*/
|
||||
|
||||
static inline int pcie_ep_map_addr(struct device *dev, uint64_t pcie_addr,
|
||||
uint64_t *mapped_addr, uint32_t size,
|
||||
enum pcie_ob_mem_type ob_mem_type)
|
||||
{
|
||||
const struct pcie_ep_driver_api *api =
|
||||
(const struct pcie_ep_driver_api *)dev->driver_api;
|
||||
|
||||
return api->map_addr(dev, pcie_addr, mapped_addr, size, ob_mem_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove mapping to PCIe outbound region
|
||||
*
|
||||
* @details This API removes mapping to PCIe outbound region.
|
||||
* Mapped PCIe outbound region address is given as argument
|
||||
* to figure out the outbound region to be unmapped
|
||||
*
|
||||
* @param dev Pointer to the device structure for the driver instance
|
||||
* @param mapped_addr PCIe outbound region address
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
|
||||
static inline void pcie_ep_unmap_addr(struct device *dev, uint64_t mapped_addr)
|
||||
{
|
||||
const struct pcie_ep_driver_api *api =
|
||||
(const struct pcie_ep_driver_api *)dev->driver_api;
|
||||
|
||||
api->unmap_addr(dev, mapped_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Raise interrupt to Host
|
||||
*
|
||||
* @details This API raises interrupt to Host
|
||||
*
|
||||
* @param dev Pointer to the device structure for the driver instance
|
||||
* @param irq_type Type of Interrupt be raised (legacy, MSI or MSI-X)
|
||||
* @param irq_num MSI or MSI-X interrupt number
|
||||
*
|
||||
* @return 0 if successful, negative errno code if failure.
|
||||
*/
|
||||
|
||||
static inline int pcie_ep_raise_irq(struct device *dev,
|
||||
enum pci_ep_irq_type irq_type,
|
||||
uint32_t irq_num)
|
||||
{
|
||||
const struct pcie_ep_driver_api *api =
|
||||
(const struct pcie_ep_driver_api *)dev->driver_api;
|
||||
return api->raise_irq(dev, irq_type, irq_num);
|
||||
}
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DRIVERS_PCIE_EP_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue