blob: 8d7873c9af332fc48a2dd511f0df7f7bfcf8e4be [file] [log] [blame]
Ilya Yanokc8500692011-11-28 06:37:32 +00001/*
2 * (C) Copyright 2011
3 * Ilya Yanok, EmCraft Systems
4 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
Ilya Yanokc8500692011-11-28 06:37:32 +00006 */
7#include <linux/types.h>
8#include <common.h>
9
10#ifndef CONFIG_SYS_DCACHE_OFF
Marek Vasutfc928512012-03-15 18:33:17 +000011
12#ifndef CONFIG_SYS_CACHELINE_SIZE
13#define CONFIG_SYS_CACHELINE_SIZE 32
14#endif
15
16void invalidate_dcache_all(void)
Ilya Yanokc8500692011-11-28 06:37:32 +000017{
Marek Vasut8ed61312012-04-06 03:25:07 +000018 asm volatile("mcr p15, 0, %0, c7, c6, 0\n" : : "r"(0));
Ilya Yanokc8500692011-11-28 06:37:32 +000019}
20
Marek Vasutfc928512012-03-15 18:33:17 +000021void flush_dcache_all(void)
Ilya Yanokc8500692011-11-28 06:37:32 +000022{
Marek Vasutfc928512012-03-15 18:33:17 +000023 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 Vasut8ed61312012-04-06 03:25:07 +000028 : : "r"(0) : "memory"
Marek Vasutfc928512012-03-15 18:33:17 +000029 );
Ilya Yanokc8500692011-11-28 06:37:32 +000030}
31
Marek Vasutfc928512012-03-15 18:33:17 +000032static 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 Babic573a2042012-04-02 06:18:49 +000043 debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
Marek Vasutfc928512012-03-15 18:33:17 +000044 start, stop);
45
46 return ok;
47}
48
Ilya Yanokc8500692011-11-28 06:37:32 +000049void invalidate_dcache_range(unsigned long start, unsigned long stop)
50{
Marek Vasutfc928512012-03-15 18:33:17 +000051 if (!check_cache_range(start, stop))
52 return;
53
54 while (start < stop) {
Marek Vasut8ed61312012-04-06 03:25:07 +000055 asm volatile("mcr p15, 0, %0, c7, c6, 1\n" : : "r"(start));
Marek Vasutfc928512012-03-15 18:33:17 +000056 start += CONFIG_SYS_CACHELINE_SIZE;
57 }
Ilya Yanokc8500692011-11-28 06:37:32 +000058}
59
60void flush_dcache_range(unsigned long start, unsigned long stop)
61{
Marek Vasutfc928512012-03-15 18:33:17 +000062 if (!check_cache_range(start, stop))
63 return;
64
65 while (start < stop) {
Marek Vasut8ed61312012-04-06 03:25:07 +000066 asm volatile("mcr p15, 0, %0, c7, c14, 1\n" : : "r"(start));
Marek Vasutfc928512012-03-15 18:33:17 +000067 start += CONFIG_SYS_CACHELINE_SIZE;
68 }
69
Marek Vasut8ed61312012-04-06 03:25:07 +000070 asm volatile("mcr p15, 0, %0, c7, c10, 4\n" : : "r"(0));
Marek Vasutfc928512012-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 Yanokc8500692011-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 Vasutfc928512012-03-15 18:33:17 +000094void flush_cache(unsigned long start, unsigned long size)
Ilya Yanokc8500692011-11-28 06:37:32 +000095{
96}
97#endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
Michael Walle5ae3eec2012-02-06 22:42:10 +053098
99/*
100 * Stub implementations for l2 cache operations
101 */
Jeroen Hofstee2f65bef2014-10-27 20:10:06 +0100102__weak void l2_cache_disable(void) {}