aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci_psycho.c
diff options
context:
space:
mode:
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 @@
20 20
21#include "pci_impl.h" 21#include "pci_impl.h"
22#include "iommu_common.h" 22#include "iommu_common.h"
23#include "psycho_common.h"
23 24
24#define DRIVER_NAME "psycho" 25#define DRIVER_NAME "psycho"
25#define PFX DRIVER_NAME ": " 26#define PFX DRIVER_NAME ": "
@@ -787,63 +788,6 @@ static void __init psycho_scan_bus(struct pci_pbm_info *pbm,
787 psycho_register_error_handlers(pbm); 788 psycho_register_error_handlers(pbm);
788} 789}
789 790
790static int psycho_iommu_init(struct pci_pbm_info *pbm)
791{
792 struct iommu *iommu = pbm->iommu;
793 unsigned long i;
794 u64 control;
795 int err;
796
797 /* Register addresses. */
798 iommu->iommu_control = pbm->controller_regs + PSYCHO_IOMMU_CONTROL;
799 iommu->iommu_tsbbase = pbm->controller_regs + PSYCHO_IOMMU_TSBBASE;
800 iommu->iommu_flush = pbm->controller_regs + PSYCHO_IOMMU_FLUSH;
801 iommu->iommu_tags = iommu->iommu_flush + (0xa580UL - 0x0210UL);
802
803 /* PSYCHO's IOMMU lacks ctx flushing. */
804 iommu->iommu_ctxflush = 0;
805
806 /* We use the main control register of PSYCHO as the write
807 * completion register.
808 */
809 iommu->write_complete_reg = pbm->controller_regs + PSYCHO_CONTROL;
810
811 /*
812 * Invalidate TLB Entries.
813 */
814 control = psycho_read(pbm->controller_regs + PSYCHO_IOMMU_CONTROL);
815 control |= PSYCHO_IOMMU_CTRL_DENAB;
816 psycho_write(pbm->controller_regs + PSYCHO_IOMMU_CONTROL, control);
817 for (i = 0; i < 16; i++) {
818 psycho_write(pbm->controller_regs + PSYCHO_IOMMU_TAG + (i * 8UL), 0);
819 psycho_write(pbm->controller_regs + PSYCHO_IOMMU_DATA + (i * 8UL), 0);
820 }
821
822 /* Leave diag mode enabled for full-flushing done
823 * in pci_iommu.c
824 */
825 err = iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff,
826 pbm->numa_node);
827 if (err) {
828 printk(KERN_ERR PFX "iommu_table_init() fails\n");
829 return err;
830 }
831
832 psycho_write(pbm->controller_regs + PSYCHO_IOMMU_TSBBASE,
833 __pa(iommu->page_table));
834
835 control = psycho_read(pbm->controller_regs + PSYCHO_IOMMU_CONTROL);
836 control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ);
837 control |= (PSYCHO_IOMMU_TSBSZ_128K | PSYCHO_IOMMU_CTRL_ENAB);
838 psycho_write(pbm->controller_regs + PSYCHO_IOMMU_CONTROL, control);
839
840 /* If necessary, hook us up for starfire IRQ translations. */
841 if (this_is_starfire)
842 starfire_hookup(pbm->portid);
843
844 return 0;
845}
846
847#define PSYCHO_IRQ_RETRY 0x1a00UL 791#define PSYCHO_IRQ_RETRY 0x1a00UL
848#define PSYCHO_PCIA_DIAG 0x2020UL 792#define PSYCHO_PCIA_DIAG 0x2020UL
849#define PSYCHO_PCIB_DIAG 0x4020UL 793#define PSYCHO_PCIB_DIAG 0x4020UL
@@ -1053,9 +997,14 @@ static int __devinit psycho_probe(struct of_device *op,
1053 997
1054 psycho_controller_hwinit(pbm); 998 psycho_controller_hwinit(pbm);
1055 if (!pbm->sibling) { 999 if (!pbm->sibling) {
1056 err = psycho_iommu_init(pbm); 1000 err = psycho_iommu_init(pbm, 128, 0xc0000000,
1001 0xffffffff, PSYCHO_CONTROL);
1057 if (err) 1002 if (err)
1058 goto out_free_iommu; 1003 goto out_free_iommu;
1004
1005 /* If necessary, hook us up for starfire IRQ translations. */
1006 if (this_is_starfire)
1007 starfire_hookup(pbm->portid);
1059 } 1008 }
1060 1009
1061 psycho_pbm_init(pbm, op, is_pbm_a); 1010 psycho_pbm_init(pbm, op, is_pbm_a);