xref: /rk3399_rockchip-uboot/arch/arm/cpu/arm11/cpu.c (revision 067716bac59716b07f1ee70d9bf6e5528289bb45)
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