diff --git a/drivers/pcie/endpoint/CMakeLists.txt b/drivers/pcie/endpoint/CMakeLists.txt index 24080d93cf0..40edaf83044 100644 --- a/drivers/pcie/endpoint/CMakeLists.txt +++ b/drivers/pcie/endpoint/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_sources(pcie_ep_common.c) + +zephyr_sources_ifdef(CONFIG_PCIE_EP_BCM_IPROC pcie_ep_bcm_iproc.c) diff --git a/drivers/pcie/endpoint/Kconfig b/drivers/pcie/endpoint/Kconfig index 617b4392f57..fe77a9740bb 100644 --- a/drivers/pcie/endpoint/Kconfig +++ b/drivers/pcie/endpoint/Kconfig @@ -7,3 +7,15 @@ menuconfig PCIE_ENDPOINT bool "Enable PCIe Endpoint support" help This option enables PCIe Endpoint support. + +if PCIE_ENDPOINT + +module = PCIE_EP +module-str = PCIE_EP +source "subsys/logging/Kconfig.template.log_config" + +comment "PCIe Endpoint Drivers" + +source "drivers/pcie/endpoint/Kconfig.bcm_iproc" + +endif # PCIE_ENDPOINT diff --git a/drivers/pcie/endpoint/Kconfig.bcm_iproc b/drivers/pcie/endpoint/Kconfig.bcm_iproc new file mode 100644 index 00000000000..eb08be49f81 --- /dev/null +++ b/drivers/pcie/endpoint/Kconfig.bcm_iproc @@ -0,0 +1,22 @@ +# iProc PCIe EP configuration options + +# Copyright 2020 Broadcom +# SPDX-License-Identifier: Apache-2.0 + +menuconfig PCIE_EP_BCM_IPROC + bool "Broadcom iProc PCIe EP driver" + default n + help + This option enables Broadcom iProc PCIe EP driver. + +if PCIE_EP_BCM_IPROC + +config PCIE_EP_BCM_IPROC_INIT_CFG + bool "Re-initialize PCIe MSI/MSIX configurations" + default n + +config PCIE_EP_BCM_IPROC_V2 + bool "Version-2 of iProc PCIe EP controller" + default n + +endif # PCIE_EP_BCM_IPROC diff --git a/drivers/pcie/endpoint/pcie_ep_bcm_iproc.c b/drivers/pcie/endpoint/pcie_ep_bcm_iproc.c new file mode 100644 index 00000000000..27748b6e078 --- /dev/null +++ b/drivers/pcie/endpoint/pcie_ep_bcm_iproc.c @@ -0,0 +1,335 @@ +/* + * Copyright 2020 Broadcom + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#define LOG_LEVEL CONFIG_PCIE_EP_LOG_LEVEL +#include +LOG_MODULE_REGISTER(iproc_pcie); + +#include "pcie_ep_bcm_iproc.h" +#include "pcie_ep_bcm_iproc_regs.h" + +#define DT_DRV_COMPAT brcm_iproc_pcie_ep + +/* Helper macro to read 64-bit data using two 32-bit data read */ +#define sys_read64(addr) (((uint64_t)(sys_read32(addr + 4)) << 32) | \ + sys_read32(addr)) + +static int iproc_pcie_conf_read(struct device *dev, uint32_t offset, + uint32_t *data) +{ + const struct iproc_pcie_ep_config *cfg = dev->config_info; + + /* Write offset to Configuration Indirect Address register */ + pcie_write32(offset, &cfg->base->paxb_config_ind_addr); + + /* Read data from Configuration Indirect Data register */ + *data = pcie_read32(&cfg->base->paxb_config_ind_data); + + return 0; +} + +static void iproc_pcie_conf_write(struct device *dev, uint32_t offset, + uint32_t data) +{ + const struct iproc_pcie_ep_config *cfg = dev->config_info; + + /* Write offset to Configuration Indirect Address register */ + pcie_write32(offset, &cfg->base->paxb_config_ind_addr); + + /* Write data to Configuration Indirect Data register */ + pcie_write32(data, &cfg->base->paxb_config_ind_data); +} + +static int iproc_pcie_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 iproc_pcie_ep_config *cfg = dev->config_info; + struct iproc_pcie_ep_ctx *ctx = dev->driver_data; + uint64_t pcie_ob_base, pcie_ob_size, pcie_addr_start, offset; + uint32_t mapped_size; + enum pcie_outbound_map idx; + k_spinlock_key_t key; + int ret; + + key = k_spin_lock(&ctx->ob_map_lock); + + /* We support 2 outbound windows, + * one in highmem region and another in lowmem region + */ + if ((ob_mem_type == PCIE_OB_HIGHMEM || + ob_mem_type == PCIE_OB_ANYMEM) && !ctx->highmem_in_use) { + idx = PCIE_MAP_HIGHMEM_IDX; + pcie_ob_base = cfg->map_high_base; + pcie_ob_size = cfg->map_high_size; + } else if ((ob_mem_type == PCIE_OB_LOWMEM || + ob_mem_type == PCIE_OB_ANYMEM) && !ctx->lowmem_in_use) { + idx = PCIE_MAP_LOWMEM_IDX; + pcie_ob_base = cfg->map_low_base; + pcie_ob_size = cfg->map_low_size; + } else { + ret = -EBUSY; + goto out; + } + + /* check if the selected OB window supports size we want to map */ + if (size > pcie_ob_size) { + ret = -ENOTSUP; + goto out; + } + + /* Host PCIe address should be aligned to outbound window size */ + pcie_addr_start = pcie_addr & ~(pcie_ob_size - 1); + + /* Program OARR with PCIe outbound address */ + pcie_write32(((pcie_ob_base & ~(pcie_ob_size - 1)) | PAXB_OARR_VALID), + &cfg->base->paxb_oarr[idx].lower); + pcie_write32(pcie_ob_base >> 32, &cfg->base->paxb_oarr[idx].upper); + + /* Program OMAP with Host PCIe address */ + pcie_write32((uint32_t)pcie_addr_start, + &cfg->base->paxb_omap[idx].lower); + pcie_write32((uint32_t)(pcie_addr_start >> 32), + &cfg->base->paxb_omap[idx].upper); + + /* Mark usage of outbound window */ + if (idx == PCIE_MAP_HIGHMEM_IDX) { + ctx->highmem_in_use = true; + } else { + ctx->lowmem_in_use = true; + } + + /* offset holds extra size mapped due to alignment requirement */ + offset = pcie_addr - pcie_addr_start; + *mapped_addr = pcie_ob_base + offset; + mapped_size = pcie_ob_size - offset; + ret = ((mapped_size >= size) ? size : mapped_size); +out: + k_spin_unlock(&ctx->ob_map_lock, key); + + return ret; +} + +static void iproc_pcie_unmap_addr(struct device *dev, uint64_t mapped_addr) +{ + struct iproc_pcie_ep_ctx *ctx = dev->driver_data; + k_spinlock_key_t key; + + key = k_spin_lock(&ctx->ob_map_lock); + + /* + * When doing Host writes using PCIe outbound window, it is seen + * that before the writes gets completed using the existing outbound + * window mapping, next mapping is overwriting it, causing few bytes + * write failure with former mapping. + * + * To safeguard outbound window mapping, perform PCIe read in unmap, + * which ensures that all PCIe writes before the read + * are completed with this window. + */ + sys_read8(mapped_addr); + + if (mapped_addr >> 32) { + ctx->highmem_in_use = false; + } else { + ctx->lowmem_in_use = false; + } + + k_spin_unlock(&ctx->ob_map_lock, key); +} + +static int iproc_pcie_generate_msi(struct device *dev, const uint32_t msi_num) +{ + int ret = 0; +#ifdef CONFIG_PCIE_EP_BCM_IPROC_V2 + uint64_t addr; + uint32_t data; + + iproc_pcie_conf_read(dev, MSI_ADDR_H, &data); + addr = ((uint64_t)data) << 32; + iproc_pcie_conf_read(dev, MSI_ADDR_L, &data); + addr = addr | data; + + if (data == 0) { + /* + * This is mostly the case where the test is being run + * from device before host driver sets up MSI. + * Returning zero instead of error because of this. + */ + LOG_WRN("MSI is not setup, skipping MSI"); + return 0; + } + + iproc_pcie_conf_read(dev, MSI_DATA, &data); + data |= msi_num; + + ret = pcie_ep_xfer_data_memcpy(dev, addr, + (uintptr_t *)&data, sizeof(data), + PCIE_OB_LOWMEM, DEVICE_TO_HOST); + +#else + const struct iproc_pcie_ep_config *cfg = dev->config_info; + + pcie_write32(msi_num, &cfg->base->paxb_pcie_sys_msi_req); +#endif + return ret; +} + +static int iproc_pcie_generate_msix(struct device *dev, const uint32_t msix_num) +{ + uint64_t addr; + uint32_t data, msix_offset; + int ret; + + msix_offset = MSIX_TABLE_BASE + (msix_num * MSIX_TABLE_ENTRY_SIZE); + + addr = sys_read64(msix_offset); + + if (addr == 0) { + /* + * This is mostly the case where the test is being run + * from device before host driver has setup MSIX table. + * Returning zero instead of error because of this. + */ + LOG_WRN("MSIX table is not setup, skipping MSIX\n"); + return 0; + } + + data = sys_read32(msix_offset + MSIX_TBL_DATA_OFF); + + ret = pcie_ep_xfer_data_memcpy(dev, addr, + (uintptr_t *)&data, sizeof(data), + PCIE_OB_LOWMEM, DEVICE_TO_HOST); + + return ret; +} + +static int iproc_pcie_raise_irq(struct device *dev, + enum pci_ep_irq_type irq_type, + uint32_t irq_num) +{ + struct iproc_pcie_ep_ctx *ctx = dev->driver_data; + k_spinlock_key_t key; + int ret; + + key = k_spin_lock(&ctx->raise_irq_lock); + + switch (irq_type) { + case PCIE_EP_IRQ_MSI: + ret = iproc_pcie_generate_msi(dev, irq_num); + break; + case PCIE_EP_IRQ_MSIX: + ret = iproc_pcie_generate_msix(dev, irq_num); + break; + case PCIE_EP_IRQ_LEGACY: + ret = -ENOTSUP; + break; + default: + LOG_ERR("Unknown IRQ type\n"); + ret = -EINVAL; + } + + k_spin_unlock(&ctx->raise_irq_lock, key); + return ret; +} + +#ifdef CONFIG_PCIE_EP_BCM_IPROC_INIT_CFG +static void iproc_pcie_msix_config(struct device *dev) +{ + /* + * Configure capability of generating 16 messages, + * MSI-X Table offset 0x10000 on BAR2, + * MSI-X PBA offset 0x10800 on BAR2. + */ + iproc_pcie_conf_write(dev, MSIX_CONTROL, (MSIX_TABLE_SIZE - 1)); + iproc_pcie_conf_write(dev, MSIX_TBL_OFF_BIR, MSIX_TBL_B2_10000); + iproc_pcie_conf_write(dev, MSIX_PBA_OFF_BIR, MSIX_PBA_B2_10800); +} + +static void iproc_pcie_msi_config(struct device *dev) +{ + uint32_t data; + + /* Configure capability of generating 16 messages */ + iproc_pcie_conf_read(dev, ID_VAL4_OFFSET, &data); + data = (data & ~(MSI_COUNT_MASK)) | (MSI_COUNT_VAL << MSI_COUNT_SHIFT); + iproc_pcie_conf_write(dev, ID_VAL4_OFFSET, data); +} +#endif + +static int iproc_pcie_mode_check(const struct iproc_pcie_ep_config *cfg) +{ + uint32_t data; + + data = pcie_read32(&cfg->base->paxb_strap_status); + LOG_DBG("PAXB_STRAP_STATUS = 0x%08X\n", data); + + if (data & PCIE_RC_MODE_MASK) { + return -ENOTSUP; + } + + return 0; +} + +static int iproc_pcie_ep_init(struct device *dev) +{ + const struct iproc_pcie_ep_config *cfg = dev->config_info; + struct iproc_pcie_ep_ctx *ctx = dev->driver_data; + int ret; + uint32_t data; + + ret = iproc_pcie_mode_check(cfg); + if (ret) { + LOG_ERR("ERROR: Only PCIe EP mode is supported\n"); + goto err_out; + } + + iproc_pcie_conf_read(dev, PCIE_LINK_STATUS_CONTROL, &data); + LOG_INF("PCIe linkup speed 0x%x\n", ((data >> + PCIE_LINKSPEED_SHIFT) & PCIE_LINKSPEED_MASK)); + LOG_INF("PCIe linkup width 0x%x\n", ((data >> + PCIE_LINKWIDTH_SHIFT) & PCIE_LINKWIDTH_MASK)); + +#ifdef CONFIG_PCIE_EP_BCM_IPROC_INIT_CFG + iproc_pcie_msi_config(dev); + iproc_pcie_msix_config(dev); +#endif + + ctx->highmem_in_use = false; + ctx->lowmem_in_use = false; + LOG_INF("PCIe initialized successfully\n"); + +err_out: + return ret; +} + +static struct iproc_pcie_ep_ctx iproc_pcie_ep_ctx_0; + +static struct iproc_pcie_ep_config iproc_pcie_ep_config_0 = { + .id = 0, + .base = (struct iproc_pcie_reg *)DT_INST_REG_ADDR(0), + .reg_size = DT_INST_REG_SIZE(0), + .map_low_base = DT_INST_REG_ADDR_BY_NAME(0, map_lowmem), + .map_low_size = DT_INST_REG_SIZE_BY_NAME(0, map_lowmem), + .map_high_base = DT_INST_REG_ADDR_BY_NAME(0, map_highmem), + .map_high_size = DT_INST_REG_SIZE_BY_NAME(0, map_highmem), +}; + +static struct pcie_ep_driver_api iproc_pcie_ep_api = { + .conf_read = iproc_pcie_conf_read, + .conf_write = iproc_pcie_conf_write, + .map_addr = iproc_pcie_map_addr, + .unmap_addr = iproc_pcie_unmap_addr, + .raise_irq = iproc_pcie_raise_irq, +}; + +DEVICE_AND_API_INIT(iproc_pcie_ep_0, DT_INST_LABEL(0), + &iproc_pcie_ep_init, &iproc_pcie_ep_ctx_0, + &iproc_pcie_ep_config_0, + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, + &iproc_pcie_ep_api); diff --git a/drivers/pcie/endpoint/pcie_ep_bcm_iproc.h b/drivers/pcie/endpoint/pcie_ep_bcm_iproc.h new file mode 100644 index 00000000000..aeb4541b694 --- /dev/null +++ b/drivers/pcie/endpoint/pcie_ep_bcm_iproc.h @@ -0,0 +1,67 @@ +/* + * Copyright 2020 Broadcom + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_PCIE_EP_BCM_IPROC_H_ +#define ZEPHYR_INCLUDE_DRIVERS_PCIE_EP_BCM_IPROC_H_ + +#include + +#define PCIE_LINK_STATUS_CONTROL 0xbc +#define PCIE_LINKSPEED_SHIFT 16 +#define PCIE_LINKWIDTH_SHIFT 20 +#define PCIE_LINKSPEED_MASK 0xf +#define PCIE_LINKWIDTH_MASK 0x3f +#define PCIE_RC_MODE_MASK 0x1 + +#define MSI_ADDR_L 0x5c +#define MSI_ADDR_H 0x60 +#define MSI_DATA 0x64 + +#define ID_VAL4_OFFSET 0x440 +#define MSIX_CONTROL 0x4c0 +#define MSIX_TBL_OFF_BIR 0x4c4 +#define MSIX_PBA_OFF_BIR 0x4c8 + +#define MSIX_TBL_B2_10000 0x10002 +#define MSIX_PBA_B2_10800 0x10802 +#define MSIX_TABLE_ENTRY_SIZE 16 +#define MSIX_TABLE_SIZE 16 +#define MSIX_TBL_DATA_OFF 8 + +#define MSIX_TABLE_BASE 0x20010000 + +#define MSI_COUNT_SHIFT 12 +#define MSI_COUNT_MASK 0x7000 +#define MSI_COUNT_VAL 4 + +#define MSI_CSR_MASK 0xffffffff +#define MSI_EN_MASK 0xf + +#define PAXB_OARR_VALID BIT(0) + +enum pcie_outbound_map { + PCIE_MAP_LOWMEM_IDX, + PCIE_MAP_HIGHMEM_IDX, +}; + +struct iproc_pcie_ep_config { + struct iproc_pcie_reg *base; /* Base address of PAXB registers */ + uint32_t reg_size; + uint32_t map_low_base; /* Base addr of outbound mapping at lowmem */ + uint32_t map_low_size; + uint64_t map_high_base; /* Base addr of outbound mapping at highmem */ + uint32_t map_high_size; + unsigned int id; +}; + +struct iproc_pcie_ep_ctx { + struct k_spinlock ob_map_lock; + struct k_spinlock raise_irq_lock; + bool highmem_in_use; + bool lowmem_in_use; +}; + +#endif /* ZEPHYR_INCLUDE_DRIVERS_PCIE_EP_BCM_IPROC_H_ */ diff --git a/drivers/pcie/endpoint/pcie_ep_bcm_iproc_regs.h b/drivers/pcie/endpoint/pcie_ep_bcm_iproc_regs.h new file mode 100644 index 00000000000..8f5e1b13e6d --- /dev/null +++ b/drivers/pcie/endpoint/pcie_ep_bcm_iproc_regs.h @@ -0,0 +1,418 @@ +/* + * Copyright 2020 Broadcom + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_PCIE_EP_BCM_IPROC_REGS_H_ +#define ZEPHYR_INCLUDE_DRIVERS_PCIE_EP_BCM_IPROC_REGS_H_ + +struct paxb_64 { + uint32_t lower; + uint32_t upper; +}; + +#ifdef CONFIG_PCIE_EP_BCM_IPROC_V2 +struct paxb_imap { + uint32_t lower; + uint32_t upper; + uint32_t axim_write_config; + uint32_t axim_read_config; +}; + +struct iproc_pcie_reg { + uint32_t paxb_clk_control; + uint32_t paxb_ep_perst_hold_off; + uint32_t paxb_global_control; + uint32_t paxb_flush_control; + uint32_t paxb_flush_status; + uint32_t paxb_strap_status; + uint32_t paxb_reset_status; + uint32_t paxb_mps_mrrs_stat; + uint32_t paxb_cfg_addr; + uint32_t paxb_cfg_data; + uint32_t paxb_cfg_be; + uint32_t paxb_config_ind_addr; + uint32_t paxb_config_ind_data; + uint32_t paxb_config_ind_cmpl_stat; + uint32_t paxb_config_ind_be; + uint32_t paxb_config_ecm_addr; + uint32_t paxb_config_ecm_data; + uint32_t paxb_hide_func_cfg; + uint32_t paxb_0_apb_timeout; + uint32_t paxb_0_apb_err_en_for_cfg_rd_cmpl; + uint32_t paxb_0_apb_err_en_for_cfg_wr_cmpl; + uint32_t paxb_0_ur_resp_on_apb_timeout; + uint32_t paxb_ordering_cfg; + uint32_t paxb_master_cfg; + uint32_t paxb_master_axid_seq_num_cfg; + uint32_t paxb_pnpn_so_traffic_shaper_count_slow; + uint32_t paxb_pnpn_so_traffic_shaper_count_fast; + uint32_t paxb_pnpn_so_traffic_shaper_thrshold; + uint32_t paxb_bdf_to_func_num_mapping; + uint32_t paxb_atomics_cfg; + uint32_t paxb_master_gic_its_address; + uint32_t paxb_master_id_seq_num_avbl_status; + uint32_t paxb_axim_rd_fsm_state; + uint32_t paxb_atomics_status; + uint32_t paxb_atomics_fail_addr_h_status; + uint32_t paxb_atomics_fail_addr_l_status; + uint32_t paxb_atomics_fail_status; + uint32_t paxb_atomics_fail_pf_vf_num; + uint32_t paxb_nullified_tx_pd_status; + uint32_t paxb_nullified_tx_pd_addr_h_status; + uint32_t paxb_nullified_tx_pd_addr_l_status; + uint32_t paxb_ds_non_posted_crdt_default; + uint32_t paxb_ds_posted_crdt_default; + uint32_t paxb_ds_cmpl_crdt_default; + uint32_t paxb_ds_cfg; + uint32_t paxb_us_cfg; + uint32_t paxb_axim_write_config_func0; + uint32_t paxb_axim_read_config_func0; + uint32_t paxb_axim_write_config_func1; + uint32_t paxb_axim_read_config_func1; + uint32_t paxb_axim_write_config_func2; + uint32_t paxb_axim_read_config_func2; + uint32_t paxb_axim_write_config_func3; + uint32_t paxb_axim_read_config_func3; + uint32_t paxb_axim_write_config_func4; + uint32_t paxb_axim_read_config_func4; + uint32_t paxb_axim_write_config_func5; + uint32_t paxb_axim_read_config_func5; + uint32_t paxb_axim_write_config_func6; + uint32_t paxb_axim_read_config_func6; + uint32_t paxb_axim_write_config_func7; + uint32_t paxb_axim_read_config_func7; + uint32_t paxb_axim_write_config_func8; + uint32_t paxb_axim_read_config_func8; + uint32_t paxb_axim_write_config_func9; + uint32_t paxb_axim_read_config_func9; + uint32_t paxb_axim_write_config_func10; + uint32_t paxb_axim_read_config_func10; + uint32_t paxb_axim_write_config_func11; + uint32_t paxb_axim_read_config_func11; + uint32_t paxb_axim_write_config_func12; + uint32_t paxb_axim_read_config_func12; + uint32_t paxb_axim_write_config_func13; + uint32_t paxb_axim_read_config_func13; + uint32_t paxb_axim_write_config_func14; + uint32_t paxb_axim_read_config_func14; + uint32_t paxb_axim_write_config_func15; + uint32_t paxb_axim_read_config_func15; + uint32_t paxb_default_imap_lower; + uint32_t paxb_default_imap_upper; + uint32_t paxb_default_imap_axim_write_config; + uint32_t paxb_default_imap_axim_read_config; + struct paxb_imap paxb_func0_imap0[8]; + struct paxb_imap paxb_func0_imap1[8]; + uint32_t paxb_func0_imap2; + uint32_t paxb_func0_imap2_upper; + uint32_t paxb_imap2_axim_write_config; + uint32_t paxb_imap2_axim_read_config; + uint32_t paxb_func0_imap3_0; + uint32_t paxb_func0_imap3_0_upper; + uint32_t paxb_imap3_0_axim_write_config; + uint32_t paxb_imap3_0_axim_read_config; + uint32_t paxb_func0_imap3_1; + uint32_t paxb_func0_imap3_1_upper; + uint32_t paxb_imap3_1_axim_write_config; + uint32_t paxb_imap3_1_axim_read_config; + uint32_t paxb_func0_imap3_2; + uint32_t paxb_func0_imap3_2_upper; + uint32_t paxb_imap3_2_axim_write_config; + uint32_t paxb_imap3_2_axim_read_config; + uint32_t paxb_func0_imap3_3; + uint32_t paxb_func0_imap3_3_upper; + uint32_t paxb_imap3_3_axim_write_config; + uint32_t paxb_imap3_3_axim_read_config; + uint32_t paxb_func0_imap3_4; + uint32_t paxb_func0_imap3_4_upper; + uint32_t paxb_imap3_4_axim_write_config; + uint32_t paxb_imap3_4_axim_read_config; + uint32_t paxb_func0_imap3_5; + uint32_t paxb_func0_imap3_5_upper; + uint32_t paxb_imap3_5_axim_write_config; + uint32_t paxb_imap3_5_axim_read_config; + uint32_t paxb_func0_imap3_6; + uint32_t paxb_func0_imap3_6_upper; + uint32_t paxb_imap3_6_axim_write_config; + uint32_t paxb_imap3_6_axim_read_config; + uint32_t paxb_func0_imap3_7; + uint32_t paxb_func0_imap3_7_upper; + uint32_t paxb_imap3_7_axim_write_config; + uint32_t paxb_imap3_7_axim_read_config; + uint32_t paxb_func0_imap4_0; + uint32_t paxb_func0_imap4_0_upper; + uint32_t paxb_imap4_0_axim_write_config; + uint32_t paxb_imap4_0_axim_read_config; + uint32_t paxb_func0_imap4_1; + uint32_t paxb_func0_imap4_1_upper; + uint32_t paxb_imap4_1_axim_write_config; + uint32_t paxb_imap4_1_axim_read_config; + uint32_t paxb_func0_imap4_2; + uint32_t paxb_func0_imap4_2_upper; + uint32_t paxb_imap4_2_axim_write_config; + uint32_t paxb_imap4_2_axim_read_config; + uint32_t paxb_func0_imap4_3; + uint32_t paxb_func0_imap4_3_upper; + uint32_t paxb_imap4_3_axim_write_config; + uint32_t paxb_imap4_3_axim_read_config; + uint32_t paxb_func0_imap4_4; + uint32_t paxb_func0_imap4_4_upper; + uint32_t paxb_imap4_4_axim_write_config; + uint32_t paxb_imap4_4_axim_read_config; + uint32_t paxb_func0_imap4_5; + uint32_t paxb_func0_imap4_5_upper; + uint32_t paxb_imap4_5_axim_write_config; + uint32_t paxb_imap4_5_axim_read_config; + uint32_t paxb_func0_imap4_6; + uint32_t paxb_func0_imap4_6_upper; + uint32_t paxb_imap4_6_axim_write_config; + uint32_t paxb_imap4_6_axim_read_config; + uint32_t paxb_func0_imap4_7; + uint32_t paxb_func0_imap4_7_upper; + uint32_t paxb_imap4_7_axim_write_config; + uint32_t paxb_imap4_7_axim_read_config; + struct paxb_64 paxb_iarr[5]; + uint32_t paxb_override_window0_cfg0; + uint32_t paxb_override_window0_cfg1; + uint32_t paxb_override_window0_write_cfg; + uint32_t paxb_override_window0_read_cfg; + uint32_t paxb_override_window1_cfg0; + uint32_t paxb_override_window1_cfg1; + uint32_t paxb_override_window1_write_cfg; + uint32_t paxb_override_window1_read_cfg; + uint32_t paxb_msi_base_addr_cfg; + uint32_t paxb_msi_high_addr_cfg; + uint32_t paxb_msi_window_write_cfg; + uint32_t paxb_oarr_func0_msi_page; + uint32_t paxb_oarr_func0_msi_page_upper; + struct paxb_64 paxb_oarr[2]; + struct paxb_64 paxb_omap[2]; + uint32_t paxb_oarr_2; + uint32_t paxb_oarr_2_upper; + uint32_t paxb_omap_2_lower; + uint32_t paxb_omap_2_upper; + uint32_t paxb_oarr_3; + uint32_t paxb_oarr_3_upper; + uint32_t paxb_omap_3_lower; + uint32_t paxb_omap_3_upper; + uint32_t paxb_oarr_4; + uint32_t paxb_oarr_4_upper; + uint32_t paxb_omap_4_upper; + uint32_t paxb_rc_pm_control; + uint32_t paxb_rc_pm_status; + uint32_t paxb_ep_pm_control; + uint32_t paxb_ep_pm_status; + uint32_t paxb_ep_ltr_control; + uint32_t paxb_ep_ltr_status; + uint32_t paxb_ep_obff_status; + uint32_t paxb_pcie_error_status; + uint32_t paxb_pcie_link_status; + uint32_t paxb_ecam_cfg_0; + uint32_t paxb_ecam_cfg_1; + uint32_t paxb_ecam_cfg_rc; + uint32_t paxb_ecam_crs_cfg; + uint32_t paxb_ecam_cfg_rd_data; + uint32_t paxb_ecam_cmpl_stat; + uint32_t paxb_ecam_apb_err_cfg; + uint32_t paxb_ecam_apb_ur_resp_cfg; + uint32_t paxb_mem_pwr_cfg; + uint32_t paxb_mem_iso_cfg; + uint32_t paxb_mem_pwr_status; + uint32_t paxb_free_cid_cfg; + uint32_t paxb_free_cid_status; + uint32_t paxb_slave_cfg; + uint32_t paxb_slave_pf_vf_offset; + uint32_t paxb_cmp_err_tx_cplh_status; + uint32_t paxb_cmp_err_tx_cplh_addr_h_status; + uint32_t paxb_cmp_err_tx_cplh_addr_l_status; + uint32_t paxb_axi_slave_debug_status; + uint32_t paxb_paxb_intr_status; + uint32_t paxb_paxb_intr_en; + uint32_t paxb_paxb_intr_clear; + uint32_t paxb_pcie_cfg_intr_status; + uint32_t paxb_pcie_cfg_intr_mask; + uint32_t paxb_pcie_cfg_intr_clear; + uint32_t paxb_master_intr_status; + uint32_t paxb_master_intr_mask; + uint32_t paxb_master_intr_clear; + uint32_t paxb_slave_intr_status; + uint32_t paxb_slave_intr_mask; + uint32_t paxb_slave_intr_clear; + uint32_t paxb_user_if_intr_status; + uint32_t paxb_user_if_intr_mask; + uint32_t paxb_user_if_intr_clear; + uint32_t paxb_master_underflow_status; + uint32_t paxb_master_overflow_status; + uint32_t paxb_master_fifo_ecc_corr_status; + uint32_t paxb_master_fifo_ecc_uncorr_status; + uint32_t paxb_slave_underflow_status; + uint32_t paxb_slave_overflow_status; + uint32_t paxb_slave_ecc_err_corrected_status; + uint32_t paxb_slave_ecc_err_uncor_status; + uint32_t paxb_userif_underflow_status; + uint32_t paxb_userif_overflow_status; + uint32_t paxb_userif_ecc_err_corrected_status; + uint32_t paxb_userif_ecc_err_uncor_status; +}; +#else +struct iproc_pcie_reg { + uint32_t paxb_clk_control; + uint32_t paxb_rc_pm_control; + uint32_t paxb_rc_pm_status; + uint32_t paxb_ep_pm_control; + uint32_t paxb_ep_pm_status; + uint32_t paxb_ep_ltr_control; + uint32_t paxb_ep_ltr_status; + uint32_t paxb_reserved_0[1]; + uint32_t paxb_ep_obff_status; + uint32_t paxb_pcie_error_status; + uint32_t paxb_reserved_1[2]; + uint32_t paxb_paxb_endianness; + uint32_t paxb_apb_timeout_count; + uint32_t paxb_paxb_tx_arbiter_priority; + uint32_t paxb_reserved_2[1]; + uint32_t paxb_paxb_rd_cmpl_buf_init_start; + uint32_t paxb_paxb_rd_cmpl_buf_init_done; + uint32_t paxb_pcie_ordering_rules_enable; + uint32_t paxb_axi_slverr_en_for_mem_rd_cmpl; + uint32_t paxb_reserved_3[44]; + uint32_t paxb_pcie_rc_axi_config; + uint32_t paxb_pcie_ep_axi_config; + uint32_t paxb_pcie_paxb_rx_debug_status_0; + uint32_t paxb_pcie_paxb_rx_debug_control_0; + uint32_t paxb_reserved_4[4]; + uint32_t paxb_config_ind_addr; + uint32_t paxb_config_ind_data; + uint32_t paxb_reserved_5[51]; + uint32_t paxb_cfg_be; + uint32_t paxb_cfg_addr; + uint32_t paxb_cfg_data; + uint32_t paxb_pcie_sys_eq_page; + uint32_t paxb_pcie_sys_msi_page; + uint32_t paxb_reserved_6[2]; + uint32_t paxb_pcie_sys_msi_ctrl[6]; + uint32_t paxb_reserved_7[10]; + uint32_t paxb_pcie_sys_eq_head_0; + uint32_t paxb_pcie_sys_eq_tail_0; + uint32_t paxb_pcie_sys_eq_head_1; + uint32_t paxb_pcie_sys_eq_tail_1; + uint32_t paxb_pcie_sys_eq_head_2; + uint32_t paxb_pcie_sys_eq_tail_2; + uint32_t paxb_pcie_sys_eq_head_3; + uint32_t paxb_pcie_sys_eq_tail_3; + uint32_t paxb_pcie_sys_eq_head_4; + uint32_t paxb_pcie_sys_eq_tail_4; + uint32_t paxb_pcie_sys_eq_head_5; + uint32_t paxb_pcie_sys_eq_tail_5; + uint32_t paxb_pcie_sys_eq_tail_early[6]; + uint32_t paxb_reserved_8[2]; + uint32_t paxb_pcie_sys_eq_overwritten[6]; + uint32_t paxb_reserved_9[2]; + uint32_t paxb_pcie_sys_eq_page_upper; + uint32_t paxb_pcie_sys_msi_page_upper; + uint32_t paxb_reserved_10[26]; + uint32_t paxb_pcie_sys_rc_intx_en; + uint32_t paxb_pcie_sys_rc_intx_csr; + uint32_t paxb_reserved_11[2]; + uint32_t paxb_pcie_sys_msi_req; + uint32_t paxb_pcie_sys_host_intr_en; + uint32_t paxb_pcie_sys_host_intr_csr; + uint32_t paxb_reserved_12[1]; + uint32_t paxb_pcie_sys_host_intr[4]; + uint32_t paxb_pcie_sys_ep_int_en0; + uint32_t paxb_pcie_sys_ep_int_en1; + uint32_t paxb_reserved_13[2]; + uint32_t paxb_pcie_sys_ep_int_csr0; + uint32_t paxb_pcie_sys_ep_int_csr1; + uint32_t paxb_reserved_14[2]; + uint32_t paxb_cmicd_to_pcie_intr_en; + uint32_t paxb_reserved_15[543]; + uint32_t paxb_func0_imap0[8]; + uint32_t paxb_func1_imap0[8]; + uint32_t paxb_func0_imap0_upper[8]; + uint32_t paxb_func1_imap0_upper[8]; + uint32_t paxb_reserved_16[16]; + uint32_t paxb_func0_imap2; + uint32_t paxb_func0_imap2_upper; + uint32_t paxb_func1_imap2; + uint32_t paxb_func1_imap2_upper; + uint32_t paxb_func0_imap0_0123_regs_type; + uint32_t paxb_reserved_17[11]; + struct paxb_64 paxb_iarr[3]; + uint32_t paxb_reserved_18[2]; + struct paxb_64 paxb_oarr[2]; + uint32_t paxb_reserved_19[1]; + uint32_t paxb_oarr_func0_msi_page; + uint32_t paxb_oarr_func1_msi_page; + uint32_t paxb_reserved_20[1]; + struct paxb_64 paxb_omap[2]; + uint32_t paxb_oarr_func0_msi_page_upper; + uint32_t paxb_oarr_func1_msi_page_upper; + uint32_t paxb_reserved_21[1]; + uint32_t paxb_func1_iarr_2_size; + uint32_t paxb_oarr_2; + uint32_t paxb_oarr_2_upper; + uint32_t paxb_omap_2_lower; + uint32_t paxb_omap_2_upper; + struct paxb_64 paxb_func0_imap1[8]; + struct paxb_64 paxb_func1_imap1[8]; + uint32_t paxb_oarr_3; + uint32_t paxb_oarr_3_upper; + uint32_t paxb_omap_3_lower; + uint32_t paxb_omap_3_upper; + uint32_t paxb_iarr_3_lower; + uint32_t paxb_iarr_3_upper; + struct paxb_64 paxb_func0_imap3[8]; + uint32_t paxb_func0_imap3_axuser[8]; + uint32_t paxb_iarr_4_lower; + uint32_t paxb_iarr_4_upper; + struct paxb_64 paxb_func0_imap4[8]; + uint32_t paxb_func0_imap4_axuser[8]; + uint32_t paxb_default_imap_lower; + uint32_t paxb_default_imap_upper; + uint32_t paxb_default_imap_axuser; + uint32_t paxb_default_imap_axcache; + uint32_t paxb_cfg_tlp_rd_status; + uint32_t paxb_reserved_22[7]; + uint32_t paxb_mem_control; + uint32_t paxb_mem_ecc_err_log_0; + uint32_t paxb_mem_ecc_err_log_1; + uint32_t paxb_pcie_link_status; + uint32_t paxb_strap_status; + uint32_t paxb_reset_status; + uint32_t paxb_reset_enable_in_pcie_link_down; + uint32_t paxb_reserved_23[1]; + uint32_t paxb_paxb_tx_debug_cfg; + uint32_t paxb_paxb_misc_config; + uint32_t paxb_reserved_24[2]; + uint32_t paxb_paxb_intr_en; + uint32_t paxb_paxb_intr_clear; + uint32_t paxb_paxb_intr_status; + uint32_t paxb_reserved_25[1]; + uint32_t paxb_apb_err_en_for_cfg_rd_cmpl; + uint32_t paxb_pcie_replay_addr_buf_ecc_log; + uint32_t paxb_pcie_replay_data_buf_ecc_log; + uint32_t paxb_pcie_dl_to_tl_buf_ecc_log; + uint32_t paxb_pcie_tl_to_dl_buf_ecc_log; + uint32_t paxb_reserved_26[3]; + uint32_t paxb_func0_imap0_axuser[8]; + uint32_t paxb_func1_imap0_axuser[8]; + uint32_t paxb_func0_imap1_axuser[8]; + uint32_t paxb_func1_imap1_axuser[8]; + uint32_t paxb_func0_imap2_axuser; + uint32_t paxb_func1_imap2_axuser; +}; +#endif + +static inline void pcie_write32(uint32_t data, uint32_t *addr) +{ + sys_write32(data, (mem_addr_t)addr); +} + +static inline uint32_t pcie_read32(uint32_t *addr) +{ + return sys_read32((mem_addr_t)addr); +} +#endif /* ZEPHYR_INCLUDE_DRIVERS_PCIE_EP_BCM_IPROC_REGS_H_ */