[linux-yocto] [PATCH 1/2] Octeon: Use cvmx-pcie.c from executive and fix compile error

Bruce Ashfield bruce.ashfield at windriver.com
Wed Feb 4 10:12:41 PST 2015


On 15-02-04 01:54 AM, Chandrakala Chavva wrote:
> From: Abhishek Paliwal <abhishek.paliwal at aricent.com>
>
> From: David Daney <david.daney at cavium.com>

How are we ending up with two From: fields in these patches ? What's
your workflow to generate and send these series ? That might explain
why we are getting two authors in the patches, when we really
want one.

To address the series as a whole, can we get them queued on a branch
in a publicly accessible linux-yocto repository, with the submission
being:

   - A description of the changes, and a quick description of how they
     are tested, or how they behave at runtime.
   - The shortlogs of the commits, grouped into functional blocks
   - An overall diffstat
   - And the upstream status for the various blocks of functionality.

I can then scan the changes for anything obviously wrong, without doing
a patch by patch review, and it will make the merge much easier.

Can we do that for all the outstanding series ? And re-send with one
master 0/N for everything ?

I see the following groups at the moment:

   [PATCH 00/12] Driver specific changes for OCTEON3
   [PATCH] Add Support for CPU power throttling
   [PATCH 00/13] MIPS-Update EDAC L2C and LMC driver support for Octeon3
   [PATCH 0/2] Sync-up S.E. files
   [PATCH 0/3] Added CIU3 interrupt handlers for cn78XX
   [PATCH 0/5] Watchdog and Coremask related changes
   [PATCH 00/13] Add USB drivers support for Octeon2 and Octeon3
   [PATCH 0/5] Add support for SPI and paravirtualization
   [PATCH 0/2] PCIE interface specific changes.

So those are the functional blocks I mentioned above, we just need them
on a branch, have the author field fixed up, and some quick descriptions
.. and then I can do a bulk merge.

Cheers,

Bruce


