summaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci_psycho.c
diff options
context:
space:
mode:
authorDavid S. Miller2008-09-10 12:07:03 +0200
committerDavid S. Miller2008-09-11 08:11:56 +0200
commita21cff3e5e39c087b5a4c5efb20f1744475c556e (patch)
tree1438e43c4d7b2d4042f074afc887fe2e7c30e7ad /arch/sparc64/kernel/pci_psycho.c
parentsparc64: Record OF device instead of device node pointer in pci_pbm_info. (diff)
downloadkernel-qcow2-linux-a21cff3e5e39c087b5a4c5efb20f1744475c556e.tar.gz
kernel-qcow2-linux-a21cff3e5e39c087b5a4c5efb20f1744475c556e.tar.xz
kernel-qcow2-linux-a21cff3e5e39c087b5a4c5efb20f1744475c556e.zip
sparc64: Start commonizing code common between SABRE and PSYCHO.
These are very similar chips, in fact they are identical in some macro blocks. So start commonizing code which they can share. We begin with the IOMMU initialization sequence. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/pci_psycho.c')
-rw-r--r--arch/sparc64/kernel/pci_psycho.c65
1 files changed, 7 insertions, 58 deletions
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 4562b3e0b544..4681e3d8b5fb 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -20,6 +20,7 @@
#include "pci_impl.h"
#include "iommu_common.h"
+#include "psycho_common.h"
#define DRIVER_NAME "psycho"
#define PFX DRIVER_NAME ": "
@@ -787,63 +788,6 @@ static void __init psycho_scan_bus(struct pci_pbm_info *pbm,
psycho_register_error_handlers(pbm);
}
-static int psycho_iommu_init(struct pci_pbm_info *pbm)
-{
- struct iommu *iommu = pbm->iommu;
- unsigned long i;
- u64 control;
- int err;
-
- /* Register addresses. */
- iommu->iommu_control = pbm->controller_regs + PSYCHO_IOMMU_CONTROL;
- iommu->iommu_tsbbase = pbm->controller_regs + PSYCHO_IOMMU_TSBBASE;
- iommu->iommu_flush = pbm->controller_regs + PSYCHO_IOMMU_FLUSH;
- iommu->iommu_tags = iommu->iommu_flush + (0xa580UL - 0x0210UL);
-
- /* PSYCHO's IOMMU lacks ctx flushing. */
- iommu->iommu_ctxflush = 0;
-
- /* We use the main control register of PSYCHO as the write
- * completion register.
- */
- iommu->write_complete_reg = pbm->controller_regs + PSYCHO_CONTROL;
-
- /*
- * Invalidate TLB Entries.
- */
- control = psycho_read(pbm->controller_regs + PSYCHO_IOMMU_CONTROL);
- control |= PSYCHO_IOMMU_CTRL_DENAB;
- psycho_write(pbm->controller_regs + PSYCHO_IOMMU_CONTROL, control);
- for (i = 0; i < 16; i++) {
- psycho_write(pbm->controller_regs + PSYCHO_IOMMU_TAG + (i * 8UL), 0);
- psycho_write(pbm->controller_regs + PSYCHO_IOMMU_DATA + (i * 8UL), 0);
- }
-
- /* Leave diag mode enabled for full-flushing done
- * in pci_iommu.c
- */
- err = iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff,
- pbm->numa_node);
- if (err) {
- printk(KERN_ERR PFX "iommu_table_init() fails\n");
- return err;
- }
-
- psycho_write(pbm->controller_regs + PSYCHO_IOMMU_TSBBASE,
- __pa(iommu->page_table));
-
- control = psycho_read(pbm->controller_regs + PSYCHO_IOMMU_CONTROL);
- control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ);
- control |= (PSYCHO_IOMMU_TSBSZ_128K | PSYCHO_IOMMU_CTRL_ENAB);
- psycho_write(pbm->controller_regs + PSYCHO_IOMMU_CONTROL, control);
-
- /* If necessary, hook us up for starfire IRQ translations. */
- if (this_is_starfire)
- starfire_hookup(pbm->portid);
-
- return 0;
-}
-
#define PSYCHO_IRQ_RETRY 0x1a00UL
#define PSYCHO_PCIA_DIAG 0x2020UL
#define PSYCHO_PCIB_DIAG 0x4020UL
@@ -1053,9 +997,14 @@ static int __devinit psycho_probe(struct of_device *op,
psycho_controller_hwinit(pbm);
if (!pbm->sibling) {
- err = psycho_iommu_init(pbm);
+ err = psycho_iommu_init(pbm, 128, 0xc0000000,
+ 0xffffffff, PSYCHO_CONTROL);
if (err)
goto out_free_iommu;
+
+ /* If necessary, hook us up for starfire IRQ translations. */
+ if (this_is_starfire)
+ starfire_hookup(pbm->portid);
}
psycho_pbm_init(pbm, op, is_pbm_a);