blob: 75ec0a8fd24f440155c93af967f6af904ba16d8e [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Michal Simek76316a32007-03-11 13:42:58 +01002/*
3 * (C) Copyright 2007 Michal Simek
4 *
Michal Simekdb14d772007-09-24 00:18:46 +02005 * Michal SIMEK <monstr@monstr.eu>
Michal Simek76316a32007-03-11 13:42:58 +01006 */
7
Simon Glass9edefc22019-11-14 12:57:37 -07008#include <cpu_func.h>
Michal Simekfb05f6d2007-05-07 23:58:31 +02009#include <asm/asm.h>
Simon Glass90526e92020-05-10 11:39:56 -060010#include <asm/cache.h>
Ovidiu Panait95b7a8f2022-05-31 21:14:31 +030011#include <asm/cpuinfo.h>
12#include <asm/global_data.h>
13
14DECLARE_GLOBAL_DATA_PTR;
Michal Simek76316a32007-03-11 13:42:58 +010015
Ovidiu Panait73b8ee62022-05-31 21:14:28 +030016static void __invalidate_icache(ulong addr, ulong size)
17{
18 if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WIC)) {
Ovidiu Panait95b7a8f2022-05-31 21:14:31 +030019 for (int i = 0; i < size;
20 i += gd_cpuinfo()->icache_line_length) {
Ovidiu Panait73b8ee62022-05-31 21:14:28 +030021 asm volatile (
22 "wic %0, r0;"
23 "nop;"
24 :
25 : "r" (addr + i)
26 : "memory");
27 }
28 }
29}
30
Ovidiu Panaitb1951342022-05-31 21:14:30 +030031void invalidate_icache_all(void)
32{
Ovidiu Panait95b7a8f2022-05-31 21:14:31 +030033 __invalidate_icache(0, gd_cpuinfo()->icache_size);
Ovidiu Panaitb1951342022-05-31 21:14:30 +030034}
35
Ovidiu Panait73b8ee62022-05-31 21:14:28 +030036static void __flush_dcache(ulong addr, ulong size)
37{
38 if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WDC)) {
Ovidiu Panait95b7a8f2022-05-31 21:14:31 +030039 for (int i = 0; i < size;
40 i += gd_cpuinfo()->dcache_line_length) {
Ovidiu Panait73b8ee62022-05-31 21:14:28 +030041 asm volatile (
42 "wdc.flush %0, r0;"
43 "nop;"
44 :
45 : "r" (addr + i)
46 : "memory");
47 }
48 }
49}
50
Ovidiu Panait10f65082022-05-31 21:14:32 +030051void flush_dcache_range(unsigned long start, unsigned long end)
52{
53 if (start >= end) {
54 debug("Invalid dcache range - start: 0x%08lx end: 0x%08lx\n",
55 start, end);
56 return;
57 }
58
59 __flush_dcache(start, end - start);
60}
61
Ovidiu Panaitb1951342022-05-31 21:14:30 +030062void flush_dcache_all(void)
63{
Ovidiu Panait95b7a8f2022-05-31 21:14:31 +030064 __flush_dcache(0, gd_cpuinfo()->dcache_size);
Ovidiu Panaitb1951342022-05-31 21:14:30 +030065}
66
Simon Glass6cc915b2019-11-14 12:57:36 -070067int dcache_status(void)
Michal Simek76316a32007-03-11 13:42:58 +010068{
69 int i = 0;
70 int mask = 0x80;
71 __asm__ __volatile__ ("mfs %0,rmsr"::"r" (i):"memory");
72 /* i&=0x80 */
73 __asm__ __volatile__ ("and %0,%0,%1"::"r" (i), "r" (mask):"memory");
74 return i;
75}
76
Simon Glass6cc915b2019-11-14 12:57:36 -070077int icache_status(void)
Michal Simek76316a32007-03-11 13:42:58 +010078{
79 int i = 0;
80 int mask = 0x20;
81 __asm__ __volatile__ ("mfs %0,rmsr"::"r" (i):"memory");
82 /* i&=0x20 */
83 __asm__ __volatile__ ("and %0,%0,%1"::"r" (i), "r" (mask):"memory");
84 return i;
85}
Michal Simekf3f001a2007-05-07 19:25:08 +020086
Simon Glass6cc915b2019-11-14 12:57:36 -070087void icache_enable(void)
88{
Michal Simekfb05f6d2007-05-07 23:58:31 +020089 MSRSET(0x20);
Michal Simekf3f001a2007-05-07 19:25:08 +020090}
91
Simon Glass6cc915b2019-11-14 12:57:36 -070092void icache_disable(void)
93{
Ovidiu Panaitb1951342022-05-31 21:14:30 +030094 invalidate_icache_all();
Ovidiu Panait73b8ee62022-05-31 21:14:28 +030095
Michal Simekfb05f6d2007-05-07 23:58:31 +020096 MSRCLR(0x20);
Michal Simekf3f001a2007-05-07 19:25:08 +020097}
98
Simon Glass6cc915b2019-11-14 12:57:36 -070099void dcache_enable(void)
100{
Michal Simekfb05f6d2007-05-07 23:58:31 +0200101 MSRSET(0x80);
Michal Simekf3f001a2007-05-07 19:25:08 +0200102}
103
Simon Glass6cc915b2019-11-14 12:57:36 -0700104void dcache_disable(void)
105{
Ovidiu Panaitb1951342022-05-31 21:14:30 +0300106 flush_dcache_all();
Ovidiu Panaitef0a5922022-05-31 21:14:26 +0300107
Michal Simekfb05f6d2007-05-07 23:58:31 +0200108 MSRCLR(0x80);
Michal Simekf3f001a2007-05-07 19:25:08 +0200109}
Michal Simek8ff972c2010-04-16 12:56:33 +0200110
Simon Glass6cc915b2019-11-14 12:57:36 -0700111void flush_cache(ulong addr, ulong size)
Michal Simek8ff972c2010-04-16 12:56:33 +0200112{
Ovidiu Panait73b8ee62022-05-31 21:14:28 +0300113 __invalidate_icache(addr, size);
114 __flush_dcache(addr, size);
Michal Simek8ff972c2010-04-16 12:56:33 +0200115}
Ovidiu Panaitb1951342022-05-31 21:14:30 +0300116
117void flush_cache_all(void)
118{
119 invalidate_icache_all();
120 flush_dcache_all();
121}