2 * Copyright (C) 2012-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
4 * SPDX-License-Identifier: GPL-2.0+
13 #ifdef CONFIG_UNIPHIER_L2CACHE_ON
14 static void uniphier_cache_maint_all(u32 operation)
16 /* try until the command is successfully set */
18 writel(SSCOQM_S_ALL | SSCOQM_CE | operation, SSCOQM);
19 } while (readl(SSCOPPQSEF) & (SSCOPPQSEF_FE | SSCOPPQSEF_OE));
21 /* wait until the operation is completed */
22 while (readl(SSCOLPQS) != SSCOLPQS_EF)
25 /* clear the complete notification flag */
26 writel(SSCOLPQS_EF, SSCOLPQS);
28 writel(SSCOPE_CM_SYNC, SSCOPE); /* drain internal buffers */
29 readl(SSCOPE); /* need a read back to confirm */
32 void v7_outer_cache_flush_all(void)
34 uniphier_cache_maint_all(SSCOQM_CM_WB_INV);
37 void v7_outer_cache_inval_all(void)
39 uniphier_cache_maint_all(SSCOQM_CM_INV);
42 static void __uniphier_cache_maint_range(u32 start, u32 size, u32 operation)
44 /* try until the command is successfully set */
46 writel(SSCOQM_S_ADDRESS | SSCOQM_CE | operation, SSCOQM);
47 writel(start, SSCOQAD);
48 writel(size, SSCOQSZ);
50 } while (readl(SSCOPPQSEF) & (SSCOPPQSEF_FE | SSCOPPQSEF_OE));
52 /* wait until the operation is completed */
53 while (readl(SSCOLPQS) != SSCOLPQS_EF)
56 /* clear the complete notification flag */
57 writel(SSCOLPQS_EF, SSCOLPQS);
60 static void uniphier_cache_maint_range(u32 start, u32 end, u32 operation)
65 * If start address is not aligned to cache-line,
66 * do cache operation for the first cache-line
68 start = start & ~(SSC_LINE_SIZE - 1);
70 if (start == 0 && end >= (u32)(-SSC_LINE_SIZE)) {
71 /* this means cache operation for all range */
72 uniphier_cache_maint_all(operation);
77 * If end address is not aligned to cache-line,
78 * do cache operation for the last cache-line
80 size = (end - start + SSC_LINE_SIZE - 1) & ~(SSC_LINE_SIZE - 1);
83 u32 chunk_size = size > SSC_RANGE_OP_MAX_SIZE ?
84 SSC_RANGE_OP_MAX_SIZE : size;
85 __uniphier_cache_maint_range(start, chunk_size, operation);
91 writel(SSCOPE_CM_SYNC, SSCOPE); /* drain internal buffers */
92 readl(SSCOPE); /* need a read back to confirm */
95 void v7_outer_cache_flush_range(u32 start, u32 end)
97 uniphier_cache_maint_range(start, end, SSCOQM_CM_WB_INV);
100 void v7_outer_cache_inval_range(u32 start, u32 end)
102 uniphier_cache_maint_range(start, end, SSCOQM_CM_INV);
105 void v7_outer_cache_enable(void)
114 void v7_outer_cache_disable(void)
122 void enable_caches(void)