1*2085ae74SAlexander Stein /*
2*2085ae74SAlexander Stein * (C) Copyright 2004 Texas Insturments
3*2085ae74SAlexander Stein *
4*2085ae74SAlexander Stein * (C) Copyright 2002
5*2085ae74SAlexander Stein * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
6*2085ae74SAlexander Stein * Marius Groeger <mgroeger@sysgo.de>
7*2085ae74SAlexander Stein *
8*2085ae74SAlexander Stein * (C) Copyright 2002
9*2085ae74SAlexander Stein * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
10*2085ae74SAlexander Stein *
11*2085ae74SAlexander Stein * SPDX-License-Identifier: GPL-2.0+
12*2085ae74SAlexander Stein */
13*2085ae74SAlexander Stein
14*2085ae74SAlexander Stein /*
15*2085ae74SAlexander Stein * CPU specific code
16*2085ae74SAlexander Stein */
17*2085ae74SAlexander Stein
18*2085ae74SAlexander Stein #include <common.h>
19*2085ae74SAlexander Stein #include <command.h>
20*2085ae74SAlexander Stein #include <asm/system.h>
21*2085ae74SAlexander Stein
22*2085ae74SAlexander Stein static void cache_flush(void);
23*2085ae74SAlexander Stein
cleanup_before_linux(void)24*2085ae74SAlexander Stein int cleanup_before_linux (void)
25*2085ae74SAlexander Stein {
26*2085ae74SAlexander Stein /*
27*2085ae74SAlexander Stein * this function is called just before we call linux
28*2085ae74SAlexander Stein * it prepares the processor for linux
29*2085ae74SAlexander Stein *
30*2085ae74SAlexander Stein * we turn off caches etc ...
31*2085ae74SAlexander Stein */
32*2085ae74SAlexander Stein
33*2085ae74SAlexander Stein disable_interrupts ();
34*2085ae74SAlexander Stein
35*2085ae74SAlexander Stein /* turn off I/D-cache */
36*2085ae74SAlexander Stein icache_disable();
37*2085ae74SAlexander Stein dcache_disable();
38*2085ae74SAlexander Stein /* flush I/D-cache */
39*2085ae74SAlexander Stein cache_flush();
40*2085ae74SAlexander Stein
41*2085ae74SAlexander Stein return 0;
42*2085ae74SAlexander Stein }
43*2085ae74SAlexander Stein
cache_flush(void)44*2085ae74SAlexander Stein static void cache_flush(void)
45*2085ae74SAlexander Stein {
46*2085ae74SAlexander Stein unsigned long i = 0;
47*2085ae74SAlexander Stein /* clean entire data cache */
48*2085ae74SAlexander Stein asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (i));
49*2085ae74SAlexander Stein /* invalidate both caches and flush btb */
50*2085ae74SAlexander Stein asm volatile("mcr p15, 0, %0, c7, c7, 0" : : "r" (i));
51*2085ae74SAlexander Stein /* mem barrier to sync things */
52*2085ae74SAlexander Stein asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (i));
53*2085ae74SAlexander Stein }
54*2085ae74SAlexander Stein
55*2085ae74SAlexander Stein #ifndef CONFIG_SYS_DCACHE_OFF
invalidate_dcache_all(void)56*2085ae74SAlexander Stein void invalidate_dcache_all(void)
57*2085ae74SAlexander Stein {
58*2085ae74SAlexander Stein asm volatile("mcr p15, 0, %0, c7, c6, 0" : : "r" (0));
59*2085ae74SAlexander Stein }
60*2085ae74SAlexander Stein
flush_dcache_all(void)61*2085ae74SAlexander Stein void flush_dcache_all(void)
62*2085ae74SAlexander Stein {
63*2085ae74SAlexander Stein asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (0));
64*2085ae74SAlexander Stein asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
65*2085ae74SAlexander Stein }
66*2085ae74SAlexander Stein
invalidate_dcache_range(unsigned long start,unsigned long stop)67*2085ae74SAlexander Stein void invalidate_dcache_range(unsigned long start, unsigned long stop)
68*2085ae74SAlexander Stein {
69*2085ae74SAlexander Stein if (!check_cache_range(start, stop))
70*2085ae74SAlexander Stein return;
71*2085ae74SAlexander Stein
72*2085ae74SAlexander Stein while (start < stop) {
73*2085ae74SAlexander Stein asm volatile("mcr p15, 0, %0, c7, c6, 1" : : "r" (start));
74*2085ae74SAlexander Stein start += CONFIG_SYS_CACHELINE_SIZE;
75*2085ae74SAlexander Stein }
76*2085ae74SAlexander Stein }
77*2085ae74SAlexander Stein
flush_dcache_range(unsigned long start,unsigned long stop)78*2085ae74SAlexander Stein void flush_dcache_range(unsigned long start, unsigned long stop)
79*2085ae74SAlexander Stein {
80*2085ae74SAlexander Stein if (!check_cache_range(start, stop))
81*2085ae74SAlexander Stein return;
82*2085ae74SAlexander Stein
83*2085ae74SAlexander Stein while (start < stop) {
84*2085ae74SAlexander Stein asm volatile("mcr p15, 0, %0, c7, c14, 1" : : "r" (start));
85*2085ae74SAlexander Stein start += CONFIG_SYS_CACHELINE_SIZE;
86*2085ae74SAlexander Stein }
87*2085ae74SAlexander Stein
88*2085ae74SAlexander Stein asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
89*2085ae74SAlexander Stein }
90*2085ae74SAlexander Stein
91*2085ae74SAlexander Stein #else /* #ifndef CONFIG_SYS_DCACHE_OFF */
invalidate_dcache_all(void)92*2085ae74SAlexander Stein void invalidate_dcache_all(void)
93*2085ae74SAlexander Stein {
94*2085ae74SAlexander Stein }
95*2085ae74SAlexander Stein
flush_dcache_all(void)96*2085ae74SAlexander Stein void flush_dcache_all(void)
97*2085ae74SAlexander Stein {
98*2085ae74SAlexander Stein }
99*2085ae74SAlexander Stein #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
100*2085ae74SAlexander Stein
101*2085ae74SAlexander Stein #if !defined(CONFIG_SYS_ICACHE_OFF) || !defined(CONFIG_SYS_DCACHE_OFF)
enable_caches(void)102*2085ae74SAlexander Stein void enable_caches(void)
103*2085ae74SAlexander Stein {
104*2085ae74SAlexander Stein #ifndef CONFIG_SYS_ICACHE_OFF
105*2085ae74SAlexander Stein icache_enable();
106*2085ae74SAlexander Stein #endif
107*2085ae74SAlexander Stein #ifndef CONFIG_SYS_DCACHE_OFF
108*2085ae74SAlexander Stein dcache_enable();
109*2085ae74SAlexander Stein #endif
110*2085ae74SAlexander Stein }
111*2085ae74SAlexander Stein #endif
112