18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  Copyright (C) 2011 Texas Instruments Incorporated
48c2ecf20Sopenharmony_ci *  Author: Mark Salter <msalter@redhat.com>
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci#include <linux/of.h>
78c2ecf20Sopenharmony_ci#include <linux/of_address.h>
88c2ecf20Sopenharmony_ci#include <linux/io.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <asm/cache.h>
118c2ecf20Sopenharmony_ci#include <asm/soc.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci/*
148c2ecf20Sopenharmony_ci * Internal Memory Control Registers for caches
158c2ecf20Sopenharmony_ci */
168c2ecf20Sopenharmony_ci#define IMCR_CCFG	  0x0000
178c2ecf20Sopenharmony_ci#define IMCR_L1PCFG	  0x0020
188c2ecf20Sopenharmony_ci#define IMCR_L1PCC	  0x0024
198c2ecf20Sopenharmony_ci#define IMCR_L1DCFG	  0x0040
208c2ecf20Sopenharmony_ci#define IMCR_L1DCC	  0x0044
218c2ecf20Sopenharmony_ci#define IMCR_L2ALLOC0	  0x2000
228c2ecf20Sopenharmony_ci#define IMCR_L2ALLOC1	  0x2004
238c2ecf20Sopenharmony_ci#define IMCR_L2ALLOC2	  0x2008
248c2ecf20Sopenharmony_ci#define IMCR_L2ALLOC3	  0x200c
258c2ecf20Sopenharmony_ci#define IMCR_L2WBAR	  0x4000
268c2ecf20Sopenharmony_ci#define IMCR_L2WWC	  0x4004
278c2ecf20Sopenharmony_ci#define IMCR_L2WIBAR	  0x4010
288c2ecf20Sopenharmony_ci#define IMCR_L2WIWC	  0x4014
298c2ecf20Sopenharmony_ci#define IMCR_L2IBAR	  0x4018
308c2ecf20Sopenharmony_ci#define IMCR_L2IWC	  0x401c
318c2ecf20Sopenharmony_ci#define IMCR_L1PIBAR	  0x4020
328c2ecf20Sopenharmony_ci#define IMCR_L1PIWC	  0x4024
338c2ecf20Sopenharmony_ci#define IMCR_L1DWIBAR	  0x4030
348c2ecf20Sopenharmony_ci#define IMCR_L1DWIWC	  0x4034
358c2ecf20Sopenharmony_ci#define IMCR_L1DWBAR	  0x4040
368c2ecf20Sopenharmony_ci#define IMCR_L1DWWC	  0x4044
378c2ecf20Sopenharmony_ci#define IMCR_L1DIBAR	  0x4048
388c2ecf20Sopenharmony_ci#define IMCR_L1DIWC	  0x404c
398c2ecf20Sopenharmony_ci#define IMCR_L2WB	  0x5000
408c2ecf20Sopenharmony_ci#define IMCR_L2WBINV	  0x5004
418c2ecf20Sopenharmony_ci#define IMCR_L2INV	  0x5008
428c2ecf20Sopenharmony_ci#define IMCR_L1PINV	  0x5028
438c2ecf20Sopenharmony_ci#define IMCR_L1DWB	  0x5040
448c2ecf20Sopenharmony_ci#define IMCR_L1DWBINV	  0x5044
458c2ecf20Sopenharmony_ci#define IMCR_L1DINV	  0x5048
468c2ecf20Sopenharmony_ci#define IMCR_MAR_BASE	  0x8000
478c2ecf20Sopenharmony_ci#define IMCR_MAR96_111	  0x8180
488c2ecf20Sopenharmony_ci#define IMCR_MAR128_191   0x8200
498c2ecf20Sopenharmony_ci#define IMCR_MAR224_239   0x8380
508c2ecf20Sopenharmony_ci#define IMCR_L2MPFAR	  0xa000
518c2ecf20Sopenharmony_ci#define IMCR_L2MPFSR	  0xa004
528c2ecf20Sopenharmony_ci#define IMCR_L2MPFCR	  0xa008
538c2ecf20Sopenharmony_ci#define IMCR_L2MPLK0	  0xa100
548c2ecf20Sopenharmony_ci#define IMCR_L2MPLK1	  0xa104
558c2ecf20Sopenharmony_ci#define IMCR_L2MPLK2	  0xa108
568c2ecf20Sopenharmony_ci#define IMCR_L2MPLK3	  0xa10c
578c2ecf20Sopenharmony_ci#define IMCR_L2MPLKCMD	  0xa110
588c2ecf20Sopenharmony_ci#define IMCR_L2MPLKSTAT   0xa114
598c2ecf20Sopenharmony_ci#define IMCR_L2MPPA_BASE  0xa200
608c2ecf20Sopenharmony_ci#define IMCR_L1PMPFAR	  0xa400
618c2ecf20Sopenharmony_ci#define IMCR_L1PMPFSR	  0xa404
628c2ecf20Sopenharmony_ci#define IMCR_L1PMPFCR	  0xa408
638c2ecf20Sopenharmony_ci#define IMCR_L1PMPLK0	  0xa500
648c2ecf20Sopenharmony_ci#define IMCR_L1PMPLK1	  0xa504
658c2ecf20Sopenharmony_ci#define IMCR_L1PMPLK2	  0xa508
668c2ecf20Sopenharmony_ci#define IMCR_L1PMPLK3	  0xa50c
678c2ecf20Sopenharmony_ci#define IMCR_L1PMPLKCMD   0xa510
688c2ecf20Sopenharmony_ci#define IMCR_L1PMPLKSTAT  0xa514
698c2ecf20Sopenharmony_ci#define IMCR_L1PMPPA_BASE 0xa600
708c2ecf20Sopenharmony_ci#define IMCR_L1DMPFAR	  0xac00
718c2ecf20Sopenharmony_ci#define IMCR_L1DMPFSR	  0xac04
728c2ecf20Sopenharmony_ci#define IMCR_L1DMPFCR	  0xac08
738c2ecf20Sopenharmony_ci#define IMCR_L1DMPLK0	  0xad00
748c2ecf20Sopenharmony_ci#define IMCR_L1DMPLK1	  0xad04
758c2ecf20Sopenharmony_ci#define IMCR_L1DMPLK2	  0xad08
768c2ecf20Sopenharmony_ci#define IMCR_L1DMPLK3	  0xad0c
778c2ecf20Sopenharmony_ci#define IMCR_L1DMPLKCMD   0xad10
788c2ecf20Sopenharmony_ci#define IMCR_L1DMPLKSTAT  0xad14
798c2ecf20Sopenharmony_ci#define IMCR_L1DMPPA_BASE 0xae00
808c2ecf20Sopenharmony_ci#define IMCR_L2PDWAKE0	  0xc040
818c2ecf20Sopenharmony_ci#define IMCR_L2PDWAKE1	  0xc044
828c2ecf20Sopenharmony_ci#define IMCR_L2PDSLEEP0   0xc050
838c2ecf20Sopenharmony_ci#define IMCR_L2PDSLEEP1   0xc054
848c2ecf20Sopenharmony_ci#define IMCR_L2PDSTAT0	  0xc060
858c2ecf20Sopenharmony_ci#define IMCR_L2PDSTAT1	  0xc064
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci/*
888c2ecf20Sopenharmony_ci * CCFG register values and bits
898c2ecf20Sopenharmony_ci */
908c2ecf20Sopenharmony_ci#define L2MODE_0K_CACHE   0x0
918c2ecf20Sopenharmony_ci#define L2MODE_32K_CACHE  0x1
928c2ecf20Sopenharmony_ci#define L2MODE_64K_CACHE  0x2
938c2ecf20Sopenharmony_ci#define L2MODE_128K_CACHE 0x3
948c2ecf20Sopenharmony_ci#define L2MODE_256K_CACHE 0x7
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci#define L2PRIO_URGENT     0x0
978c2ecf20Sopenharmony_ci#define L2PRIO_HIGH       0x1
988c2ecf20Sopenharmony_ci#define L2PRIO_MEDIUM     0x2
998c2ecf20Sopenharmony_ci#define L2PRIO_LOW        0x3
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci#define CCFG_ID           0x100   /* Invalidate L1P bit */
1028c2ecf20Sopenharmony_ci#define CCFG_IP           0x200   /* Invalidate L1D bit */
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_cistatic void __iomem *cache_base;
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci/*
1078c2ecf20Sopenharmony_ci * L1 & L2 caches generic functions
1088c2ecf20Sopenharmony_ci */
1098c2ecf20Sopenharmony_ci#define imcr_get(reg) soc_readl(cache_base + (reg))
1108c2ecf20Sopenharmony_ci#define imcr_set(reg, value) \
1118c2ecf20Sopenharmony_cido {								\
1128c2ecf20Sopenharmony_ci	soc_writel((value), cache_base + (reg));		\
1138c2ecf20Sopenharmony_ci	soc_readl(cache_base + (reg));				\
1148c2ecf20Sopenharmony_ci} while (0)
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_cistatic void cache_block_operation_wait(unsigned int wc_reg)
1178c2ecf20Sopenharmony_ci{
1188c2ecf20Sopenharmony_ci	/* Wait for completion */
1198c2ecf20Sopenharmony_ci	while (imcr_get(wc_reg))
1208c2ecf20Sopenharmony_ci		cpu_relax();
1218c2ecf20Sopenharmony_ci}
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_cistatic DEFINE_SPINLOCK(cache_lock);
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci/*
1268c2ecf20Sopenharmony_ci * Generic function to perform a block cache operation as
1278c2ecf20Sopenharmony_ci * invalidate or writeback/invalidate
1288c2ecf20Sopenharmony_ci */
1298c2ecf20Sopenharmony_cistatic void cache_block_operation(unsigned int *start,
1308c2ecf20Sopenharmony_ci				  unsigned int *end,
1318c2ecf20Sopenharmony_ci				  unsigned int bar_reg,
1328c2ecf20Sopenharmony_ci				  unsigned int wc_reg)
1338c2ecf20Sopenharmony_ci{
1348c2ecf20Sopenharmony_ci	unsigned long flags;
1358c2ecf20Sopenharmony_ci	unsigned int wcnt =
1368c2ecf20Sopenharmony_ci		(L2_CACHE_ALIGN_CNT((unsigned int) end)
1378c2ecf20Sopenharmony_ci		 - L2_CACHE_ALIGN_LOW((unsigned int) start)) >> 2;
1388c2ecf20Sopenharmony_ci	unsigned int wc = 0;
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	for (; wcnt; wcnt -= wc, start += wc) {
1418c2ecf20Sopenharmony_ciloop:
1428c2ecf20Sopenharmony_ci		spin_lock_irqsave(&cache_lock, flags);
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci		/*
1458c2ecf20Sopenharmony_ci		 * If another cache operation is occurring
1468c2ecf20Sopenharmony_ci		 */
1478c2ecf20Sopenharmony_ci		if (unlikely(imcr_get(wc_reg))) {
1488c2ecf20Sopenharmony_ci			spin_unlock_irqrestore(&cache_lock, flags);
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci			/* Wait for previous operation completion */
1518c2ecf20Sopenharmony_ci			cache_block_operation_wait(wc_reg);
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci			/* Try again */
1548c2ecf20Sopenharmony_ci			goto loop;
1558c2ecf20Sopenharmony_ci		}
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ci		imcr_set(bar_reg, L2_CACHE_ALIGN_LOW((unsigned int) start));
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci		if (wcnt > 0xffff)
1608c2ecf20Sopenharmony_ci			wc = 0xffff;
1618c2ecf20Sopenharmony_ci		else
1628c2ecf20Sopenharmony_ci			wc = wcnt;
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci		/* Set word count value in the WC register */
1658c2ecf20Sopenharmony_ci		imcr_set(wc_reg, wc & 0xffff);
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci		spin_unlock_irqrestore(&cache_lock, flags);
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci		/* Wait for completion */
1708c2ecf20Sopenharmony_ci		cache_block_operation_wait(wc_reg);
1718c2ecf20Sopenharmony_ci	}
1728c2ecf20Sopenharmony_ci}
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_cistatic void cache_block_operation_nowait(unsigned int *start,
1758c2ecf20Sopenharmony_ci					 unsigned int *end,
1768c2ecf20Sopenharmony_ci					 unsigned int bar_reg,
1778c2ecf20Sopenharmony_ci					 unsigned int wc_reg)
1788c2ecf20Sopenharmony_ci{
1798c2ecf20Sopenharmony_ci	unsigned long flags;
1808c2ecf20Sopenharmony_ci	unsigned int wcnt =
1818c2ecf20Sopenharmony_ci		(L2_CACHE_ALIGN_CNT((unsigned int) end)
1828c2ecf20Sopenharmony_ci		 - L2_CACHE_ALIGN_LOW((unsigned int) start)) >> 2;
1838c2ecf20Sopenharmony_ci	unsigned int wc = 0;
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci	for (; wcnt; wcnt -= wc, start += wc) {
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci		spin_lock_irqsave(&cache_lock, flags);
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci		imcr_set(bar_reg, L2_CACHE_ALIGN_LOW((unsigned int) start));
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci		if (wcnt > 0xffff)
1928c2ecf20Sopenharmony_ci			wc = 0xffff;
1938c2ecf20Sopenharmony_ci		else
1948c2ecf20Sopenharmony_ci			wc = wcnt;
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci		/* Set word count value in the WC register */
1978c2ecf20Sopenharmony_ci		imcr_set(wc_reg, wc & 0xffff);
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_ci		spin_unlock_irqrestore(&cache_lock, flags);
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_ci		/* Don't wait for completion on last cache operation */
2028c2ecf20Sopenharmony_ci		if (wcnt > 0xffff)
2038c2ecf20Sopenharmony_ci			cache_block_operation_wait(wc_reg);
2048c2ecf20Sopenharmony_ci	}
2058c2ecf20Sopenharmony_ci}
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci/*
2088c2ecf20Sopenharmony_ci * L1 caches management
2098c2ecf20Sopenharmony_ci */
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci/*
2128c2ecf20Sopenharmony_ci * Disable L1 caches
2138c2ecf20Sopenharmony_ci */
2148c2ecf20Sopenharmony_civoid L1_cache_off(void)
2158c2ecf20Sopenharmony_ci{
2168c2ecf20Sopenharmony_ci	unsigned int dummy;
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci	imcr_set(IMCR_L1PCFG, 0);
2198c2ecf20Sopenharmony_ci	dummy = imcr_get(IMCR_L1PCFG);
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci	imcr_set(IMCR_L1DCFG, 0);
2228c2ecf20Sopenharmony_ci	dummy = imcr_get(IMCR_L1DCFG);
2238c2ecf20Sopenharmony_ci}
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci/*
2268c2ecf20Sopenharmony_ci * Enable L1 caches
2278c2ecf20Sopenharmony_ci */
2288c2ecf20Sopenharmony_civoid L1_cache_on(void)
2298c2ecf20Sopenharmony_ci{
2308c2ecf20Sopenharmony_ci	unsigned int dummy;
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ci	imcr_set(IMCR_L1PCFG, 7);
2338c2ecf20Sopenharmony_ci	dummy = imcr_get(IMCR_L1PCFG);
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_ci	imcr_set(IMCR_L1DCFG, 7);
2368c2ecf20Sopenharmony_ci	dummy = imcr_get(IMCR_L1DCFG);
2378c2ecf20Sopenharmony_ci}
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ci/*
2408c2ecf20Sopenharmony_ci *  L1P global-invalidate all
2418c2ecf20Sopenharmony_ci */
2428c2ecf20Sopenharmony_civoid L1P_cache_global_invalidate(void)
2438c2ecf20Sopenharmony_ci{
2448c2ecf20Sopenharmony_ci	unsigned int set = 1;
2458c2ecf20Sopenharmony_ci	imcr_set(IMCR_L1PINV, set);
2468c2ecf20Sopenharmony_ci	while (imcr_get(IMCR_L1PINV) & 1)
2478c2ecf20Sopenharmony_ci		cpu_relax();
2488c2ecf20Sopenharmony_ci}
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_ci/*
2518c2ecf20Sopenharmony_ci *  L1D global-invalidate all
2528c2ecf20Sopenharmony_ci *
2538c2ecf20Sopenharmony_ci * Warning: this operation causes all updated data in L1D to
2548c2ecf20Sopenharmony_ci * be discarded rather than written back to the lower levels of
2558c2ecf20Sopenharmony_ci * memory
2568c2ecf20Sopenharmony_ci */
2578c2ecf20Sopenharmony_civoid L1D_cache_global_invalidate(void)
2588c2ecf20Sopenharmony_ci{
2598c2ecf20Sopenharmony_ci	unsigned int set = 1;
2608c2ecf20Sopenharmony_ci	imcr_set(IMCR_L1DINV, set);
2618c2ecf20Sopenharmony_ci	while (imcr_get(IMCR_L1DINV) & 1)
2628c2ecf20Sopenharmony_ci		cpu_relax();
2638c2ecf20Sopenharmony_ci}
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_civoid L1D_cache_global_writeback(void)
2668c2ecf20Sopenharmony_ci{
2678c2ecf20Sopenharmony_ci	unsigned int set = 1;
2688c2ecf20Sopenharmony_ci	imcr_set(IMCR_L1DWB, set);
2698c2ecf20Sopenharmony_ci	while (imcr_get(IMCR_L1DWB) & 1)
2708c2ecf20Sopenharmony_ci		cpu_relax();
2718c2ecf20Sopenharmony_ci}
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_civoid L1D_cache_global_writeback_invalidate(void)
2748c2ecf20Sopenharmony_ci{
2758c2ecf20Sopenharmony_ci	unsigned int set = 1;
2768c2ecf20Sopenharmony_ci	imcr_set(IMCR_L1DWBINV, set);
2778c2ecf20Sopenharmony_ci	while (imcr_get(IMCR_L1DWBINV) & 1)
2788c2ecf20Sopenharmony_ci		cpu_relax();
2798c2ecf20Sopenharmony_ci}
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_ci/*
2828c2ecf20Sopenharmony_ci * L2 caches management
2838c2ecf20Sopenharmony_ci */
2848c2ecf20Sopenharmony_ci
2858c2ecf20Sopenharmony_ci/*
2868c2ecf20Sopenharmony_ci * Set L2 operation mode
2878c2ecf20Sopenharmony_ci */
2888c2ecf20Sopenharmony_civoid L2_cache_set_mode(unsigned int mode)
2898c2ecf20Sopenharmony_ci{
2908c2ecf20Sopenharmony_ci	unsigned int ccfg = imcr_get(IMCR_CCFG);
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_ci	/* Clear and set the L2MODE bits in CCFG */
2938c2ecf20Sopenharmony_ci	ccfg &= ~7;
2948c2ecf20Sopenharmony_ci	ccfg |= (mode & 7);
2958c2ecf20Sopenharmony_ci	imcr_set(IMCR_CCFG, ccfg);
2968c2ecf20Sopenharmony_ci	ccfg = imcr_get(IMCR_CCFG);
2978c2ecf20Sopenharmony_ci}
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_ci/*
3008c2ecf20Sopenharmony_ci *  L2 global-writeback and global-invalidate all
3018c2ecf20Sopenharmony_ci */
3028c2ecf20Sopenharmony_civoid L2_cache_global_writeback_invalidate(void)
3038c2ecf20Sopenharmony_ci{
3048c2ecf20Sopenharmony_ci	imcr_set(IMCR_L2WBINV, 1);
3058c2ecf20Sopenharmony_ci	while (imcr_get(IMCR_L2WBINV))
3068c2ecf20Sopenharmony_ci		cpu_relax();
3078c2ecf20Sopenharmony_ci}
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_ci/*
3108c2ecf20Sopenharmony_ci *  L2 global-writeback all
3118c2ecf20Sopenharmony_ci */
3128c2ecf20Sopenharmony_civoid L2_cache_global_writeback(void)
3138c2ecf20Sopenharmony_ci{
3148c2ecf20Sopenharmony_ci	imcr_set(IMCR_L2WB, 1);
3158c2ecf20Sopenharmony_ci	while (imcr_get(IMCR_L2WB))
3168c2ecf20Sopenharmony_ci		cpu_relax();
3178c2ecf20Sopenharmony_ci}
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_ci/*
3208c2ecf20Sopenharmony_ci * Cacheability controls
3218c2ecf20Sopenharmony_ci */
3228c2ecf20Sopenharmony_civoid enable_caching(unsigned long start, unsigned long end)
3238c2ecf20Sopenharmony_ci{
3248c2ecf20Sopenharmony_ci	unsigned int mar = IMCR_MAR_BASE + ((start >> 24) << 2);
3258c2ecf20Sopenharmony_ci	unsigned int mar_e = IMCR_MAR_BASE + ((end >> 24) << 2);
3268c2ecf20Sopenharmony_ci
3278c2ecf20Sopenharmony_ci	for (; mar <= mar_e; mar += 4)
3288c2ecf20Sopenharmony_ci		imcr_set(mar, imcr_get(mar) | 1);
3298c2ecf20Sopenharmony_ci}
3308c2ecf20Sopenharmony_ci
3318c2ecf20Sopenharmony_civoid disable_caching(unsigned long start, unsigned long end)
3328c2ecf20Sopenharmony_ci{
3338c2ecf20Sopenharmony_ci	unsigned int mar = IMCR_MAR_BASE + ((start >> 24) << 2);
3348c2ecf20Sopenharmony_ci	unsigned int mar_e = IMCR_MAR_BASE + ((end >> 24) << 2);
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_ci	for (; mar <= mar_e; mar += 4)
3378c2ecf20Sopenharmony_ci		imcr_set(mar, imcr_get(mar) & ~1);
3388c2ecf20Sopenharmony_ci}
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_ci
3418c2ecf20Sopenharmony_ci/*
3428c2ecf20Sopenharmony_ci *  L1 block operations
3438c2ecf20Sopenharmony_ci */
3448c2ecf20Sopenharmony_civoid L1P_cache_block_invalidate(unsigned int start, unsigned int end)
3458c2ecf20Sopenharmony_ci{
3468c2ecf20Sopenharmony_ci	cache_block_operation((unsigned int *) start,
3478c2ecf20Sopenharmony_ci			      (unsigned int *) end,
3488c2ecf20Sopenharmony_ci			      IMCR_L1PIBAR, IMCR_L1PIWC);
3498c2ecf20Sopenharmony_ci}
3508c2ecf20Sopenharmony_ciEXPORT_SYMBOL(L1P_cache_block_invalidate);
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_civoid L1D_cache_block_invalidate(unsigned int start, unsigned int end)
3538c2ecf20Sopenharmony_ci{
3548c2ecf20Sopenharmony_ci	cache_block_operation((unsigned int *) start,
3558c2ecf20Sopenharmony_ci			      (unsigned int *) end,
3568c2ecf20Sopenharmony_ci			      IMCR_L1DIBAR, IMCR_L1DIWC);
3578c2ecf20Sopenharmony_ci}
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_civoid L1D_cache_block_writeback_invalidate(unsigned int start, unsigned int end)
3608c2ecf20Sopenharmony_ci{
3618c2ecf20Sopenharmony_ci	cache_block_operation((unsigned int *) start,
3628c2ecf20Sopenharmony_ci			      (unsigned int *) end,
3638c2ecf20Sopenharmony_ci			      IMCR_L1DWIBAR, IMCR_L1DWIWC);
3648c2ecf20Sopenharmony_ci}
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_civoid L1D_cache_block_writeback(unsigned int start, unsigned int end)
3678c2ecf20Sopenharmony_ci{
3688c2ecf20Sopenharmony_ci	cache_block_operation((unsigned int *) start,
3698c2ecf20Sopenharmony_ci			      (unsigned int *) end,
3708c2ecf20Sopenharmony_ci			      IMCR_L1DWBAR, IMCR_L1DWWC);
3718c2ecf20Sopenharmony_ci}
3728c2ecf20Sopenharmony_ciEXPORT_SYMBOL(L1D_cache_block_writeback);
3738c2ecf20Sopenharmony_ci
3748c2ecf20Sopenharmony_ci/*
3758c2ecf20Sopenharmony_ci *  L2 block operations
3768c2ecf20Sopenharmony_ci */
3778c2ecf20Sopenharmony_civoid L2_cache_block_invalidate(unsigned int start, unsigned int end)
3788c2ecf20Sopenharmony_ci{
3798c2ecf20Sopenharmony_ci	cache_block_operation((unsigned int *) start,
3808c2ecf20Sopenharmony_ci			      (unsigned int *) end,
3818c2ecf20Sopenharmony_ci			      IMCR_L2IBAR, IMCR_L2IWC);
3828c2ecf20Sopenharmony_ci}
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_civoid L2_cache_block_writeback(unsigned int start, unsigned int end)
3858c2ecf20Sopenharmony_ci{
3868c2ecf20Sopenharmony_ci	cache_block_operation((unsigned int *) start,
3878c2ecf20Sopenharmony_ci			      (unsigned int *) end,
3888c2ecf20Sopenharmony_ci			      IMCR_L2WBAR, IMCR_L2WWC);
3898c2ecf20Sopenharmony_ci}
3908c2ecf20Sopenharmony_ci
3918c2ecf20Sopenharmony_civoid L2_cache_block_writeback_invalidate(unsigned int start, unsigned int end)
3928c2ecf20Sopenharmony_ci{
3938c2ecf20Sopenharmony_ci	cache_block_operation((unsigned int *) start,
3948c2ecf20Sopenharmony_ci			      (unsigned int *) end,
3958c2ecf20Sopenharmony_ci			      IMCR_L2WIBAR, IMCR_L2WIWC);
3968c2ecf20Sopenharmony_ci}
3978c2ecf20Sopenharmony_ci
3988c2ecf20Sopenharmony_civoid L2_cache_block_invalidate_nowait(unsigned int start, unsigned int end)
3998c2ecf20Sopenharmony_ci{
4008c2ecf20Sopenharmony_ci	cache_block_operation_nowait((unsigned int *) start,
4018c2ecf20Sopenharmony_ci				     (unsigned int *) end,
4028c2ecf20Sopenharmony_ci				     IMCR_L2IBAR, IMCR_L2IWC);
4038c2ecf20Sopenharmony_ci}
4048c2ecf20Sopenharmony_ci
4058c2ecf20Sopenharmony_civoid L2_cache_block_writeback_nowait(unsigned int start, unsigned int end)
4068c2ecf20Sopenharmony_ci{
4078c2ecf20Sopenharmony_ci	cache_block_operation_nowait((unsigned int *) start,
4088c2ecf20Sopenharmony_ci				     (unsigned int *) end,
4098c2ecf20Sopenharmony_ci				     IMCR_L2WBAR, IMCR_L2WWC);
4108c2ecf20Sopenharmony_ci}
4118c2ecf20Sopenharmony_ci
4128c2ecf20Sopenharmony_civoid L2_cache_block_writeback_invalidate_nowait(unsigned int start,
4138c2ecf20Sopenharmony_ci						unsigned int end)
4148c2ecf20Sopenharmony_ci{
4158c2ecf20Sopenharmony_ci	cache_block_operation_nowait((unsigned int *) start,
4168c2ecf20Sopenharmony_ci				     (unsigned int *) end,
4178c2ecf20Sopenharmony_ci				     IMCR_L2WIBAR, IMCR_L2WIWC);
4188c2ecf20Sopenharmony_ci}
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_ci
4218c2ecf20Sopenharmony_ci/*
4228c2ecf20Sopenharmony_ci * L1 and L2 caches configuration
4238c2ecf20Sopenharmony_ci */
4248c2ecf20Sopenharmony_civoid __init c6x_cache_init(void)
4258c2ecf20Sopenharmony_ci{
4268c2ecf20Sopenharmony_ci	struct device_node *node;
4278c2ecf20Sopenharmony_ci
4288c2ecf20Sopenharmony_ci	node = of_find_compatible_node(NULL, NULL, "ti,c64x+cache");
4298c2ecf20Sopenharmony_ci	if (!node)
4308c2ecf20Sopenharmony_ci		return;
4318c2ecf20Sopenharmony_ci
4328c2ecf20Sopenharmony_ci	cache_base = of_iomap(node, 0);
4338c2ecf20Sopenharmony_ci
4348c2ecf20Sopenharmony_ci	of_node_put(node);
4358c2ecf20Sopenharmony_ci
4368c2ecf20Sopenharmony_ci	if (!cache_base)
4378c2ecf20Sopenharmony_ci		return;
4388c2ecf20Sopenharmony_ci
4398c2ecf20Sopenharmony_ci	/* Set L2 caches on the the whole L2 SRAM memory */
4408c2ecf20Sopenharmony_ci	L2_cache_set_mode(L2MODE_SIZE);
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_ci	/* Enable L1 */
4438c2ecf20Sopenharmony_ci	L1_cache_on();
4448c2ecf20Sopenharmony_ci}
445