Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 204607
b: refs/heads/master
c: 2b5987a
h: refs/heads/master
i:
  204605: f82eac6
  204603: 9ff2bb2
  204599: 3ac8873
  204591: 46129d9
  204575: 5d3250e
  204543: edb436f
v: v3
  • Loading branch information
David Daney authored and Ralf Baechle committed Aug 5, 2010
1 parent a79e120 commit 8e65657
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 70dc6f045fce6907b5d10377850a78ada6837ffb
refs/heads/master: 2b5987abaf2dd6c3934e0376b7d9f64411cdcf03
17 changes: 10 additions & 7 deletions trunk/arch/mips/cavium-octeon/dma-octeon.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,16 @@ dma_addr_t octeon_map_dma_mem(struct device *dev, void *ptr, size_t size)
panic("dma_map_single: "
"Attempt to map illegal memory address 0x%llx\n",
physical);
else if ((physical + size >=
(4ull<<30) - (OCTEON_PCI_BAR1_HOLE_SIZE<<20))
&& physical < (4ull<<30))
pr_warning("dma_map_single: Warning: "
"Mapping memory address that might "
"conflict with devices 0x%llx-0x%llx\n",
physical, physical+size-1);
else if (physical >= CVMX_PCIE_BAR1_PHYS_BASE &&
physical + size < (CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_PHYS_SIZE)) {
result = physical - CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_RC_BASE;

if (((result+size-1) & dma_mask) != result+size-1)
panic("dma_map_single: Attempt to map address 0x%llx-0x%llx, which can't be accessed according to the dma mask 0x%llx\n",
physical, physical+size-1, dma_mask);
goto done;
}

/* The 2nd 256MB is mapped at 256<<20 instead of 0x410000000 */
if ((physical >= 0x410000000ull) && physical < 0x420000000ull)
result = physical - 0x400000000ull;
Expand Down
34 changes: 33 additions & 1 deletion trunk/arch/mips/cavium-octeon/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <asm/time.h>

#include <asm/octeon/octeon.h>
#include <asm/octeon/pci-octeon.h>

#ifdef CONFIG_CAVIUM_DECODE_RSL
extern void cvmx_interrupt_rsl_decode(void);
Expand Down Expand Up @@ -609,6 +610,22 @@ void __init prom_init(void)
register_smp_ops(&octeon_smp_ops);
}

/* Exclude a single page from the regions obtained in plat_mem_setup. */
static __init void memory_exclude_page(u64 addr, u64 *mem, u64 *size)
{
if (addr > *mem && addr < *mem + *size) {
u64 inc = addr - *mem;
add_memory_region(*mem, inc, BOOT_MEM_RAM);
*mem += inc;
*size -= inc;
}

if (addr == *mem && *size > PAGE_SIZE) {
*mem += PAGE_SIZE;
*size -= PAGE_SIZE;
}
}

void __init plat_mem_setup(void)
{
uint64_t mem_alloc_size;
Expand Down Expand Up @@ -659,12 +676,27 @@ void __init plat_mem_setup(void)
CVMX_BOOTMEM_FLAG_NO_LOCKING);
#endif
if (memory >= 0) {
u64 size = mem_alloc_size;

/*
* exclude a page at the beginning and end of
* the 256MB PCIe 'hole' so the kernel will not
* try to allocate multi-page buffers that
* span the discontinuity.
*/
memory_exclude_page(CVMX_PCIE_BAR1_PHYS_BASE,
&memory, &size);
memory_exclude_page(CVMX_PCIE_BAR1_PHYS_BASE +
CVMX_PCIE_BAR1_PHYS_SIZE,
&memory, &size);

/*
* This function automatically merges address
* regions next to each other if they are
* received in incrementing order.
*/
add_memory_region(memory, mem_alloc_size, BOOT_MEM_RAM);
if (size)
add_memory_region(memory, size, BOOT_MEM_RAM);
total += mem_alloc_size;
} else {
break;
Expand Down
13 changes: 13 additions & 0 deletions trunk/arch/mips/include/asm/octeon/pci-octeon.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@
/* Some PCI cards require delays when accessing config space. */
#define PCI_CONFIG_SPACE_DELAY 10000

/*
* 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 (1ull << 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 (1ull << 41)

/*
* pcibios_map_irq() is defined inside pci-octeon.c. All it does is
* call the Octeon specific version pointed to by this variable. This
Expand Down
37 changes: 31 additions & 6 deletions trunk/arch/mips/pci/pcie-octeon.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,10 @@ static void __cvmx_pcie_rc_initialize_config_space(int pcie_port)
npei_ctl_status2.s.mps = 0;
/* Max read request size = 128 bytes for best Octeon DMA performance */
npei_ctl_status2.s.mrrs = 0;
if (pcie_port)
npei_ctl_status2.s.c1_b1_s = 3; /* Port1 BAR1 Size 256MB */
else
npei_ctl_status2.s.c0_b1_s = 3; /* Port0 BAR1 Size 256MB */
cvmx_write_csr(CVMX_PEXP_NPEI_CTL_STATUS2, npei_ctl_status2.u64);

/* ECRC Generation (PCIE*_CFG070[GE,CE]) */
Expand Down Expand Up @@ -666,6 +670,8 @@ static int __cvmx_pcie_rc_initialize_link(int pcie_port)
static int cvmx_pcie_rc_initialize(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;
Expand All @@ -674,6 +680,7 @@ static int cvmx_pcie_rc_initialize(int pcie_port)
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_npei_bar1_indexx bar1_index;

/*
* Make sure we aren't trying to setup a target mode interface
Expand Down Expand Up @@ -918,12 +925,30 @@ static int cvmx_pcie_rc_initialize(int pcie_port)
/* Set Octeon's BAR0 to decode 0-16KB. It overlaps with Bar2 */
cvmx_write_csr(CVMX_PESCX_P2N_BAR0_START(pcie_port), 0);

/*
* Disable Octeon's BAR1. It isn't needed in RC mode since
* BAR2 maps all of memory. BAR2 also maps 256MB-512MB into
* the 2nd 256MB of memory.
*/
cvmx_write_csr(CVMX_PESCX_P2N_BAR1_START(pcie_port), -1);
/* BAR1 follows BAR2 with a gap. */
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
Expand Down

0 comments on commit 8e65657

Please sign in to comment.