diff options
author | David S. Miller <davem@davemloft.net> | 2008-09-10 06:07:03 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-09-11 02:11:56 -0400 |
commit | a21cff3e5e39c087b5a4c5efb20f1744475c556e (patch) | |
tree | 1438e43c4d7b2d4042f074afc887fe2e7c30e7ad /arch/sparc64/kernel/pci_psycho.c | |
parent | 22fecbae4446ad470b9237ee9b79f80f343b3838 (diff) |
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.c | 65 |
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 | ||
790 | static 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); |