aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-02-10 00:32:07 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 04:12:10 -0500
commit8f6a93a196ba6c569c3e8daa6e81cca7e3ba81b1 (patch)
tree80d4747608148c56fd8c67baf016ad4fc58610ea /arch/sparc64
parent4cce4b7cc56abc3d7b269d09224b8297aad15138 (diff)
[SPARC64]: Beginnings of SUN4V PCI controller support.
Abstract out IOMMU operations so that we can have a different set of calls on sun4v, which needs to do things through hypervisor calls. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64')
-rw-r--r--arch/sparc64/kernel/Makefile2
-rw-r--r--arch/sparc64/kernel/pci.c13
-rw-r--r--arch/sparc64/kernel/pci_iommu.c27
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c74
4 files changed, 107 insertions, 9 deletions
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index a482a9ffe5bc..44043390e34f 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -14,7 +14,7 @@ obj-y := process.o setup.o cpu.o idprom.o \
14 power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o 14 power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o
15 15
16obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ 16obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \
17 pci_psycho.o pci_sabre.o pci_schizo.o 17 pci_psycho.o pci_sabre.o pci_schizo.o pci_sun4v.o
18obj-$(CONFIG_SMP) += smp.o trampoline.o 18obj-$(CONFIG_SMP) += smp.o trampoline.o
19obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o 19obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o
20obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o 20obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 2ff7c32ab0ce..95ffa9418620 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -188,6 +188,7 @@ extern void psycho_init(int, char *);
188extern void schizo_init(int, char *); 188extern void schizo_init(int, char *);
189extern void schizo_plus_init(int, char *); 189extern void schizo_plus_init(int, char *);
190extern void tomatillo_init(int, char *); 190extern void tomatillo_init(int, char *);
191extern void sun4v_pci_init(int, char *);
191 192
192static struct { 193static struct {
193 char *model_name; 194 char *model_name;
@@ -204,6 +205,7 @@ static struct {
204 { "pci108e,8002", schizo_plus_init }, 205 { "pci108e,8002", schizo_plus_init },
205 { "SUNW,tomatillo", tomatillo_init }, 206 { "SUNW,tomatillo", tomatillo_init },
206 { "pci108e,a801", tomatillo_init }, 207 { "pci108e,a801", tomatillo_init },
208 { "SUNW,sun4v-pci", sun4v_pci_init },
207}; 209};
208#define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \ 210#define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \
209 sizeof(pci_controller_table[0])) 211 sizeof(pci_controller_table[0]))
@@ -283,6 +285,12 @@ int __init pcic_present(void)
283 return pci_controller_scan(pci_is_controller); 285 return pci_controller_scan(pci_is_controller);
284} 286}
285 287
288struct pci_iommu_ops *pci_iommu_ops;
289EXPORT_SYMBOL(pci_iommu_ops);
290
291extern struct pci_iommu_ops pci_sun4u_iommu_ops,
292 pci_sun4v_iommu_ops;
293
286/* Find each controller in the system, attach and initialize 294/* Find each controller in the system, attach and initialize
287 * software state structure for each and link into the 295 * software state structure for each and link into the
288 * pci_controller_root. Setup the controller enough such 296 * pci_controller_root. Setup the controller enough such
@@ -290,6 +298,11 @@ int __init pcic_present(void)
290 */ 298 */
291static void __init pci_controller_probe(void) 299static void __init pci_controller_probe(void)
292{ 300{
301 if (tlb_type == hypervisor)
302 pci_iommu_ops = &pci_sun4v_iommu_ops;
303 else
304 pci_iommu_ops = &pci_sun4u_iommu_ops;
305
293 printk("PCI: Probing for controllers.\n"); 306 printk("PCI: Probing for controllers.\n");
294 307
295 pci_controller_scan(pci_controller_init); 308 pci_controller_scan(pci_controller_init);
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c
index a11910be1013..8e52232f6f31 100644
--- a/arch/sparc64/kernel/pci_iommu.c
+++ b/arch/sparc64/kernel/pci_iommu.c
@@ -219,7 +219,7 @@ static inline void iommu_free_ctx(struct pci_iommu *iommu, int ctx)
219 * DMA for PCI device PDEV. Return non-NULL cpu-side address if 219 * DMA for PCI device PDEV. Return non-NULL cpu-side address if
220 * successful and set *DMA_ADDRP to the PCI side dma address. 220 * successful and set *DMA_ADDRP to the PCI side dma address.
221 */ 221 */
222void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp) 222static void *pci_4u_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp)
223{ 223{
224 struct pcidev_cookie *pcp; 224 struct pcidev_cookie *pcp;
225 struct pci_iommu *iommu; 225 struct pci_iommu *iommu;
@@ -267,7 +267,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_ad
267} 267}
268 268
269/* Free and unmap a consistent DMA translation. */ 269/* Free and unmap a consistent DMA translation. */
270void pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_t dvma) 270static void pci_4u_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_t dvma)
271{ 271{
272 struct pcidev_cookie *pcp; 272 struct pcidev_cookie *pcp;
273 struct pci_iommu *iommu; 273 struct pci_iommu *iommu;
@@ -294,7 +294,7 @@ void pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_
294/* Map a single buffer at PTR of SZ bytes for PCI DMA 294/* Map a single buffer at PTR of SZ bytes for PCI DMA
295 * in streaming mode. 295 * in streaming mode.
296 */ 296 */
297dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direction) 297static dma_addr_t pci_4u_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direction)
298{ 298{
299 struct pcidev_cookie *pcp; 299 struct pcidev_cookie *pcp;
300 struct pci_iommu *iommu; 300 struct pci_iommu *iommu;
@@ -415,7 +415,7 @@ do_flush_sync:
415} 415}
416 416
417/* Unmap a single streaming mode DMA translation. */ 417/* Unmap a single streaming mode DMA translation. */
418void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) 418static void pci_4u_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction)
419{ 419{
420 struct pcidev_cookie *pcp; 420 struct pcidev_cookie *pcp;
421 struct pci_iommu *iommu; 421 struct pci_iommu *iommu;
@@ -548,7 +548,7 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg,
548 * When making changes here, inspect the assembly output. I was having 548 * When making changes here, inspect the assembly output. I was having
549 * hard time to kepp this routine out of using stack slots for holding variables. 549 * hard time to kepp this routine out of using stack slots for holding variables.
550 */ 550 */
551int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) 551static int pci_4u_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction)
552{ 552{
553 struct pcidev_cookie *pcp; 553 struct pcidev_cookie *pcp;
554 struct pci_iommu *iommu; 554 struct pci_iommu *iommu;
@@ -635,7 +635,7 @@ bad_no_ctx:
635} 635}
636 636
637/* Unmap a set of streaming mode DMA translations. */ 637/* Unmap a set of streaming mode DMA translations. */
638void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) 638static void pci_4u_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction)
639{ 639{
640 struct pcidev_cookie *pcp; 640 struct pcidev_cookie *pcp;
641 struct pci_iommu *iommu; 641 struct pci_iommu *iommu;
@@ -695,7 +695,7 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems,
695/* Make physical memory consistent for a single 695/* Make physical memory consistent for a single
696 * streaming mode DMA translation after a transfer. 696 * streaming mode DMA translation after a transfer.
697 */ 697 */
698void pci_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) 698static void pci_4u_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction)
699{ 699{
700 struct pcidev_cookie *pcp; 700 struct pcidev_cookie *pcp;
701 struct pci_iommu *iommu; 701 struct pci_iommu *iommu;
@@ -735,7 +735,7 @@ void pci_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size
735/* Make physical memory consistent for a set of streaming 735/* Make physical memory consistent for a set of streaming
736 * mode DMA translations after a transfer. 736 * mode DMA translations after a transfer.
737 */ 737 */
738void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction) 738static void pci_4u_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction)
739{ 739{
740 struct pcidev_cookie *pcp; 740 struct pcidev_cookie *pcp;
741 struct pci_iommu *iommu; 741 struct pci_iommu *iommu;
@@ -776,6 +776,17 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i
776 spin_unlock_irqrestore(&iommu->lock, flags); 776 spin_unlock_irqrestore(&iommu->lock, flags);
777} 777}
778 778
779struct pci_iommu_ops pci_sun4u_iommu_ops = {
780 .alloc_consistent = pci_4u_alloc_consistent,
781 .free_consistent = pci_4u_free_consistent,
782 .map_single = pci_4u_map_single,
783 .unmap_single = pci_4u_unmap_single,
784 .map_sg = pci_4u_map_sg,
785 .unmap_sg = pci_4u_unmap_sg,
786 .dma_sync_single_for_cpu = pci_4u_dma_sync_single_for_cpu,
787 .dma_sync_sg_for_cpu = pci_4u_dma_sync_sg_for_cpu,
788};
789
779static void ali_sound_dma_hack(struct pci_dev *pdev, int set_bit) 790static void ali_sound_dma_hack(struct pci_dev *pdev, int set_bit)
780{ 791{
781 struct pci_dev *ali_isa_bridge; 792 struct pci_dev *ali_isa_bridge;
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
new file mode 100644
index 000000000000..c1a077196c57
--- /dev/null
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -0,0 +1,74 @@
1/* pci_sun4v.c: SUN4V specific PCI controller support.
2 *
3 * Copyright (C) 2006 David S. Miller (davem@davemloft.net)
4 */
5
6#include <linux/kernel.h>
7#include <linux/types.h>
8#include <linux/pci.h>
9#include <linux/init.h>
10#include <linux/slab.h>
11#include <linux/interrupt.h>
12
13#include <asm/pbm.h>
14#include <asm/iommu.h>
15#include <asm/irq.h>
16#include <asm/upa.h>
17#include <asm/pstate.h>
18#include <asm/oplib.h>
19#include <asm/hypervisor.h>
20
21#include "pci_impl.h"
22#include "iommu_common.h"
23
24static void *pci_4v_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp)
25{
26 return NULL;
27}
28
29static void pci_4v_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_t dvma)
30{
31}
32
33static dma_addr_t pci_4v_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direction)
34{
35 return 0;
36}
37
38static void pci_4v_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction)
39{
40}
41
42static int pci_4v_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction)
43{
44 return nelems;
45}
46
47static void pci_4v_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction)
48{
49}
50
51static void pci_4v_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction)
52{
53}
54
55static void pci_4v_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction)
56{
57}
58
59struct pci_iommu_ops pci_sun4v_iommu_ops = {
60 .alloc_consistent = pci_4v_alloc_consistent,
61 .free_consistent = pci_4v_free_consistent,
62 .map_single = pci_4v_map_single,
63 .unmap_single = pci_4v_unmap_single,
64 .map_sg = pci_4v_map_sg,
65 .unmap_sg = pci_4v_unmap_sg,
66 .dma_sync_single_for_cpu = pci_4v_dma_sync_single_for_cpu,
67 .dma_sync_sg_for_cpu = pci_4v_dma_sync_sg_for_cpu,
68};
69
70void sun4v_pci_init(int node, char *model_name)
71{
72 prom_printf("sun4v_pci_init: Implement me.\n");
73 prom_halt();
74}