/* SPDX-License-Identifier: GPL-2.0+ */ /* * PCIe DMA EPF Library for Tegra PCIe * * Copyright (C) 2021-2022 NVIDIA Corporation. All rights reserved. */ #ifndef TEGRA_PCIE_EDMA_H #define TEGRA_PCIE_EDMA_H #define DMA_RD_CHNL_NUM 2 #define DMA_WR_CHNL_NUM 4 #define EDMA_DESC_SZ 32 /** * Application can use this macro as default number of descriptors. * Number of descriptors should always be power of 2. */ #define NUM_EDMA_DESC 4096 /** * @brief typedef to define various values for xfer status passed for edma_complete_t or * tegra_pcie_edma_submit_xfer() */ typedef enum { EDMA_XFER_SUCCESS = 0, EDMA_XFER_FAIL_INVAL_INPUTS, EDMA_XFER_FAIL_NOMEM, EDMA_XFER_FAIL_TIMEOUT, EDMA_XFER_ABORT, EDMA_XFER_DEINIT, } edma_xfer_status_t; /** @brief typedef to define various values for xfer type passed tegra_pcie_edma_submit_xfer() */ typedef enum { EDMA_XFER_WRITE = 0, EDMA_XFER_READ, } edma_xfer_type_t; /** * @brief typedef to define various values for channel xfer configuration done * during tegra_pcie_edma_submit_init() */ typedef enum { EDMA_CHAN_XFER_SYNC = 0, EDMA_CHAN_XFER_ASYNC, } edma_chan_type_t; /** Forward declaration */ struct tegra_pcie_edma_desc; /** @brief Tx Async callback function pointer */ typedef void (edma_complete_t)(void *priv, edma_xfer_status_t status, struct tegra_pcie_edma_desc *desc); /** @brief Remote EDMA controller details. * @note: this is initial revision and expected to be modified. */ struct pcie_tegra_edma_remote_info { /** MSI IRQ number */ uint32_t msi_irq; /** MSI data that needs to be configured on EP DMA registers */ uint16_t msi_data; /** MSI address that needs to be configured on EP DMA registers */ uint64_t msi_addr; /** EP's DMA PHY base address, which same as BAR4 base address */ phys_addr_t dma_phy_base; /** EP's DMA register spec size, which same as BAR4 size */ uint32_t dma_size; /** &pci_dev.dev poniter used for devm_* and logging */ struct device *dev; }; /** @brief details of EDMA Tx channel configuration */ struct tegra_pcie_edma_chans_info { /** Variable to specify if corresponding channel should run in Sync/Async mode. */ edma_chan_type_t ch_type; /** Number of descriptors that needs to be configured for this channel. * @note * - If 0 is passed, this channel will be treated un-used. * - else it must be power of 2. */ uint32_t num_descriptors; /* Below parameter are used, only if edma_remote is present in #tegra_pcie_edma_init_info */ /** Descriptor PHY base allocated by client which is part of BAR0. Memory allocated for this * should be 1 more than number of descriptors. */ phys_addr_t desc_phy_base; /** Abosolute IOVA address of desc of desc_phy_base. */ dma_addr_t desc_iova; }; /** @brief init data structure to be used for tegra_pcie_edma_init() API */ struct tegra_pcie_edma_init_info { /** configuration details for edma Tx channels */ struct tegra_pcie_edma_chans_info tx[DMA_WR_CHNL_NUM]; /** configuration details for edma Tx channels */ struct tegra_pcie_edma_chans_info rx[DMA_RD_CHNL_NUM]; /** device node for corresponding edma to read information from DT */ struct device_node *np; /** * Remote edma pointer: if not NULL, library uses remote EDMA engine for transfers * else uses local controller EDMA engine. */ struct pcie_tegra_edma_remote_info *edma_remote; }; /** @brief edma descriptor for data transfer operations */ struct tegra_pcie_edma_desc { /** source address of data buffer */ dma_addr_t src; /** destination address where data buffer needs to be transferred */ dma_addr_t dst; /** Size of data buffer */ uint32_t sz; }; /** @brief data strcuture needs to be passed for Tx operations */ struct tegra_pcie_edma_xfer_info { /** Read or write operation. 0 -> write, 1->read */ edma_xfer_type_t type; /** Channel on which operation needs to be performed. * Range 0 to (DMA_RD_CHNL_NUM-1)/(DMA_WR_CHNL_NUM-1) */ uint32_t channel_num; /** EDMA descriptor structure with source, destination DMA addr along with its size. */ struct tegra_pcie_edma_desc *desc; /** Number of desc entries. */ uint32_t nents; /** complete callback to be called */ edma_complete_t *complete; /** Caller'z private data pointer which will be passed as part of edma_complete_t */ void *priv; }; /** * @brief: API to perform EDMA library initialization. * @param[in] info: EDMA init data structure. Refer struct tegra_pcie_edma_init_info for details. * @retVal: NULL on failure and valid pointer if success and this should * be passed for all subsequent calls of this library. */ void *tegra_pcie_edma_initialize(struct tegra_pcie_edma_init_info *info); /** * @brief: API to perform transfer operation. * @param[in] tx_info: EDMA Tx data structure. Refer struct tegra_pcie_edma_xfer_info for details. * @param[in] coockie : cookie data returned in tegra_pcie_edma_initialize() call. * @retVal: Refer edma_xfer_status_t. */ edma_xfer_status_t tegra_pcie_edma_submit_xfer(void *cookie, struct tegra_pcie_edma_xfer_info *tx_info); /** * @brief: API to stop EDMA engine,. * @param[in] cookie : cookie data returned in tegra_pcie_edma_initialize() call. * @retVal: Returns true on success and false on failure. */ bool tegra_pcie_edma_stop(void *cookie); /** * @brief: API to perform de-init of EDMA library. * @param[in] cookie : cookie data returned in tegra_pcie_edma_initialize() call. */ void tegra_pcie_edma_deinit(void *cookie); #endif //TEGRA_PCIE_EDMA_H