summaryrefslogtreecommitdiffstats
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,
union tce_entry t;
union tce_entry *tp;
+ index <<= TCE_PAGE_FACTOR;
+ npages <<= TCE_PAGE_FACTOR;
+
t.te_word = 0;
t.te_rdwr = 1; // Read allowed
@@ -70,11 +73,11 @@ static void tce_build_pSeries(struct iommu_table *tbl, long index,
while (npages--) {
/* can't move this out since we might cross LMB boundary */
- t.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT;
+ t.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
tp->te_word = t.te_word;
- uaddr += PAGE_SIZE;
+ uaddr += TCE_PAGE_SIZE;
tp++;
}
}
@@ -85,6 +88,9 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages)
union tce_entry t;
union tce_entry *tp;
+ npages <<= TCE_PAGE_FACTOR;
+ index <<= TCE_PAGE_FACTOR;
+
t.te_word = 0;
tp = ((union tce_entry *)tbl->it_base) + index;
@@ -104,7 +110,7 @@ static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
union tce_entry tce;
tce.te_word = 0;
- tce.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT;
+ tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
tce.te_rdwr = 1;
if (direction != DMA_TO_DEVICE)
tce.te_pciwr = 1;
@@ -137,6 +143,9 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
union tce_entry tce, *tcep;
long l, limit;
+ tcenum <<= TCE_PAGE_FACTOR;
+ npages <<= TCE_PAGE_FACTOR;
+
if (npages == 1)
return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
direction);
@@ -156,7 +165,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
}
tce.te_word = 0;
- tce.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT;
+ tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
tce.te_rdwr = 1;
if (direction != DMA_TO_DEVICE)
tce.te_pciwr = 1;
@@ -167,7 +176,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
* Set up the page with TCE data, looping through and setting
* the values.
*/
- limit = min_t(long, npages, PAGE_SIZE/sizeof(union tce_entry));
+ limit = min_t(long, npages, 4096/sizeof(union tce_entry));
for (l = 0; l < limit; l++) {
tcep[l] = tce;
@@ -197,6 +206,9 @@ static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages
u64 rc;
union tce_entry tce;
+ tcenum <<= TCE_PAGE_FACTOR;
+ npages <<= TCE_PAGE_FACTOR;
+
tce.te_word = 0;
while (npages--) {
@@ -222,6 +234,9 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n
u64 rc;
union tce_entry tce;
+ tcenum <<= TCE_PAGE_FACTOR;
+ npages <<= TCE_PAGE_FACTOR;
+
tce.te_word = 0;
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,
DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr);
+ index <<= DART_PAGE_FACTOR;
+ npages <<= DART_PAGE_FACTOR;
+
dp = ((unsigned int*)tbl->it_base) + index;
/* On U3, all memory is contigous, so we can move this
* out of the loop.
*/
while (npages--) {
- rpn = virt_to_abs(uaddr) >> PAGE_SHIFT;
+ rpn = virt_to_abs(uaddr) >> DART_PAGE_SHIFT;
*(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK);
rpn++;
- uaddr += PAGE_SIZE;
+ uaddr += DART_PAGE_SIZE;
}
dart_dirty = 1;
@@ -154,6 +157,9 @@ static void dart_free(struct iommu_table *tbl, long index, long npages)
DBG("dart: free at: %lx, %lx\n", index, npages);
+ index <<= DART_PAGE_FACTOR;
+ npages <<= DART_PAGE_FACTOR;
+
dp = ((unsigned int *)tbl->it_base) + index;
while (npages--)
@@ -182,10 +188,10 @@ static int dart_init(struct device_node *dart_node)
* that to work around what looks like a problem with the HT bridge
* prefetching into invalid pages and corrupting data
*/
- tmp = lmb_alloc(PAGE_SIZE, PAGE_SIZE);
+ tmp = lmb_alloc(DART_PAGE_SIZE, DART_PAGE_SIZE);
if (!tmp)
panic("U3-DART: Cannot allocate spare page!");
- dart_emptyval = DARTMAP_VALID | ((tmp >> PAGE_SHIFT) & DARTMAP_RPNMASK);
+ dart_emptyval = DARTMAP_VALID | ((tmp >> DART_PAGE_SHIFT) & DARTMAP_RPNMASK);
/* Map in DART registers. FIXME: Use device node to get base address */
dart = ioremap(DART_BASE, 0x7000);
@@ -196,8 +202,8 @@ static int dart_init(struct device_node *dart_node)
* table size and enable bit
*/
regword = DARTCNTL_ENABLE |
- ((dart_tablebase >> PAGE_SHIFT) << DARTCNTL_BASE_SHIFT) |
- (((dart_tablesize >> PAGE_SHIFT) & DARTCNTL_SIZE_MASK)
+ ((dart_tablebase >> DART_PAGE_SHIFT) << DARTCNTL_BASE_SHIFT) |
+ (((dart_tablesize >> DART_PAGE_SHIFT) & DARTCNTL_SIZE_MASK)
<< DARTCNTL_SIZE_SHIFT);
dart_vbase = ioremap(virt_to_abs(dart_tablebase), dart_tablesize);
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 @@
#define DARTMAP_RPNMASK 0x00ffffff
+#define DART_SHIFT 12
+#define DART_PAGE_SIZE (1 << DART_SHIFT)
+#define DART_PAGE_FACTOR (PAGE_SHIFT - DART_SHIFT)
+
#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 @@
#define TCE_VB 0
#define TCE_PCI 1
+/* TCE page size is 4096 bytes (1 << 12) */
+
+#define TCE_SHIFT 12
+#define TCE_PAGE_SIZE (1 << TCE_SHIFT)
+#define TCE_PAGE_FACTOR (PAGE_SHIFT - TCE_SHIFT)
+
+
/* tce_entry
* Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's
* abstracted so layout is irrelevant.
OpenPOWER on IntegriCloud