1ea0364f1SPeter Tyser /*
2ea0364f1SPeter Tyser * (C) Copyright 2002
3ea0364f1SPeter Tyser * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4ea0364f1SPeter Tyser *
51a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+
6ea0364f1SPeter Tyser */
7ea0364f1SPeter Tyser
8ea0364f1SPeter Tyser /* for now: just dummy functions to satisfy the linker */
9ea0364f1SPeter Tyser
10ea0364f1SPeter Tyser #include <common.h>
111dfdd9baSThierry Reding #include <malloc.h>
12ea0364f1SPeter Tyser
13633b6cceSWu, Josh /*
14633b6cceSWu, Josh * Flush range from all levels of d-cache/unified-cache.
15633b6cceSWu, Josh * Affects the range [start, start + size - 1].
16633b6cceSWu, Josh */
flush_cache(unsigned long start,unsigned long size)17fcfddfd5SJeroen Hofstee __weak void flush_cache(unsigned long start, unsigned long size)
18ea0364f1SPeter Tyser {
19633b6cceSWu, Josh flush_dcache_range(start, start + size);
20ea0364f1SPeter Tyser }
21e05f0079SAneesh V
22e05f0079SAneesh V /*
23e05f0079SAneesh V * Default implementation:
24e05f0079SAneesh V * do a range flush for the entire range
25e05f0079SAneesh V */
flush_dcache_all(void)26fcfddfd5SJeroen Hofstee __weak void flush_dcache_all(void)
27e05f0079SAneesh V {
28e05f0079SAneesh V flush_cache(0, ~0);
29e05f0079SAneesh V }
30cba4b180SAneesh V
31cba4b180SAneesh V /*
32cba4b180SAneesh V * Default implementation of enable_caches()
33cba4b180SAneesh V * Real implementation should be in platform code
34cba4b180SAneesh V */
enable_caches(void)35fcfddfd5SJeroen Hofstee __weak void enable_caches(void)
36cba4b180SAneesh V {
37cba4b180SAneesh V puts("WARNING: Caches not enabled\n");
38cba4b180SAneesh V }
391dfdd9baSThierry Reding
invalidate_dcache_range(unsigned long start,unsigned long stop)40387871a1SWu, Josh __weak void invalidate_dcache_range(unsigned long start, unsigned long stop)
41387871a1SWu, Josh {
42387871a1SWu, Josh /* An empty stub, real implementation should be in platform code */
43387871a1SWu, Josh }
flush_dcache_range(unsigned long start,unsigned long stop)44387871a1SWu, Josh __weak void flush_dcache_range(unsigned long start, unsigned long stop)
45387871a1SWu, Josh {
46387871a1SWu, Josh /* An empty stub, real implementation should be in platform code */
47387871a1SWu, Josh }
48387871a1SWu, Josh
check_cache_range(unsigned long start,unsigned long stop)49397b5697SSimon Glass int check_cache_range(unsigned long start, unsigned long stop)
50397b5697SSimon Glass {
51397b5697SSimon Glass int ok = 1;
52397b5697SSimon Glass
53397b5697SSimon Glass if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
54397b5697SSimon Glass ok = 0;
55397b5697SSimon Glass
56397b5697SSimon Glass if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
57397b5697SSimon Glass ok = 0;
58397b5697SSimon Glass
59397b5697SSimon Glass if (!ok) {
60bcc53bf0SSimon Glass warn_non_spl("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
61397b5697SSimon Glass start, stop);
62397b5697SSimon Glass }
63397b5697SSimon Glass
64397b5697SSimon Glass return ok;
65397b5697SSimon Glass }
66397b5697SSimon Glass
671dfdd9baSThierry Reding #ifdef CONFIG_SYS_NONCACHED_MEMORY
681dfdd9baSThierry Reding /*
691dfdd9baSThierry Reding * Reserve one MMU section worth of address space below the malloc() area that
701dfdd9baSThierry Reding * will be mapped uncached.
711dfdd9baSThierry Reding */
721dfdd9baSThierry Reding static unsigned long noncached_start;
731dfdd9baSThierry Reding static unsigned long noncached_end;
741dfdd9baSThierry Reding static unsigned long noncached_next;
751dfdd9baSThierry Reding
noncached_init(void)761dfdd9baSThierry Reding void noncached_init(void)
771dfdd9baSThierry Reding {
781dfdd9baSThierry Reding phys_addr_t start, end;
791dfdd9baSThierry Reding size_t size;
801dfdd9baSThierry Reding
811dfdd9baSThierry Reding end = ALIGN(mem_malloc_start, MMU_SECTION_SIZE) - MMU_SECTION_SIZE;
821dfdd9baSThierry Reding size = ALIGN(CONFIG_SYS_NONCACHED_MEMORY, MMU_SECTION_SIZE);
831dfdd9baSThierry Reding start = end - size;
841dfdd9baSThierry Reding
851dfdd9baSThierry Reding debug("mapping memory %pa-%pa non-cached\n", &start, &end);
861dfdd9baSThierry Reding
871dfdd9baSThierry Reding noncached_start = start;
881dfdd9baSThierry Reding noncached_end = end;
891dfdd9baSThierry Reding noncached_next = start;
901dfdd9baSThierry Reding
911dfdd9baSThierry Reding #ifndef CONFIG_SYS_DCACHE_OFF
921dfdd9baSThierry Reding mmu_set_region_dcache_behaviour(noncached_start, size, DCACHE_OFF);
931dfdd9baSThierry Reding #endif
941dfdd9baSThierry Reding }
951dfdd9baSThierry Reding
noncached_alloc(size_t size,size_t align)961dfdd9baSThierry Reding phys_addr_t noncached_alloc(size_t size, size_t align)
971dfdd9baSThierry Reding {
981dfdd9baSThierry Reding phys_addr_t next = ALIGN(noncached_next, align);
991dfdd9baSThierry Reding
1001dfdd9baSThierry Reding if (next >= noncached_end || (noncached_end - next) < size)
1011dfdd9baSThierry Reding return 0;
1021dfdd9baSThierry Reding
1031dfdd9baSThierry Reding debug("allocated %zu bytes of uncached memory @%pa\n", size, &next);
1041dfdd9baSThierry Reding noncached_next = next + size;
1051dfdd9baSThierry Reding
1061dfdd9baSThierry Reding return next;
1071dfdd9baSThierry Reding }
1081dfdd9baSThierry Reding #endif /* CONFIG_SYS_NONCACHED_MEMORY */
10962e92077SAlbert ARIBAUD
110*3a649407STom Rini #if CONFIG_IS_ENABLED(SYS_THUMB_BUILD)
invalidate_l2_cache(void)11162e92077SAlbert ARIBAUD void invalidate_l2_cache(void)
11262e92077SAlbert ARIBAUD {
11362e92077SAlbert ARIBAUD unsigned int val = 0;
11462e92077SAlbert ARIBAUD
11562e92077SAlbert ARIBAUD asm volatile("mcr p15, 1, %0, c15, c11, 0 @ invl l2 cache"
11662e92077SAlbert ARIBAUD : : "r" (val) : "cc");
11762e92077SAlbert ARIBAUD isb();
11862e92077SAlbert ARIBAUD }
11962e92077SAlbert ARIBAUD #endif
120