diff options
-rw-r--r-- | arch/ppc64/kernel/pSeries_iommu.c | 25 | ||||
-rw-r--r-- | arch/ppc64/kernel/u3_iommu.c | 18 | ||||
-rw-r--r-- | include/asm-ppc64/dart.h | 4 | ||||
-rw-r--r-- | include/asm-ppc64/tce.h | 7 |
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. |