2 * Copyright (C) 2012-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
4 * SPDX-License-Identifier: GPL-2.0+
10 #include <mach/ssc-regs.h>
12 #ifdef CONFIG_UNIPHIER_L2CACHE_ON
13 static void uniphier_cache_maint_all(u32 operation)
15 /* try until the command is successfully set */
17 writel(SSCOQM_S_ALL | SSCOQM_CE | operation, SSCOQM);
18 } while (readl(SSCOPPQSEF) & (SSCOPPQSEF_FE | SSCOPPQSEF_OE));
20 /* wait until the operation is completed */
21 while (readl(SSCOLPQS) != SSCOLPQS_EF)
24 /* clear the complete notification flag */
25 writel(SSCOLPQS_EF, SSCOLPQS);
27 writel(SSCOPE_CM_SYNC, SSCOPE); /* drain internal buffers */
28 readl(SSCOPE); /* need a read back to confirm */
31 void v7_outer_cache_flush_all(void)
33 uniphier_cache_maint_all(SSCOQM_CM_WB_INV);
36 void v7_outer_cache_inval_all(void)
38 uniphier_cache_maint_all(SSCOQM_CM_INV);
41 static void __uniphier_cache_maint_range(u32 start, u32 size, u32 operation)
43 /* try until the command is successfully set */
45 writel(SSCOQM_S_ADDRESS | SSCOQM_CE | operation, SSCOQM);
46 writel(start, SSCOQAD);
47 writel(size, SSCOQSZ);
49 } while (readl(SSCOPPQSEF) & (SSCOPPQSEF_FE | SSCOPPQSEF_OE));
51 /* wait until the operation is completed */
52 while (readl(SSCOLPQS) != SSCOLPQS_EF)
55 /* clear the complete notification flag */
56 writel(SSCOLPQS_EF, SSCOLPQS);
59 static void uniphier_cache_maint_range(u32 start, u32 end, u32 operation)
64 * If start address is not aligned to cache-line,
65 * do cache operation for the first cache-line
67 start = start & ~(SSC_LINE_SIZE - 1);
69 if (start == 0 && end >= (u32)(-SSC_LINE_SIZE)) {
70 /* this means cache operation for all range */
71 uniphier_cache_maint_all(operation);
76 * If end address is not aligned to cache-line,
77 * do cache operation for the last cache-line
79 size = (end - start + SSC_LINE_SIZE - 1) & ~(SSC_LINE_SIZE - 1);
82 u32 chunk_size = size > SSC_RANGE_OP_MAX_SIZE ?
83 SSC_RANGE_OP_MAX_SIZE : size;
84 __uniphier_cache_maint_range(start, chunk_size, operation);
90 writel(SSCOPE_CM_SYNC, SSCOPE); /* drain internal buffers */
91 readl(SSCOPE); /* need a read back to confirm */
94 void v7_outer_cache_flush_range(u32 start, u32 end)
96 uniphier_cache_maint_range(start, end, SSCOQM_CM_WB_INV);
99 void v7_outer_cache_inval_range(u32 start, u32 end)
101 uniphier_cache_maint_range(start, end, SSCOQM_CM_INV);
104 void v7_outer_cache_enable(void)
113 void v7_outer_cache_disable(void)
121 void enable_caches(void)