summaryrefslogtreecommitdiffstats
path: root/arch/arm/cpu
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2015-09-01 09:43:53 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2015-09-01 09:43:53 +0200
commit2df4ac1f8d209af7fa0cab1caac16dad03663c6f (patch)
tree7c2798b84ad205045343901fa5157e73f5b3eb3e /arch/arm/cpu
parent60e8d757151496a64813a268ed2b5f7dbdcab3df (diff)
parent3a375c99af4aba38dfd55da13855545999dcb8ae (diff)
downloadbarebox-2df4ac1f8d209af7fa0cab1caac16dad03663c6f.tar.gz
barebox-2df4ac1f8d209af7fa0cab1caac16dad03663c6f.tar.xz
Merge branch 'for-next/arm-l2x0'
Diffstat (limited to 'arch/arm/cpu')
-rw-r--r--arch/arm/cpu/cache-l2x0.c48
-rw-r--r--arch/arm/cpu/cache.c2
-rw-r--r--arch/arm/cpu/cpu.c3
-rw-r--r--arch/arm/cpu/mmu.c2
4 files changed, 49 insertions, 6 deletions
diff --git a/arch/arm/cpu/cache-l2x0.c b/arch/arm/cpu/cache-l2x0.c
index 2be562d7de..428dd93249 100644
--- a/arch/arm/cpu/cache-l2x0.c
+++ b/arch/arm/cpu/cache-l2x0.c
@@ -1,3 +1,5 @@
+#define pr_fmt(fmt) "l2x0: " fmt
+
#include <common.h>
#include <init.h>
#include <io.h>
@@ -7,6 +9,7 @@
#define CACHE_LINE_SIZE 32
static void __iomem *l2x0_base;
+static uint32_t l2x0_way_mask; /* Bitmask of active ways */
static inline void cache_wait(void __iomem *reg, unsigned long mask)
{
@@ -50,8 +53,8 @@ static inline void l2x0_flush_line(unsigned long addr)
static inline void l2x0_inv_all(void)
{
/* invalidate all ways */
- 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();
}
@@ -112,6 +115,13 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
cache_sync();
}
+static void l2x0_flush_all(void)
+{
+ writel(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY);
+ cache_wait(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask);
+ cache_sync();
+}
+
static void l2x0_disable(void)
{
writel(0xff, l2x0_base + L2X0_CLEAN_INV_WAY);
@@ -122,9 +132,37 @@ static void l2x0_disable(void)
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
@@ -149,5 +187,9 @@ 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;
outer_cache.disable = l2x0_disable;
-}
+ outer_cache.flush_all = l2x0_flush_all;
+ pr_debug("%s cache controller enabled\n", type);
+ pr_debug("l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
+ ways, cache_id, aux);
+}
diff --git a/arch/arm/cpu/cache.c b/arch/arm/cpu/cache.c
index 7b161d59d6..27ead1c177 100644
--- a/arch/arm/cpu/cache.c
+++ b/arch/arm/cpu/cache.c
@@ -71,6 +71,8 @@ void __mmu_cache_flush(void)
{
if (cache_fns)
cache_fns->mmu_cache_flush();
+ if (outer_cache.flush_all)
+ outer_cache.flush_all();
}
int arm_set_cache_functions(void)
diff --git a/arch/arm/cpu/cpu.c b/arch/arm/cpu/cpu.c
index 5e708023e4..ff8f43d175 100644
--- a/arch/arm/cpu/cpu.c
+++ b/arch/arm/cpu/cpu.c
@@ -79,10 +79,9 @@ struct outer_cache_fns outer_cache;
*/
void mmu_disable(void)
{
+ __mmu_cache_flush();
if (outer_cache.disable)
outer_cache.disable();
-
- __mmu_cache_flush();
__mmu_cache_off();
}
diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index 37bfa058a5..1bd6080f5c 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -159,9 +159,9 @@ static u32 *find_pte(unsigned long adr)
static void dma_flush_range(unsigned long start, unsigned long end)
{
+ __dma_flush_range(start, end);
if (outer_cache.flush_range)
outer_cache.flush_range(start, end);
- __dma_flush_range(start, end);
}
static void dma_inv_range(unsigned long start, unsigned long end)