aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/ppc64/kernel/pSeries_iommu.c25
-rw-r--r--arch/ppc64/kernel/u3_iommu.c18
-rw-r--r--include/asm-ppc64/dart.h4
-rw-r--r--include/asm-ppc64/tce.h7
4 files changed, 43 insertions, 11 deletions
diff --git a/arch/ppc64/kernel/pSeries_iommu.c b/arch/ppc64/kernel/pSeries_iommu.c
index 7f7947c3e12f..2b5e622732f4 100644
--- a/arch/ppc64/kernel/pSeries_iommu.c
+++ b/arch/ppc64/kernel/pSeries_iommu.c
@@ -60,6 +60,9 @@ static void tce_build_pSeries(struct iommu_table *tbl, long index,
60 union tce_entry t; 60 union tce_entry t;
61 union tce_entry *tp; 61 union tce_entry *tp;
62 62
63 index <<= TCE_PAGE_FACTOR;
64 npages <<= TCE_PAGE_FACTOR;
65
63 t.te_word = 0; 66 t.te_word = 0;
64 t.te_rdwr = 1; // Read allowed 67 t.te_rdwr = 1; // Read allowed
65 68
@@ -70,11 +73,11 @@ static void tce_build_pSeries(struct iommu_table *tbl, long index,
70 73
71 while (npages--) { 74 while (npages--) {
72 /* can't move this out since we might cross LMB boundary */ 75 /* can't move this out since we might cross LMB boundary */
73 t.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT; 76 t.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
74 77
75 tp->te_word = t.te_word; 78 tp->te_word = t.te_word;
76 79
77 uaddr += PAGE_SIZE; 80 uaddr += TCE_PAGE_SIZE;
78 tp++; 81 tp++;
79 } 82 }
80} 83}
@@ -85,6 +88,9 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages)
85 union tce_entry t; 88 union tce_entry t;
86 union tce_entry *tp; 89 union tce_entry *tp;
87 90
91 npages <<= TCE_PAGE_FACTOR;
92 index <<= TCE_PAGE_FACTOR;
93
88 t.te_word = 0; 94 t.te_word = 0;
89 tp = ((union tce_entry *)tbl->it_base) + index; 95 tp = ((union tce_entry *)tbl->it_base) + index;
90 96
@@ -104,7 +110,7 @@ static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
104 union tce_entry tce; 110 union tce_entry tce;
105 111
106 tce.te_word = 0; 112 tce.te_word = 0;
107 tce.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT; 113 tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
108 tce.te_rdwr = 1; 114 tce.te_rdwr = 1;
109 if (direction != DMA_TO_DEVICE) 115 if (direction != DMA_TO_DEVICE)
110 tce.te_pciwr = 1; 116 tce.te_pciwr = 1;
@@ -137,6 +143,9 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
137 union tce_entry tce, *tcep; 143 union tce_entry tce, *tcep;
138 long l, limit; 144 long l, limit;
139 145
146 tcenum <<= TCE_PAGE_FACTOR;
147 npages <<= TCE_PAGE_FACTOR;
148
140 if (npages == 1) 149 if (npages == 1)
141 return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, 150 return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
142 direction); 151 direction);
@@ -156,7 +165,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
156 } 165 }
157 166
158 tce.te_word = 0; 167 tce.te_word = 0;
159 tce.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT; 168 tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
160 tce.te_rdwr = 1; 169 tce.te_rdwr = 1;
161 if (direction != DMA_TO_DEVICE) 170 if (direction != DMA_TO_DEVICE)
162 tce.te_pciwr = 1; 171 tce.te_pciwr = 1;
@@ -167,7 +176,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
167 * Set up the page with TCE data, looping through and setting 176 * Set up the page with TCE data, looping through and setting
168 * the values. 177 * the values.
169 */ 178 */
170 limit = min_t(long, npages, PAGE_SIZE/sizeof(union tce_entry)); 179 limit = min_t(long, npages, 4096/sizeof(union tce_entry));
171 180
172 for (l = 0; l < limit; l++) { 181 for (l = 0; l < limit; l++) {
173 tcep[l] = tce; 182 tcep[l] = tce;
@@ -197,6 +206,9 @@ static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages
197 u64 rc; 206 u64 rc;
198 union tce_entry tce; 207 union tce_entry tce;
199 208
209 tcenum <<= TCE_PAGE_FACTOR;
210 npages <<= TCE_PAGE_FACTOR;
211
200 tce.te_word = 0; 212 tce.te_word = 0;
201 213
202 while (npages--) { 214 while (npages--) {
@@ -222,6 +234,9 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n
222 u64 rc; 234 u64 rc;
223 union tce_entry tce; 235 union tce_entry tce;
224 236
237 tcenum <<= TCE_PAGE_FACTOR;
238 npages <<= TCE_PAGE_FACTOR;
239
225 tce.te_word = 0; 240 tce.te_word = 0;
226 241
227 rc = plpar_tce_stuff((u64)tbl->it_index, 242 rc = plpar_tce_stuff((u64)tbl->it_index,
diff --git a/arch/ppc64/kernel/u3_iommu.c b/arch/ppc64/kernel/u3_iommu.c
index 115cbdf3b13b..df9c775f4955 100644
--- a/arch/ppc64/kernel/u3_iommu.c
+++ b/arch/ppc64/kernel/u3_iommu.c
@@ -125,18 +125,21 @@ static void dart_build(struct iommu_table *tbl, long index,
125 125
126 DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr); 126 DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr);
127 127
128 index <<= DART_PAGE_FACTOR;
129 npages <<= DART_PAGE_FACTOR;
130
128 dp = ((unsigned int*)tbl->it_base) + index; 131 dp = ((unsigned int*)tbl->it_base) + index;
129 132
130 /* On U3, all memory is contigous, so we can move this 133 /* On U3, all memory is contigous, so we can move this
131 * out of the loop. 134 * out of the loop.
132 */ 135 */
133 while (npages--) { 136 while (npages--) {
134 rpn = virt_to_abs(uaddr) >> PAGE_SHIFT; 137 rpn = virt_to_abs(uaddr) >> DART_PAGE_SHIFT;
135 138
136 *(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK); 139 *(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK);
137 140
138 rpn++; 141 rpn++;
139 uaddr += PAGE_SIZE; 142 uaddr += DART_PAGE_SIZE;
140 } 143 }
141 144
142 dart_dirty = 1; 145 dart_dirty = 1;
@@ -154,6 +157,9 @@ static void dart_free(struct iommu_table *tbl, long index, long npages)
154 157
155 DBG("dart: free at: %lx, %lx\n", index, npages); 158 DBG("dart: free at: %lx, %lx\n", index, npages);
156 159
160 index <<= DART_PAGE_FACTOR;
161 npages <<= DART_PAGE_FACTOR;
162
157 dp = ((unsigned int *)tbl->it_base) + index; 163 dp = ((unsigned int *)tbl->it_base) + index;
158 164
159 while (npages--) 165 while (npages--)
@@ -182,10 +188,10 @@ static int dart_init(struct device_node *dart_node)
182 * that to work around what looks like a problem with the HT bridge 188 * that to work around what looks like a problem with the HT bridge
183 * prefetching into invalid pages and corrupting data 189 * prefetching into invalid pages and corrupting data
184 */ 190 */
185 tmp = lmb_alloc(PAGE_SIZE, PAGE_SIZE); 191 tmp = lmb_alloc(DART_PAGE_SIZE, DART_PAGE_SIZE);
186 if (!tmp) 192 if (!tmp)
187 panic("U3-DART: Cannot allocate spare page!"); 193 panic("U3-DART: Cannot allocate spare page!");
188 dart_emptyval = DARTMAP_VALID | ((tmp >> PAGE_SHIFT) & DARTMAP_RPNMASK); 194 dart_emptyval = DARTMAP_VALID | ((tmp >> DART_PAGE_SHIFT) & DARTMAP_RPNMASK);
189 195
190 /* Map in DART registers. FIXME: Use device node to get base address */ 196 /* Map in DART registers. FIXME: Use device node to get base address */
191 dart = ioremap(DART_BASE, 0x7000); 197 dart = ioremap(DART_BASE, 0x7000);
@@ -196,8 +202,8 @@ static int dart_init(struct device_node *dart_node)
196 * table size and enable bit 202 * table size and enable bit
197 */ 203 */
198 regword = DARTCNTL_ENABLE | 204 regword = DARTCNTL_ENABLE |
199 ((dart_tablebase >> PAGE_SHIFT) << DARTCNTL_BASE_SHIFT) | 205 ((dart_tablebase >> DART_PAGE_SHIFT) << DARTCNTL_BASE_SHIFT) |
200 (((dart_tablesize >> PAGE_SHIFT) & DARTCNTL_SIZE_MASK) 206 (((dart_tablesize >> DART_PAGE_SHIFT) & DARTCNTL_SIZE_MASK)
201 << DARTCNTL_SIZE_SHIFT); 207 << DARTCNTL_SIZE_SHIFT);
202 dart_vbase = ioremap(virt_to_abs(dart_tablebase), dart_tablesize); 208 dart_vbase = ioremap(virt_to_abs(dart_tablebase), dart_tablesize);
203 209
diff --git a/include/asm-ppc64/dart.h b/include/asm-ppc64/dart.h
index 306799a31a5d..a9000de8a2e3 100644
--- a/include/asm-ppc64/dart.h
+++ b/include/asm-ppc64/dart.h
@@ -51,5 +51,9 @@
51#define DARTMAP_RPNMASK 0x00ffffff 51#define DARTMAP_RPNMASK 0x00ffffff
52 52
53 53
54#define DART_SHIFT 12
55#define DART_PAGE_SIZE (1 << DART_SHIFT)
56#define DART_PAGE_FACTOR (PAGE_SHIFT - DART_SHIFT)
57
54 58
55#endif 59#endif
diff --git a/include/asm-ppc64/tce.h b/include/asm-ppc64/tce.h
index 636504c62c88..d40b6b42ab35 100644
--- a/include/asm-ppc64/tce.h
+++ b/include/asm-ppc64/tce.h
@@ -28,6 +28,13 @@
28#define TCE_VB 0 28#define TCE_VB 0
29#define TCE_PCI 1 29#define TCE_PCI 1
30 30
31/* TCE page size is 4096 bytes (1 << 12) */
32
33#define TCE_SHIFT 12
34#define TCE_PAGE_SIZE (1 << TCE_SHIFT)
35#define TCE_PAGE_FACTOR (PAGE_SHIFT - TCE_SHIFT)
36
37
31/* tce_entry 38/* tce_entry
32 * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's 39 * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's
33 * abstracted so layout is irrelevant. 40 * abstracted so layout is irrelevant.