aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci_psycho.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-09-10 06:07:03 -0400
committerDavid S. Miller <davem@davemloft.net>2008-09-11 02:11:56 -0400
commita21cff3e5e39c087b5a4c5efb20f1744475c556e (patch)
tree1438e43c4d7b2d4042f074afc887fe2e7c30e7ad /arch/sparc64/kernel/pci_psycho.c
parent22fecbae4446ad470b9237ee9b79f80f343b3838 (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.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 4562b3e0b54..4681e3d8b5f 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);