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