summaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci_psycho.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-02-05 06:47:02 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-02-05 06:47:02 +0000
commit99a7e12f34b3661a0d1354eef83a0eef4df5e34c (patch)
tree3560aca9ca86792f9ab7bd87861ea143a1b3c7a3 /arch/sparc64/kernel/pci_psycho.c
parente73a04659c0b8cdee4dd40e58630e2cf63afb316 (diff)
Merge with Linux 2.3.38.
Diffstat (limited to 'arch/sparc64/kernel/pci_psycho.c')
-rw-r--r--arch/sparc64/kernel/pci_psycho.c72
1 files changed, 46 insertions, 26 deletions
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 1afe5a67b..d66086bfa 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -1,9 +1,9 @@
-/* $Id: pci_psycho.c,v 1.4 1999/09/05 09:33:36 ecd Exp $
+/* $Id: pci_psycho.c,v 1.7 1999/12/17 12:31:57 jj Exp $
* pci_psycho.c: PSYCHO/U2P specific PCI controller support.
*
* Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
* Copyright (C) 1998, 1999 Eddie C. Dost (ecd@skynet.be)
- * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz)
+ * Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com)
*/
#include <linux/kernel.h>
@@ -380,7 +380,7 @@ static unsigned int __init psycho_irq_build(struct pci_controller_info *p,
unsigned int ino)
{
struct ino_bucket *bucket;
- volatile unsigned int *imap, *iclr;
+ unsigned long imap, iclr;
unsigned long imap_off, iclr_off;
int pil, inofixup = 0;
@@ -399,12 +399,12 @@ static unsigned int __init psycho_irq_build(struct pci_controller_info *p,
/* Now build the IRQ bucket. */
pil = psycho_ino_to_pil(pdev, ino);
- imap = (volatile unsigned int *)__va(p->controller_regs + imap_off);
- imap += 1;
+ imap = p->controller_regs + imap_off;
+ imap += 4;
iclr_off = psycho_iclr_offset(ino);
- iclr = (volatile unsigned int *)__va(p->controller_regs + iclr_off);
- iclr += 1;
+ iclr = p->controller_regs + iclr_off;
+ iclr += 4;
if ((ino & 0x20) == 0)
inofixup = ino & 0x03;
@@ -838,6 +838,10 @@ static void psycho_ce_intr(int irq, void *dev_id, struct pt_regs *regs)
"DMA Read" :
((error_bits & PSYCHO_CEAFSR_PDWR) ?
"DMA Write" : "???")))));
+
+ /* XXX Use syndrome and afar to print out module string just like
+ * XXX UDB CE trap handler does... -DaveM
+ */
printk("PSYCHO%d: syndrome[%02lx] bytemask[%04lx] dword_offset[%lx] "
"UPA_MID[%02lx] was_block(%d)\n",
p->index,
@@ -1213,26 +1217,28 @@ static void __init psycho_scan_bus(struct pci_controller_info *p)
psycho_register_error_handlers(p);
}
-static void __init psycho_iommu_init(struct pci_controller_info *p, int tsbsize)
+static void __init psycho_iommu_init(struct pci_controller_info *p)
{
- extern int this_is_starfire;
- extern void *starfire_hookup(int);
+#ifndef NEW_PCI_DMA_MAP
struct linux_mlist_p1275 *mlist;
- unsigned long tsbbase, i, n, order;
+ unsigned long n;
iopte_t *iopte;
+ int tsbsize = 32;
+#endif
+ extern int this_is_starfire;
+ extern void *starfire_hookup(int);
+ unsigned long tsbbase, i;
u64 control;
/* Setup initial software IOMMU state. */
spin_lock_init(&p->iommu.lock);
p->iommu.iommu_cur_ctx = 0;
- /* PSYCHO's IOMMU lacks ctx flushing. */
- p->iommu.iommu_has_ctx_flush = 0;
-
/* Register addresses. */
p->iommu.iommu_control = p->controller_regs + PSYCHO_IOMMU_CONTROL;
p->iommu.iommu_tsbbase = p->controller_regs + PSYCHO_IOMMU_TSBBASE;
p->iommu.iommu_flush = p->controller_regs + PSYCHO_IOMMU_FLUSH;
+ /* PSYCHO's IOMMU lacks ctx flushing. */
p->iommu.iommu_ctxflush = 0;
/* We use the main control register of PSYCHO as the write
@@ -1252,18 +1258,29 @@ static void __init psycho_iommu_init(struct pci_controller_info *p, int tsbsize)
control &= ~(PSYCHO_IOMMU_CTRL_DENAB);
psycho_write(p->controller_regs + PSYCHO_IOMMU_CONTROL, control);
- for(order = 0;; order++)
- if((PAGE_SIZE << order) >= ((tsbsize * 1024) * 8))
- break;
-
- tsbbase = __get_free_pages(GFP_DMA, order);
+#ifndef NEW_PCI_DMA_MAP
+ /* Using assumed page size 64K with 32K entries we need 256KB iommu page
+ * table (32K ioptes * 8 bytes per iopte). This is
+ * page order 5 on UltraSparc.
+ */
+ tsbbase = __get_free_pages(GFP_KERNEL, 5);
+#else
+ /* Using assumed page size 8K with 128K entries we need 1MB iommu page
+ * table (128K ioptes * 8 bytes per iopte). This is
+ * page order 7 on UltraSparc.
+ */
+ tsbbase = __get_free_pages(GFP_KERNEL, 7);
+#endif
if (!tsbbase) {
prom_printf("PSYCHO_IOMMU: Error, gfp(tsb) failed.\n");
prom_halt();
}
- p->iommu.page_table = iopte = (iopte_t *)tsbbase;
- p->iommu.page_table_sz = (tsbsize * 1024);
+ p->iommu.page_table = (iopte_t *)tsbbase;
+ p->iommu.page_table_sz_bits = 17;
+ p->iommu.page_table_map_base = 0xc0000000;
+#ifndef NEW_PCI_DMA_MAP
+ iopte = (iopte_t *)tsbbase;
/* Initialize to "none" settings. */
for(i = 0; i < PCI_DVMA_HASHSZ; i++) {
pci_dvma_v2p_hash[i] = PCI_DVMA_HASH_NONE;
@@ -1329,10 +1346,11 @@ out:
prom_printf("Try booting with mem=xxxM or similar\n");
prom_halt();
}
-
+#endif
psycho_write(p->controller_regs + PSYCHO_IOMMU_TSBBASE, __pa(tsbbase));
control = psycho_read(p->controller_regs + PSYCHO_IOMMU_CONTROL);
+#ifndef NEW_PCI_DMA_MAP
control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ);
control |= (PSYCHO_IOMMU_CTRL_TBWSZ | PSYCHO_IOMMU_CTRL_ENAB);
switch(tsbsize) {
@@ -1353,6 +1371,10 @@ out:
prom_halt();
break;
}
+#else
+ control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ);
+ control |= (PSYCHO_IOMMU_TSBSZ_128K | PSYCHO_IOMMU_CTRL_ENAB);
+#endif
psycho_write(p->controller_regs + PSYCHO_IOMMU_CONTROL, control);
/* If necessary, hook us up for starfire IRQ translations. */
@@ -1426,9 +1448,6 @@ static void psycho_pbm_strbuf_init(struct pci_controller_info *p,
/* Currently we don't even use it. */
pbm->stc.strbuf_enabled = 0;
- /* PSYCHO's streaming buffer lacks ctx flushing. */
- pbm->stc.strbuf_has_ctx_flush = 0;
-
if (is_pbm_a) {
pbm->stc.strbuf_control = base + PSYCHO_STRBUF_CONTROL_A;
pbm->stc.strbuf_pflush = base + PSYCHO_STRBUF_FLUSH_A;
@@ -1438,6 +1457,7 @@ static void psycho_pbm_strbuf_init(struct pci_controller_info *p,
pbm->stc.strbuf_pflush = base + PSYCHO_STRBUF_FLUSH_B;
pbm->stc.strbuf_fsync = base + PSYCHO_STRBUF_FSYNC_B;
}
+ /* PSYCHO's streaming buffer lacks ctx flushing. */
pbm->stc.strbuf_ctxflush = 0;
pbm->stc.strbuf_ctxmatch_base = 0;
@@ -1599,7 +1619,7 @@ void __init psycho_init(int node)
psycho_controller_hwinit(p);
- psycho_iommu_init(p, 32);
+ psycho_iommu_init(p);
is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000);
psycho_pbm_init(p, node, is_pbm_a);