>
> Cleanup PCIe setup code.
> Consolidate code for each PCIe interface for assigning memory and IO
> resources.
>
> Initialize 3 PCIe ports for OCTEON3.
>
> preparation for cn78XX support, create an array of PCIe interface
> structures, instead of a mess of macros
>
> Signed-off-by: David Daney <david.daney at cavium.com>
> Signed-off-by: Leonid Rosenboim <lrosenboim at caviumnetworks.com>
> Signed-off-by: Chandrakala Chavva <cchavva at caviumnetworks.com>
> Signed-off-by: Abhishek Paliwal <abhishek.paliwal at aricent.com>
> ---
>   arch/mips/pci/pcie-octeon.c | 1623 +++++--------------------------------------
>   1 file changed, 168 insertions(+), 1455 deletions(-)
>
> diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c
> index faed7d0..04c955c 100644
> --- a/arch/mips/pci/pcie-octeon.c
> +++ b/arch/mips/pci/pcie-octeon.c
> @@ -20,1237 +20,30 @@
>   #include <asm/octeon/cvmx-pexp-defs.h>
>   #include <asm/octeon/cvmx-pemx-defs.h>
>   #include <asm/octeon/cvmx-dpi-defs.h>
> +#include <asm/octeon/cvmx-rst-defs.h>
>   #include <asm/octeon/cvmx-sli-defs.h>
>   #include <asm/octeon/cvmx-sriox-defs.h>
>   #include <asm/octeon/cvmx-helper-errata.h>
>   #include <asm/octeon/pci-octeon.h>
> -
> -#define MRRS_CN5XXX 0 /* 128 byte Max Read Request Size */
> -#define MPS_CN5XXX  0 /* 128 byte Max Packet Size (Limit of most PCs) */
> -#define MRRS_CN6XXX 3 /* 1024 byte Max Read Request Size */
> -#define MPS_CN6XXX  0 /* 128 byte Max Packet Size (Limit of most PCs) */
> +#include <asm/octeon/cvmx-pcie.h>
>
>   /* Module parameter to disable PCI probing */
>   static int pcie_disable;
>   module_param(pcie_disable, int, S_IRUGO);
>
>   static int enable_pcie_14459_war;
> -static int enable_pcie_bus_num_war[2];
> -
> -union cvmx_pcie_address {
> -	uint64_t u64;
> -	struct {
> -		uint64_t upper:2;	/* Normally 2 for XKPHYS */
> -		uint64_t reserved_49_61:13;	/* Must be zero */
> -		uint64_t io:1;	/* 1 for IO space access */
> -		uint64_t did:5; /* PCIe DID = 3 */
> -		uint64_t subdid:3;	/* PCIe SubDID = 1 */
> -		uint64_t reserved_36_39:4;	/* Must be zero */
> -		uint64_t es:2;	/* Endian swap = 1 */
> -		uint64_t port:2;	/* PCIe port 0,1 */
> -		uint64_t reserved_29_31:3;	/* Must be zero */
> -		/*
> -		 * Selects the type of the configuration request (0 = type 0,
> -		 * 1 = type 1).
> -		 */
> -		uint64_t ty:1;
> -		/* Target bus number sent in the ID in the request. */
> -		uint64_t bus:8;
> -		/*
> -		 * Target device number sent in the ID in the
> -		 * request. Note that Dev must be zero for type 0
> -		 * configuration requests.
> -		 */
> -		uint64_t dev:5;
> -		/* Target function number sent in the ID in the request. */
> -		uint64_t func:3;
> -		/*
> -		 * Selects a register in the configuration space of
> -		 * the target.
> -		 */
> -		uint64_t reg:12;
> -	} config;
> -	struct {
> -		uint64_t upper:2;	/* Normally 2 for XKPHYS */
> -		uint64_t reserved_49_61:13;	/* Must be zero */
> -		uint64_t io:1;	/* 1 for IO space access */
> -		uint64_t did:5; /* PCIe DID = 3 */
> -		uint64_t subdid:3;	/* PCIe SubDID = 2 */
> -		uint64_t reserved_36_39:4;	/* Must be zero */
> -		uint64_t es:2;	/* Endian swap = 1 */
> -		uint64_t port:2;	/* PCIe port 0,1 */
> -		uint64_t address:32;	/* PCIe IO address */
> -	} io;
> -	struct {
> -		uint64_t upper:2;	/* Normally 2 for XKPHYS */
> -		uint64_t reserved_49_61:13;	/* Must be zero */
> -		uint64_t io:1;	/* 1 for IO space access */
> -		uint64_t did:5; /* PCIe DID = 3 */
> -		uint64_t subdid:3;	/* PCIe SubDID = 3-6 */
> -		uint64_t reserved_36_39:4;	/* Must be zero */
> -		uint64_t address:36;	/* PCIe Mem address */
> -	} mem;
> +static int enable_pcie_bus_num_war[CVMX_PCIE_MAX_PORTS];
> +
> +struct octeon_pcie_interface {
> +	struct pci_controller controller;
> +	struct resource mem;
> +	struct resource io;
> +	char mem_name[20];
> +	char io_name[20];
> +	int node;
> +	int pem;
>   };
>
> -static int cvmx_pcie_rc_initialize(int pcie_port);
> -
> -#include <dma-coherence.h>
> -
> -/**
> - * Return the Core virtual base address for PCIe IO access. IOs are
> - * read/written as an offset from this address.
> - *
> - * @pcie_port: PCIe port the IO is for
> - *
> - * Returns 64bit Octeon IO base address for read/write
> - */
> -static inline uint64_t cvmx_pcie_get_io_base_address(int pcie_port)
> -{
> -	union cvmx_pcie_address pcie_addr;
> -	pcie_addr.u64 = 0;
> -	pcie_addr.io.upper = 0;
> -	pcie_addr.io.io = 1;
> -	pcie_addr.io.did = 3;
> -	pcie_addr.io.subdid = 2;
> -	pcie_addr.io.es = 1;
> -	pcie_addr.io.port = pcie_port;
> -	return pcie_addr.u64;
> -}
> -
> -/**
> - * Size of the IO address region returned at address
> - * cvmx_pcie_get_io_base_address()
> - *
> - * @pcie_port: PCIe port the IO is for
> - *
> - * Returns Size of the IO window
> - */
> -static inline uint64_t cvmx_pcie_get_io_size(int pcie_port)
> -{
> -	return 1ull << 32;
> -}
> -
> -/**
> - * Return the Core virtual base address for PCIe MEM access. Memory is
> - * read/written as an offset from this address.
> - *
> - * @pcie_port: PCIe port the IO is for
> - *
> - * Returns 64bit Octeon IO base address for read/write
> - */
> -static inline uint64_t cvmx_pcie_get_mem_base_address(int pcie_port)
> -{
> -	union cvmx_pcie_address pcie_addr;
> -	pcie_addr.u64 = 0;
> -	pcie_addr.mem.upper = 0;
> -	pcie_addr.mem.io = 1;
> -	pcie_addr.mem.did = 3;
> -	pcie_addr.mem.subdid = 3 + pcie_port;
> -	return pcie_addr.u64;
> -}
> -
> -/**
> - * Size of the Mem address region returned at address
> - * cvmx_pcie_get_mem_base_address()
> - *
> - * @pcie_port: PCIe port the IO is for
> - *
> - * Returns Size of the Mem window
> - */
> -static inline uint64_t cvmx_pcie_get_mem_size(int pcie_port)
> -{
> -	return 1ull << 36;
> -}
> -
> -/**
> - * Read a PCIe config space register indirectly. This is used for
> - * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???.
> - *
> - * @pcie_port:	PCIe port to read from
> - * @cfg_offset: Address to read
> - *
> - * Returns Value read
> - */
> -static uint32_t cvmx_pcie_cfgx_read(int pcie_port, uint32_t cfg_offset)
> -{
> -	if (octeon_has_feature(OCTEON_FEATURE_NPEI)) {
> -		union cvmx_pescx_cfg_rd pescx_cfg_rd;
> -		pescx_cfg_rd.u64 = 0;
> -		pescx_cfg_rd.s.addr = cfg_offset;
> -		cvmx_write_csr(CVMX_PESCX_CFG_RD(pcie_port), pescx_cfg_rd.u64);
> -		pescx_cfg_rd.u64 = cvmx_read_csr(CVMX_PESCX_CFG_RD(pcie_port));
> -		return pescx_cfg_rd.s.data;
> -	} else {
> -		union cvmx_pemx_cfg_rd pemx_cfg_rd;
> -		pemx_cfg_rd.u64 = 0;
> -		pemx_cfg_rd.s.addr = cfg_offset;
> -		cvmx_write_csr(CVMX_PEMX_CFG_RD(pcie_port), pemx_cfg_rd.u64);
> -		pemx_cfg_rd.u64 = cvmx_read_csr(CVMX_PEMX_CFG_RD(pcie_port));
> -		return pemx_cfg_rd.s.data;
> -	}
> -}
> -
> -/**
> - * Write a PCIe config space register indirectly. This is used for
> - * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???.
> - *
> - * @pcie_port:	PCIe port to write to
> - * @cfg_offset: Address to write
> - * @val:	Value to write
> - */
> -static void cvmx_pcie_cfgx_write(int pcie_port, uint32_t cfg_offset,
> -				 uint32_t val)
> -{
> -	if (octeon_has_feature(OCTEON_FEATURE_NPEI)) {
> -		union cvmx_pescx_cfg_wr pescx_cfg_wr;
> -		pescx_cfg_wr.u64 = 0;
> -		pescx_cfg_wr.s.addr = cfg_offset;
> -		pescx_cfg_wr.s.data = val;
> -		cvmx_write_csr(CVMX_PESCX_CFG_WR(pcie_port), pescx_cfg_wr.u64);
> -	} else {
> -		union cvmx_pemx_cfg_wr pemx_cfg_wr;
> -		pemx_cfg_wr.u64 = 0;
> -		pemx_cfg_wr.s.addr = cfg_offset;
> -		pemx_cfg_wr.s.data = val;
> -		cvmx_write_csr(CVMX_PEMX_CFG_WR(pcie_port), pemx_cfg_wr.u64);
> -	}
> -}
> -
> -/**
> - * Build a PCIe config space request address for a device
> - *
> - * @pcie_port: PCIe port to access
> - * @bus:       Sub bus
> - * @dev:       Device ID
> - * @fn:	       Device sub function
> - * @reg:       Register to access
> - *
> - * Returns 64bit Octeon IO address
> - */
> -static inline uint64_t __cvmx_pcie_build_config_addr(int pcie_port, int bus,
> -						     int dev, int fn, int reg)
> -{
> -	union cvmx_pcie_address pcie_addr;
> -	union cvmx_pciercx_cfg006 pciercx_cfg006;
> -
> -	pciercx_cfg006.u32 =
> -	    cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG006(pcie_port));
> -	if ((bus <= pciercx_cfg006.s.pbnum) && (dev != 0))
> -		return 0;
> -
> -	pcie_addr.u64 = 0;
> -	pcie_addr.config.upper = 2;
> -	pcie_addr.config.io = 1;
> -	pcie_addr.config.did = 3;
> -	pcie_addr.config.subdid = 1;
> -	pcie_addr.config.es = 1;
> -	pcie_addr.config.port = pcie_port;
> -	pcie_addr.config.ty = (bus > pciercx_cfg006.s.pbnum);
> -	pcie_addr.config.bus = bus;
> -	pcie_addr.config.dev = dev;
> -	pcie_addr.config.func = fn;
> -	pcie_addr.config.reg = reg;
> -	return pcie_addr.u64;
> -}
> -
> -/**
> - * Read 8bits from a Device's config space
> - *
> - * @pcie_port: PCIe port the device is on
> - * @bus:       Sub bus
> - * @dev:       Device ID
> - * @fn:	       Device sub function
> - * @reg:       Register to access
> - *
> - * Returns Result of the read
> - */
> -static uint8_t cvmx_pcie_config_read8(int pcie_port, int bus, int dev,
> -				      int fn, int reg)
> -{
> -	uint64_t address =
> -	    __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
> -	if (address)
> -		return cvmx_read64_uint8(address);
> -	else
> -		return 0xff;
> -}
> -
> -/**
> - * Read 16bits from a Device's config space
> - *
> - * @pcie_port: PCIe port the device is on
> - * @bus:       Sub bus
> - * @dev:       Device ID
> - * @fn:	       Device sub function
> - * @reg:       Register to access
> - *
> - * Returns Result of the read
> - */
> -static uint16_t cvmx_pcie_config_read16(int pcie_port, int bus, int dev,
> -					int fn, int reg)
> -{
> -	uint64_t address =
> -	    __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
> -	if (address)
> -		return le16_to_cpu(cvmx_read64_uint16(address));
> -	else
> -		return 0xffff;
> -}
> -
> -/**
> - * Read 32bits from a Device's config space
> - *
> - * @pcie_port: PCIe port the device is on
> - * @bus:       Sub bus
> - * @dev:       Device ID
> - * @fn:	       Device sub function
> - * @reg:       Register to access
> - *
> - * Returns Result of the read
> - */
> -static uint32_t cvmx_pcie_config_read32(int pcie_port, int bus, int dev,
> -					int fn, int reg)
> -{
> -	uint64_t address =
> -	    __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
> -	if (address)
> -		return le32_to_cpu(cvmx_read64_uint32(address));
> -	else
> -		return 0xffffffff;
> -}
> -
> -/**
> - * Write 8bits to a Device's config space
> - *
> - * @pcie_port: PCIe port the device is on
> - * @bus:       Sub bus
> - * @dev:       Device ID
> - * @fn:	       Device sub function
> - * @reg:       Register to access
> - * @val:       Value to write
> - */
> -static void cvmx_pcie_config_write8(int pcie_port, int bus, int dev, int fn,
> -				    int reg, uint8_t val)
> -{
> -	uint64_t address =
> -	    __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
> -	if (address)
> -		cvmx_write64_uint8(address, val);
> -}
> -
> -/**
> - * Write 16bits to a Device's config space
> - *
> - * @pcie_port: PCIe port the device is on
> - * @bus:       Sub bus
> - * @dev:       Device ID
> - * @fn:	       Device sub function
> - * @reg:       Register to access
> - * @val:       Value to write
> - */
> -static void cvmx_pcie_config_write16(int pcie_port, int bus, int dev, int fn,
> -				     int reg, uint16_t val)
> -{
> -	uint64_t address =
> -	    __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
> -	if (address)
> -		cvmx_write64_uint16(address, cpu_to_le16(val));
> -}
> -
> -/**
> - * Write 32bits to a Device's config space
> - *
> - * @pcie_port: PCIe port the device is on
> - * @bus:       Sub bus
> - * @dev:       Device ID
> - * @fn:	       Device sub function
> - * @reg:       Register to access
> - * @val:       Value to write
> - */
> -static void cvmx_pcie_config_write32(int pcie_port, int bus, int dev, int fn,
> -				     int reg, uint32_t val)
> -{
> -	uint64_t address =
> -	    __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
> -	if (address)
> -		cvmx_write64_uint32(address, cpu_to_le32(val));
> -}
> -
> -/**
> - * Initialize a host mode PCIe gen 1 link. This function takes a PCIe
> - * port from reset to a link up state. Software can then begin
> - * configuring the rest of the link.
> - *
> - * @pcie_port: PCIe port to initialize
> - *
> - * Returns Zero on success
> - */
> -static int __cvmx_pcie_rc_initialize_link_gen1(int pcie_port)
> -{
> -	uint64_t start_cycle;
> -	union cvmx_pescx_ctl_status pescx_ctl_status;
> -	union cvmx_pciercx_cfg452 pciercx_cfg452;
> -	union cvmx_pciercx_cfg032 pciercx_cfg032;
> -	union cvmx_pciercx_cfg448 pciercx_cfg448;
> -
> -	/* Set the lane width */
> -	pciercx_cfg452.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG452(pcie_port));
> -	pescx_ctl_status.u64 = cvmx_read_csr(CVMX_PESCX_CTL_STATUS(pcie_port));
> -	if (pescx_ctl_status.s.qlm_cfg == 0)
> -		/* We're in 8 lane (56XX) or 4 lane (54XX) mode */
> -		pciercx_cfg452.s.lme = 0xf;
> -	else
> -		/* We're in 4 lane (56XX) or 2 lane (52XX) mode */
> -		pciercx_cfg452.s.lme = 0x7;
> -	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG452(pcie_port), pciercx_cfg452.u32);
> -
> -	/*
> -	 * CN52XX pass 1.x has an errata where length mismatches on UR
> -	 * responses can cause bus errors on 64bit memory
> -	 * reads. Turning off length error checking fixes this.
> -	 */
> -	if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
> -		union cvmx_pciercx_cfg455 pciercx_cfg455;
> -		pciercx_cfg455.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG455(pcie_port));
> -		pciercx_cfg455.s.m_cpl_len_err = 1;
> -		cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG455(pcie_port), pciercx_cfg455.u32);
> -	}
> -
> -	/* Lane swap needs to be manually enabled for CN52XX */
> -	if (OCTEON_IS_MODEL(OCTEON_CN52XX) && (pcie_port == 1)) {
> -		pescx_ctl_status.s.lane_swp = 1;
> -		cvmx_write_csr(CVMX_PESCX_CTL_STATUS(pcie_port), pescx_ctl_status.u64);
> -	}
> -
> -	/* Bring up the link */
> -	pescx_ctl_status.u64 = cvmx_read_csr(CVMX_PESCX_CTL_STATUS(pcie_port));
> -	pescx_ctl_status.s.lnk_enb = 1;
> -	cvmx_write_csr(CVMX_PESCX_CTL_STATUS(pcie_port), pescx_ctl_status.u64);
> -
> -	/*
> -	 * CN52XX pass 1.0: Due to a bug in 2nd order CDR, it needs to
> -	 * be disabled.
> -	 */
> -	if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0))
> -		__cvmx_helper_errata_qlm_disable_2nd_order_cdr(0);
> -
> -	/* Wait for the link to come up */
> -	start_cycle = cvmx_get_cycle();
> -	do {
> -		if (cvmx_get_cycle() - start_cycle > 2 * octeon_get_clock_rate()) {
> -			cvmx_dprintf("PCIe: Port %d link timeout\n", pcie_port);
> -			return -1;
> -		}
> -		cvmx_wait(10000);
> -		pciercx_cfg032.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
> -	} while (pciercx_cfg032.s.dlla == 0);
> -
> -	/* Clear all pending errors */
> -	cvmx_write_csr(CVMX_PEXP_NPEI_INT_SUM, cvmx_read_csr(CVMX_PEXP_NPEI_INT_SUM));
> -
> -	/*
> -	 * Update the Replay Time Limit. Empirically, some PCIe
> -	 * devices take a little longer to respond than expected under
> -	 * load. As a workaround for this we configure the Replay Time
> -	 * Limit to the value expected for a 512 byte MPS instead of
> -	 * our actual 256 byte MPS. The numbers below are directly
> -	 * from the PCIe spec table 3-4.
> -	 */
> -	pciercx_cfg448.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG448(pcie_port));
> -	switch (pciercx_cfg032.s.nlw) {
> -	case 1:		/* 1 lane */
> -		pciercx_cfg448.s.rtl = 1677;
> -		break;
> -	case 2:		/* 2 lanes */
> -		pciercx_cfg448.s.rtl = 867;
> -		break;
> -	case 4:		/* 4 lanes */
> -		pciercx_cfg448.s.rtl = 462;
> -		break;
> -	case 8:		/* 8 lanes */
> -		pciercx_cfg448.s.rtl = 258;
> -		break;
> -	}
> -	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG448(pcie_port), pciercx_cfg448.u32);
> -
> -	return 0;
> -}
> -
> -static void __cvmx_increment_ba(union cvmx_sli_mem_access_subidx *pmas)
> -{
> -	if (OCTEON_IS_MODEL(OCTEON_CN68XX))
> -		pmas->cn68xx.ba++;
> -	else
> -		pmas->cn63xx.ba++;
> -}
> -
> -/**
> - * Initialize a PCIe gen 1 port for use in host(RC) mode. It doesn't
> - * enumerate the bus.
> - *
> - * @pcie_port: PCIe port to initialize
> - *
> - * Returns Zero on success
> - */
> -static int __cvmx_pcie_rc_initialize_gen1(int pcie_port)
> -{
> -	int i;
> -	int base;
> -	u64 addr_swizzle;
> -	union cvmx_ciu_soft_prst ciu_soft_prst;
> -	union cvmx_pescx_bist_status pescx_bist_status;
> -	union cvmx_pescx_bist_status2 pescx_bist_status2;
> -	union cvmx_npei_ctl_status npei_ctl_status;
> -	union cvmx_npei_mem_access_ctl npei_mem_access_ctl;
> -	union cvmx_npei_mem_access_subidx mem_access_subid;
> -	union cvmx_npei_dbg_data npei_dbg_data;
> -	union cvmx_pescx_ctl_status2 pescx_ctl_status2;
> -	union cvmx_pciercx_cfg032 pciercx_cfg032;
> -	union cvmx_npei_bar1_indexx bar1_index;
> -
> -retry:
> -	/*
> -	 * Make sure we aren't trying to setup a target mode interface
> -	 * in host mode.
> -	 */
> -	npei_ctl_status.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS);
> -	if ((pcie_port == 0) && !npei_ctl_status.s.host_mode) {
> -		cvmx_dprintf("PCIe: Port %d in endpoint mode\n", pcie_port);
> -		return -1;
> -	}
> -
> -	/*
> -	 * Make sure a CN52XX isn't trying to bring up port 1 when it
> -	 * is disabled.
> -	 */
> -	if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
> -		npei_dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA);
> -		if ((pcie_port == 1) && npei_dbg_data.cn52xx.qlm0_link_width) {
> -			cvmx_dprintf("PCIe: ERROR: cvmx_pcie_rc_initialize() called on port1, but port1 is disabled\n");
> -			return -1;
> -		}
> -	}
> -
> -	/*
> -	 * PCIe switch arbitration mode. '0' == fixed priority NPEI,
> -	 * PCIe0, then PCIe1. '1' == round robin.
> -	 */
> -	npei_ctl_status.s.arb = 1;
> -	/* Allow up to 0x20 config retries */
> -	npei_ctl_status.s.cfg_rtry = 0x20;
> -	/*
> -	 * CN52XX pass1.x has an errata where P0_NTAGS and P1_NTAGS
> -	 * don't reset.
> -	 */
> -	if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
> -		npei_ctl_status.s.p0_ntags = 0x20;
> -		npei_ctl_status.s.p1_ntags = 0x20;
> -	}
> -	cvmx_write_csr(CVMX_PEXP_NPEI_CTL_STATUS, npei_ctl_status.u64);
> -
> -	/* Bring the PCIe out of reset */
> -	if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_EBH5200) {
> -		/*
> -		 * The EBH5200 board swapped the PCIe reset lines on
> -		 * the board. As a workaround for this bug, we bring
> -		 * both PCIe ports out of reset at the same time
> -		 * instead of on separate calls. So for port 0, we
> -		 * bring both out of reset and do nothing on port 1
> -		 */
> -		if (pcie_port == 0) {
> -			ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
> -			/*
> -			 * After a chip reset the PCIe will also be in
> -			 * reset. If it isn't, most likely someone is
> -			 * trying to init it again without a proper
> -			 * PCIe reset.
> -			 */
> -			if (ciu_soft_prst.s.soft_prst == 0) {
> -				/* Reset the ports */
> -				ciu_soft_prst.s.soft_prst = 1;
> -				cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64);
> -				ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
> -				ciu_soft_prst.s.soft_prst = 1;
> -				cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64);
> -				/* Wait until pcie resets the ports. */
> -				udelay(2000);
> -			}
> -			ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
> -			ciu_soft_prst.s.soft_prst = 0;
> -			cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64);
> -			ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
> -			ciu_soft_prst.s.soft_prst = 0;
> -			cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64);
> -		}
> -	} else {
> -		/*
> -		 * The normal case: The PCIe ports are completely
> -		 * separate and can be brought out of reset
> -		 * independently.
> -		 */
> -		if (pcie_port)
> -			ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
> -		else
> -			ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
> -		/*
> -		 * After a chip reset the PCIe will also be in
> -		 * reset. If it isn't, most likely someone is trying
> -		 * to init it again without a proper PCIe reset.
> -		 */
> -		if (ciu_soft_prst.s.soft_prst == 0) {
> -			/* Reset the port */
> -			ciu_soft_prst.s.soft_prst = 1;
> -			if (pcie_port)
> -				cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64);
> -			else
> -				cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64);
> -			/* Wait until pcie resets the ports. */
> -			udelay(2000);
> -		}
> -		if (pcie_port) {
> -			ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
> -			ciu_soft_prst.s.soft_prst = 0;
> -			cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64);
> -		} else {
> -			ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
> -			ciu_soft_prst.s.soft_prst = 0;
> -			cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64);
> -		}
> -	}
> -
> -	/*
> -	 * Wait for PCIe reset to complete. Due to errata PCIE-700, we
> -	 * don't poll PESCX_CTL_STATUS2[PCIERST], but simply wait a
> -	 * fixed number of cycles.
> -	 */
> -	cvmx_wait(400000);
> -
> -	/*
> -	 * PESCX_BIST_STATUS2[PCLK_RUN] was missing on pass 1 of
> -	 * CN56XX and CN52XX, so we only probe it on newer chips
> -	 */
> -	if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X) && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
> -		/* Clear PCLK_RUN so we can check if the clock is running */
> -		pescx_ctl_status2.u64 = cvmx_read_csr(CVMX_PESCX_CTL_STATUS2(pcie_port));
> -		pescx_ctl_status2.s.pclk_run = 1;
> -		cvmx_write_csr(CVMX_PESCX_CTL_STATUS2(pcie_port), pescx_ctl_status2.u64);
> -		/* Now that we cleared PCLK_RUN, wait for it to be set
> -		 * again telling us the clock is running
> -		 */
> -		if (CVMX_WAIT_FOR_FIELD64(CVMX_PESCX_CTL_STATUS2(pcie_port),
> -					  union cvmx_pescx_ctl_status2, pclk_run, ==, 1, 10000)) {
> -			cvmx_dprintf("PCIe: Port %d isn't clocked, skipping.\n", pcie_port);
> -			return -1;
> -		}
> -	}
> -
> -	/*
> -	 * Check and make sure PCIe came out of reset. If it doesn't
> -	 * the board probably hasn't wired the clocks up and the
> -	 * interface should be skipped.
> -	 */
> -	pescx_ctl_status2.u64 = cvmx_read_csr(CVMX_PESCX_CTL_STATUS2(pcie_port));
> -	if (pescx_ctl_status2.s.pcierst) {
> -		cvmx_dprintf("PCIe: Port %d stuck in reset, skipping.\n", pcie_port);
> -		return -1;
> -	}
> -
> -	/*
> -	 * Check BIST2 status. If any bits are set skip this
> -	 * interface. This is an attempt to catch PCIE-813 on pass 1
> -	 * parts.
> -	 */
> -	pescx_bist_status2.u64 = cvmx_read_csr(CVMX_PESCX_BIST_STATUS2(pcie_port));
> -	if (pescx_bist_status2.u64) {
> -		cvmx_dprintf("PCIe: Port %d BIST2 failed. Most likely this port isn't hooked up, skipping.\n",
> -			     pcie_port);
> -		return -1;
> -	}
> -
> -	/* Check BIST status */
> -	pescx_bist_status.u64 = cvmx_read_csr(CVMX_PESCX_BIST_STATUS(pcie_port));
> -	if (pescx_bist_status.u64)
> -		cvmx_dprintf("PCIe: BIST FAILED for port %d (0x%016llx)\n",
> -			     pcie_port, CAST64(pescx_bist_status.u64));
> -
> -
> -	/* Bring the link up */
> -	if (__cvmx_pcie_rc_initialize_link_gen1(pcie_port)) {
> -		cvmx_dprintf("PCIe: Failed to initialize port %d, probably the slot is empty\n",
> -			     pcie_port);
> -		return -1;
> -	}
> -
> -	/* Store merge control (NPEI_MEM_ACCESS_CTL[TIMER,MAX_WORD]) */
> -	npei_mem_access_ctl.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_MEM_ACCESS_CTL);
> -	npei_mem_access_ctl.s.max_word = 0;	/* Allow 16 words to combine */
> -	npei_mem_access_ctl.s.timer = 127;	/* Wait up to 127 cycles for more data */
> -	cvmx_write_csr(CVMX_PEXP_NPEI_MEM_ACCESS_CTL, npei_mem_access_ctl.u64);
> -
> -	/* Setup Mem access SubDIDs */
> -	mem_access_subid.u64 = 0;
> -	mem_access_subid.s.port = pcie_port; /* Port the request is sent to. */
> -	mem_access_subid.s.nmerge = 1;	/* Due to an errata on pass 1 chips, no merging is allowed. */
> -	mem_access_subid.s.esr = 1;	/* Endian-swap for Reads. */
> -	mem_access_subid.s.esw = 1;	/* Endian-swap for Writes. */
> -	mem_access_subid.s.nsr = 0;	/* Enable Snooping for Reads. Octeon doesn't care, but devices might want this more conservative setting */
> -	mem_access_subid.s.nsw = 0;	/* Enable Snoop for Writes. */
> -	mem_access_subid.s.ror = 0;	/* Disable Relaxed Ordering for Reads. */
> -	mem_access_subid.s.row = 0;	/* Disable Relaxed Ordering for Writes. */
> -	mem_access_subid.s.ba = 0;	/* PCIe Adddress Bits <63:34>. */
> -
> -	/*
> -	 * Setup mem access 12-15 for port 0, 16-19 for port 1,
> -	 * supplying 36 bits of address space.
> -	 */
> -	for (i = 12 + pcie_port * 4; i < 16 + pcie_port * 4; i++) {
> -		cvmx_write_csr(CVMX_PEXP_NPEI_MEM_ACCESS_SUBIDX(i), mem_access_subid.u64);
> -		mem_access_subid.s.ba += 1; /* Set each SUBID to extend the addressable range */
> -	}
> -
> -	/*
> -	 * Disable the peer to peer forwarding register. This must be
> -	 * setup by the OS after it enumerates the bus and assigns
> -	 * addresses to the PCIe busses.
> -	 */
> -	for (i = 0; i < 4; i++) {
> -		cvmx_write_csr(CVMX_PESCX_P2P_BARX_START(i, pcie_port), -1);
> -		cvmx_write_csr(CVMX_PESCX_P2P_BARX_END(i, pcie_port), -1);
> -	}
> -
> -	/* Set Octeon's BAR0 to decode 0-16KB. It overlaps with Bar2 */
> -	cvmx_write_csr(CVMX_PESCX_P2N_BAR0_START(pcie_port), 0);
> -
> -	/* BAR1 follows BAR2 with a gap so it has the same address as for gen2. */
> -	cvmx_write_csr(CVMX_PESCX_P2N_BAR1_START(pcie_port), CVMX_PCIE_BAR1_RC_BASE);
> -
> -	bar1_index.u32 = 0;
> -	bar1_index.s.addr_idx = (CVMX_PCIE_BAR1_PHYS_BASE >> 22);
> -	bar1_index.s.ca = 1;	   /* Not Cached */
> -	bar1_index.s.end_swp = 1;  /* Endian Swap mode */
> -	bar1_index.s.addr_v = 1;   /* Valid entry */
> -
> -	base = pcie_port ? 16 : 0;
> -
> -	/* Big endian swizzle for 32-bit PEXP_NCB register. */
> -#ifdef __MIPSEB__
> -	addr_swizzle = 4;
> -#else
> -	addr_swizzle = 0;
> -#endif
> -	for (i = 0; i < 16; i++) {
> -		cvmx_write64_uint32((CVMX_PEXP_NPEI_BAR1_INDEXX(base) ^ addr_swizzle),
> -				    bar1_index.u32);
> -		base++;
> -		/* 256MB / 16 >> 22 == 4 */
> -		bar1_index.s.addr_idx += (((1ull << 28) / 16ull) >> 22);
> -	}
> -
> -	/*
> -	 * Set Octeon's BAR2 to decode 0-2^39. Bar0 and Bar1 take
> -	 * precedence where they overlap. It also overlaps with the
> -	 * device addresses, so make sure the peer to peer forwarding
> -	 * is set right.
> -	 */
> -	cvmx_write_csr(CVMX_PESCX_P2N_BAR2_START(pcie_port), 0);
> -
> -	/*
> -	 * Setup BAR2 attributes
> -	 *
> -	 * Relaxed Ordering (NPEI_CTL_PORTn[PTLP_RO,CTLP_RO, WAIT_COM])
> -	 * - PTLP_RO,CTLP_RO should normally be set (except for debug).
> -	 * - WAIT_COM=0 will likely work for all applications.
> -	 *
> -	 * Load completion relaxed ordering (NPEI_CTL_PORTn[WAITL_COM]).
> -	 */
> -	if (pcie_port) {
> -		union cvmx_npei_ctl_port1 npei_ctl_port;
> -		npei_ctl_port.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_PORT1);
> -		npei_ctl_port.s.bar2_enb = 1;
> -		npei_ctl_port.s.bar2_esx = 1;
> -		npei_ctl_port.s.bar2_cax = 0;
> -		npei_ctl_port.s.ptlp_ro = 1;
> -		npei_ctl_port.s.ctlp_ro = 1;
> -		npei_ctl_port.s.wait_com = 0;
> -		npei_ctl_port.s.waitl_com = 0;
> -		cvmx_write_csr(CVMX_PEXP_NPEI_CTL_PORT1, npei_ctl_port.u64);
> -	} else {
> -		union cvmx_npei_ctl_port0 npei_ctl_port;
> -		npei_ctl_port.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_PORT0);
> -		npei_ctl_port.s.bar2_enb = 1;
> -		npei_ctl_port.s.bar2_esx = 1;
> -		npei_ctl_port.s.bar2_cax = 0;
> -		npei_ctl_port.s.ptlp_ro = 1;
> -		npei_ctl_port.s.ctlp_ro = 1;
> -		npei_ctl_port.s.wait_com = 0;
> -		npei_ctl_port.s.waitl_com = 0;
> -		cvmx_write_csr(CVMX_PEXP_NPEI_CTL_PORT0, npei_ctl_port.u64);
> -	}
> -
> -	/*
> -	 * Both pass 1 and pass 2 of CN52XX and CN56XX have an errata
> -	 * that causes TLP ordering to not be preserved after multiple
> -	 * PCIe port resets. This code detects this fault and corrects
> -	 * it by aligning the TLP counters properly. Another link
> -	 * reset is then performed. See PCIE-13340
> -	 */
> -	if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) ||
> -	    OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X) ||
> -	    OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X) ||
> -	    OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
> -		union cvmx_npei_dbg_data dbg_data;
> -		int old_in_fif_p_count;
> -		int in_fif_p_count;
> -		int out_p_count;
> -		int in_p_offset = (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X) || OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)) ? 4 : 1;
> -		int i;
> -
> -		/*
> -		 * Choose a write address of 1MB. It should be
> -		 * harmless as all bars haven't been setup.
> -		 */
> -		uint64_t write_address = (cvmx_pcie_get_mem_base_address(pcie_port) + 0x100000) | (1ull<<63);
> -
> -		/*
> -		 * Make sure at least in_p_offset have been executed before we try and
> -		 * read in_fif_p_count
> -		 */
> -		i = in_p_offset;
> -		while (i--) {
> -			cvmx_write64_uint32(write_address, 0);
> -			cvmx_wait(10000);
> -		}
> -
> -		/*
> -		 * Read the IN_FIF_P_COUNT from the debug
> -		 * select. IN_FIF_P_COUNT can be unstable sometimes so
> -		 * read it twice with a write between the reads.  This
> -		 * way we can tell the value is good as it will
> -		 * increment by one due to the write
> -		 */
> -		cvmx_write_csr(CVMX_PEXP_NPEI_DBG_SELECT, (pcie_port) ? 0xd7fc : 0xcffc);
> -		cvmx_read_csr(CVMX_PEXP_NPEI_DBG_SELECT);
> -		do {
> -			dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA);
> -			old_in_fif_p_count = dbg_data.s.data & 0xff;
> -			cvmx_write64_uint32(write_address, 0);
> -			cvmx_wait(10000);
> -			dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA);
> -			in_fif_p_count = dbg_data.s.data & 0xff;
> -		} while (in_fif_p_count != ((old_in_fif_p_count+1) & 0xff));
> -
> -		/* Update in_fif_p_count for it's offset with respect to out_p_count */
> -		in_fif_p_count = (in_fif_p_count + in_p_offset) & 0xff;
> -
> -		/* Read the OUT_P_COUNT from the debug select */
> -		cvmx_write_csr(CVMX_PEXP_NPEI_DBG_SELECT, (pcie_port) ? 0xd00f : 0xc80f);
> -		cvmx_read_csr(CVMX_PEXP_NPEI_DBG_SELECT);
> -		dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA);
> -		out_p_count = (dbg_data.s.data>>1) & 0xff;
> -
> -		/* Check that the two counters are aligned */
> -		if (out_p_count != in_fif_p_count) {
> -			cvmx_dprintf("PCIe: Port %d aligning TLP counters as workaround to maintain ordering\n", pcie_port);
> -			while (in_fif_p_count != 0) {
> -				cvmx_write64_uint32(write_address, 0);
> -				cvmx_wait(10000);
> -				in_fif_p_count = (in_fif_p_count + 1) & 0xff;
> -			}
> -			/*
> -			 * The EBH5200 board swapped the PCIe reset
> -			 * lines on the board. This means we must
> -			 * bring both links down and up, which will
> -			 * cause the PCIe0 to need alignment
> -			 * again. Lots of messages will be displayed,
> -			 * but everything should work
> -			 */
> -			if ((cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_EBH5200) &&
> -				(pcie_port == 1))
> -				cvmx_pcie_rc_initialize(0);
> -			/* Rety bringing this port up */
> -			goto retry;
> -		}
> -	}
> -
> -	/* Display the link status */
> -	pciercx_cfg032.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
> -	cvmx_dprintf("PCIe: Port %d link active, %d lanes\n", pcie_port, pciercx_cfg032.s.nlw);
> -
> -	return 0;
> -}
> -
> -/**
> -  * Initialize a host mode PCIe gen 2 link. This function takes a PCIe
> - * port from reset to a link up state. Software can then begin
> - * configuring the rest of the link.
> - *
> - * @pcie_port: PCIe port to initialize
> - *
> - * Return Zero on success.
> - */
> -static int __cvmx_pcie_rc_initialize_link_gen2(int pcie_port)
> -{
> -	uint64_t start_cycle;
> -	union cvmx_pemx_ctl_status pem_ctl_status;
> -	union cvmx_pciercx_cfg032 pciercx_cfg032;
> -	union cvmx_pciercx_cfg448 pciercx_cfg448;
> -
> -	/* Bring up the link */
> -	pem_ctl_status.u64 = cvmx_read_csr(CVMX_PEMX_CTL_STATUS(pcie_port));
> -	pem_ctl_status.s.lnk_enb = 1;
> -	cvmx_write_csr(CVMX_PEMX_CTL_STATUS(pcie_port), pem_ctl_status.u64);
> -
> -	/* Wait for the link to come up */
> -	start_cycle = cvmx_get_cycle();
> -	do {
> -		if (cvmx_get_cycle() - start_cycle >  octeon_get_clock_rate())
> -			return -1;
> -		cvmx_wait(10000);
> -		pciercx_cfg032.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
> -	} while ((pciercx_cfg032.s.dlla == 0) || (pciercx_cfg032.s.lt == 1));
> -
> -	/*
> -	 * Update the Replay Time Limit. Empirically, some PCIe
> -	 * devices take a little longer to respond than expected under
> -	 * load. As a workaround for this we configure the Replay Time
> -	 * Limit to the value expected for a 512 byte MPS instead of
> -	 * our actual 256 byte MPS. The numbers below are directly
> -	 * from the PCIe spec table 3-4
> -	 */
> -	pciercx_cfg448.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG448(pcie_port));
> -	switch (pciercx_cfg032.s.nlw) {
> -	case 1: /* 1 lane */
> -		pciercx_cfg448.s.rtl = 1677;
> -		break;
> -	case 2: /* 2 lanes */
> -		pciercx_cfg448.s.rtl = 867;
> -		break;
> -	case 4: /* 4 lanes */
> -		pciercx_cfg448.s.rtl = 462;
> -		break;
> -	case 8: /* 8 lanes */
> -		pciercx_cfg448.s.rtl = 258;
> -		break;
> -	}
> -	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG448(pcie_port), pciercx_cfg448.u32);
> -
> -	return 0;
> -}
> -
> -
> -/**
> - * Initialize a PCIe gen 2 port for use in host(RC) mode. It doesn't enumerate
> - * the bus.
> - *
> - * @pcie_port: PCIe port to initialize
> - *
> - * Returns Zero on success.
> - */
> -static int __cvmx_pcie_rc_initialize_gen2(int pcie_port)
> -{
> -	int i;
> -	union cvmx_ciu_soft_prst ciu_soft_prst;
> -	union cvmx_mio_rst_ctlx mio_rst_ctl;
> -	union cvmx_pemx_bar_ctl pemx_bar_ctl;
> -	union cvmx_pemx_ctl_status pemx_ctl_status;
> -	union cvmx_pemx_bist_status pemx_bist_status;
> -	union cvmx_pemx_bist_status2 pemx_bist_status2;
> -	union cvmx_pciercx_cfg032 pciercx_cfg032;
> -	union cvmx_pciercx_cfg515 pciercx_cfg515;
> -	union cvmx_sli_ctl_portx sli_ctl_portx;
> -	union cvmx_sli_mem_access_ctl sli_mem_access_ctl;
> -	union cvmx_sli_mem_access_subidx mem_access_subid;
> -	union cvmx_sriox_status_reg sriox_status_reg;
> -	union cvmx_pemx_bar1_indexx bar1_index;
> -
> -	if (octeon_has_feature(OCTEON_FEATURE_SRIO)) {
> -		/* Make sure this interface isn't SRIO */
> -		if (OCTEON_IS_MODEL(OCTEON_CN66XX)) {
> -			/*
> -			 * The CN66XX requires reading the
> -			 * MIO_QLMX_CFG register to figure out the
> -			 * port type.
> -			 */
> -			union cvmx_mio_qlmx_cfg qlmx_cfg;
> -			qlmx_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(pcie_port));
> -
> -			if (qlmx_cfg.s.qlm_spd == 15) {
> -				pr_notice("PCIe: Port %d is disabled, skipping.\n", pcie_port);
> -				return -1;
> -			}
> -
> -			switch (qlmx_cfg.s.qlm_spd) {
> -			case 0x1: /* SRIO 1x4 short */
> -			case 0x3: /* SRIO 1x4 long */
> -			case 0x4: /* SRIO 2x2 short */
> -			case 0x6: /* SRIO 2x2 long */
> -				pr_notice("PCIe: Port %d is SRIO, skipping.\n", pcie_port);
> -				return -1;
> -			case 0x9: /* SGMII */
> -				pr_notice("PCIe: Port %d is SGMII, skipping.\n", pcie_port);
> -				return -1;
> -			case 0xb: /* XAUI */
> -				pr_notice("PCIe: Port %d is XAUI, skipping.\n", pcie_port);
> -				return -1;
> -			case 0x0: /* PCIE gen2 */
> -			case 0x8: /* PCIE gen2 (alias) */
> -			case 0x2: /* PCIE gen1 */
> -			case 0xa: /* PCIE gen1 (alias) */
> -				break;
> -			default:
> -				pr_notice("PCIe: Port %d is unknown, skipping.\n", pcie_port);
> -				return -1;
> -			}
> -		} else {
> -			sriox_status_reg.u64 = cvmx_read_csr(CVMX_SRIOX_STATUS_REG(pcie_port));
> -			if (sriox_status_reg.s.srio) {
> -				pr_notice("PCIe: Port %d is SRIO, skipping.\n", pcie_port);
> -				return -1;
> -			}
> -		}
> -	}
> -
> -#if 0
> -    /* This code is so that the PCIe analyzer is able to see 63XX traffic */
> -	pr_notice("PCIE : init for pcie analyzer.\n");
> -	cvmx_helper_qlm_jtag_init();
> -	cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 85);
> -	cvmx_helper_qlm_jtag_shift(pcie_port, 1, 1);
> -	cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 300-86);
> -	cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 85);
> -	cvmx_helper_qlm_jtag_shift(pcie_port, 1, 1);
> -	cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 300-86);
> -	cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 85);
> -	cvmx_helper_qlm_jtag_shift(pcie_port, 1, 1);
> -	cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 300-86);
> -	cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 85);
> -	cvmx_helper_qlm_jtag_shift(pcie_port, 1, 1);
> -	cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 300-86);
> -	cvmx_helper_qlm_jtag_update(pcie_port);
> -#endif
> -
> -	/* Make sure we aren't trying to setup a target mode interface in host mode */
> -	mio_rst_ctl.u64 = cvmx_read_csr(CVMX_MIO_RST_CTLX(pcie_port));
> -	if (!mio_rst_ctl.s.host_mode) {
> -		pr_notice("PCIe: Port %d in endpoint mode.\n", pcie_port);
> -		return -1;
> -	}
> -
> -	/* CN63XX Pass 1.0 errata G-14395 requires the QLM De-emphasis be programmed */
> -	if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_0)) {
> -		if (pcie_port) {
> -			union cvmx_ciu_qlm1 ciu_qlm;
> -			ciu_qlm.u64 = cvmx_read_csr(CVMX_CIU_QLM1);
> -			ciu_qlm.s.txbypass = 1;
> -			ciu_qlm.s.txdeemph = 5;
> -			ciu_qlm.s.txmargin = 0x17;
> -			cvmx_write_csr(CVMX_CIU_QLM1, ciu_qlm.u64);
> -		} else {
> -			union cvmx_ciu_qlm0 ciu_qlm;
> -			ciu_qlm.u64 = cvmx_read_csr(CVMX_CIU_QLM0);
> -			ciu_qlm.s.txbypass = 1;
> -			ciu_qlm.s.txdeemph = 5;
> -			ciu_qlm.s.txmargin = 0x17;
> -			cvmx_write_csr(CVMX_CIU_QLM0, ciu_qlm.u64);
> -		}
> -	}
> -	/* Bring the PCIe out of reset */
> -	if (pcie_port)
> -		ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
> -	else
> -		ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
> -	/*
> -	 * After a chip reset the PCIe will also be in reset. If it
> -	 * isn't, most likely someone is trying to init it again
> -	 * without a proper PCIe reset
> -	 */
> -	if (ciu_soft_prst.s.soft_prst == 0) {
> -		/* Reset the port */
> -		ciu_soft_prst.s.soft_prst = 1;
> -		if (pcie_port)
> -			cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64);
> -		else
> -			cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64);
> -		/* Wait until pcie resets the ports. */
> -		udelay(2000);
> -	}
> -	if (pcie_port) {
> -		ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
> -		ciu_soft_prst.s.soft_prst = 0;
> -		cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64);
> -	} else {
> -		ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
> -		ciu_soft_prst.s.soft_prst = 0;
> -		cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64);
> -	}
> -
> -	/* Wait for PCIe reset to complete */
> -	udelay(1000);
> -
> -	/*
> -	 * Check and make sure PCIe came out of reset. If it doesn't
> -	 * the board probably hasn't wired the clocks up and the
> -	 * interface should be skipped.
> -	 */
> -	if (CVMX_WAIT_FOR_FIELD64(CVMX_MIO_RST_CTLX(pcie_port), union cvmx_mio_rst_ctlx, rst_done, ==, 1, 10000)) {
> -		pr_notice("PCIe: Port %d stuck in reset, skipping.\n", pcie_port);
> -		return -1;
> -	}
> -
> -	/* Check BIST status */
> -	pemx_bist_status.u64 = cvmx_read_csr(CVMX_PEMX_BIST_STATUS(pcie_port));
> -	if (pemx_bist_status.u64)
> -		pr_notice("PCIe: BIST FAILED for port %d (0x%016llx)\n", pcie_port, CAST64(pemx_bist_status.u64));
> -	pemx_bist_status2.u64 = cvmx_read_csr(CVMX_PEMX_BIST_STATUS2(pcie_port));
> -	/* Errata PCIE-14766 may cause the lower 6 bits to be randomly set on CN63XXp1 */
> -	if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
> -		pemx_bist_status2.u64 &= ~0x3full;
> -	if (pemx_bist_status2.u64)
> -		pr_notice("PCIe: BIST2 FAILED for port %d (0x%016llx)\n", pcie_port, CAST64(pemx_bist_status2.u64));
> -
> -
> -	/* Enable gen2 speed selection */
> -	pciercx_cfg515.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG515(pcie_port));
> -	pciercx_cfg515.s.dsc = 1;
> -	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG515(pcie_port), pciercx_cfg515.u32);
> -
> -	/* Bring the link up */
> -	if (__cvmx_pcie_rc_initialize_link_gen2(pcie_port)) {
> -		/*
> -		 * Some gen1 devices don't handle the gen 2 training
> -		 * correctly. Disable gen2 and try again with only
> -		 * gen1
> -		 */
> -		union cvmx_pciercx_cfg031 pciercx_cfg031;
> -		pciercx_cfg031.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG031(pcie_port));
> -		pciercx_cfg031.s.mls = 1;
> -		cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG031(pcie_port), pciercx_cfg031.u32);
> -		if (__cvmx_pcie_rc_initialize_link_gen2(pcie_port)) {
> -			pr_notice("PCIe: Link timeout on port %d, probably the slot is empty\n", pcie_port);
> -			return -1;
> -		}
> -	}
> -
> -	/* Store merge control (SLI_MEM_ACCESS_CTL[TIMER,MAX_WORD]) */
> -	sli_mem_access_ctl.u64 = cvmx_read_csr(CVMX_PEXP_SLI_MEM_ACCESS_CTL);
> -	sli_mem_access_ctl.s.max_word = 0;	/* Allow 16 words to combine */
> -	sli_mem_access_ctl.s.timer = 127;	/* Wait up to 127 cycles for more data */
> -	cvmx_write_csr(CVMX_PEXP_SLI_MEM_ACCESS_CTL, sli_mem_access_ctl.u64);
> -
> -	/* Setup Mem access SubDIDs */
> -	mem_access_subid.u64 = 0;
> -	mem_access_subid.s.port = pcie_port; /* Port the request is sent to. */
> -	mem_access_subid.s.nmerge = 0;	/* Allow merging as it works on CN6XXX. */
> -	mem_access_subid.s.esr = 1;	/* Endian-swap for Reads. */
> -	mem_access_subid.s.esw = 1;	/* Endian-swap for Writes. */
> -	mem_access_subid.s.wtype = 0;	/* "No snoop" and "Relaxed ordering" are not set */
> -	mem_access_subid.s.rtype = 0;	/* "No snoop" and "Relaxed ordering" are not set */
> -	/* PCIe Adddress Bits <63:34>. */
> -	if (OCTEON_IS_MODEL(OCTEON_CN68XX))
> -		mem_access_subid.cn68xx.ba = 0;
> -	else
> -		mem_access_subid.cn63xx.ba = 0;
> -
> -	/*
> -	 * Setup mem access 12-15 for port 0, 16-19 for port 1,
> -	 * supplying 36 bits of address space.
> -	 */
> -	for (i = 12 + pcie_port * 4; i < 16 + pcie_port * 4; i++) {
> -		cvmx_write_csr(CVMX_PEXP_SLI_MEM_ACCESS_SUBIDX(i), mem_access_subid.u64);
> -		/* Set each SUBID to extend the addressable range */
> -		__cvmx_increment_ba(&mem_access_subid);
> -	}
> -
> -	/*
> -	 * Disable the peer to peer forwarding register. This must be
> -	 * setup by the OS after it enumerates the bus and assigns
> -	 * addresses to the PCIe busses.
> -	 */
> -	for (i = 0; i < 4; i++) {
> -		cvmx_write_csr(CVMX_PEMX_P2P_BARX_START(i, pcie_port), -1);
> -		cvmx_write_csr(CVMX_PEMX_P2P_BARX_END(i, pcie_port), -1);
> -	}
> -
> -	/* Set Octeon's BAR0 to decode 0-16KB. It overlaps with Bar2 */
> -	cvmx_write_csr(CVMX_PEMX_P2N_BAR0_START(pcie_port), 0);
> -
> -	/*
> -	 * Set Octeon's BAR2 to decode 0-2^41. Bar0 and Bar1 take
> -	 * precedence where they overlap. It also overlaps with the
> -	 * device addresses, so make sure the peer to peer forwarding
> -	 * is set right.
> -	 */
> -	cvmx_write_csr(CVMX_PEMX_P2N_BAR2_START(pcie_port), 0);
> -
> -	/*
> -	 * Setup BAR2 attributes
> -	 * Relaxed Ordering (NPEI_CTL_PORTn[PTLP_RO,CTLP_RO, WAIT_COM])
> -	 * - PTLP_RO,CTLP_RO should normally be set (except for debug).
> -	 * - WAIT_COM=0 will likely work for all applications.
> -	 * Load completion relaxed ordering (NPEI_CTL_PORTn[WAITL_COM])
> -	 */
> -	pemx_bar_ctl.u64 = cvmx_read_csr(CVMX_PEMX_BAR_CTL(pcie_port));
> -	pemx_bar_ctl.s.bar1_siz = 3;  /* 256MB BAR1*/
> -	pemx_bar_ctl.s.bar2_enb = 1;
> -	pemx_bar_ctl.s.bar2_esx = 1;
> -	pemx_bar_ctl.s.bar2_cax = 0;
> -	cvmx_write_csr(CVMX_PEMX_BAR_CTL(pcie_port), pemx_bar_ctl.u64);
> -	sli_ctl_portx.u64 = cvmx_read_csr(CVMX_PEXP_SLI_CTL_PORTX(pcie_port));
> -	sli_ctl_portx.s.ptlp_ro = 1;
> -	sli_ctl_portx.s.ctlp_ro = 1;
> -	sli_ctl_portx.s.wait_com = 0;
> -	sli_ctl_portx.s.waitl_com = 0;
> -	cvmx_write_csr(CVMX_PEXP_SLI_CTL_PORTX(pcie_port), sli_ctl_portx.u64);
> -
> -	/* BAR1 follows BAR2 */
> -	cvmx_write_csr(CVMX_PEMX_P2N_BAR1_START(pcie_port), CVMX_PCIE_BAR1_RC_BASE);
> -
> -	bar1_index.u64 = 0;
> -	bar1_index.s.addr_idx = (CVMX_PCIE_BAR1_PHYS_BASE >> 22);
> -	bar1_index.s.ca = 1;	   /* Not Cached */
> -	bar1_index.s.end_swp = 1;  /* Endian Swap mode */
> -	bar1_index.s.addr_v = 1;   /* Valid entry */
> -
> -	for (i = 0; i < 16; i++) {
> -		cvmx_write_csr(CVMX_PEMX_BAR1_INDEXX(i, pcie_port), bar1_index.u64);
> -		/* 256MB / 16 >> 22 == 4 */
> -		bar1_index.s.addr_idx += (((1ull << 28) / 16ull) >> 22);
> -	}
> -
> -	/*
> -	 * Allow config retries for 250ms. Count is based off the 5Ghz
> -	 * SERDES clock.
> -	 */
> -	pemx_ctl_status.u64 = cvmx_read_csr(CVMX_PEMX_CTL_STATUS(pcie_port));
> -	pemx_ctl_status.s.cfg_rtry = 250 * 5000000 / 0x10000;
> -	cvmx_write_csr(CVMX_PEMX_CTL_STATUS(pcie_port), pemx_ctl_status.u64);
> -
> -	/* Display the link status */
> -	pciercx_cfg032.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
> -	pr_notice("PCIe: Port %d link active, %d lanes, speed gen%d\n", pcie_port, pciercx_cfg032.s.nlw, pciercx_cfg032.s.ls);
> -
> -	return 0;
> -}
> -
> -/**
> - * Initialize a PCIe port for use in host(RC) mode. It doesn't enumerate the bus.
> - *
> - * @pcie_port: PCIe port to initialize
> - *
> - * Returns Zero on success
> - */
> -static int cvmx_pcie_rc_initialize(int pcie_port)
> -{
> -	int result;
> -	if (octeon_has_feature(OCTEON_FEATURE_NPEI))
> -		result = __cvmx_pcie_rc_initialize_gen1(pcie_port);
> -	else
> -		result = __cvmx_pcie_rc_initialize_gen2(pcie_port);
> -	return result;
> -}
> -
> -/* Above was cvmx-pcie.c, below original pcie.c */
> -
>   /**
>    * Map a PCI device to the appropriate interrupt line
>    *
> @@ -1305,7 +98,7 @@ static	void set_cfg_read_retry(u32 retry_cnt)
>   {
>   	union cvmx_pemx_ctl_status pemx_ctl;
>   	pemx_ctl.u64 = cvmx_read_csr(CVMX_PEMX_CTL_STATUS(1));
> -	pemx_ctl.s.cfg_rtry = retry_cnt;
> +	pemx_ctl.cn63xx.cfg_rtry = retry_cnt;
>   	cvmx_write_csr(CVMX_PEMX_CTL_STATUS(1), pemx_ctl.u64);
>   }
>
> @@ -1316,8 +109,8 @@ static u32 disable_cfg_read_retry(void)
>
>   	union cvmx_pemx_ctl_status pemx_ctl;
>   	pemx_ctl.u64 = cvmx_read_csr(CVMX_PEMX_CTL_STATUS(1));
> -	retry_cnt =  pemx_ctl.s.cfg_rtry;
> -	pemx_ctl.s.cfg_rtry = 0;
> +	retry_cnt =  pemx_ctl.cn63xx.cfg_rtry;
> +	pemx_ctl.cn63xx.cfg_rtry = 0;
>   	cvmx_write_csr(CVMX_PEMX_CTL_STATUS(1), pemx_ctl.u64);
>   	return retry_cnt;
>   }
> @@ -1335,9 +128,8 @@ static int is_cfg_retry(void)
>    * Read a value from configuration space
>    *
>    */
> -static int octeon_pcie_read_config(unsigned int pcie_port, struct pci_bus *bus,
> -				   unsigned int devfn, int reg, int size,
> -				   u32 *val)
> +static int octeon_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
> +					int reg, int size, u32 *val)
>   {
>   	union octeon_cvmemctl cvmmemctl;
>   	union octeon_cvmemctl cvmmemctl_save;
> @@ -1346,6 +138,7 @@ static int octeon_pcie_read_config(unsigned int pcie_port, struct pci_bus *bus,
>   	int retry_cnt = 0;
>   	int max_retry_cnt = 10;
>   	u32 cfg_retry_cnt = 0;
> +	unsigned int pcie_port = pci_domain_nr(bus);
>
>   	cvmmemctl_save.u64 = 0;
>   	BUG_ON(pcie_port >= ARRAY_SIZE(enable_pcie_bus_num_war));
> @@ -1507,18 +300,6 @@ static int octeon_pcie_read_config(unsigned int pcie_port, struct pci_bus *bus,
>   	return PCIBIOS_SUCCESSFUL;
>   }
>
> -static int octeon_pcie0_read_config(struct pci_bus *bus, unsigned int devfn,
> -				    int reg, int size, u32 *val)
> -{
> -	return octeon_pcie_read_config(0, bus, devfn, reg, size, val);
> -}
> -
> -static int octeon_pcie1_read_config(struct pci_bus *bus, unsigned int devfn,
> -				    int reg, int size, u32 *val)
> -{
> -	return octeon_pcie_read_config(1, bus, devfn, reg, size, val);
> -}
> -
>   static int octeon_dummy_read_config(struct pci_bus *bus, unsigned int devfn,
>   				    int reg, int size, u32 *val)
>   {
> @@ -1528,11 +309,11 @@ static int octeon_dummy_read_config(struct pci_bus *bus, unsigned int devfn,
>   /*
>    * Write a value to PCI configuration space
>    */
> -static int octeon_pcie_write_config(unsigned int pcie_port, struct pci_bus *bus,
> -				    unsigned int devfn, int reg,
> -				    int size, u32 val)
> +static int octeon_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
> +					int reg, int size, u32 val)
>   {
>   	int bus_number = bus->number;
> +	unsigned int pcie_port = pci_domain_nr(bus);
>
>   	BUG_ON(pcie_port >= ARRAY_SIZE(enable_pcie_bus_num_war));
>
> @@ -1571,65 +352,36 @@ static int octeon_pcie_write_config(unsigned int pcie_port, struct pci_bus *bus,
>   	return PCIBIOS_SUCCESSFUL;
>   }
>
> -static int octeon_pcie0_write_config(struct pci_bus *bus, unsigned int devfn,
> -				     int reg, int size, u32 val)
> -{
> -	return octeon_pcie_write_config(0, bus, devfn, reg, size, val);
> -}
> -
> -static int octeon_pcie1_write_config(struct pci_bus *bus, unsigned int devfn,
> -				     int reg, int size, u32 val)
> -{
> -	return octeon_pcie_write_config(1, bus, devfn, reg, size, val);
> -}
> -
>   static int octeon_dummy_write_config(struct pci_bus *bus, unsigned int devfn,
>   				     int reg, int size, u32 val)
>   {
>   	return PCIBIOS_FUNC_NOT_SUPPORTED;
>   }
>
> -static struct pci_ops octeon_pcie0_ops = {
> -	octeon_pcie0_read_config,
> -	octeon_pcie0_write_config,
> -};
> -
> -static struct resource octeon_pcie0_mem_resource = {
> -	.name = "Octeon PCIe0 MEM",
> -	.flags = IORESOURCE_MEM,
> +static struct pci_ops octeon_pcie_ops = {
> +	octeon_pcie_read_config,
> +	octeon_pcie_write_config,
>   };
>
> -static struct resource octeon_pcie0_io_resource = {
> -	.name = "Octeon PCIe0 IO",
> -	.flags = IORESOURCE_IO,
> -};
> +static struct octeon_pcie_interface octeon_pcie[4];
>
> -static struct pci_controller octeon_pcie0_controller = {
> -	.pci_ops = &octeon_pcie0_ops,
> -	.mem_resource = &octeon_pcie0_mem_resource,
> -	.io_resource = &octeon_pcie0_io_resource,
> -};
> -
> -static struct pci_ops octeon_pcie1_ops = {
> -	octeon_pcie1_read_config,
> -	octeon_pcie1_write_config,
> -};
> +static void octeon_pcie_interface_init(struct octeon_pcie_interface *iface, int node, int pem)
> +{
> +	snprintf(iface->mem_name, sizeof(iface->mem_name), "OCTEON PCIe-%d MEM", pem);
> +	iface->mem.name = iface->mem_name;
> +	iface->mem.flags = IORESOURCE_MEM;
>
> -static struct resource octeon_pcie1_mem_resource = {
> -	.name = "Octeon PCIe1 MEM",
> -	.flags = IORESOURCE_MEM,
> -};
> +	snprintf(iface->mem_name, sizeof(iface->mem_name), "OCTEON PCIe-%d IO", pem);
> +	iface->io.name = iface->io_name;
> +	iface->io.flags = IORESOURCE_IO;
>
> -static struct resource octeon_pcie1_io_resource = {
> -	.name = "Octeon PCIe1 IO",
> -	.flags = IORESOURCE_IO,
> -};
> +	iface->controller.pci_ops = &octeon_pcie_ops;
> +	iface->controller.mem_resource = &iface->mem;
> +	iface->controller.io_resource = &iface->io;
>
> -static struct pci_controller octeon_pcie1_controller = {
> -	.pci_ops = &octeon_pcie1_ops,
> -	.mem_resource = &octeon_pcie1_mem_resource,
> -	.io_resource = &octeon_pcie1_io_resource,
> -};
> +	iface->node = node;
> +	iface->pem = pem;
> +}
>
>   static struct pci_ops octeon_dummy_ops = {
>   	octeon_dummy_read_config,
> @@ -1669,8 +421,8 @@ static int device_needs_bus_num_war(uint32_t deviceid)
>   static int __init octeon_pcie_setup(void)
>   {
>   	int result;
> -	int host_mode;
> -	int srio_war15205 = 0, port;
> +	int host_mode = 0, port;
> +	int srio_war15205 = 0;
>   	union cvmx_sli_ctl_portx sli_ctl_portx;
>   	union cvmx_sriox_status_reg sriox_status_reg;
>
> @@ -1696,7 +448,7 @@ static int __init octeon_pcie_setup(void)
>   	set_io_port_base(CVMX_ADD_IO_SEG(cvmx_pcie_get_io_base_address(0)));
>   	ioport_resource.start = 0;
>   	ioport_resource.end =
> -		cvmx_pcie_get_io_base_address(1) -
> +		cvmx_pcie_get_io_base_address(CVMX_PCIE_PORTS) -
>   		cvmx_pcie_get_io_base_address(0) + cvmx_pcie_get_io_size(1) - 1;
>
>   	/*
> @@ -1710,183 +462,144 @@ static int __init octeon_pcie_setup(void)
>   	octeon_dummy_controller.mem_resource->end = (1ull<<48);
>   	register_pci_controller(&octeon_dummy_controller);
>
> -	if (octeon_has_feature(OCTEON_FEATURE_NPEI)) {
> -		union cvmx_npei_ctl_status npei_ctl_status;
> -		npei_ctl_status.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS);
> -		host_mode = npei_ctl_status.s.host_mode;
> -		octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_PCIE;
> -	} else {
> -		union cvmx_mio_rst_ctlx mio_rst_ctl;
> -		mio_rst_ctl.u64 = cvmx_read_csr(CVMX_MIO_RST_CTLX(0));
> -		host_mode = mio_rst_ctl.s.host_mode;
> -		octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_PCIE2;
> -	}
> -
> -	if (host_mode) {
> -		pr_notice("PCIe: Initializing port 0\n");
> -		/* CN63XX pass 1_x/2.0 errata PCIe-15205 */
> -		if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) ||
> -			OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_0)) {
> -			sriox_status_reg.u64 = cvmx_read_csr(CVMX_SRIOX_STATUS_REG(0));
> -			if (sriox_status_reg.s.srio) {
> -				srio_war15205 += 1;	 /* Port is SRIO */
> -				port = 0;
> +	for (port = 0; port < CVMX_PCIE_PORTS; port++) {
> +		if (octeon_has_feature(OCTEON_FEATURE_NPEI)) {
> +			if (port == 1) {
> +				host_mode = 1;
> +				/*
> +				 * Skip the 2nd port on CN52XX if port is in
> +				 * 4 lane mode
> +				 */
> +				if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
> +					union cvmx_npei_dbg_data dbg_data;
> +					dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA);
> +					if (dbg_data.cn52xx.qlm0_link_width)
> +						host_mode = 0;
> +				}
> +			} else {
> +				union cvmx_npei_ctl_status npei_ctl_status;
> +				npei_ctl_status.u64 =
> +					cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS);
> +				host_mode = npei_ctl_status.s.host_mode;
> +				octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_PCIE;
>   			}
> +		} else {
> +			union cvmx_mio_rst_ctlx mio_rst_ctl;
> +			if (OCTEON_IS_OCTEON3())
> +				mio_rst_ctl.u64 = cvmx_read_csr(CVMX_RST_CTLX(port));
> +			else
> +				mio_rst_ctl.u64 = cvmx_read_csr(CVMX_MIO_RST_CTLX(port));
> +			host_mode = mio_rst_ctl.s.host_mode;
> +			if (port == 0)
> +				octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_PCIE2;
>   		}
> -		result = cvmx_pcie_rc_initialize(0);
> -		if (result == 0) {
> -			uint32_t device0;
> -			/* Memory offsets are physical addresses */
> -			octeon_pcie0_controller.mem_offset =
> -				cvmx_pcie_get_mem_base_address(0);
> -			/* IO offsets are Mips virtual addresses */
> -			octeon_pcie0_controller.io_map_base =
> -				CVMX_ADD_IO_SEG(cvmx_pcie_get_io_base_address
> -						(0));
> -			octeon_pcie0_controller.io_offset = 0;
> -			/*
> -			 * To keep things similar to PCI, we start
> -			 * device addresses at the same place as PCI
> -			 * uisng big bar support. This normally
> -			 * translates to 4GB-256MB, which is the same
> -			 * as most x86 PCs.
> -			 */
> -			octeon_pcie0_controller.mem_resource->start =
> -				cvmx_pcie_get_mem_base_address(0) +
> -				(4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20);
> -			octeon_pcie0_controller.mem_resource->end =
> -				cvmx_pcie_get_mem_base_address(0) +
> -				cvmx_pcie_get_mem_size(0) - 1;
> -			/*
> -			 * Ports must be above 16KB for the ISA bus
> -			 * filtering in the PCI-X to PCI bridge.
> -			 */
> -			octeon_pcie0_controller.io_resource->start = 4 << 10;
> -			octeon_pcie0_controller.io_resource->end =
> -				cvmx_pcie_get_io_size(0) - 1;
> -			msleep(100); /* Some devices need extra time */
> -			register_pci_controller(&octeon_pcie0_controller);
> -			device0 = cvmx_pcie_config_read32(0, 0, 0, 0, 0);
> -			enable_pcie_bus_num_war[0] =
> -				device_needs_bus_num_war(device0);
> -		}
> -	} else {
> -		pr_notice("PCIe: Port 0 in endpoint mode, skipping.\n");
> -		/* CN63XX pass 1_x/2.0 errata PCIe-15205 */
> -		if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) ||
> -			OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_0)) {
> -			srio_war15205 += 1;
> -			port = 0;
> -		}
> -	}
> -
> -	if (octeon_has_feature(OCTEON_FEATURE_NPEI)) {
> -		host_mode = 1;
> -		/* Skip the 2nd port on CN52XX if port 0 is in 4 lane mode */
> -		if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
> -			union cvmx_npei_dbg_data dbg_data;
> -			dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA);
> -			if (dbg_data.cn52xx.qlm0_link_width)
> -				host_mode = 0;
> -		}
> -	} else {
> -		union cvmx_mio_rst_ctlx mio_rst_ctl;
> -		mio_rst_ctl.u64 = cvmx_read_csr(CVMX_MIO_RST_CTLX(1));
> -		host_mode = mio_rst_ctl.s.host_mode;
> -	}
> -
> -	if (host_mode) {
> -		pr_notice("PCIe: Initializing port 1\n");
> -		/* CN63XX pass 1_x/2.0 errata PCIe-15205 */
> -		if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) ||
> -			OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_0)) {
> -			sriox_status_reg.u64 = cvmx_read_csr(CVMX_SRIOX_STATUS_REG(1));
> -			if (sriox_status_reg.s.srio) {
> -				srio_war15205 += 1;	 /* Port is SRIO */
> -				port = 1;
> +		if (host_mode) {
> +			uint32_t device;
> +			pr_notice("PCIe: Initializing port %d\n", port);
> +
> +			/* CN63XX pass 1_x/2.0 errata PCIe-15205 */
> +			if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) ||
> +				OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_0)) {
> +				sriox_status_reg.u64 = cvmx_read_csr(
> +							CVMX_SRIOX_STATUS_REG(port));
> +				if (sriox_status_reg.s.srio)
> +					/* Port is SRIO */
> +					srio_war15205 += 1;
> +			}
> +			result = cvmx_pcie_rc_initialize(port);
> +			if (result < 0)
> +				continue;
> +
> +			/* Set IO offsets, Memory/IO resource start and end limits */
> +			switch (port) {
> +			case 0:
> +			case 1:
> +			case 2:
> +			case 3:
> +				octeon_pcie_interface_init(&octeon_pcie[port], 0, port);
> +				/* Memory offsets are physical addresses */
> +				octeon_pcie[port].controller.mem_offset = cvmx_pcie_get_mem_base_address(port);
> +				/*
> +				 * To calculate the address for accessing the 2nd PCIe device,
> +				 * either 'io_map_base' (pci_iomap()), or 'mips_io_port_base'
> +				 * (ioport_map()) value is added to
> +				 * pci_resource_start(dev,bar)). The 'mips_io_port_base' is set
> +				 * only once based on first PCIe. Also changing 'io_map_base'
> +				 * based on first slot's value so that both the routines will
> +				 * work properly.
> +				 */
> +				octeon_pcie[port].controller.io_map_base = CVMX_ADD_IO_SEG(cvmx_pcie_get_io_base_address(port));
> +				/*
> +				 * To keep things similar to PCI, we start
> +				 * device addresses at the same place as PCI
> +				 * uisng big bar support. This normally
> +				 * translates to 4GB-256MB, which is the same
> +				 * as most x86 PCs.
> +				 */
> +				octeon_pcie[port].mem.start =
> +						cvmx_pcie_get_mem_base_address(port) + (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20);
> +				octeon_pcie[port].mem.end =
> +						cvmx_pcie_get_mem_base_address(port) + cvmx_pcie_get_mem_size(port) - 1;
> +				if (port == 0) {
> +					/* IO offsets are Mips virtual addresses */
> +					octeon_pcie[port].controller.io_offset = 0;
> +					/*
> +					 * Ports must be above 16KB for the ISA bus
> +					 * filtering in the PCI-X to PCI bridge.
> +					 */
> +					octeon_pcie[port].io.start = 4 << 10;
> +					octeon_pcie[port].io.end = cvmx_pcie_get_io_size(port) - 1;
> +				} else {
> +					octeon_pcie[port].controller.io_offset =
> +						cvmx_pcie_get_io_base_address(port) - cvmx_pcie_get_io_base_address(port - 1);
> +					octeon_pcie[port].io.start =
> +						cvmx_pcie_get_io_base_address(port) - cvmx_pcie_get_io_base_address(port - 1);
> +					octeon_pcie[port].io.end = octeon_pcie[port].io.start + cvmx_pcie_get_io_size(port) - 1;
> +				}
> +				msleep(100); /* Some devices need extra time */
> +				octeon_pcie[port].controller.index = port;
> +				register_pci_controller(&octeon_pcie[port].controller);
> +				break;
> +			default:
> +				break;
> +			}
> +			device = cvmx_pcie_config_read32(port, 0, 0, 0, 0);
> +			enable_pcie_bus_num_war[port] =
> +				device_needs_bus_num_war(device);
> +		} else {
> +			pr_notice("PCIe: Port 0 in endpoint mode, skipping.\n");
> +			/* CN63XX pass 1_x/2.0 errata PCIe-15205 */
> +			if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) ||
> +				OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_0)) {
> +				srio_war15205 += 1;
>   			}
>   		}
> -		result = cvmx_pcie_rc_initialize(1);
> -		if (result == 0) {
> -			uint32_t device0;
> -			/* Memory offsets are physical addresses */
> -			octeon_pcie1_controller.mem_offset =
> -				cvmx_pcie_get_mem_base_address(1);
> -			/*
> -			 * To calculate the address for accessing the 2nd PCIe device,
> -			 * either 'io_map_base' (pci_iomap()), or 'mips_io_port_base'
> -			 * (ioport_map()) value is added to
> -			 * pci_resource_start(dev,bar)). The 'mips_io_port_base' is set
> -			 * only once based on first PCIe. Also changing 'io_map_base'
> -			 * based on first slot's value so that both the routines will
> -			 * work properly.
> -			 */
> -			octeon_pcie1_controller.io_map_base =
> -				CVMX_ADD_IO_SEG(cvmx_pcie_get_io_base_address(0));
> -			/* IO offsets are Mips virtual addresses */
> -			octeon_pcie1_controller.io_offset =
> -				cvmx_pcie_get_io_base_address(1) -
> -				cvmx_pcie_get_io_base_address(0);
> -			/*
> -			 * To keep things similar to PCI, we start device
> -			 * addresses at the same place as PCI uisng big bar
> -			 * support. This normally translates to 4GB-256MB,
> -			 * which is the same as most x86 PCs.
> -			 */
> -			octeon_pcie1_controller.mem_resource->start =
> -				cvmx_pcie_get_mem_base_address(1) + (4ul << 30) -
> -				(OCTEON_PCI_BAR1_HOLE_SIZE << 20);
> -			octeon_pcie1_controller.mem_resource->end =
> -				cvmx_pcie_get_mem_base_address(1) +
> -				cvmx_pcie_get_mem_size(1) - 1;
> -			/*
> -			 * Ports must be above 16KB for the ISA bus filtering
> -			 * in the PCI-X to PCI bridge.
> -			 */
> -			octeon_pcie1_controller.io_resource->start =
> -				cvmx_pcie_get_io_base_address(1) -
> -				cvmx_pcie_get_io_base_address(0);
> -			octeon_pcie1_controller.io_resource->end =
> -				octeon_pcie1_controller.io_resource->start +
> -				cvmx_pcie_get_io_size(1) - 1;
> -			msleep(100); /* Some devices need extra time */
> -			register_pci_controller(&octeon_pcie1_controller);
> -			device0 = cvmx_pcie_config_read32(1, 0, 0, 0, 0);
> -			enable_pcie_bus_num_war[1] =
> -				device_needs_bus_num_war(device0);
> -		}
> -	} else {
> -		pr_notice("PCIe: Port 1 not in root complex mode, skipping.\n");
> -		/* CN63XX pass 1_x/2.0 errata PCIe-15205  */
> -		if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) ||
> -			OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_0)) {
> -			srio_war15205 += 1;
> -			port = 1;
> -		}
> -	}
>
> +	}
>   	/*
>   	 * CN63XX pass 1_x/2.0 errata PCIe-15205 requires setting all
>   	 * of SRIO MACs SLI_CTL_PORT*[INT*_MAP] to similar value and
>   	 * all of PCIe Macs SLI_CTL_PORT*[INT*_MAP] to different value
>   	 * from the previous set values
>   	 */
> -	if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) ||
> +	for (port = 0; port < CVMX_PCIE_PORTS; port++) {
> +		if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) ||
>   		OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_0)) {
> -		if (srio_war15205 == 1) {
> -			sli_ctl_portx.u64 = cvmx_read_csr(CVMX_PEXP_SLI_CTL_PORTX(port));
> -			sli_ctl_portx.s.inta_map = 1;
> -			sli_ctl_portx.s.intb_map = 1;
> -			sli_ctl_portx.s.intc_map = 1;
> -			sli_ctl_portx.s.intd_map = 1;
> -			cvmx_write_csr(CVMX_PEXP_SLI_CTL_PORTX(port), sli_ctl_portx.u64);
> -
> -			sli_ctl_portx.u64 = cvmx_read_csr(CVMX_PEXP_SLI_CTL_PORTX(!port));
> -			sli_ctl_portx.s.inta_map = 0;
> -			sli_ctl_portx.s.intb_map = 0;
> -			sli_ctl_portx.s.intc_map = 0;
> -			sli_ctl_portx.s.intd_map = 0;
> -			cvmx_write_csr(CVMX_PEXP_SLI_CTL_PORTX(!port), sli_ctl_portx.u64);
> +			if (srio_war15205 == 1) {
> +				sli_ctl_portx.u64 = cvmx_read_csr(CVMX_PEXP_SLI_CTL_PORTX(port));
> +				sli_ctl_portx.s.inta_map = 1;
> +				sli_ctl_portx.s.intb_map = 1;
> +				sli_ctl_portx.s.intc_map = 1;
> +				sli_ctl_portx.s.intd_map = 1;
> +				cvmx_write_csr(CVMX_PEXP_SLI_CTL_PORTX(port), sli_ctl_portx.u64);
> +
> +				sli_ctl_portx.u64 = cvmx_read_csr(CVMX_PEXP_SLI_CTL_PORTX(!port));
> +				sli_ctl_portx.s.inta_map = 0;
> +				sli_ctl_portx.s.intb_map = 0;
> +				sli_ctl_portx.s.intc_map = 0;
> +				sli_ctl_portx.s.intd_map = 0;
> +				cvmx_write_csr(CVMX_PEXP_SLI_CTL_PORTX(!port), sli_ctl_portx.u64);
> +			}
>   		}
>   	}
>
>



More information about the linux-yocto mailing list