/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2020 Marvell International Ltd. */ #ifndef __CVMX_PCIE_H__ #define __CVMX_PCIE_H__ #define CVMX_PCIE_MAX_PORTS 4 #define CVMX_PCIE_PORTS \ ((OCTEON_IS_MODEL(OCTEON_CN78XX) || OCTEON_IS_MODEL(OCTEON_CN73XX)) ? \ CVMX_PCIE_MAX_PORTS : \ (OCTEON_IS_MODEL(OCTEON_CN70XX) ? 3 : 2)) /* * The physical memory base mapped by BAR1. 256MB at the end of the * first 4GB. */ #define CVMX_PCIE_BAR1_PHYS_BASE ((1ull << 32) - (1ull << 28)) #define CVMX_PCIE_BAR1_PHYS_SIZE BIT_ULL(28) /* * The RC base of BAR1. gen1 has a 39-bit BAR2, gen2 has 41-bit BAR2, * place BAR1 so it is the same for both. */ #define CVMX_PCIE_BAR1_RC_BASE BIT_ULL(41) typedef union { u64 u64; struct { u64 upper : 2; /* Normally 2 for XKPHYS */ u64 reserved_49_61 : 13; /* Must be zero */ u64 io : 1; /* 1 for IO space access */ u64 did : 5; /* PCIe DID = 3 */ u64 subdid : 3; /* PCIe SubDID = 1 */ u64 reserved_38_39 : 2; /* Must be zero */ u64 node : 2; /* Numa node number */ u64 es : 2; /* Endian swap = 1 */ u64 port : 2; /* PCIe port 0,1 */ u64 reserved_29_31 : 3; /* Must be zero */ u64 ty : 1; u64 bus : 8; u64 dev : 5; u64 func : 3; u64 reg : 12; } config; struct { u64 upper : 2; /* Normally 2 for XKPHYS */ u64 reserved_49_61 : 13; /* Must be zero */ u64 io : 1; /* 1 for IO space access */ u64 did : 5; /* PCIe DID = 3 */ u64 subdid : 3; /* PCIe SubDID = 2 */ u64 reserved_38_39 : 2; /* Must be zero */ u64 node : 2; /* Numa node number */ u64 es : 2; /* Endian swap = 1 */ u64 port : 2; /* PCIe port 0,1 */ u64 address : 32; /* PCIe IO address */ } io; struct { u64 upper : 2; /* Normally 2 for XKPHYS */ u64 reserved_49_61 : 13; /* Must be zero */ u64 io : 1; /* 1 for IO space access */ u64 did : 5; /* PCIe DID = 3 */ u64 subdid : 3; /* PCIe SubDID = 3-6 */ u64 reserved_38_39 : 2; /* Must be zero */ u64 node : 2; /* Numa node number */ u64 address : 36; /* PCIe Mem address */ } mem; } cvmx_pcie_address_t; /** * Return the Core virtual base address for PCIe IO access. IOs are * read/written as an offset from this address. * * @param pcie_port PCIe port the IO is for * * Return: 64bit Octeon IO base address for read/write */ u64 cvmx_pcie_get_io_base_address(int pcie_port); /** * Size of the IO address region returned at address * cvmx_pcie_get_io_base_address() * * @param pcie_port PCIe port the IO is for * * Return: Size of the IO window */ u64 cvmx_pcie_get_io_size(int pcie_port); /** * Return the Core virtual base address for PCIe MEM access. Memory is * read/written as an offset from this address. * * @param pcie_port PCIe port the IO is for * * Return: 64bit Octeon IO base address for read/write */ u64 cvmx_pcie_get_mem_base_address(int pcie_port); /** * Size of the Mem address region returned at address * cvmx_pcie_get_mem_base_address() * * @param pcie_port PCIe port the IO is for * * Return: Size of the Mem window */ u64 cvmx_pcie_get_mem_size(int pcie_port); /** * Initialize a PCIe port for use in host(RC) mode. It doesn't enumerate the bus. * * @param pcie_port PCIe port to initialize * * Return: Zero on success */ int cvmx_pcie_rc_initialize(int pcie_port); /** * Shutdown a PCIe port and put it in reset * * @param pcie_port PCIe port to shutdown * * Return: Zero on success */ int cvmx_pcie_rc_shutdown(int pcie_port); /** * Read 8bits from a Device's config space * * @param pcie_port PCIe port the device is on * @param bus Sub bus * @param dev Device ID * @param fn Device sub function * @param reg Register to access * * Return: Result of the read */ u8 cvmx_pcie_config_read8(int pcie_port, int bus, int dev, int fn, int reg); /** * Read 16bits from a Device's config space * * @param pcie_port PCIe port the device is on * @param bus Sub bus * @param dev Device ID * @param fn Device sub function * @param reg Register to access * * Return: Result of the read */ u16 cvmx_pcie_config_read16(int pcie_port, int bus, int dev, int fn, int reg); /** * Read 32bits from a Device's config space * * @param pcie_port PCIe port the device is on * @param bus Sub bus * @param dev Device ID * @param fn Device sub function * @param reg Register to access * * Return: Result of the read */ u32 cvmx_pcie_config_read32(int pcie_port, int bus, int dev, int fn, int reg); /** * Write 8bits to a Device's config space * * @param pcie_port PCIe port the device is on * @param bus Sub bus * @param dev Device ID * @param fn Device sub function * @param reg Register to access * @param val Value to write */ void cvmx_pcie_config_write8(int pcie_port, int bus, int dev, int fn, int reg, u8 val); /** * Write 16bits to a Device's config space * * @param pcie_port PCIe port the device is on * @param bus Sub bus * @param dev Device ID * @param fn Device sub function * @param reg Register to access * @param val Value to write */ void cvmx_pcie_config_write16(int pcie_port, int bus, int dev, int fn, int reg, u16 val); /** * Write 32bits to a Device's config space * * @param pcie_port PCIe port the device is on * @param bus Sub bus * @param dev Device ID * @param fn Device sub function * @param reg Register to access * @param val Value to write */ void cvmx_pcie_config_write32(int pcie_port, int bus, int dev, int fn, int reg, u32 val); /** * Read a PCIe config space register indirectly. This is used for * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???. * * @param pcie_port PCIe port to read from * @param cfg_offset Address to read * * Return: Value read */ u32 cvmx_pcie_cfgx_read(int pcie_port, u32 cfg_offset); u32 cvmx_pcie_cfgx_read_node(int node, int pcie_port, u32 cfg_offset); /** * Write a PCIe config space register indirectly. This is used for * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???. * * @param pcie_port PCIe port to write to * @param cfg_offset Address to write * @param val Value to write */ void cvmx_pcie_cfgx_write(int pcie_port, u32 cfg_offset, u32 val); void cvmx_pcie_cfgx_write_node(int node, int pcie_port, u32 cfg_offset, u32 val); /** * Write a 32bit value to the Octeon NPEI register space * * @param address Address to write to * @param val Value to write */ static inline void cvmx_pcie_npei_write32(u64 address, u32 val) { cvmx_write64_uint32(address ^ 4, val); cvmx_read64_uint32(address ^ 4); } /** * Read a 32bit value from the Octeon NPEI register space * * @param address Address to read * Return: The result */ static inline u32 cvmx_pcie_npei_read32(u64 address) { return cvmx_read64_uint32(address ^ 4); } /** * Initialize a PCIe port for use in target(EP) mode. * * @param pcie_port PCIe port to initialize * * Return: Zero on success */ int cvmx_pcie_ep_initialize(int pcie_port); /** * Wait for posted PCIe read/writes to reach the other side of * the internal PCIe switch. This will insure that core * read/writes are posted before anything after this function * is called. This may be necessary when writing to memory that * will later be read using the DMA/PKT engines. * * @param pcie_port PCIe port to wait for */ void cvmx_pcie_wait_for_pending(int pcie_port); /** * Returns if a PCIe port is in host or target mode. * * @param pcie_port PCIe port number (PEM number) * * Return: 0 if PCIe port is in target mode, !0 if in host mode. */ int cvmx_pcie_is_host_mode(int pcie_port); #endif