Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 279683
b: refs/heads/master
c: 96ea3b4
h: refs/heads/master
i:
  279681: 1c5ee9c
  279679: 5cbd587
v: v3
  • Loading branch information
Kumar Gala committed Jan 4, 2012
1 parent e549f9f commit ccf2fd6
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e4f387d8db3ba3c2dae4d8bdfe7bb5f4fe1bcb0d
refs/heads/master: 96ea3b4a70edc9fdfaa7080ced102b1eb62a6616
55 changes: 55 additions & 0 deletions trunk/arch/powerpc/sysdev/fsl_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,30 @@ static int __init fsl_pcie_check_link(struct pci_controller *hose)
}

#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)

#define MAX_PHYS_ADDR_BITS 40
static u64 pci64_dma_offset = 1ull << MAX_PHYS_ADDR_BITS;

static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
{
if (!dev->dma_mask || !dma_supported(dev, dma_mask))
return -EIO;

/*
* Fixup PCI devices that are able to DMA to above the physical
* address width of the SoC such that we can address any internal
* SoC address from across PCI if needed
*/
if ((dev->bus == &pci_bus_type) &&
dma_mask >= DMA_BIT_MASK(MAX_PHYS_ADDR_BITS)) {
set_dma_ops(dev, &dma_direct_ops);
set_dma_offset(dev, pci64_dma_offset);
}

*dev->dma_mask = dma_mask;
return 0;
}

static int __init setup_one_atmu(struct ccsr_pci __iomem *pci,
unsigned int index, const struct resource *res,
resource_size_t offset)
Expand Down Expand Up @@ -228,6 +252,37 @@ static void __init setup_pci_atmu(struct pci_controller *hose,

hose->dma_window_base_cur = 0x00000000;
hose->dma_window_size = (resource_size_t)sz;

/*
* if we have >4G of memory setup second PCI inbound window to
* let devices that are 64-bit address capable to work w/o
* SWIOTLB and access the full range of memory
*/
if (sz != mem) {
mem_log = __ilog2_u64(mem);

/* Size window up if we dont fit in exact power-of-2 */
if ((1ull << mem_log) != mem)
mem_log++;

piwar = (piwar & ~PIWAR_SZ_MASK) | (mem_log - 1);

/* Setup inbound memory window */
out_be32(&pci->piw[win_idx].pitar, 0x00000000);
out_be32(&pci->piw[win_idx].piwbear,
pci64_dma_offset >> 44);
out_be32(&pci->piw[win_idx].piwbar,
pci64_dma_offset >> 12);
out_be32(&pci->piw[win_idx].piwar, piwar);

/*
* install our own dma_set_mask handler to fixup dma_ops
* and dma_offset
*/
ppc_md.dma_set_mask = fsl_pci_dma_set_mask;

pr_info("%s: Setup 64-bit PCI DMA window\n", name);
}
} else {
u64 paddr = 0;

Expand Down

0 comments on commit ccf2fd6

Please sign in to comment.