Wolfgang Denk | 72a087e | 2006-10-24 14:27:35 +0200 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2004-2006 Atmel Corporation |
| 3 | * |
Wolfgang Denk | 1a45966 | 2013-07-08 09:37:19 +0200 | [diff] [blame] | 4 | * SPDX-License-Identifier: GPL-2.0+ |
Wolfgang Denk | 72a087e | 2006-10-24 14:27:35 +0200 | [diff] [blame] | 5 | */ |
| 6 | |
| 7 | #include <common.h> |
| 8 | |
Olav Morken | d8f2aa3 | 2009-01-23 12:56:27 +0100 | [diff] [blame] | 9 | #include <asm/arch/cacheflush.h> |
Wolfgang Denk | 72a087e | 2006-10-24 14:27:35 +0200 | [diff] [blame] | 10 | |
| 11 | void dcache_clean_range(volatile void *start, size_t size) |
| 12 | { |
| 13 | unsigned long v, begin, end, linesz; |
| 14 | |
Jean-Christophe PLAGNIOL-VILLARD | 6d0f6bc | 2008-10-16 15:01:15 +0200 | [diff] [blame] | 15 | linesz = CONFIG_SYS_DCACHE_LINESZ; |
Wolfgang Denk | 72a087e | 2006-10-24 14:27:35 +0200 | [diff] [blame] | 16 | |
| 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ßmann | 0e05543 | 2014-06-12 22:07:52 +0200 | [diff] [blame] | 27 | void invalidate_dcache_range(unsigned long start, unsigned long stop) |
Wolfgang Denk | 72a087e | 2006-10-24 14:27:35 +0200 | [diff] [blame] | 28 | { |
Andreas Bießmann | 0e05543 | 2014-06-12 22:07:52 +0200 | [diff] [blame] | 29 | unsigned long v, linesz; |
Wolfgang Denk | 72a087e | 2006-10-24 14:27:35 +0200 | [diff] [blame] | 30 | |
Jean-Christophe PLAGNIOL-VILLARD | 6d0f6bc | 2008-10-16 15:01:15 +0200 | [diff] [blame] | 31 | linesz = CONFIG_SYS_DCACHE_LINESZ; |
Wolfgang Denk | 72a087e | 2006-10-24 14:27:35 +0200 | [diff] [blame] | 32 | |
| 33 | /* You asked for it, you got it */ |
Andreas Bießmann | 0e05543 | 2014-06-12 22:07:52 +0200 | [diff] [blame] | 34 | start = start & ~(linesz - 1); |
| 35 | stop = (stop + linesz - 1) & ~(linesz - 1); |
Wolfgang Denk | 72a087e | 2006-10-24 14:27:35 +0200 | [diff] [blame] | 36 | |
Andreas Bießmann | 0e05543 | 2014-06-12 22:07:52 +0200 | [diff] [blame] | 37 | for (v = start; v < stop; v += linesz) |
Wolfgang Denk | 72a087e | 2006-10-24 14:27:35 +0200 | [diff] [blame] | 38 | dcache_invalidate_line((void *)v); |
| 39 | } |
| 40 | |
Andreas Bießmann | 0e05543 | 2014-06-12 22:07:52 +0200 | [diff] [blame] | 41 | void flush_dcache_range(unsigned long start, unsigned long stop) |
Wolfgang Denk | 72a087e | 2006-10-24 14:27:35 +0200 | [diff] [blame] | 42 | { |
Andreas Bießmann | 0e05543 | 2014-06-12 22:07:52 +0200 | [diff] [blame] | 43 | unsigned long v, linesz; |
Wolfgang Denk | 72a087e | 2006-10-24 14:27:35 +0200 | [diff] [blame] | 44 | |
Jean-Christophe PLAGNIOL-VILLARD | 6d0f6bc | 2008-10-16 15:01:15 +0200 | [diff] [blame] | 45 | linesz = CONFIG_SYS_DCACHE_LINESZ; |
Wolfgang Denk | 72a087e | 2006-10-24 14:27:35 +0200 | [diff] [blame] | 46 | |
| 47 | /* You asked for it, you got it */ |
Andreas Bießmann | 0e05543 | 2014-06-12 22:07:52 +0200 | [diff] [blame] | 48 | start = start & ~(linesz - 1); |
| 49 | stop = (stop + linesz - 1) & ~(linesz - 1); |
Wolfgang Denk | 72a087e | 2006-10-24 14:27:35 +0200 | [diff] [blame] | 50 | |
Andreas Bießmann | 0e05543 | 2014-06-12 22:07:52 +0200 | [diff] [blame] | 51 | for (v = start; v < stop; v += linesz) |
Wolfgang Denk | 72a087e | 2006-10-24 14:27:35 +0200 | [diff] [blame] | 52 | dcache_flush_line((void *)v); |
| 53 | |
| 54 | sync_write_buffer(); |
| 55 | } |
| 56 | |
| 57 | void icache_invalidate_range(volatile void *start, size_t size) |
| 58 | { |
| 59 | unsigned long v, begin, end, linesz; |
| 60 | |
Jean-Christophe PLAGNIOL-VILLARD | 6d0f6bc | 2008-10-16 15:01:15 +0200 | [diff] [blame] | 61 | linesz = CONFIG_SYS_ICACHE_LINESZ; |
Wolfgang Denk | 72a087e | 2006-10-24 14:27:35 +0200 | [diff] [blame] | 62 | |
| 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 | */ |
| 77 | void 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 | } |