sparc64: Start commonizing code common between SABRE and PSYCHO.
[deliverable/linux.git] / arch / sparc64 / kernel / psycho_common.c
CommitLineData
a21cff3e
DM
1/* psycho_common.c: Code common to PSYCHO and derivative PCI controllers.
2 *
3 * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
4 */
5#include <linux/kernel.h>
6
7#include <asm/upa.h>
8
9#include "pci_impl.h"
10#include "psycho_common.h"
11
12#define PSYCHO_IOMMU_TAG 0xa580UL
13#define PSYCHO_IOMMU_DATA 0xa600UL
14
15static void psycho_iommu_flush(struct pci_pbm_info *pbm)
16{
17 int i;
18
19 for (i = 0; i < 16; i++) {
20 unsigned long off = i * 8;
21
22 upa_writeq(0, pbm->controller_regs + PSYCHO_IOMMU_TAG + off);
23 upa_writeq(0, pbm->controller_regs + PSYCHO_IOMMU_DATA + off);
24 }
25}
26
27#define PSYCHO_IOMMU_CONTROL 0x0200UL
28#define PSYCHO_IOMMU_CTRL_TSBSZ 0x0000000000070000UL
29#define PSYCHO_IOMMU_TSBSZ_1K 0x0000000000000000UL
30#define PSYCHO_IOMMU_TSBSZ_2K 0x0000000000010000UL
31#define PSYCHO_IOMMU_TSBSZ_4K 0x0000000000020000UL
32#define PSYCHO_IOMMU_TSBSZ_8K 0x0000000000030000UL
33#define PSYCHO_IOMMU_TSBSZ_16K 0x0000000000040000UL
34#define PSYCHO_IOMMU_TSBSZ_32K 0x0000000000050000UL
35#define PSYCHO_IOMMU_TSBSZ_64K 0x0000000000060000UL
36#define PSYCHO_IOMMU_TSBSZ_128K 0x0000000000070000UL
37#define PSYCHO_IOMMU_CTRL_TBWSZ 0x0000000000000004UL
38#define PSYCHO_IOMMU_CTRL_DENAB 0x0000000000000002UL
39#define PSYCHO_IOMMU_CTRL_ENAB 0x0000000000000001UL
40#define PSYCHO_IOMMU_FLUSH 0x0210UL
41#define PSYCHO_IOMMU_TSBBASE 0x0208UL
42
43int psycho_iommu_init(struct pci_pbm_info *pbm, int tsbsize,
44 u32 dvma_offset, u32 dma_mask,
45 unsigned long write_complete_offset)
46{
47 struct iommu *iommu = pbm->iommu;
48 u64 control;
49 int err;
50
51 iommu->iommu_control = pbm->controller_regs + PSYCHO_IOMMU_CONTROL;
52 iommu->iommu_tsbbase = pbm->controller_regs + PSYCHO_IOMMU_TSBBASE;
53 iommu->iommu_flush = pbm->controller_regs + PSYCHO_IOMMU_FLUSH;
54 iommu->iommu_tags = pbm->controller_regs + PSYCHO_IOMMU_TAG;
55 iommu->write_complete_reg = (pbm->controller_regs +
56 write_complete_offset);
57
58 iommu->iommu_ctxflush = 0;
59
60 control = upa_readq(iommu->iommu_control);
61 control |= PSYCHO_IOMMU_CTRL_DENAB;
62 upa_writeq(control, iommu->iommu_control);
63
64 psycho_iommu_flush(pbm);
65
66 /* Leave diag mode enabled for full-flushing done in pci_iommu.c */
67 err = iommu_table_init(iommu, tsbsize * 1024 * 8,
68 dvma_offset, dma_mask, pbm->numa_node);
69 if (err)
70 return err;
71
72 upa_writeq(__pa(iommu->page_table), iommu->iommu_tsbbase);
73
74 control = upa_readq(iommu->iommu_control);
75 control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ);
76 control |= PSYCHO_IOMMU_CTRL_ENAB;
77
78 switch (tsbsize) {
79 case 64:
80 control |= PSYCHO_IOMMU_TSBSZ_64K;
81 break;
82 case 128:
83 control |= PSYCHO_IOMMU_TSBSZ_128K;
84 break;
85 default:
86 return -EINVAL;
87 }
88
89 upa_writeq(control, iommu->iommu_control);
90
91 return 0;
92
93}
This page took 0.042795 seconds and 5 git commands to generate.