18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * r2300.c: R2000 and R3000 specific mmu/cache code.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * with a lot of changes to make this thing work for R3000s
88c2ecf20Sopenharmony_ci * Tx39XX R4k style caches added. HK
98c2ecf20Sopenharmony_ci * Copyright (C) 1998, 1999, 2000 Harald Koerfgen
108c2ecf20Sopenharmony_ci * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
118c2ecf20Sopenharmony_ci */
128c2ecf20Sopenharmony_ci#include <linux/init.h>
138c2ecf20Sopenharmony_ci#include <linux/kernel.h>
148c2ecf20Sopenharmony_ci#include <linux/sched.h>
158c2ecf20Sopenharmony_ci#include <linux/smp.h>
168c2ecf20Sopenharmony_ci#include <linux/mm.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#include <asm/cacheops.h>
198c2ecf20Sopenharmony_ci#include <asm/page.h>
208c2ecf20Sopenharmony_ci#include <asm/mmu_context.h>
218c2ecf20Sopenharmony_ci#include <asm/isadep.h>
228c2ecf20Sopenharmony_ci#include <asm/io.h>
238c2ecf20Sopenharmony_ci#include <asm/bootinfo.h>
248c2ecf20Sopenharmony_ci#include <asm/cpu.h>
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci/* For R3000 cores with R4000 style caches */
278c2ecf20Sopenharmony_cistatic unsigned long icache_size, dcache_size;		/* Size in bytes */
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci#include <asm/r4kcache.h>
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci/* This sequence is required to ensure icache is disabled immediately */
328c2ecf20Sopenharmony_ci#define TX39_STOP_STREAMING() \
338c2ecf20Sopenharmony_ci__asm__ __volatile__( \
348c2ecf20Sopenharmony_ci	".set	 push\n\t" \
358c2ecf20Sopenharmony_ci	".set	 noreorder\n\t" \
368c2ecf20Sopenharmony_ci	"b	 1f\n\t" \
378c2ecf20Sopenharmony_ci	"nop\n\t" \
388c2ecf20Sopenharmony_ci	"1:\n\t" \
398c2ecf20Sopenharmony_ci	".set pop" \
408c2ecf20Sopenharmony_ci	)
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci/* TX39H-style cache flush routines. */
438c2ecf20Sopenharmony_cistatic void tx39h_flush_icache_all(void)
448c2ecf20Sopenharmony_ci{
458c2ecf20Sopenharmony_ci	unsigned long flags, config;
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci	/* disable icache (set ICE#) */
488c2ecf20Sopenharmony_ci	local_irq_save(flags);
498c2ecf20Sopenharmony_ci	config = read_c0_conf();
508c2ecf20Sopenharmony_ci	write_c0_conf(config & ~TX39_CONF_ICE);
518c2ecf20Sopenharmony_ci	TX39_STOP_STREAMING();
528c2ecf20Sopenharmony_ci	blast_icache16();
538c2ecf20Sopenharmony_ci	write_c0_conf(config);
548c2ecf20Sopenharmony_ci	local_irq_restore(flags);
558c2ecf20Sopenharmony_ci}
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_cistatic void tx39h_dma_cache_wback_inv(unsigned long addr, unsigned long size)
588c2ecf20Sopenharmony_ci{
598c2ecf20Sopenharmony_ci	/* Catch bad driver code */
608c2ecf20Sopenharmony_ci	BUG_ON(size == 0);
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	iob();
638c2ecf20Sopenharmony_ci	blast_inv_dcache_range(addr, addr + size);
648c2ecf20Sopenharmony_ci}
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci/* TX39H2,TX39H3 */
688c2ecf20Sopenharmony_cistatic inline void tx39_blast_dcache_page(unsigned long addr)
698c2ecf20Sopenharmony_ci{
708c2ecf20Sopenharmony_ci	if (current_cpu_type() != CPU_TX3912)
718c2ecf20Sopenharmony_ci		blast_dcache16_page(addr);
728c2ecf20Sopenharmony_ci}
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_cistatic inline void tx39_blast_dcache_page_indexed(unsigned long addr)
758c2ecf20Sopenharmony_ci{
768c2ecf20Sopenharmony_ci	blast_dcache16_page_indexed(addr);
778c2ecf20Sopenharmony_ci}
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_cistatic inline void tx39_blast_dcache(void)
808c2ecf20Sopenharmony_ci{
818c2ecf20Sopenharmony_ci	blast_dcache16();
828c2ecf20Sopenharmony_ci}
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_cistatic inline void tx39_blast_icache_page(unsigned long addr)
858c2ecf20Sopenharmony_ci{
868c2ecf20Sopenharmony_ci	unsigned long flags, config;
878c2ecf20Sopenharmony_ci	/* disable icache (set ICE#) */
888c2ecf20Sopenharmony_ci	local_irq_save(flags);
898c2ecf20Sopenharmony_ci	config = read_c0_conf();
908c2ecf20Sopenharmony_ci	write_c0_conf(config & ~TX39_CONF_ICE);
918c2ecf20Sopenharmony_ci	TX39_STOP_STREAMING();
928c2ecf20Sopenharmony_ci	blast_icache16_page(addr);
938c2ecf20Sopenharmony_ci	write_c0_conf(config);
948c2ecf20Sopenharmony_ci	local_irq_restore(flags);
958c2ecf20Sopenharmony_ci}
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_cistatic inline void tx39_blast_icache_page_indexed(unsigned long addr)
988c2ecf20Sopenharmony_ci{
998c2ecf20Sopenharmony_ci	unsigned long flags, config;
1008c2ecf20Sopenharmony_ci	/* disable icache (set ICE#) */
1018c2ecf20Sopenharmony_ci	local_irq_save(flags);
1028c2ecf20Sopenharmony_ci	config = read_c0_conf();
1038c2ecf20Sopenharmony_ci	write_c0_conf(config & ~TX39_CONF_ICE);
1048c2ecf20Sopenharmony_ci	TX39_STOP_STREAMING();
1058c2ecf20Sopenharmony_ci	blast_icache16_page_indexed(addr);
1068c2ecf20Sopenharmony_ci	write_c0_conf(config);
1078c2ecf20Sopenharmony_ci	local_irq_restore(flags);
1088c2ecf20Sopenharmony_ci}
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_cistatic inline void tx39_blast_icache(void)
1118c2ecf20Sopenharmony_ci{
1128c2ecf20Sopenharmony_ci	unsigned long flags, config;
1138c2ecf20Sopenharmony_ci	/* disable icache (set ICE#) */
1148c2ecf20Sopenharmony_ci	local_irq_save(flags);
1158c2ecf20Sopenharmony_ci	config = read_c0_conf();
1168c2ecf20Sopenharmony_ci	write_c0_conf(config & ~TX39_CONF_ICE);
1178c2ecf20Sopenharmony_ci	TX39_STOP_STREAMING();
1188c2ecf20Sopenharmony_ci	blast_icache16();
1198c2ecf20Sopenharmony_ci	write_c0_conf(config);
1208c2ecf20Sopenharmony_ci	local_irq_restore(flags);
1218c2ecf20Sopenharmony_ci}
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_cistatic void tx39__flush_cache_vmap(void)
1248c2ecf20Sopenharmony_ci{
1258c2ecf20Sopenharmony_ci	tx39_blast_dcache();
1268c2ecf20Sopenharmony_ci}
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_cistatic void tx39__flush_cache_vunmap(void)
1298c2ecf20Sopenharmony_ci{
1308c2ecf20Sopenharmony_ci	tx39_blast_dcache();
1318c2ecf20Sopenharmony_ci}
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_cistatic inline void tx39_flush_cache_all(void)
1348c2ecf20Sopenharmony_ci{
1358c2ecf20Sopenharmony_ci	if (!cpu_has_dc_aliases)
1368c2ecf20Sopenharmony_ci		return;
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci	tx39_blast_dcache();
1398c2ecf20Sopenharmony_ci}
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_cistatic inline void tx39___flush_cache_all(void)
1428c2ecf20Sopenharmony_ci{
1438c2ecf20Sopenharmony_ci	tx39_blast_dcache();
1448c2ecf20Sopenharmony_ci	tx39_blast_icache();
1458c2ecf20Sopenharmony_ci}
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_cistatic void tx39_flush_cache_mm(struct mm_struct *mm)
1488c2ecf20Sopenharmony_ci{
1498c2ecf20Sopenharmony_ci	if (!cpu_has_dc_aliases)
1508c2ecf20Sopenharmony_ci		return;
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci	if (cpu_context(smp_processor_id(), mm) != 0)
1538c2ecf20Sopenharmony_ci		tx39_blast_dcache();
1548c2ecf20Sopenharmony_ci}
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_cistatic void tx39_flush_cache_range(struct vm_area_struct *vma,
1578c2ecf20Sopenharmony_ci	unsigned long start, unsigned long end)
1588c2ecf20Sopenharmony_ci{
1598c2ecf20Sopenharmony_ci	if (!cpu_has_dc_aliases)
1608c2ecf20Sopenharmony_ci		return;
1618c2ecf20Sopenharmony_ci	if (!(cpu_context(smp_processor_id(), vma->vm_mm)))
1628c2ecf20Sopenharmony_ci		return;
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci	tx39_blast_dcache();
1658c2ecf20Sopenharmony_ci}
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_cistatic void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn)
1688c2ecf20Sopenharmony_ci{
1698c2ecf20Sopenharmony_ci	int exec = vma->vm_flags & VM_EXEC;
1708c2ecf20Sopenharmony_ci	struct mm_struct *mm = vma->vm_mm;
1718c2ecf20Sopenharmony_ci	pmd_t *pmdp;
1728c2ecf20Sopenharmony_ci	pte_t *ptep;
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci	/*
1758c2ecf20Sopenharmony_ci	 * If ownes no valid ASID yet, cannot possibly have gotten
1768c2ecf20Sopenharmony_ci	 * this page into the cache.
1778c2ecf20Sopenharmony_ci	 */
1788c2ecf20Sopenharmony_ci	if (cpu_context(smp_processor_id(), mm) == 0)
1798c2ecf20Sopenharmony_ci		return;
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci	page &= PAGE_MASK;
1828c2ecf20Sopenharmony_ci	pmdp = pmd_off(mm, page);
1838c2ecf20Sopenharmony_ci	ptep = pte_offset_kernel(pmdp, page);
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci	/*
1868c2ecf20Sopenharmony_ci	 * If the page isn't marked valid, the page cannot possibly be
1878c2ecf20Sopenharmony_ci	 * in the cache.
1888c2ecf20Sopenharmony_ci	 */
1898c2ecf20Sopenharmony_ci	if (!(pte_val(*ptep) & _PAGE_PRESENT))
1908c2ecf20Sopenharmony_ci		return;
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci	/*
1938c2ecf20Sopenharmony_ci	 * Doing flushes for another ASID than the current one is
1948c2ecf20Sopenharmony_ci	 * too difficult since stupid R4k caches do a TLB translation
1958c2ecf20Sopenharmony_ci	 * for every cache flush operation.  So we do indexed flushes
1968c2ecf20Sopenharmony_ci	 * in that case, which doesn't overly flush the cache too much.
1978c2ecf20Sopenharmony_ci	 */
1988c2ecf20Sopenharmony_ci	if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
1998c2ecf20Sopenharmony_ci		if (cpu_has_dc_aliases || exec)
2008c2ecf20Sopenharmony_ci			tx39_blast_dcache_page(page);
2018c2ecf20Sopenharmony_ci		if (exec)
2028c2ecf20Sopenharmony_ci			tx39_blast_icache_page(page);
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci		return;
2058c2ecf20Sopenharmony_ci	}
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci	/*
2088c2ecf20Sopenharmony_ci	 * Do indexed flush, too much work to get the (possible) TLB refills
2098c2ecf20Sopenharmony_ci	 * to work correctly.
2108c2ecf20Sopenharmony_ci	 */
2118c2ecf20Sopenharmony_ci	if (cpu_has_dc_aliases || exec)
2128c2ecf20Sopenharmony_ci		tx39_blast_dcache_page_indexed(page);
2138c2ecf20Sopenharmony_ci	if (exec)
2148c2ecf20Sopenharmony_ci		tx39_blast_icache_page_indexed(page);
2158c2ecf20Sopenharmony_ci}
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_cistatic void local_tx39_flush_data_cache_page(void * addr)
2188c2ecf20Sopenharmony_ci{
2198c2ecf20Sopenharmony_ci	tx39_blast_dcache_page((unsigned long)addr);
2208c2ecf20Sopenharmony_ci}
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_cistatic void tx39_flush_data_cache_page(unsigned long addr)
2238c2ecf20Sopenharmony_ci{
2248c2ecf20Sopenharmony_ci	tx39_blast_dcache_page(addr);
2258c2ecf20Sopenharmony_ci}
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_cistatic void tx39_flush_icache_range(unsigned long start, unsigned long end)
2288c2ecf20Sopenharmony_ci{
2298c2ecf20Sopenharmony_ci	if (end - start > dcache_size)
2308c2ecf20Sopenharmony_ci		tx39_blast_dcache();
2318c2ecf20Sopenharmony_ci	else
2328c2ecf20Sopenharmony_ci		protected_blast_dcache_range(start, end);
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci	if (end - start > icache_size)
2358c2ecf20Sopenharmony_ci		tx39_blast_icache();
2368c2ecf20Sopenharmony_ci	else {
2378c2ecf20Sopenharmony_ci		unsigned long flags, config;
2388c2ecf20Sopenharmony_ci		/* disable icache (set ICE#) */
2398c2ecf20Sopenharmony_ci		local_irq_save(flags);
2408c2ecf20Sopenharmony_ci		config = read_c0_conf();
2418c2ecf20Sopenharmony_ci		write_c0_conf(config & ~TX39_CONF_ICE);
2428c2ecf20Sopenharmony_ci		TX39_STOP_STREAMING();
2438c2ecf20Sopenharmony_ci		protected_blast_icache_range(start, end);
2448c2ecf20Sopenharmony_ci		write_c0_conf(config);
2458c2ecf20Sopenharmony_ci		local_irq_restore(flags);
2468c2ecf20Sopenharmony_ci	}
2478c2ecf20Sopenharmony_ci}
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_cistatic void tx39_flush_kernel_vmap_range(unsigned long vaddr, int size)
2508c2ecf20Sopenharmony_ci{
2518c2ecf20Sopenharmony_ci	BUG();
2528c2ecf20Sopenharmony_ci}
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_cistatic void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size)
2558c2ecf20Sopenharmony_ci{
2568c2ecf20Sopenharmony_ci	unsigned long end;
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_ci	if (((size | addr) & (PAGE_SIZE - 1)) == 0) {
2598c2ecf20Sopenharmony_ci		end = addr + size;
2608c2ecf20Sopenharmony_ci		do {
2618c2ecf20Sopenharmony_ci			tx39_blast_dcache_page(addr);
2628c2ecf20Sopenharmony_ci			addr += PAGE_SIZE;
2638c2ecf20Sopenharmony_ci		} while(addr != end);
2648c2ecf20Sopenharmony_ci	} else if (size > dcache_size) {
2658c2ecf20Sopenharmony_ci		tx39_blast_dcache();
2668c2ecf20Sopenharmony_ci	} else {
2678c2ecf20Sopenharmony_ci		blast_dcache_range(addr, addr + size);
2688c2ecf20Sopenharmony_ci	}
2698c2ecf20Sopenharmony_ci}
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_cistatic void tx39_dma_cache_inv(unsigned long addr, unsigned long size)
2728c2ecf20Sopenharmony_ci{
2738c2ecf20Sopenharmony_ci	unsigned long end;
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_ci	if (((size | addr) & (PAGE_SIZE - 1)) == 0) {
2768c2ecf20Sopenharmony_ci		end = addr + size;
2778c2ecf20Sopenharmony_ci		do {
2788c2ecf20Sopenharmony_ci			tx39_blast_dcache_page(addr);
2798c2ecf20Sopenharmony_ci			addr += PAGE_SIZE;
2808c2ecf20Sopenharmony_ci		} while(addr != end);
2818c2ecf20Sopenharmony_ci	} else if (size > dcache_size) {
2828c2ecf20Sopenharmony_ci		tx39_blast_dcache();
2838c2ecf20Sopenharmony_ci	} else {
2848c2ecf20Sopenharmony_ci		blast_inv_dcache_range(addr, addr + size);
2858c2ecf20Sopenharmony_ci	}
2868c2ecf20Sopenharmony_ci}
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_cistatic __init void tx39_probe_cache(void)
2898c2ecf20Sopenharmony_ci{
2908c2ecf20Sopenharmony_ci	unsigned long config;
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_ci	config = read_c0_conf();
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_ci	icache_size = 1 << (10 + ((config & TX39_CONF_ICS_MASK) >>
2958c2ecf20Sopenharmony_ci				  TX39_CONF_ICS_SHIFT));
2968c2ecf20Sopenharmony_ci	dcache_size = 1 << (10 + ((config & TX39_CONF_DCS_MASK) >>
2978c2ecf20Sopenharmony_ci				  TX39_CONF_DCS_SHIFT));
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_ci	current_cpu_data.icache.linesz = 16;
3008c2ecf20Sopenharmony_ci	switch (current_cpu_type()) {
3018c2ecf20Sopenharmony_ci	case CPU_TX3912:
3028c2ecf20Sopenharmony_ci		current_cpu_data.icache.ways = 1;
3038c2ecf20Sopenharmony_ci		current_cpu_data.dcache.ways = 1;
3048c2ecf20Sopenharmony_ci		current_cpu_data.dcache.linesz = 4;
3058c2ecf20Sopenharmony_ci		break;
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_ci	case CPU_TX3927:
3088c2ecf20Sopenharmony_ci		current_cpu_data.icache.ways = 2;
3098c2ecf20Sopenharmony_ci		current_cpu_data.dcache.ways = 2;
3108c2ecf20Sopenharmony_ci		current_cpu_data.dcache.linesz = 16;
3118c2ecf20Sopenharmony_ci		break;
3128c2ecf20Sopenharmony_ci
3138c2ecf20Sopenharmony_ci	case CPU_TX3922:
3148c2ecf20Sopenharmony_ci	default:
3158c2ecf20Sopenharmony_ci		current_cpu_data.icache.ways = 1;
3168c2ecf20Sopenharmony_ci		current_cpu_data.dcache.ways = 1;
3178c2ecf20Sopenharmony_ci		current_cpu_data.dcache.linesz = 16;
3188c2ecf20Sopenharmony_ci		break;
3198c2ecf20Sopenharmony_ci	}
3208c2ecf20Sopenharmony_ci}
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_civoid tx39_cache_init(void)
3238c2ecf20Sopenharmony_ci{
3248c2ecf20Sopenharmony_ci	extern void build_clear_page(void);
3258c2ecf20Sopenharmony_ci	extern void build_copy_page(void);
3268c2ecf20Sopenharmony_ci	unsigned long config;
3278c2ecf20Sopenharmony_ci
3288c2ecf20Sopenharmony_ci	config = read_c0_conf();
3298c2ecf20Sopenharmony_ci	config &= ~TX39_CONF_WBON;
3308c2ecf20Sopenharmony_ci	write_c0_conf(config);
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_ci	tx39_probe_cache();
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ci	switch (current_cpu_type()) {
3358c2ecf20Sopenharmony_ci	case CPU_TX3912:
3368c2ecf20Sopenharmony_ci		/* TX39/H core (writethru direct-map cache) */
3378c2ecf20Sopenharmony_ci		__flush_cache_vmap	= tx39__flush_cache_vmap;
3388c2ecf20Sopenharmony_ci		__flush_cache_vunmap	= tx39__flush_cache_vunmap;
3398c2ecf20Sopenharmony_ci		flush_cache_all = tx39h_flush_icache_all;
3408c2ecf20Sopenharmony_ci		__flush_cache_all	= tx39h_flush_icache_all;
3418c2ecf20Sopenharmony_ci		flush_cache_mm		= (void *) tx39h_flush_icache_all;
3428c2ecf20Sopenharmony_ci		flush_cache_range	= (void *) tx39h_flush_icache_all;
3438c2ecf20Sopenharmony_ci		flush_cache_page	= (void *) tx39h_flush_icache_all;
3448c2ecf20Sopenharmony_ci		flush_icache_range	= (void *) tx39h_flush_icache_all;
3458c2ecf20Sopenharmony_ci		local_flush_icache_range = (void *) tx39h_flush_icache_all;
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ci		local_flush_data_cache_page	= (void *) tx39h_flush_icache_all;
3488c2ecf20Sopenharmony_ci		flush_data_cache_page	= (void *) tx39h_flush_icache_all;
3498c2ecf20Sopenharmony_ci
3508c2ecf20Sopenharmony_ci		_dma_cache_wback_inv	= tx39h_dma_cache_wback_inv;
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_ci		shm_align_mask		= PAGE_SIZE - 1;
3538c2ecf20Sopenharmony_ci
3548c2ecf20Sopenharmony_ci		break;
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_ci	case CPU_TX3922:
3578c2ecf20Sopenharmony_ci	case CPU_TX3927:
3588c2ecf20Sopenharmony_ci	default:
3598c2ecf20Sopenharmony_ci		/* TX39/H2,H3 core (writeback 2way-set-associative cache) */
3608c2ecf20Sopenharmony_ci		/* board-dependent init code may set WBON */
3618c2ecf20Sopenharmony_ci
3628c2ecf20Sopenharmony_ci		__flush_cache_vmap	= tx39__flush_cache_vmap;
3638c2ecf20Sopenharmony_ci		__flush_cache_vunmap	= tx39__flush_cache_vunmap;
3648c2ecf20Sopenharmony_ci
3658c2ecf20Sopenharmony_ci		flush_cache_all = tx39_flush_cache_all;
3668c2ecf20Sopenharmony_ci		__flush_cache_all = tx39___flush_cache_all;
3678c2ecf20Sopenharmony_ci		flush_cache_mm = tx39_flush_cache_mm;
3688c2ecf20Sopenharmony_ci		flush_cache_range = tx39_flush_cache_range;
3698c2ecf20Sopenharmony_ci		flush_cache_page = tx39_flush_cache_page;
3708c2ecf20Sopenharmony_ci		flush_icache_range = tx39_flush_icache_range;
3718c2ecf20Sopenharmony_ci		local_flush_icache_range = tx39_flush_icache_range;
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_ci		__flush_kernel_vmap_range = tx39_flush_kernel_vmap_range;
3748c2ecf20Sopenharmony_ci
3758c2ecf20Sopenharmony_ci		local_flush_data_cache_page = local_tx39_flush_data_cache_page;
3768c2ecf20Sopenharmony_ci		flush_data_cache_page = tx39_flush_data_cache_page;
3778c2ecf20Sopenharmony_ci
3788c2ecf20Sopenharmony_ci		_dma_cache_wback_inv = tx39_dma_cache_wback_inv;
3798c2ecf20Sopenharmony_ci		_dma_cache_wback = tx39_dma_cache_wback_inv;
3808c2ecf20Sopenharmony_ci		_dma_cache_inv = tx39_dma_cache_inv;
3818c2ecf20Sopenharmony_ci
3828c2ecf20Sopenharmony_ci		shm_align_mask = max_t(unsigned long,
3838c2ecf20Sopenharmony_ci				       (dcache_size / current_cpu_data.dcache.ways) - 1,
3848c2ecf20Sopenharmony_ci				       PAGE_SIZE - 1);
3858c2ecf20Sopenharmony_ci
3868c2ecf20Sopenharmony_ci		break;
3878c2ecf20Sopenharmony_ci	}
3888c2ecf20Sopenharmony_ci
3898c2ecf20Sopenharmony_ci	__flush_icache_user_range = flush_icache_range;
3908c2ecf20Sopenharmony_ci	__local_flush_icache_user_range = local_flush_icache_range;
3918c2ecf20Sopenharmony_ci
3928c2ecf20Sopenharmony_ci	current_cpu_data.icache.waysize = icache_size / current_cpu_data.icache.ways;
3938c2ecf20Sopenharmony_ci	current_cpu_data.dcache.waysize = dcache_size / current_cpu_data.dcache.ways;
3948c2ecf20Sopenharmony_ci
3958c2ecf20Sopenharmony_ci	current_cpu_data.icache.sets =
3968c2ecf20Sopenharmony_ci		current_cpu_data.icache.waysize / current_cpu_data.icache.linesz;
3978c2ecf20Sopenharmony_ci	current_cpu_data.dcache.sets =
3988c2ecf20Sopenharmony_ci		current_cpu_data.dcache.waysize / current_cpu_data.dcache.linesz;
3998c2ecf20Sopenharmony_ci
4008c2ecf20Sopenharmony_ci	if (current_cpu_data.dcache.waysize > PAGE_SIZE)
4018c2ecf20Sopenharmony_ci		current_cpu_data.dcache.flags |= MIPS_CACHE_ALIASES;
4028c2ecf20Sopenharmony_ci
4038c2ecf20Sopenharmony_ci	current_cpu_data.icache.waybit = 0;
4048c2ecf20Sopenharmony_ci	current_cpu_data.dcache.waybit = 0;
4058c2ecf20Sopenharmony_ci
4068c2ecf20Sopenharmony_ci	pr_info("Primary instruction cache %ldkB, linesize %d bytes\n",
4078c2ecf20Sopenharmony_ci		icache_size >> 10, current_cpu_data.icache.linesz);
4088c2ecf20Sopenharmony_ci	pr_info("Primary data cache %ldkB, linesize %d bytes\n",
4098c2ecf20Sopenharmony_ci		dcache_size >> 10, current_cpu_data.dcache.linesz);
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci	build_clear_page();
4128c2ecf20Sopenharmony_ci	build_copy_page();
4138c2ecf20Sopenharmony_ci	tx39h_flush_icache_all();
4148c2ecf20Sopenharmony_ci}
415