^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2011 Texas Instruments Incorporated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author: Mark Salter <msalter@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/cache.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Internal Memory Control Registers for caches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define IMCR_CCFG 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define IMCR_L1PCFG 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define IMCR_L1PCC 0x0024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define IMCR_L1DCFG 0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define IMCR_L1DCC 0x0044
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define IMCR_L2ALLOC0 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define IMCR_L2ALLOC1 0x2004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define IMCR_L2ALLOC2 0x2008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define IMCR_L2ALLOC3 0x200c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define IMCR_L2WBAR 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define IMCR_L2WWC 0x4004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define IMCR_L2WIBAR 0x4010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define IMCR_L2WIWC 0x4014
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define IMCR_L2IBAR 0x4018
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define IMCR_L2IWC 0x401c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define IMCR_L1PIBAR 0x4020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define IMCR_L1PIWC 0x4024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define IMCR_L1DWIBAR 0x4030
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define IMCR_L1DWIWC 0x4034
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define IMCR_L1DWBAR 0x4040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define IMCR_L1DWWC 0x4044
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define IMCR_L1DIBAR 0x4048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define IMCR_L1DIWC 0x404c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define IMCR_L2WB 0x5000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define IMCR_L2WBINV 0x5004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define IMCR_L2INV 0x5008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define IMCR_L1PINV 0x5028
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define IMCR_L1DWB 0x5040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define IMCR_L1DWBINV 0x5044
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define IMCR_L1DINV 0x5048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define IMCR_MAR_BASE 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define IMCR_MAR96_111 0x8180
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define IMCR_MAR128_191 0x8200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define IMCR_MAR224_239 0x8380
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define IMCR_L2MPFAR 0xa000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define IMCR_L2MPFSR 0xa004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define IMCR_L2MPFCR 0xa008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define IMCR_L2MPLK0 0xa100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define IMCR_L2MPLK1 0xa104
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define IMCR_L2MPLK2 0xa108
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define IMCR_L2MPLK3 0xa10c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define IMCR_L2MPLKCMD 0xa110
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define IMCR_L2MPLKSTAT 0xa114
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define IMCR_L2MPPA_BASE 0xa200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define IMCR_L1PMPFAR 0xa400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define IMCR_L1PMPFSR 0xa404
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define IMCR_L1PMPFCR 0xa408
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define IMCR_L1PMPLK0 0xa500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define IMCR_L1PMPLK1 0xa504
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define IMCR_L1PMPLK2 0xa508
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define IMCR_L1PMPLK3 0xa50c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define IMCR_L1PMPLKCMD 0xa510
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define IMCR_L1PMPLKSTAT 0xa514
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define IMCR_L1PMPPA_BASE 0xa600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define IMCR_L1DMPFAR 0xac00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define IMCR_L1DMPFSR 0xac04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define IMCR_L1DMPFCR 0xac08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define IMCR_L1DMPLK0 0xad00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define IMCR_L1DMPLK1 0xad04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define IMCR_L1DMPLK2 0xad08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define IMCR_L1DMPLK3 0xad0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define IMCR_L1DMPLKCMD 0xad10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define IMCR_L1DMPLKSTAT 0xad14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define IMCR_L1DMPPA_BASE 0xae00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define IMCR_L2PDWAKE0 0xc040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define IMCR_L2PDWAKE1 0xc044
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define IMCR_L2PDSLEEP0 0xc050
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define IMCR_L2PDSLEEP1 0xc054
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define IMCR_L2PDSTAT0 0xc060
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define IMCR_L2PDSTAT1 0xc064
^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) * CCFG register values and bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define L2MODE_0K_CACHE 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define L2MODE_32K_CACHE 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define L2MODE_64K_CACHE 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define L2MODE_128K_CACHE 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define L2MODE_256K_CACHE 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define L2PRIO_URGENT 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define L2PRIO_HIGH 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define L2PRIO_MEDIUM 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define L2PRIO_LOW 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define CCFG_ID 0x100 /* Invalidate L1P bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define CCFG_IP 0x200 /* Invalidate L1D bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static void __iomem *cache_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * L1 & L2 caches generic functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define imcr_get(reg) soc_readl(cache_base + (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define imcr_set(reg, value) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) soc_writel((value), cache_base + (reg)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) soc_readl(cache_base + (reg)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static void cache_block_operation_wait(unsigned int wc_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* Wait for completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) while (imcr_get(wc_reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static DEFINE_SPINLOCK(cache_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * Generic function to perform a block cache operation as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * invalidate or writeback/invalidate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static void cache_block_operation(unsigned int *start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) unsigned int *end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) unsigned int bar_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) unsigned int wc_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) unsigned int wcnt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) (L2_CACHE_ALIGN_CNT((unsigned int) end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) - L2_CACHE_ALIGN_LOW((unsigned int) start)) >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) unsigned int wc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) for (; wcnt; wcnt -= wc, start += wc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) spin_lock_irqsave(&cache_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * If another cache operation is occurring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (unlikely(imcr_get(wc_reg))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) spin_unlock_irqrestore(&cache_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* Wait for previous operation completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) cache_block_operation_wait(wc_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* Try again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) goto loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) imcr_set(bar_reg, L2_CACHE_ALIGN_LOW((unsigned int) start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (wcnt > 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) wc = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) wc = wcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* Set word count value in the WC register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) imcr_set(wc_reg, wc & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) spin_unlock_irqrestore(&cache_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* Wait for completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) cache_block_operation_wait(wc_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static void cache_block_operation_nowait(unsigned int *start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) unsigned int *end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) unsigned int bar_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) unsigned int wc_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) unsigned int wcnt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) (L2_CACHE_ALIGN_CNT((unsigned int) end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) - L2_CACHE_ALIGN_LOW((unsigned int) start)) >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) unsigned int wc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) for (; wcnt; wcnt -= wc, start += wc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) spin_lock_irqsave(&cache_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) imcr_set(bar_reg, L2_CACHE_ALIGN_LOW((unsigned int) start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (wcnt > 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) wc = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) wc = wcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /* Set word count value in the WC register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) imcr_set(wc_reg, wc & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) spin_unlock_irqrestore(&cache_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* Don't wait for completion on last cache operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (wcnt > 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) cache_block_operation_wait(wc_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^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) * L1 caches management
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * Disable L1 caches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) void L1_cache_off(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) unsigned int dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) imcr_set(IMCR_L1PCFG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) dummy = imcr_get(IMCR_L1PCFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) imcr_set(IMCR_L1DCFG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) dummy = imcr_get(IMCR_L1DCFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * Enable L1 caches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) void L1_cache_on(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) unsigned int dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) imcr_set(IMCR_L1PCFG, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) dummy = imcr_get(IMCR_L1PCFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) imcr_set(IMCR_L1DCFG, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) dummy = imcr_get(IMCR_L1DCFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * L1P global-invalidate all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) void L1P_cache_global_invalidate(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) unsigned int set = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) imcr_set(IMCR_L1PINV, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) while (imcr_get(IMCR_L1PINV) & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * L1D global-invalidate all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * Warning: this operation causes all updated data in L1D to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * be discarded rather than written back to the lower levels of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) void L1D_cache_global_invalidate(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) unsigned int set = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) imcr_set(IMCR_L1DINV, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) while (imcr_get(IMCR_L1DINV) & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) cpu_relax();
^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) void L1D_cache_global_writeback(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) unsigned int set = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) imcr_set(IMCR_L1DWB, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) while (imcr_get(IMCR_L1DWB) & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) void L1D_cache_global_writeback_invalidate(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) unsigned int set = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) imcr_set(IMCR_L1DWBINV, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) while (imcr_get(IMCR_L1DWBINV) & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * L2 caches management
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * Set L2 operation mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) void L2_cache_set_mode(unsigned int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) unsigned int ccfg = imcr_get(IMCR_CCFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* Clear and set the L2MODE bits in CCFG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ccfg &= ~7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) ccfg |= (mode & 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) imcr_set(IMCR_CCFG, ccfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) ccfg = imcr_get(IMCR_CCFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * L2 global-writeback and global-invalidate all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) void L2_cache_global_writeback_invalidate(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) imcr_set(IMCR_L2WBINV, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) while (imcr_get(IMCR_L2WBINV))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * L2 global-writeback all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) void L2_cache_global_writeback(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) imcr_set(IMCR_L2WB, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) while (imcr_get(IMCR_L2WB))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * Cacheability controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) void enable_caching(unsigned long start, unsigned long end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) unsigned int mar = IMCR_MAR_BASE + ((start >> 24) << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) unsigned int mar_e = IMCR_MAR_BASE + ((end >> 24) << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) for (; mar <= mar_e; mar += 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) imcr_set(mar, imcr_get(mar) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) void disable_caching(unsigned long start, unsigned long end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) unsigned int mar = IMCR_MAR_BASE + ((start >> 24) << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) unsigned int mar_e = IMCR_MAR_BASE + ((end >> 24) << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) for (; mar <= mar_e; mar += 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) imcr_set(mar, imcr_get(mar) & ~1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * L1 block operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) void L1P_cache_block_invalidate(unsigned int start, unsigned int end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) cache_block_operation((unsigned int *) start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) (unsigned int *) end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) IMCR_L1PIBAR, IMCR_L1PIWC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) EXPORT_SYMBOL(L1P_cache_block_invalidate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) void L1D_cache_block_invalidate(unsigned int start, unsigned int end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) cache_block_operation((unsigned int *) start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) (unsigned int *) end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) IMCR_L1DIBAR, IMCR_L1DIWC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) void L1D_cache_block_writeback_invalidate(unsigned int start, unsigned int end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) cache_block_operation((unsigned int *) start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) (unsigned int *) end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) IMCR_L1DWIBAR, IMCR_L1DWIWC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) void L1D_cache_block_writeback(unsigned int start, unsigned int end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) cache_block_operation((unsigned int *) start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) (unsigned int *) end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) IMCR_L1DWBAR, IMCR_L1DWWC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) EXPORT_SYMBOL(L1D_cache_block_writeback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * L2 block operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) void L2_cache_block_invalidate(unsigned int start, unsigned int end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) cache_block_operation((unsigned int *) start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) (unsigned int *) end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) IMCR_L2IBAR, IMCR_L2IWC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) void L2_cache_block_writeback(unsigned int start, unsigned int end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) cache_block_operation((unsigned int *) start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) (unsigned int *) end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) IMCR_L2WBAR, IMCR_L2WWC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) void L2_cache_block_writeback_invalidate(unsigned int start, unsigned int end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) cache_block_operation((unsigned int *) start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) (unsigned int *) end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) IMCR_L2WIBAR, IMCR_L2WIWC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) void L2_cache_block_invalidate_nowait(unsigned int start, unsigned int end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) cache_block_operation_nowait((unsigned int *) start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) (unsigned int *) end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) IMCR_L2IBAR, IMCR_L2IWC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) void L2_cache_block_writeback_nowait(unsigned int start, unsigned int end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) cache_block_operation_nowait((unsigned int *) start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) (unsigned int *) end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) IMCR_L2WBAR, IMCR_L2WWC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) void L2_cache_block_writeback_invalidate_nowait(unsigned int start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) unsigned int end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) cache_block_operation_nowait((unsigned int *) start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) (unsigned int *) end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) IMCR_L2WIBAR, IMCR_L2WIWC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * L1 and L2 caches configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) void __init c6x_cache_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct device_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) node = of_find_compatible_node(NULL, NULL, "ti,c64x+cache");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (!node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) cache_base = of_iomap(node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) of_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (!cache_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /* Set L2 caches on the the whole L2 SRAM memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) L2_cache_set_mode(L2MODE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /* Enable L1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) L1_cache_on();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }