diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2012-06-15 15:23:06 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2012-07-18 16:40:17 -0400 |
commit | 41bb38fc5398ae878c799647f3c4b25374029afb (patch) | |
tree | 5d7e01bd4176db1241b801f83cf92f32231b8e8b /arch/tile/kernel/setup.c | |
parent | eef015c8aa74451f848307fe5f65485070533bbb (diff) |
tile pci: enable IOMMU to support DMA for legacy devices
This change uses the TRIO IOMMU to map the PCI DMA space and physical
memory at different addresses. We also now use the dma_mapping_ops
to provide support for non-PCI DMA, PCIe DMA (64-bit) and legacy PCI
DMA (32-bit). We use the kernel's software I/O TLB framework
(i.e. bounce buffers) for the legacy 32-bit PCI device support since
there are a limited number of TLB entries in the IOMMU and it is
non-trivial to handle indexing, searching, matching, etc. For 32-bit
devices the performance impact of bounce buffers should not be a concern.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile/kernel/setup.c')
-rw-r--r-- | arch/tile/kernel/setup.c | 35 |
1 files changed, 16 insertions, 19 deletions
diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c index fdde3b6986e5..2b8b689e596d 100644 --- a/arch/tile/kernel/setup.c +++ b/arch/tile/kernel/setup.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/irq.h> | 23 | #include <linux/irq.h> |
24 | #include <linux/kexec.h> | 24 | #include <linux/kexec.h> |
25 | #include <linux/pci.h> | 25 | #include <linux/pci.h> |
26 | #include <linux/swiotlb.h> | ||
26 | #include <linux/initrd.h> | 27 | #include <linux/initrd.h> |
27 | #include <linux/io.h> | 28 | #include <linux/io.h> |
28 | #include <linux/highmem.h> | 29 | #include <linux/highmem.h> |
@@ -109,7 +110,7 @@ static unsigned int __initdata maxnodemem_pfn[MAX_NUMNODES] = { | |||
109 | }; | 110 | }; |
110 | static nodemask_t __initdata isolnodes; | 111 | static nodemask_t __initdata isolnodes; |
111 | 112 | ||
112 | #ifdef CONFIG_PCI | 113 | #if defined(CONFIG_PCI) && !defined(__tilegx__) |
113 | enum { DEFAULT_PCI_RESERVE_MB = 64 }; | 114 | enum { DEFAULT_PCI_RESERVE_MB = 64 }; |
114 | static unsigned int __initdata pci_reserve_mb = DEFAULT_PCI_RESERVE_MB; | 115 | static unsigned int __initdata pci_reserve_mb = DEFAULT_PCI_RESERVE_MB; |
115 | unsigned long __initdata pci_reserve_start_pfn = -1U; | 116 | unsigned long __initdata pci_reserve_start_pfn = -1U; |
@@ -160,7 +161,7 @@ static int __init setup_isolnodes(char *str) | |||
160 | } | 161 | } |
161 | early_param("isolnodes", setup_isolnodes); | 162 | early_param("isolnodes", setup_isolnodes); |
162 | 163 | ||
163 | #ifdef CONFIG_PCI | 164 | #if defined(CONFIG_PCI) && !defined(__tilegx__) |
164 | static int __init setup_pci_reserve(char* str) | 165 | static int __init setup_pci_reserve(char* str) |
165 | { | 166 | { |
166 | unsigned long mb; | 167 | unsigned long mb; |
@@ -171,7 +172,7 @@ static int __init setup_pci_reserve(char* str) | |||
171 | 172 | ||
172 | pci_reserve_mb = mb; | 173 | pci_reserve_mb = mb; |
173 | pr_info("Reserving %dMB for PCIE root complex mappings\n", | 174 | pr_info("Reserving %dMB for PCIE root complex mappings\n", |
174 | pci_reserve_mb); | 175 | pci_reserve_mb); |
175 | return 0; | 176 | return 0; |
176 | } | 177 | } |
177 | early_param("pci_reserve", setup_pci_reserve); | 178 | early_param("pci_reserve", setup_pci_reserve); |
@@ -411,7 +412,7 @@ static void __init setup_memory(void) | |||
411 | continue; | 412 | continue; |
412 | } | 413 | } |
413 | #endif | 414 | #endif |
414 | #ifdef CONFIG_PCI | 415 | #if defined(CONFIG_PCI) && !defined(__tilegx__) |
415 | /* | 416 | /* |
416 | * Blocks that overlap the pci reserved region must | 417 | * Blocks that overlap the pci reserved region must |
417 | * have enough space to hold the maximum percpu data | 418 | * have enough space to hold the maximum percpu data |
@@ -604,11 +605,9 @@ static void __init setup_bootmem_allocator_node(int i) | |||
604 | /* Free all the space back into the allocator. */ | 605 | /* Free all the space back into the allocator. */ |
605 | free_bootmem(PFN_PHYS(start), PFN_PHYS(end - start)); | 606 | free_bootmem(PFN_PHYS(start), PFN_PHYS(end - start)); |
606 | 607 | ||
607 | #if defined(CONFIG_PCI) | 608 | #if defined(CONFIG_PCI) && !defined(__tilegx__) |
608 | /* | 609 | /* |
609 | * Throw away any memory aliased by the PCI region. FIXME: this | 610 | * Throw away any memory aliased by the PCI region. |
610 | * is a temporary hack to work around bug 10502, and needs to be | ||
611 | * fixed properly. | ||
612 | */ | 611 | */ |
613 | if (pci_reserve_start_pfn < end && pci_reserve_end_pfn > start) | 612 | if (pci_reserve_start_pfn < end && pci_reserve_end_pfn > start) |
614 | reserve_bootmem(PFN_PHYS(pci_reserve_start_pfn), | 613 | reserve_bootmem(PFN_PHYS(pci_reserve_start_pfn), |
@@ -1353,8 +1352,7 @@ void __init setup_arch(char **cmdline_p) | |||
1353 | setup_cpu_maps(); | 1352 | setup_cpu_maps(); |
1354 | 1353 | ||
1355 | 1354 | ||
1356 | #ifdef CONFIG_PCI | 1355 | #if defined(CONFIG_PCI) && !defined(__tilegx__) |
1357 | #if !defined (__tilegx__) | ||
1358 | /* | 1356 | /* |
1359 | * Initialize the PCI structures. This is done before memory | 1357 | * Initialize the PCI structures. This is done before memory |
1360 | * setup so that we know whether or not a pci_reserve region | 1358 | * setup so that we know whether or not a pci_reserve region |
@@ -1362,7 +1360,6 @@ void __init setup_arch(char **cmdline_p) | |||
1362 | */ | 1360 | */ |
1363 | if (tile_pci_init() == 0) | 1361 | if (tile_pci_init() == 0) |
1364 | pci_reserve_mb = 0; | 1362 | pci_reserve_mb = 0; |
1365 | #endif | ||
1366 | 1363 | ||
1367 | /* PCI systems reserve a region just below 4GB for mapping iomem. */ | 1364 | /* PCI systems reserve a region just below 4GB for mapping iomem. */ |
1368 | pci_reserve_end_pfn = (1 << (32 - PAGE_SHIFT)); | 1365 | pci_reserve_end_pfn = (1 << (32 - PAGE_SHIFT)); |
@@ -1384,6 +1381,10 @@ void __init setup_arch(char **cmdline_p) | |||
1384 | * any memory using the bootmem allocator. | 1381 | * any memory using the bootmem allocator. |
1385 | */ | 1382 | */ |
1386 | 1383 | ||
1384 | #ifdef CONFIG_SWIOTLB | ||
1385 | swiotlb_init(0); | ||
1386 | #endif | ||
1387 | |||
1387 | paging_init(); | 1388 | paging_init(); |
1388 | setup_numa_mapping(); | 1389 | setup_numa_mapping(); |
1389 | zone_sizes_init(); | 1390 | zone_sizes_init(); |
@@ -1391,10 +1392,6 @@ void __init setup_arch(char **cmdline_p) | |||
1391 | setup_cpu(1); | 1392 | setup_cpu(1); |
1392 | setup_clock(); | 1393 | setup_clock(); |
1393 | load_hv_initrd(); | 1394 | load_hv_initrd(); |
1394 | |||
1395 | #if defined(CONFIG_PCI) && defined (__tilegx__) | ||
1396 | tile_pci_init(); | ||
1397 | #endif | ||
1398 | } | 1395 | } |
1399 | 1396 | ||
1400 | 1397 | ||
@@ -1538,11 +1535,11 @@ static struct resource code_resource = { | |||
1538 | }; | 1535 | }; |
1539 | 1536 | ||
1540 | /* | 1537 | /* |
1541 | * We reserve all resources above 4GB so that PCI won't try to put | 1538 | * On Pro, we reserve all resources above 4GB so that PCI won't try to put |
1542 | * mappings above 4GB; the standard allows that for some devices but | 1539 | * mappings above 4GB; the standard allows that for some devices but |
1543 | * the probing code trunates values to 32 bits. | 1540 | * the probing code trunates values to 32 bits. |
1544 | */ | 1541 | */ |
1545 | #ifdef CONFIG_PCI | 1542 | #if defined(CONFIG_PCI) && !defined(__tilegx__) |
1546 | static struct resource* __init | 1543 | static struct resource* __init |
1547 | insert_non_bus_resource(void) | 1544 | insert_non_bus_resource(void) |
1548 | { | 1545 | { |
@@ -1588,7 +1585,7 @@ static int __init request_standard_resources(void) | |||
1588 | enum { CODE_DELTA = MEM_SV_INTRPT - PAGE_OFFSET }; | 1585 | enum { CODE_DELTA = MEM_SV_INTRPT - PAGE_OFFSET }; |
1589 | 1586 | ||
1590 | iomem_resource.end = -1LL; | 1587 | iomem_resource.end = -1LL; |
1591 | #ifdef CONFIG_PCI | 1588 | #if defined(CONFIG_PCI) && !defined(__tilegx__) |
1592 | insert_non_bus_resource(); | 1589 | insert_non_bus_resource(); |
1593 | #endif | 1590 | #endif |
1594 | 1591 | ||
@@ -1596,7 +1593,7 @@ static int __init request_standard_resources(void) | |||
1596 | u64 start_pfn = node_start_pfn[i]; | 1593 | u64 start_pfn = node_start_pfn[i]; |
1597 | u64 end_pfn = node_end_pfn[i]; | 1594 | u64 end_pfn = node_end_pfn[i]; |
1598 | 1595 | ||
1599 | #ifdef CONFIG_PCI | 1596 | #if defined(CONFIG_PCI) && !defined(__tilegx__) |
1600 | if (start_pfn <= pci_reserve_start_pfn && | 1597 | if (start_pfn <= pci_reserve_start_pfn && |
1601 | end_pfn > pci_reserve_start_pfn) { | 1598 | end_pfn > pci_reserve_start_pfn) { |
1602 | if (end_pfn > pci_reserve_end_pfn) | 1599 | if (end_pfn > pci_reserve_end_pfn) |