|
@@ -39,6 +39,7 @@ int icache_exists __section(".data");
|
|
|
#ifdef CONFIG_ISA_ARCV2
|
|
|
int slc_line_sz __section(".data");
|
|
|
int slc_exists __section(".data");
|
|
|
+int ioc_exists __section(".data");
|
|
|
|
|
|
static unsigned int __before_slc_op(const int op)
|
|
|
{
|
|
@@ -147,6 +148,21 @@ static void read_decode_cache_bcr_arcv2(void)
|
|
|
slc_exists = 1;
|
|
|
slc_line_sz = (slc_cfg.fields.lsz == 0) ? 128 : 64;
|
|
|
}
|
|
|
+
|
|
|
+ union {
|
|
|
+ struct bcr_clust_cfg {
|
|
|
+#ifdef CONFIG_CPU_BIG_ENDIAN
|
|
|
+ unsigned int pad:7, c:1, num_entries:8, num_cores:8, ver:8;
|
|
|
+#else
|
|
|
+ unsigned int ver:8, num_cores:8, num_entries:8, c:1, pad:7;
|
|
|
+#endif
|
|
|
+ } fields;
|
|
|
+ unsigned int word;
|
|
|
+ } cbcr;
|
|
|
+
|
|
|
+ cbcr.word = read_aux_reg(ARC_BCR_CLUSTER);
|
|
|
+ if (cbcr.fields.c)
|
|
|
+ ioc_exists = 1;
|
|
|
}
|
|
|
#endif
|
|
|
|
|
@@ -191,6 +207,17 @@ void cache_init(void)
|
|
|
|
|
|
#ifdef CONFIG_ISA_ARCV2
|
|
|
read_decode_cache_bcr_arcv2();
|
|
|
+
|
|
|
+ if (ioc_exists) {
|
|
|
+ /* IO coherency base - 0x8z */
|
|
|
+ write_aux_reg(ARC_AUX_IO_COH_AP0_BASE, 0x80000);
|
|
|
+ /* IO coherency aperture size - 512Mb: 0x8z-0xAz */
|
|
|
+ write_aux_reg(ARC_AUX_IO_COH_AP0_SIZE, 0x11);
|
|
|
+ /* Enable partial writes */
|
|
|
+ write_aux_reg(ARC_AUX_IO_COH_PARTIAL, 1);
|
|
|
+ /* Enable IO coherency */
|
|
|
+ write_aux_reg(ARC_AUX_IO_COH_ENABLE, 1);
|
|
|
+ }
|
|
|
#endif
|
|
|
}
|
|
|
|
|
@@ -359,18 +386,26 @@ static inline void __dc_line_op(unsigned long paddr, unsigned long sz,
|
|
|
|
|
|
void invalidate_dcache_range(unsigned long start, unsigned long end)
|
|
|
{
|
|
|
- __dc_line_op(start, end - start, OP_INV);
|
|
|
#ifdef CONFIG_ISA_ARCV2
|
|
|
- if (slc_exists)
|
|
|
+ if (!ioc_exists)
|
|
|
+#endif
|
|
|
+ __dc_line_op(start, end - start, OP_INV);
|
|
|
+
|
|
|
+#ifdef CONFIG_ISA_ARCV2
|
|
|
+ if (slc_exists && !ioc_exists)
|
|
|
__slc_line_op(start, end - start, OP_INV);
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
void flush_dcache_range(unsigned long start, unsigned long end)
|
|
|
{
|
|
|
- __dc_line_op(start, end - start, OP_FLUSH);
|
|
|
#ifdef CONFIG_ISA_ARCV2
|
|
|
- if (slc_exists)
|
|
|
+ if (!ioc_exists)
|
|
|
+#endif
|
|
|
+ __dc_line_op(start, end - start, OP_FLUSH);
|
|
|
+
|
|
|
+#ifdef CONFIG_ISA_ARCV2
|
|
|
+ if (slc_exists && !ioc_exists)
|
|
|
__slc_line_op(start, end - start, OP_FLUSH);
|
|
|
#endif
|
|
|
}
|
|
@@ -382,18 +417,26 @@ void flush_cache(unsigned long start, unsigned long size)
|
|
|
|
|
|
void invalidate_dcache_all(void)
|
|
|
{
|
|
|
- __dc_entire_op(OP_INV);
|
|
|
#ifdef CONFIG_ISA_ARCV2
|
|
|
- if (slc_exists)
|
|
|
+ if (!ioc_exists)
|
|
|
+#endif
|
|
|
+ __dc_entire_op(OP_INV);
|
|
|
+
|
|
|
+#ifdef CONFIG_ISA_ARCV2
|
|
|
+ if (slc_exists && !ioc_exists)
|
|
|
__slc_entire_op(OP_INV);
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
void flush_dcache_all(void)
|
|
|
{
|
|
|
- __dc_entire_op(OP_FLUSH);
|
|
|
#ifdef CONFIG_ISA_ARCV2
|
|
|
- if (slc_exists)
|
|
|
+ if (!ioc_exists)
|
|
|
+#endif
|
|
|
+ __dc_entire_op(OP_FLUSH);
|
|
|
+
|
|
|
+#ifdef CONFIG_ISA_ARCV2
|
|
|
+ if (slc_exists && !ioc_exists)
|
|
|
__slc_entire_op(OP_FLUSH);
|
|
|
#endif
|
|
|
}
|