diff options
author | rick <rick@andestech.com> | 2017-05-18 14:37:53 +0800 |
---|---|---|
committer | Andes <uboot@andestech.com> | 2017-05-22 14:05:46 +0800 |
commit | b841b6e94662b3b21a56d6ecaab64dcdfb0d311c (patch) | |
tree | 92847f53ffaeb104754e2940b32b981314627750 /arch/nds32/lib/cache.c | |
parent | f5076f869855045e527de7f1367c65f55a2b1448 (diff) |
nds32: Support AE3XX platform.
Support Andestech AE3xx platform: serial, timer device tree flow.
Signed-off-by: rick <rick@andestech.com>
Diffstat (limited to 'arch/nds32/lib/cache.c')
-rw-r--r-- | arch/nds32/lib/cache.c | 197 |
1 files changed, 160 insertions, 37 deletions
diff --git a/arch/nds32/lib/cache.c b/arch/nds32/lib/cache.c index 866dc1a98a5..846948167fd 100644 --- a/arch/nds32/lib/cache.c +++ b/arch/nds32/lib/cache.c @@ -7,32 +7,56 @@ */ #include <common.h> +#if (!defined(CONFIG_SYS_ICACHE_OFF) || !defined(CONFIG_SYS_DCACHE_OFF)) +static inline unsigned long CACHE_SET(unsigned char cache) +{ + if (cache == ICACHE) + return 64 << ((GET_ICM_CFG() & ICM_CFG_MSK_ISET) \ + >> ICM_CFG_OFF_ISET); + else + return 64 << ((GET_DCM_CFG() & DCM_CFG_MSK_DSET) \ + >> DCM_CFG_OFF_DSET); +} + +static inline unsigned long CACHE_WAY(unsigned char cache) +{ + if (cache == ICACHE) + return 1 + ((GET_ICM_CFG() & ICM_CFG_MSK_IWAY) \ + >> ICM_CFG_OFF_IWAY); + else + return 1 + ((GET_DCM_CFG() & DCM_CFG_MSK_DWAY) \ + >> DCM_CFG_OFF_DWAY); +} static inline unsigned long CACHE_LINE_SIZE(enum cache_t cache) { if (cache == ICACHE) return 8 << (((GET_ICM_CFG() & ICM_CFG_MSK_ISZ) \ - >> ICM_CFG_OFF_ISZ) - 1); + >> ICM_CFG_OFF_ISZ) - 1); else return 8 << (((GET_DCM_CFG() & DCM_CFG_MSK_DSZ) \ - >> DCM_CFG_OFF_DSZ) - 1); + >> DCM_CFG_OFF_DSZ) - 1); } +#endif -void flush_dcache_range(unsigned long start, unsigned long end) +#ifndef CONFIG_SYS_ICACHE_OFF +void invalidate_icache_all(void) { - unsigned long line_size; + unsigned long end, line_size; + line_size = CACHE_LINE_SIZE(ICACHE); + end = line_size * CACHE_WAY(ICACHE) * CACHE_SET(ICACHE); + do { + end -= line_size; + __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end)); - line_size = CACHE_LINE_SIZE(DCACHE); + end -= line_size; + __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end)); - while (end > start) { - asm volatile ( - "\n\tcctl %0, L1D_VA_WB" - "\n\tcctl %0, L1D_VA_INVAL" - : - : "r" (start) - ); - start += line_size; - } + end -= line_size; + __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end)); + end -= line_size; + __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL" : : "r" (end)); + } while (end > 0); } void invalidate_icache_range(unsigned long start, unsigned long end) @@ -50,27 +74,6 @@ void invalidate_icache_range(unsigned long start, unsigned long end) } } -void invalidate_dcache_range(unsigned long start, unsigned long end) -{ - unsigned long line_size; - - line_size = CACHE_LINE_SIZE(DCACHE); - while (end > start) { - asm volatile ( - "\n\tcctl %0, L1D_VA_INVAL" - : - : "r"(start) - ); - start += line_size; - } -} - -void flush_cache(unsigned long addr, unsigned long size) -{ - flush_dcache_range(addr, addr + size); - invalidate_icache_range(addr, addr + size); -} - void icache_enable(void) { asm volatile ( @@ -107,6 +110,81 @@ int icache_status(void) return ret; } +#else +void invalidate_icache_all(void) +{ +} + +void invalidate_icache_range(unsigned long start, unsigned long end) +{ +} + +void icache_enable(void) +{ +} + +void icache_disable(void) +{ +} + +int icache_status(void) +{ + return 0; +} + +#endif + +#ifndef CONFIG_SYS_DCACHE_OFF +void dcache_wbinval_all(void) +{ + unsigned long end, line_size; + line_size = CACHE_LINE_SIZE(DCACHE); + end = line_size * CACHE_WAY(DCACHE) * CACHE_SET(DCACHE); + do { + end -= line_size; + __asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end)); + __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end)); + end -= line_size; + __asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end)); + __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end)); + end -= line_size; + __asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end)); + __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end)); + end -= line_size; + __asm__ volatile ("\n\tcctl %0, L1D_IX_WB" : : "r" (end)); + __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL" : : "r" (end)); + + } while (end > 0); +} + +void flush_dcache_range(unsigned long start, unsigned long end) +{ + unsigned long line_size; + + line_size = CACHE_LINE_SIZE(DCACHE); + + while (end > start) { + asm volatile ( + "\n\tcctl %0, L1D_VA_WB" + "\n\tcctl %0, L1D_VA_INVAL" : : "r" (start) + ); + start += line_size; + } +} + +void invalidate_dcache_range(unsigned long start, unsigned long end) +{ + unsigned long line_size; + + line_size = CACHE_LINE_SIZE(DCACHE); + while (end > start) { + asm volatile ( + "\n\tcctl %0, L1D_VA_INVAL" : : "r"(start) + ); + start += line_size; + } +} + void dcache_enable(void) { asm volatile ( @@ -131,7 +209,6 @@ void dcache_disable(void) int dcache_status(void) { int ret; - asm volatile ( "mfsr $p0, $mr8\n\t" "andi %0, $p0, 0x02\n\t" @@ -139,6 +216,52 @@ int dcache_status(void) : : "memory" ); - return ret; } + +#else +void dcache_wbinval_all(void) +{ +} + +void flush_dcache_range(unsigned long start, unsigned long end) +{ +} + +void invalidate_dcache_range(unsigned long start, unsigned long end) +{ +} + +void dcache_enable(void) +{ +} + +void dcache_disable(void) +{ +} + +int dcache_status(void) +{ + return 0; +} + +#endif + + +void flush_dcache_all(void) +{ + dcache_wbinval_all(); +} + +void cache_flush(void) +{ + flush_dcache_all(); + invalidate_icache_all(); +} + + +void flush_cache(unsigned long addr, unsigned long size) +{ + flush_dcache_range(addr, addr + size); + invalidate_icache_range(addr, addr + size); +} |