From: Jia Qingtong <jiaqingtong97@xxxxxxx> Supply little-endian address bit definitions as well as set proper endian swapping modes. Signed-off-by: Jia Qingtong <jiaqingtong97@xxxxxxx> --- fix pcie setup error when Octeon in little-endian mode [<ffffffff81bee02c>] octeon_pcie_setup+0x264/0x4e8 [<ffffffff81100514>] do_one_initcall+0x54/0x190 [<ffffffff81bbee7c>] kernel_init_freeable+0x1bc/0x230 [<ffffffff8188b674>] kernel_init+0x10/0x104 [<ffffffff81115350>] ret_from_kernel_thread+0x14/0x1c arch/mips/pci/pcie-octeon.c | 85 +++++++++++++++++++++++++++++++------ 1 file changed, 73 insertions(+), 12 deletions(-) diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c index d919a0d813a1..512df1e0063a 100644 --- a/arch/mips/pci/pcie-octeon.c +++ b/arch/mips/pci/pcie-octeon.c @@ -39,6 +39,7 @@ static int enable_pcie_bus_num_war[2]; union cvmx_pcie_address { uint64_t u64; +#ifdef __BIG_ENDIAN_BITFIELD struct { uint64_t upper:2; /* Normally 2 for XKPHYS */ uint64_t reserved_49_61:13; /* Must be zero */ @@ -90,8 +91,68 @@ union cvmx_pcie_address { uint64_t reserved_36_39:4; /* Must be zero */ uint64_t address:36; /* PCIe Mem address */ } mem; +#else + struct { + /* + * Selects a register in the configuration space of + * the target. + */ + uint64_t reg:12; + /* Target function number sent in the ID in the request. */ + uint64_t func:3; + /* + * 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 bus number sent in the ID in the request. */ + uint64_t bus:8; + /* + * Selects the type of the configuration request (0 = type 0, + * 1 = type 1). + */ + uint64_t ty:1; + uint64_t reserved_29_31:3; /* Must be zero */ + uint64_t port:2; /* PCIe port 0,1 */ + uint64_t es:2; /* Endian swap = 1 */ + uint64_t reserved_36_39:4; /* Must be zero */ + uint64_t subdid:3; /* PCIe SubDID = 1 */ + uint64_t did:5; /* PCIe DID = 3 */ + uint64_t io:1; /* 1 for IO space access */ + uint64_t reserved_49_61:13; /* Must be zero */ + uint64_t upper:2; /* Normally 2 for XKPHYS */ + } config; + struct { + uint64_t address:32; /* PCIe IO address */ + uint64_t port:2; /* PCIe port 0,1 */ + uint64_t es:2; /* Endian swap = 1 */ + uint64_t reserved_36_39:4; /* Must be zero */ + uint64_t subdid:3; /* PCIe SubDID = 2 */ + uint64_t did:5; /* PCIe DID = 3 */ + uint64_t io:1; /* 1 for IO space access */ + uint64_t reserved_49_61:13; /* Must be zero */ + uint64_t upper:2; /* Normally 2 for XKPHYS */ + } io; + struct { + uint64_t address:36; /* PCIe Mem address */ + uint64_t reserved_36_39:4; /* Must be zero */ + uint64_t subdid:3; /* PCIe SubDID = 3-6 */ + uint64_t did:5; /* PCIe DID = 3 */ + uint64_t io:1; /* 1 for IO space access */ + uint64_t reserved_49_61:13; /* Must be zero */ + uint64_t upper:2; /* Normally 2 for XKPHYS */ + } mem; +#endif }; +/* Endian swap mode. */ +#ifdef __BIG_ENDIAN_BITFIELD +#define _CVMX_PCIE_ES 1 +#else +#define _CVMX_PCIE_ES 0 +#endif + static int cvmx_pcie_rc_initialize(int pcie_port); /** @@ -102,7 +163,7 @@ static int cvmx_pcie_rc_initialize(int pcie_port); * * Returns 64bit Octeon IO base address for read/write */ -static inline uint64_t cvmx_pcie_get_io_base_address(int pcie_port) +static uint64_t cvmx_pcie_get_io_base_address(int pcie_port) { union cvmx_pcie_address pcie_addr; pcie_addr.u64 = 0; @@ -110,7 +171,7 @@ static inline uint64_t cvmx_pcie_get_io_base_address(int pcie_port) pcie_addr.io.io = 1; pcie_addr.io.did = 3; pcie_addr.io.subdid = 2; - pcie_addr.io.es = 1; + pcie_addr.io.es = _CVMX_PCIE_ES; pcie_addr.io.port = pcie_port; return pcie_addr.u64; } @@ -241,7 +302,7 @@ static inline uint64_t __cvmx_pcie_build_config_addr(int pcie_port, int bus, pcie_addr.config.io = 1; pcie_addr.config.did = 3; pcie_addr.config.subdid = 1; - pcie_addr.config.es = 1; + pcie_addr.config.es = _CVMX_PCIE_ES; pcie_addr.config.port = pcie_port; pcie_addr.config.ty = (bus > pciercx_cfg006.s.pbnum); pcie_addr.config.bus = bus; @@ -889,8 +950,8 @@ static int __cvmx_pcie_rc_initialize_gen1(int pcie_port) 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.esr = _CVMX_PCIE_ES; /* Endian-swap for Reads. */ + mem_access_subid.s.esw = _CVMX_PCIE_ES; /* 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. */ @@ -925,7 +986,7 @@ static int __cvmx_pcie_rc_initialize_gen1(int pcie_port) 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.end_swp = _CVMX_PCIE_ES; /* Endian Swap mode */ bar1_index.s.addr_v = 1; /* Valid entry */ base = pcie_port ? 16 : 0; @@ -965,7 +1026,7 @@ static int __cvmx_pcie_rc_initialize_gen1(int 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_esx = _CVMX_PCIE_ES; npei_ctl_port.s.bar2_cax = 0; npei_ctl_port.s.ptlp_ro = 1; npei_ctl_port.s.ctlp_ro = 1; @@ -976,7 +1037,7 @@ static int __cvmx_pcie_rc_initialize_gen1(int pcie_port) 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_esx = _CVMX_PCIE_ES; npei_ctl_port.s.bar2_cax = 0; npei_ctl_port.s.ptlp_ro = 1; npei_ctl_port.s.ctlp_ro = 1; @@ -1341,8 +1402,8 @@ static int __cvmx_pcie_rc_initialize_gen2(int pcie_port) 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.esr = _CVMX_PCIE_ES; /* Endian-swap for Reads. */ + mem_access_subid.s.esw = _CVMX_PCIE_ES; /* 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>. */ @@ -1392,7 +1453,7 @@ static int __cvmx_pcie_rc_initialize_gen2(int pcie_port) 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_esx = _CVMX_PCIE_ES; 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)); @@ -1408,7 +1469,7 @@ static int __cvmx_pcie_rc_initialize_gen2(int pcie_port) 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.end_swp = _CVMX_PCIE_ES; /* Endian Swap mode */ bar1_index.s.addr_v = 1; /* Valid entry */ for (i = 0; i < 16; i++) { -- 2.28.0