summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYe.Li <B37916@freescale.com>2015-04-13 17:18:14 +0800
committerYe.Li <B37916@freescale.com>2015-04-14 14:50:25 +0800
commitf5d5f07fba936c4bb05c887de9d72fb75b3dc0f2 (patch)
tree77637913f7652a61146c283f92687c1e634c76d6
parented53487d36a886fb4557088804a4b5232b168889 (diff)
downloadu-boot-imx-f5d5f07fba936c4bb05c887de9d72fb75b3dc0f2.zip
u-boot-imx-f5d5f07fba936c4bb05c887de9d72fb75b3dc0f2.tar.gz
u-boot-imx-f5d5f07fba936c4bb05c887de9d72fb75b3dc0f2.tar.bz2
MLK-10647 armv7: Fix Dcache disable issue on i.MX7
The issue on the i.MX7D is that, there is one cache-able memory access between the L1 and L2 cache flush by calling the flush_dache_all-> v7_maint_dcache_all() [Flush L1 and L2 cache) which written in the C code. L1-cache-flush -> This will flush L1 cache to L2 cache in the end. Cache-able memory access -> This will have the chance cause the L1 line-fill with dirty data from L2 cache(L1 cache-line dirty, L2 clean) L2-cache-flush -> This will only flush L2 cache to L3, but still some dirty data on the L1 cacheline. After C & M bit clean, -> The dirty data on the L1 cache line lost, which will cause memory coherent issue if that dirty cache line has some useful data The only problem here is: there is one cache-cable memory access between L1 and L2 cache flush. This patch should works fine on the i.MX6 and i.MX7. The second cache flush have zero impact on the i.MX6, but this is really need for the i.MX7D platform due to the L1 line-fill during the first dcache_flush. And the second flush will not bring in the L1 dirty cache line due to the C bit is clear now, which means the dcache is disabled. Acked-by: Jason Liu<r64343@freescale.com> Reviewed-by: Jason Liu<r64343@freescale.com> Signed-off-by: Ye.Li <B37916@freescale.com>
-rw-r--r--arch/arm/lib/cache-cp15.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c
index 5d34aac..2ff5292 100644
--- a/arch/arm/lib/cache-cp15.c
+++ b/arch/arm/lib/cache-cp15.c
@@ -149,8 +149,11 @@ static void cache_disable(uint32_t cache_bit)
}
reg = get_cr();
cp_delay();
- if (cache_bit == (CR_C | CR_M))
+ if (cache_bit == (CR_C | CR_M)) {
flush_dcache_all();
+ set_cr(reg & ~CR_C);
+ flush_dcache_all();
+ }
set_cr(reg & ~cache_bit);
}
#endif