blob: b3ffc3348b514e90805336b4e1a308b37b84bf92 [file] [log] [blame]
Wolfgang Denk64702552006-10-24 14:27:35 +02001/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02004 * SPDX-License-Identifier: GPL-2.0+
Wolfgang Denk64702552006-10-24 14:27:35 +02005 */
6
7#include <common.h>
8
Olav Morkencbc6ce02009-01-23 12:56:27 +01009#include <asm/arch/cacheflush.h>
Wolfgang Denk64702552006-10-24 14:27:35 +020010
11void dcache_clean_range(volatile void *start, size_t size)
12{
13 unsigned long v, begin, end, linesz;
14
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020015 linesz = CONFIG_SYS_DCACHE_LINESZ;
Wolfgang Denk64702552006-10-24 14:27:35 +020016
17 /* You asked for it, you got it */
18 begin = (unsigned long)start & ~(linesz - 1);
19 end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
20
21 for (v = begin; v < end; v += linesz)
22 dcache_clean_line((void *)v);
23
24 sync_write_buffer();
25}
26
Andreas Bießmannd1461212014-06-12 22:07:52 +020027void invalidate_dcache_range(unsigned long start, unsigned long stop)
Wolfgang Denk64702552006-10-24 14:27:35 +020028{
Andreas Bießmannd1461212014-06-12 22:07:52 +020029 unsigned long v, linesz;
Wolfgang Denk64702552006-10-24 14:27:35 +020030
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020031 linesz = CONFIG_SYS_DCACHE_LINESZ;
Wolfgang Denk64702552006-10-24 14:27:35 +020032
33 /* You asked for it, you got it */
Andreas Bießmannd1461212014-06-12 22:07:52 +020034 start = start & ~(linesz - 1);
35 stop = (stop + linesz - 1) & ~(linesz - 1);
Wolfgang Denk64702552006-10-24 14:27:35 +020036
Andreas Bießmannd1461212014-06-12 22:07:52 +020037 for (v = start; v < stop; v += linesz)
Wolfgang Denk64702552006-10-24 14:27:35 +020038 dcache_invalidate_line((void *)v);
39}
40
Andreas Bießmannd1461212014-06-12 22:07:52 +020041void flush_dcache_range(unsigned long start, unsigned long stop)
Wolfgang Denk64702552006-10-24 14:27:35 +020042{
Andreas Bießmannd1461212014-06-12 22:07:52 +020043 unsigned long v, linesz;
Wolfgang Denk64702552006-10-24 14:27:35 +020044
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020045 linesz = CONFIG_SYS_DCACHE_LINESZ;
Wolfgang Denk64702552006-10-24 14:27:35 +020046
47 /* You asked for it, you got it */
Andreas Bießmannd1461212014-06-12 22:07:52 +020048 start = start & ~(linesz - 1);
49 stop = (stop + linesz - 1) & ~(linesz - 1);
Wolfgang Denk64702552006-10-24 14:27:35 +020050
Andreas Bießmannd1461212014-06-12 22:07:52 +020051 for (v = start; v < stop; v += linesz)
Wolfgang Denk64702552006-10-24 14:27:35 +020052 dcache_flush_line((void *)v);
53
54 sync_write_buffer();
55}
56
57void icache_invalidate_range(volatile void *start, size_t size)
58{
59 unsigned long v, begin, end, linesz;
60
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020061 linesz = CONFIG_SYS_ICACHE_LINESZ;
Wolfgang Denk64702552006-10-24 14:27:35 +020062
63 /* You asked for it, you got it */
64 begin = (unsigned long)start & ~(linesz - 1);
65 end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
66
67 for (v = begin; v < end; v += linesz)
68 icache_invalidate_line((void *)v);
69}
70
71/*
72 * This is called after loading something into memory. We need to
73 * make sure that everything that was loaded is actually written to
74 * RAM, and that the icache will look for it. Cleaning the dcache and
75 * invalidating the icache will do the trick.
76 */
77void flush_cache (unsigned long start_addr, unsigned long size)
78{
79 dcache_clean_range((void *)start_addr, size);
80 icache_invalidate_range((void *)start_addr, size);
81}