Loongson-3 maintains cache coherency by hardware. So we introduce a cpu feature named cpu_has_coherent_cache and use it to modify MIPS's cache flushing functions. Signed-off-by: Huacai Chen <chenhc@xxxxxxxxxx> Signed-off-by: Hongliang Tao <taohl@xxxxxxxxxx> --- arch/mips/Kconfig | 3 +++ arch/mips/include/asm/cpu-features.h | 3 +++ .../asm/mach-loongson64/cpu-feature-overrides.h | 1 + arch/mips/mm/c-r4k.c | 21 +++++++++++++++++++++ 4 files changed, 28 insertions(+) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 9322d26..3a8b7e5 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1769,6 +1769,7 @@ config CPU_BMIPS5000 config SYS_HAS_CPU_LOONGSON3 bool select CPU_SUPPORTS_CPUFREQ + select CPU_SUPPORTS_COHERENT_CACHE config SYS_HAS_CPU_LOONGSON2E bool @@ -1950,6 +1951,8 @@ config CPU_SUPPORTS_HUGEPAGES bool config CPU_SUPPORTS_UNCACHED_ACCELERATED bool +config CPU_SUPPORTS_COHERENT_CACHE + bool config MIPS_PGD_C0_CONTEXT bool default y if 64BIT && CPU_MIPSR2 && !CPU_XLP diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index d1e04c9..565940e 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h @@ -157,6 +157,9 @@ #ifndef cpu_has_pindexed_dcache #define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX) #endif +#ifndef cpu_has_coherent_cache +#define cpu_has_coherent_cache 0 +#endif #ifndef cpu_has_local_ebase #define cpu_has_local_ebase 1 #endif diff --git a/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h index 98963c2..e0bef38 100644 --- a/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h @@ -57,5 +57,6 @@ #define cpu_has_local_ebase 0 #define cpu_has_wsbh IS_ENABLED(CONFIG_CPU_LOONGSON3) +#define cpu_has_coherent_cache IS_ENABLED(CONFIG_CPU_SUPPORTS_COHERENT_CACHE) #endif /* __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H */ diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 5d3a25e..ed6e36e 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -428,6 +428,9 @@ static void r4k_blast_scache_setup(void) static inline void local_r4k___flush_cache_all(void * args) { + if (cpu_has_coherent_cache) + return; + switch (current_cpu_type()) { case CPU_LOONGSON2: case CPU_LOONGSON3: @@ -456,6 +459,9 @@ static inline void local_r4k___flush_cache_all(void * args) static void r4k___flush_cache_all(void) { + if (cpu_has_coherent_cache) + return; + r4k_on_each_cpu(local_r4k___flush_cache_all, NULL); } @@ -502,6 +508,9 @@ static void r4k_flush_cache_range(struct vm_area_struct *vma, { int exec = vma->vm_flags & VM_EXEC; + if (cpu_has_coherent_cache) + return; + if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) r4k_on_each_cpu(local_r4k_flush_cache_range, vma); } @@ -625,6 +634,9 @@ static void r4k_flush_cache_page(struct vm_area_struct *vma, { struct flush_cache_page_args args; + if (cpu_has_coherent_cache) + return; + args.vma = vma; args.addr = addr; args.pfn = pfn; @@ -634,11 +646,17 @@ static void r4k_flush_cache_page(struct vm_area_struct *vma, static inline void local_r4k_flush_data_cache_page(void * addr) { + if (cpu_has_coherent_cache) + return; + r4k_blast_dcache_page((unsigned long) addr); } static void r4k_flush_data_cache_page(unsigned long addr) { + if (cpu_has_coherent_cache) + return; + if (in_atomic()) local_r4k_flush_data_cache_page((void *)addr); else @@ -823,6 +841,9 @@ static void local_r4k_flush_cache_sigtramp(void * arg) static void r4k_flush_cache_sigtramp(unsigned long addr) { + if (cpu_has_coherent_cache) + return; + r4k_on_each_cpu(local_r4k_flush_cache_sigtramp, (void *) addr); } -- 2.4.6