Skip to content

Commit

Permalink
[POWERPC] U4 DART improvements
Browse files Browse the repository at this point in the history
Better late than never...

Respin based on previous comment. Only remaining issue last time was an
extra mb() that I've taken out.

Signed-off-by: Paul Mackerras <paulus@samba.org>
  • Loading branch information
Olof Johansson authored and Paul Mackerras committed Jun 29, 2006
1 parent c220153 commit feb76c7
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 7 deletions.
6 changes: 5 additions & 1 deletion arch/powerpc/sysdev/dart.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,12 @@
/* U4 registers */
#define DART_BASE_U4_BASE_MASK 0xffffff
#define DART_BASE_U4_BASE_SHIFT 0
#define DART_CNTL_U4_FLUSHTLB 0x20000000
#define DART_CNTL_U4_ENABLE 0x80000000
#define DART_CNTL_U4_IONE 0x40000000
#define DART_CNTL_U4_FLUSHTLB 0x20000000
#define DART_CNTL_U4_IDLE 0x10000000
#define DART_CNTL_U4_PAR_EN 0x08000000
#define DART_CNTL_U4_IONE_MASK 0x07ffffff
#define DART_SIZE_U4_SIZE_MASK 0x1fff
#define DART_SIZE_U4_SIZE_SHIFT 0

Expand Down
49 changes: 43 additions & 6 deletions arch/powerpc/sysdev/dart_iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ static inline void dart_tlb_invalidate_all(void)
if (l == (1L << limit)) {
if (limit < 4) {
limit++;
reg = DART_IN(DART_CNTL);
reg &= ~inv_bit;
reg = DART_IN(DART_CNTL);
reg &= ~inv_bit;
DART_OUT(DART_CNTL, reg);
goto retry;
} else
Expand All @@ -111,11 +111,39 @@ static inline void dart_tlb_invalidate_all(void)
}
}

static inline void dart_tlb_invalidate_one(unsigned long bus_rpn)
{
unsigned int reg;
unsigned int l, limit;

reg = DART_CNTL_U4_ENABLE | DART_CNTL_U4_IONE |
(bus_rpn & DART_CNTL_U4_IONE_MASK);
DART_OUT(DART_CNTL, reg);

limit = 0;
wait_more:
l = 0;
while ((DART_IN(DART_CNTL) & DART_CNTL_U4_IONE) && l < (1L << limit)) {
rmb();
l++;
}

if (l == (1L << limit)) {
if (limit < 4) {
limit++;
goto wait_more;
} else
panic("DART: TLB did not flush after waiting a long "
"time. Buggy U4 ?");
}
}

static void dart_flush(struct iommu_table *tbl)
{
if (dart_dirty)
if (dart_dirty) {
dart_tlb_invalidate_all();
dart_dirty = 0;
dart_dirty = 0;
}
}

static void dart_build(struct iommu_table *tbl, long index,
Expand All @@ -124,6 +152,7 @@ static void dart_build(struct iommu_table *tbl, long index,
{
unsigned int *dp;
unsigned int rpn;
long l;

DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr);

Expand All @@ -135,15 +164,23 @@ static void dart_build(struct iommu_table *tbl, long index,
/* On U3, all memory is contigous, so we can move this
* out of the loop.
*/
while (npages--) {
l = npages;
while (l--) {
rpn = virt_to_abs(uaddr) >> DART_PAGE_SHIFT;

*(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK);

uaddr += DART_PAGE_SIZE;
}

dart_dirty = 1;
if (dart_is_u4) {
rpn = index;
mb(); /* make sure all updates have reached memory */
while (npages--)
dart_tlb_invalidate_one(rpn++);
} else {
dart_dirty = 1;
}
}


Expand Down

0 comments on commit feb76c7

Please sign in to comment.