mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-08 14:14:32 +00:00
280 lines
7.7 KiB
C
280 lines
7.7 KiB
C
|
/* 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
|