blob: 8d7873c9af332fc48a2dd511f0df7f7bfcf8e4be [file] [log] [blame]
Ilya Yanok2f3427c2011-11-28 06:37:32 +00001/*
2 * (C) Copyright 2011
3 * Ilya Yanok, EmCraft Systems
4 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
Ilya Yanok2f3427c2011-11-28 06:37:32 +00006 */
7#include <linux/types.h>
8#include <common.h>
9
10#ifndef CONFIG_SYS_DCACHE_OFF
Marek Vasuta4aaad72012-03-15 18:33:17 +000011
12#ifndef CONFIG_SYS_CACHELINE_SIZE
13#define CONFIG_SYS_CACHELINE_SIZE 32
14#endif
Ilya Yanok2f3427c2011-11-28 06:37:32 +000015
16void invalidate_dcache_all(void)
17{
Marek Vasut2694bb92012-04-06 03:25:07 +000018 asm volatile("mcr p15, 0, %0, c7, c6, 0\n" : : "r"(0));
Marek Vasuta4aaad72012-03-15 18:33:17 +000019}
20
21void flush_dcache_all(void)
22{
23 asm volatile(
24 "0:"
25 "mrc p15, 0, r15, c7, c14, 3\n"
26 "bne 0b\n"
27 "mcr p15, 0, %0, c7, c10, 4\n"
Marek Vasut2694bb92012-04-06 03:25:07 +000028 : : "r"(0) : "memory"
Marek Vasuta4aaad72012-03-15 18:33:17 +000029 );
30}
31
32static int check_cache_range(unsigned long start, unsigned long stop)
33{
34 int ok = 1;
35
36 if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
37 ok = 0;
38
39 if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
40 ok = 0;
41
42 if (!ok)
Stefano Babicc8d9cea2012-04-02 06:18:49 +000043 debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
Marek Vasuta4aaad72012-03-15 18:33:17 +000044 start, stop);
45
46 return ok;
Ilya Yanok2f3427c2011-11-28 06:37:32 +000047}
48
Ilya Yanok2f3427c2011-11-28 06:37:32 +000049void invalidate_dcache_range(unsigned long start, unsigned long stop)
50{
Marek Vasuta4aaad72012-03-15 18:33:17 +000051 if (!check_cache_range(start, stop))
52 return;
53
54 while (start < stop) {
Marek Vasut2694bb92012-04-06 03:25:07 +000055 asm volatile("mcr p15, 0, %0, c7, c6, 1\n" : : "r"(start));
Marek Vasuta4aaad72012-03-15 18:33:17 +000056 start += CONFIG_SYS_CACHELINE_SIZE;
57 }
Ilya Yanok2f3427c2011-11-28 06:37:32 +000058}
59
60void flush_dcache_range(unsigned long start, unsigned long stop)
61{
Marek Vasuta4aaad72012-03-15 18:33:17 +000062 if (!check_cache_range(start, stop))
63 return;
64
65 while (start < stop) {
Marek Vasut2694bb92012-04-06 03:25:07 +000066 asm volatile("mcr p15, 0, %0, c7, c14, 1\n" : : "r"(start));
Marek Vasuta4aaad72012-03-15 18:33:17 +000067 start += CONFIG_SYS_CACHELINE_SIZE;
68 }
69
Marek Vasut2694bb92012-04-06 03:25:07 +000070 asm volatile("mcr p15, 0, %0, c7, c10, 4\n" : : "r"(0));
Marek Vasuta4aaad72012-03-15 18:33:17 +000071}
72
73void flush_cache(unsigned long start, unsigned long size)
74{
75 flush_dcache_range(start, start + size);
Ilya Yanok2f3427c2011-11-28 06:37:32 +000076}
77#else /* #ifndef CONFIG_SYS_DCACHE_OFF */
78void invalidate_dcache_all(void)
79{
80}
81
82void flush_dcache_all(void)
83{
84}
85
86void invalidate_dcache_range(unsigned long start, unsigned long stop)
87{
88}
89
90void flush_dcache_range(unsigned long start, unsigned long stop)
91{
92}
93
Marek Vasuta4aaad72012-03-15 18:33:17 +000094void flush_cache(unsigned long start, unsigned long size)
Ilya Yanok2f3427c2011-11-28 06:37:32 +000095{
96}
97#endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
Michael Walle67953022012-02-06 22:42:10 +053098
99/*
100 * Stub implementations for l2 cache operations
101 */
Jeroen Hofstee09e6e0b2014-10-27 20:10:06 +0100102__weak void l2_cache_disable(void) {}