blob: 2839c863e82c790f2345332f8b7eb23033d96bab [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}
Ilya Yanok2f3427c2011-11-28 06:37:32 +000072#else /* #ifndef CONFIG_SYS_DCACHE_OFF */
73void invalidate_dcache_all(void)
74{
75}
76
77void flush_dcache_all(void)
78{
79}
Ilya Yanok2f3427c2011-11-28 06:37:32 +000080#endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
Michael Walle67953022012-02-06 22:42:10 +053081
82/*
83 * Stub implementations for l2 cache operations
84 */
Albert ARIBAUD62e92072015-10-23 18:06:40 +020085
Jeroen Hofstee09e6e0b2014-10-27 20:10:06 +010086__weak void l2_cache_disable(void) {}
Albert ARIBAUD62e92072015-10-23 18:06:40 +020087
88#if defined CONFIG_SYS_THUMB_BUILD
89__weak void invalidate_l2_cache(void) {}
90#endif