^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * arch/arm/mm/cache-tauros2.c - Tauros2 L2 cache controller support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2008 Marvell Semiconductor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This file is licensed under the terms of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * License version 2. This program is licensed "as is" without any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * warranty of any kind, whether express or implied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * References:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * - PJ1 CPU Core Datasheet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Document ID MV-S104837-01, Rev 0.7, January 24 2008.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * - PJ4 CPU Core Datasheet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Document ID MV-S105190-00, Rev 0.7, March 14 2008.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/cp15.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <asm/cputype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/hardware/cache-tauros2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* CP15 PJ4 Control configuration register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define CCR_L2C_PREFETCH_DISABLE BIT(24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define CCR_L2C_ECC_ENABLE BIT(23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define CCR_L2C_WAY7_4_DISABLE BIT(21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define CCR_L2C_BURST8_ENABLE BIT(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * When Tauros2 is used on a CPU that supports the v7 hierarchical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * cache operations, the cache handling code in proc-v7.S takes care
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * of everything, including handling DMA coherency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * So, we only need to register outer cache operations here if we're
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * being used on a pre-v7 CPU, and we only need to build support for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * outer cache operations into the kernel image if the kernel has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * configured to support a pre-v7 CPU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #ifdef CONFIG_CPU_32v5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * Low-level cache maintenance operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static inline void tauros2_clean_pa(unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) __asm__("mcr p15, 1, %0, c7, c11, 3" : : "r" (addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static inline void tauros2_clean_inv_pa(unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) __asm__("mcr p15, 1, %0, c7, c15, 3" : : "r" (addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static inline void tauros2_inv_pa(unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) __asm__("mcr p15, 1, %0, c7, c7, 3" : : "r" (addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * Linux primitives.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * Note that the end addresses passed to Linux primitives are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * noninclusive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define CACHE_LINE_SIZE 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static void tauros2_inv_range(unsigned long start, unsigned long end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * Clean and invalidate partial first cache line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (start & (CACHE_LINE_SIZE - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) tauros2_clean_inv_pa(start & ~(CACHE_LINE_SIZE - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) start = (start | (CACHE_LINE_SIZE - 1)) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * Clean and invalidate partial last cache line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (end & (CACHE_LINE_SIZE - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) tauros2_clean_inv_pa(end & ~(CACHE_LINE_SIZE - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) end &= ~(CACHE_LINE_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * Invalidate all full cache lines between 'start' and 'end'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) while (start < end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) tauros2_inv_pa(start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) start += CACHE_LINE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) dsb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static void tauros2_clean_range(unsigned long start, unsigned long end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) start &= ~(CACHE_LINE_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) while (start < end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) tauros2_clean_pa(start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) start += CACHE_LINE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) dsb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static void tauros2_flush_range(unsigned long start, unsigned long end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) start &= ~(CACHE_LINE_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) while (start < end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) tauros2_clean_inv_pa(start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) start += CACHE_LINE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) dsb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static void tauros2_disable(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) __asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) "mcr p15, 1, %0, c7, c11, 0 @L2 Cache Clean All\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) "mrc p15, 0, %0, c1, c0, 0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) "bic %0, %0, #(1 << 26)\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) "mcr p15, 0, %0, c1, c0, 0 @Disable L2 Cache\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) : : "r" (0x0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static void tauros2_resume(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) __asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) "mcr p15, 1, %0, c7, c7, 0 @L2 Cache Invalidate All\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) "mrc p15, 0, %0, c1, c0, 0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) "orr %0, %0, #(1 << 26)\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) "mcr p15, 0, %0, c1, c0, 0 @Enable L2 Cache\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) : : "r" (0x0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static inline u32 __init read_extra_features(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u32 u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) __asm__("mrc p15, 1, %0, c15, c1, 0" : "=r" (u));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static inline void __init write_extra_features(u32 u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) __asm__("mcr p15, 1, %0, c15, c1, 0" : : "r" (u));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static inline int __init cpuid_scheme(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return !!((processor_id & 0x000f0000) == 0x000f0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static inline u32 __init read_mmfr3(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) u32 mmfr3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) __asm__("mrc p15, 0, %0, c0, c1, 7\n" : "=r" (mmfr3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return mmfr3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static inline u32 __init read_actlr(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) u32 actlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) __asm__("mrc p15, 0, %0, c1, c0, 1\n" : "=r" (actlr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return actlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static inline void __init write_actlr(u32 actlr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) __asm__("mcr p15, 0, %0, c1, c0, 1\n" : : "r" (actlr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static void enable_extra_feature(unsigned int features)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) u32 u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) u = read_extra_features();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (features & CACHE_TAUROS2_PREFETCH_ON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) u &= ~CCR_L2C_PREFETCH_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) u |= CCR_L2C_PREFETCH_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) pr_info("Tauros2: %s L2 prefetch.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) (features & CACHE_TAUROS2_PREFETCH_ON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) ? "Enabling" : "Disabling");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (features & CACHE_TAUROS2_LINEFILL_BURST8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) u |= CCR_L2C_BURST8_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) u &= ~CCR_L2C_BURST8_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) pr_info("Tauros2: %s burst8 line fill.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) (features & CACHE_TAUROS2_LINEFILL_BURST8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ? "Enabling" : "Disabling");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) write_extra_features(u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static void __init tauros2_internal_init(unsigned int features)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) char *mode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) enable_extra_feature(features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #ifdef CONFIG_CPU_32v5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if ((processor_id & 0xff0f0000) == 0x56050000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) u32 feat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * v5 CPUs with Tauros2 have the L2 cache enable bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * located in the CPU Extra Features register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) feat = read_extra_features();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (!(feat & 0x00400000)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) pr_info("Tauros2: Enabling L2 cache.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) write_extra_features(feat | 0x00400000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) mode = "ARMv5";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) outer_cache.inv_range = tauros2_inv_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) outer_cache.clean_range = tauros2_clean_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) outer_cache.flush_range = tauros2_flush_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) outer_cache.disable = tauros2_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) outer_cache.resume = tauros2_resume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) #ifdef CONFIG_CPU_32v7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * Check whether this CPU has support for the v7 hierarchical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * cache ops. (PJ4 is in its v7 personality mode if the MMFR3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * register indicates support for the v7 hierarchical cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * ops.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * (Although strictly speaking there may exist CPUs that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * implement the v7 cache ops but are only ARMv6 CPUs (due to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * not complying with all of the other ARMv7 requirements),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * there are no real-life examples of Tauros2 being used on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * such CPUs as of yet.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (cpuid_scheme() && (read_mmfr3() & 0xf) == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) u32 actlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * When Tauros2 is used in an ARMv7 system, the L2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * enable bit is located in the Auxiliary System Control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * Register (which is the only register allowed by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * ARMv7 spec to contain fine-grained cache control bits).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) actlr = read_actlr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (!(actlr & 0x00000002)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) pr_info("Tauros2: Enabling L2 cache.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) write_actlr(actlr | 0x00000002);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) mode = "ARMv7";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (mode == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) pr_crit("Tauros2: Unable to detect CPU mode.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) pr_info("Tauros2: L2 cache support initialised "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) "in %s mode.\n", mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static const struct of_device_id tauros2_ids[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) { .compatible = "marvell,tauros2-cache"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) void __init tauros2_init(unsigned int features)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct device_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) unsigned int f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) node = of_find_matching_node(NULL, tauros2_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (!node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) pr_info("Not found marvell,tauros2-cache, disable it\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) ret = of_property_read_u32(node, "marvell,tauros2-cache-features", &f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) pr_info("Not found marvell,tauros-cache-features property, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) "disable extra features\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) features = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) features = f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) tauros2_internal_init(features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }