fdt: Added helper to set PCI dma-ranges property
Added fdt_pci_dma_ranges() that parses the pci_region info from the struct pci_controller and populates the dma-ranges based on it. The max # of windws/dma-ranges we support is 3 since on embedded PowerPC based systems this is the max number of windows. Signed-off-by: Kumar Gala <galak@kernel.crashing.org> Signed-off-by: Andrew Fleming-AFLEMING <afleming@freescale.com>
This commit is contained in:
parent
3bed2aaf2d
commit
8ab451c46b
@ -620,3 +620,72 @@ int fdt_resize(void *blob)
|
||||
|
||||
return actualsize;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
#define CONFIG_SYS_PCI_NR_INBOUND_WIN 3
|
||||
|
||||
#define FDT_PCI_PREFETCH (0x40000000)
|
||||
#define FDT_PCI_MEM32 (0x02000000)
|
||||
#define FDT_PCI_IO (0x01000000)
|
||||
#define FDT_PCI_MEM64 (0x03000000)
|
||||
|
||||
int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose) {
|
||||
|
||||
int addrcell, sizecell, len, r;
|
||||
u32 *dma_range;
|
||||
/* sized based on pci addr cells, size-cells, & address-cells */
|
||||
u32 dma_ranges[(3 + 2 + 2) * CONFIG_SYS_PCI_NR_INBOUND_WIN];
|
||||
|
||||
addrcell = fdt_getprop_u32_default(blob, "/", "#address-cells", 1);
|
||||
sizecell = fdt_getprop_u32_default(blob, "/", "#size-cells", 1);
|
||||
|
||||
dma_range = &dma_ranges[0];
|
||||
for (r = 0; r < hose->region_count; r++) {
|
||||
u64 bus_start, phys_start, size;
|
||||
|
||||
/* skip if !PCI_REGION_MEMORY */
|
||||
if (!(hose->regions[r].flags & PCI_REGION_MEMORY))
|
||||
continue;
|
||||
|
||||
bus_start = (u64)hose->regions[r].bus_start;
|
||||
phys_start = (u64)hose->regions[r].phys_start;
|
||||
size = (u64)hose->regions[r].size;
|
||||
|
||||
dma_range[0] = 0;
|
||||
if (size > 0x100000000ull)
|
||||
dma_range[0] |= FDT_PCI_MEM64;
|
||||
else
|
||||
dma_range[0] |= FDT_PCI_MEM32;
|
||||
if (hose->regions[r].flags & PCI_REGION_PREFETCH)
|
||||
dma_range[0] |= FDT_PCI_PREFETCH;
|
||||
#ifdef CONFIG_SYS_PCI_64BIT
|
||||
dma_range[1] = bus_start >> 32;
|
||||
#else
|
||||
dma_range[1] = 0;
|
||||
#endif
|
||||
dma_range[2] = bus_start & 0xffffffff;
|
||||
|
||||
if (addrcell == 2) {
|
||||
dma_range[3] = phys_start >> 32;
|
||||
dma_range[4] = phys_start & 0xffffffff;
|
||||
} else {
|
||||
dma_range[3] = phys_start & 0xffffffff;
|
||||
}
|
||||
|
||||
if (sizecell == 2) {
|
||||
dma_range[3 + addrcell + 0] = size >> 32;
|
||||
dma_range[3 + addrcell + 1] = size & 0xffffffff;
|
||||
} else {
|
||||
dma_range[3 + addrcell + 0] = size & 0xffffffff;
|
||||
}
|
||||
|
||||
dma_range += (3 + addrcell + sizecell);
|
||||
}
|
||||
|
||||
len = dma_range - &dma_ranges[0];
|
||||
if (len)
|
||||
fdt_setprop(blob, phb_off, "dma-ranges", &dma_ranges[0], len*4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -65,6 +65,11 @@ void fdt_fixup_crypto_node(void *blob, int sec_rev);
|
||||
static inline void fdt_fixup_crypto_node(void *blob, int sec_rev) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
#include <pci.h>
|
||||
int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF_BOARD_SETUP
|
||||
void ft_board_setup(void *blob, bd_t *bd);
|
||||
void ft_cpu_setup(void *blob, bd_t *bd);
|
||||
|
Loading…
Reference in New Issue
Block a user