Skip to content

Commit

Permalink
ARM: 6094/1: Extend cache-l2x0 to support the 16-way PL310
Browse files Browse the repository at this point in the history
The L310 cache controller's interface is almost identical
to the L210. One major difference is that the PL310 can
have up to 16 ways.

This change uses the cache's part ID and the Associativity
bits in the AUX_CTRL register to determine the number of ways.

Also, this version prints out the CACHE_ID and AUX_CTRL registers.

Acked-by: Will Deacon <will.deacon@arm.com>
Acked-by: Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Jason S. McMullan <jason.mcmullan@netronome.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Jason McMullan authored and Russell King committed May 15, 2010
1 parent a222712 commit 64039be
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 5 deletions.
3 changes: 3 additions & 0 deletions arch/arm/include/asm/hardware/cache-l2x0.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
#define __ASM_ARM_HARDWARE_L2X0_H

#define L2X0_CACHE_ID 0x000
#define L2X0_CACHE_ID_PART_MASK (0xf << 6)
#define L2X0_CACHE_ID_PART_L210 (1 << 6)
#define L2X0_CACHE_ID_PART_L310 (3 << 6)
#define L2X0_CACHE_TYPE 0x004
#define L2X0_CTRL 0x100
#define L2X0_AUX_CTRL 0x104
Expand Down
39 changes: 34 additions & 5 deletions arch/arm/mm/cache-l2x0.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

static void __iomem *l2x0_base;
static DEFINE_SPINLOCK(l2x0_lock);
static uint32_t l2x0_way_mask; /* Bitmask of active ways */

static inline void cache_wait(void __iomem *reg, unsigned long mask)
{
Expand Down Expand Up @@ -99,8 +100,8 @@ static inline void l2x0_inv_all(void)

/* invalidate all ways */
spin_lock_irqsave(&l2x0_lock, flags);
writel(0xff, l2x0_base + L2X0_INV_WAY);
cache_wait(l2x0_base + L2X0_INV_WAY, 0xff);
writel(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
cache_sync();
spin_unlock_irqrestore(&l2x0_lock, flags);
}
Expand Down Expand Up @@ -199,9 +200,37 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
{
__u32 aux;
__u32 cache_id;
int ways;
const char *type;

l2x0_base = base;

cache_id = readl(l2x0_base + L2X0_CACHE_ID);
aux = readl(l2x0_base + L2X0_AUX_CTRL);

/* Determine the number of ways */
switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
case L2X0_CACHE_ID_PART_L310:
if (aux & (1 << 16))
ways = 16;
else
ways = 8;
type = "L310";
break;
case L2X0_CACHE_ID_PART_L210:
ways = (aux >> 13) & 0xf;
type = "L210";
break;
default:
/* Assume unknown chips have 8 ways */
ways = 8;
type = "L2x0 series";
break;
}

l2x0_way_mask = (1 << ways) - 1;

/*
* Check if l2x0 controller is already enabled.
* If you are booting from non-secure mode
Expand All @@ -210,8 +239,6 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
if (!(readl(l2x0_base + L2X0_CTRL) & 1)) {

/* l2x0 controller is disabled */

aux = readl(l2x0_base + L2X0_AUX_CTRL);
aux &= aux_mask;
aux |= aux_val;
writel(aux, l2x0_base + L2X0_AUX_CTRL);
Expand All @@ -226,5 +253,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
outer_cache.clean_range = l2x0_clean_range;
outer_cache.flush_range = l2x0_flush_range;

printk(KERN_INFO "L2X0 cache controller enabled\n");
printk(KERN_INFO "%s cache controller enabled\n", type);
printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
ways, cache_id, aux);
}

0 comments on commit 64039be

Please sign in to comment.