summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSantosh Shilimkar <santosh.shilimkar@ti.com>2010-07-11 14:58:41 +0530
committerSantosh Shilimkar <santosh.shilimkar@ti.com>2010-10-26 11:40:05 +0530
commit444457c1f59d58bc48acf5b4fc585225106c11ff (patch)
tree87d0b8262f776680a6dfc8c48c74fd5eea1f7b2c
parent5ba70372289a1fb378b95cee2cf46b0203d65291 (diff)
ARM: l2x0: Optimise the range based operations
For the big buffers which are in excess of cache size, the maintaince operations by PA are very slow. For such buffers the maintainace operations can be speeded up by using the WAY based method. Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Acked-by: Linus Walleij <linus.walleij@stericsson.com>
-rw-r--r--arch/arm/mm/cache-l2x0.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 262c7529bcdb..170c9bb95866 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -125,6 +125,18 @@ static void l2x0_flush_all(void)
spin_unlock_irqrestore(&l2x0_lock, flags);
}
+static void l2x0_clean_all(void)
+{
+ unsigned long flags;
+
+ /* clean all ways */
+ spin_lock_irqsave(&l2x0_lock, flags);
+ writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_WAY);
+ cache_wait_way(l2x0_base + L2X0_CLEAN_WAY, l2x0_way_mask);
+ cache_sync();
+ spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
static void l2x0_inv_all(void)
{
unsigned long flags;
@@ -183,6 +195,11 @@ static void l2x0_clean_range(unsigned long start, unsigned long end)
void __iomem *base = l2x0_base;
unsigned long flags;
+ if ((end - start) >= l2x0_size) {
+ l2x0_clean_all();
+ return;
+ }
+
spin_lock_irqsave(&l2x0_lock, flags);
start &= ~(CACHE_LINE_SIZE - 1);
while (start < end) {
@@ -208,6 +225,11 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
void __iomem *base = l2x0_base;
unsigned long flags;
+ if ((end - start) >= l2x0_size) {
+ l2x0_flush_all();
+ return;
+ }
+
spin_lock_irqsave(&l2x0_lock, flags);
start &= ~(CACHE_LINE_SIZE - 1);
while (start < end) {