xref: /linux/arch/arm/mm/proc-arm925.S (revision 4853f1f6ace32c68a04287353e428c4cfc3fa8ed)
11a59d1b8SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-or-later */
21da177e4SLinus Torvalds/*
31da177e4SLinus Torvalds *  linux/arch/arm/mm/arm925.S: MMU functions for ARM925
41da177e4SLinus Torvalds *
51da177e4SLinus Torvalds *  Copyright (C) 1999,2000 ARM Limited
61da177e4SLinus Torvalds *  Copyright (C) 2000 Deep Blue Solutions Ltd.
71da177e4SLinus Torvalds *  Copyright (C) 2002 RidgeRun, Inc.
81da177e4SLinus Torvalds *  Copyright (C) 2002-2003 MontaVista Software, Inc.
91da177e4SLinus Torvalds *
101da177e4SLinus Torvalds *  Update for Linux-2.6 and cache flush improvements
111da177e4SLinus Torvalds *  Copyright (C) 2004 Nokia Corporation by Tony Lindgren <tony@atomide.com>
121da177e4SLinus Torvalds *
13d090dddaSHyok S. Choi *  hacked for non-paged-MM by Hyok S. Choi, 2004.
14d090dddaSHyok S. Choi *
151da177e4SLinus Torvalds * These are the low level assembler for performing cache and TLB
161da177e4SLinus Torvalds * functions on the arm925.
171da177e4SLinus Torvalds *
181da177e4SLinus Torvalds *  CONFIG_CPU_ARM925_CPU_IDLE -> nohlt
191da177e4SLinus Torvalds *
201da177e4SLinus Torvalds * Some additional notes based on deciphering the TI TRM on OMAP-5910:
211da177e4SLinus Torvalds *
221da177e4SLinus Torvalds * NOTE1: The TI925T Configuration Register bit "D-cache clean and flush
231da177e4SLinus Torvalds *	  entry mode" must be 0 to flush the entries in both segments
241da177e4SLinus Torvalds *	  at once. This is the default value. See TRM 2-20 and 2-24 for
251da177e4SLinus Torvalds *	  more information.
261da177e4SLinus Torvalds *
271da177e4SLinus Torvalds * NOTE2: Default is the "D-cache clean and flush entry mode". It looks
281da177e4SLinus Torvalds *	  like the "Transparent mode" must be on for partial cache flushes
291da177e4SLinus Torvalds *	  to work in this mode. This mode only works with 16-bit external
301da177e4SLinus Torvalds *	  memory. See TRM 2-24 for more information.
311da177e4SLinus Torvalds *
321da177e4SLinus Torvalds * NOTE3: Write-back cache flushing seems to be flakey with devices using
331da177e4SLinus Torvalds *        direct memory access, such as USB OHCI. The workaround is to use
341da177e4SLinus Torvalds *        write-through cache with CONFIG_CPU_DCACHE_WRITETHROUGH (this is
351da177e4SLinus Torvalds *        the default for OMAP-1510).
361da177e4SLinus Torvalds */
371da177e4SLinus Torvalds
381da177e4SLinus Torvalds#include <linux/linkage.h>
391da177e4SLinus Torvalds#include <linux/init.h>
401036b895SLinus Walleij#include <linux/cfi_types.h>
4165fddcfcSMike Rapoport#include <linux/pgtable.h>
421da177e4SLinus Torvalds#include <asm/assembler.h>
435ec9407dSRussell King#include <asm/hwcap.h>
4474945c86SRussell King#include <asm/pgtable-hwdef.h>
451da177e4SLinus Torvalds#include <asm/page.h>
461da177e4SLinus Torvalds#include <asm/ptrace.h>
471da177e4SLinus Torvalds#include "proc-macros.S"
481da177e4SLinus Torvalds
491da177e4SLinus Torvalds/*
501da177e4SLinus Torvalds * The size of one data cache line.
511da177e4SLinus Torvalds */
521da177e4SLinus Torvalds#define CACHE_DLINESIZE	16
531da177e4SLinus Torvalds
541da177e4SLinus Torvalds/*
551da177e4SLinus Torvalds * The number of data cache segments.
561da177e4SLinus Torvalds */
571da177e4SLinus Torvalds#define CACHE_DSEGMENTS	2
581da177e4SLinus Torvalds
591da177e4SLinus Torvalds/*
601da177e4SLinus Torvalds * The number of lines in a cache segment.
611da177e4SLinus Torvalds */
621da177e4SLinus Torvalds#define CACHE_DENTRIES	256
631da177e4SLinus Torvalds
641da177e4SLinus Torvalds/*
651da177e4SLinus Torvalds * This is the size at which it becomes more efficient to
661da177e4SLinus Torvalds * clean the whole cache, rather than using the individual
6725985edcSLucas De Marchi * cache line maintenance instructions.
681da177e4SLinus Torvalds */
691da177e4SLinus Torvalds#define CACHE_DLIMIT	8192
701da177e4SLinus Torvalds
711da177e4SLinus Torvalds	.text
721da177e4SLinus Torvalds/*
731da177e4SLinus Torvalds * cpu_arm925_proc_init()
741da177e4SLinus Torvalds */
7551db13aaSLinus WalleijSYM_TYPED_FUNC_START(cpu_arm925_proc_init)
766ebbf2ceSRussell King	ret	lr
7751db13aaSLinus WalleijSYM_FUNC_END(cpu_arm925_proc_init)
781da177e4SLinus Torvalds
791da177e4SLinus Torvalds/*
801da177e4SLinus Torvalds * cpu_arm925_proc_fin()
811da177e4SLinus Torvalds */
8251db13aaSLinus WalleijSYM_TYPED_FUNC_START(cpu_arm925_proc_fin)
831da177e4SLinus Torvalds	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
841da177e4SLinus Torvalds	bic	r0, r0, #0x1000			@ ...i............
851da177e4SLinus Torvalds	bic	r0, r0, #0x000e			@ ............wca.
861da177e4SLinus Torvalds	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
876ebbf2ceSRussell King	ret	lr
8851db13aaSLinus WalleijSYM_FUNC_END(cpu_arm925_proc_fin)
891da177e4SLinus Torvalds
901da177e4SLinus Torvalds/*
911da177e4SLinus Torvalds * cpu_arm925_reset(loc)
921da177e4SLinus Torvalds *
931da177e4SLinus Torvalds * Perform a soft reset of the system.  Put the CPU into the
941da177e4SLinus Torvalds * same state as it would be if it had been reset, and branch
951da177e4SLinus Torvalds * to what would be the reset vector.
961da177e4SLinus Torvalds *
971da177e4SLinus Torvalds * loc: location to jump to for soft reset
981da177e4SLinus Torvalds */
991da177e4SLinus Torvalds	.align	5
1001a4baafaSWill Deacon	.pushsection	.idmap.text, "ax"
10151db13aaSLinus WalleijSYM_TYPED_FUNC_START(cpu_arm925_reset)
1021da177e4SLinus Torvalds	/* Send software reset to MPU and DSP */
1031da177e4SLinus Torvalds	mov	ip, #0xff000000
1041da177e4SLinus Torvalds	orr	ip, ip, #0x00fe0000
1051da177e4SLinus Torvalds	orr	ip, ip, #0x0000ce00
1061da177e4SLinus Torvalds	mov	r4, #1
1071da177e4SLinus Torvalds	strh	r4, [ip, #0x10]
10851db13aaSLinus WalleijSYM_FUNC_END(cpu_arm925_reset)
1091a4baafaSWill Deacon	.popsection
1101da177e4SLinus Torvalds
1111da177e4SLinus Torvalds	mov	ip, #0
1121da177e4SLinus Torvalds	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
1131da177e4SLinus Torvalds	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
114d090dddaSHyok S. Choi#ifdef CONFIG_MMU
1151da177e4SLinus Torvalds	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
116d090dddaSHyok S. Choi#endif
1171da177e4SLinus Torvalds	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
1181da177e4SLinus Torvalds	bic	ip, ip, #0x000f			@ ............wcam
1191da177e4SLinus Torvalds	bic	ip, ip, #0x1100			@ ...i...s........
1201da177e4SLinus Torvalds	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
1216ebbf2ceSRussell King	ret	r0
1221da177e4SLinus Torvalds
1231da177e4SLinus Torvalds/*
1241da177e4SLinus Torvalds * cpu_arm925_do_idle()
1251da177e4SLinus Torvalds *
1261da177e4SLinus Torvalds * Called with IRQs disabled
1271da177e4SLinus Torvalds */
1281da177e4SLinus Torvalds	.align	10
12951db13aaSLinus WalleijSYM_TYPED_FUNC_START(cpu_arm925_do_idle)
1301da177e4SLinus Torvalds	mov	r0, #0
1311da177e4SLinus Torvalds	mrc	p15, 0, r1, c1, c0, 0		@ Read control register
1321da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 4		@ Drain write buffer
1331da177e4SLinus Torvalds	bic	r2, r1, #1 << 12
1341da177e4SLinus Torvalds	mcr	p15, 0, r2, c1, c0, 0		@ Disable I cache
1351da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
1361da177e4SLinus Torvalds	mcr	p15, 0, r1, c1, c0, 0		@ Restore ICache enable
1376ebbf2ceSRussell King	ret	lr
13851db13aaSLinus WalleijSYM_FUNC_END(cpu_arm925_do_idle)
1391da177e4SLinus Torvalds
1401da177e4SLinus Torvalds/*
141c8c90860SMika Westerberg *	flush_icache_all()
142c8c90860SMika Westerberg *
143c8c90860SMika Westerberg *	Unconditionally clean and invalidate the entire icache.
144c8c90860SMika Westerberg */
1451036b895SLinus WalleijSYM_TYPED_FUNC_START(arm925_flush_icache_all)
146c8c90860SMika Westerberg	mov	r0, #0
147c8c90860SMika Westerberg	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
1486ebbf2ceSRussell King	ret	lr
1491036b895SLinus WalleijSYM_FUNC_END(arm925_flush_icache_all)
150c8c90860SMika Westerberg
151c8c90860SMika Westerberg/*
1521da177e4SLinus Torvalds *	flush_user_cache_all()
1531da177e4SLinus Torvalds *
1541da177e4SLinus Torvalds *	Clean and invalidate all cache entries in a particular
1551da177e4SLinus Torvalds *	address space.
1561da177e4SLinus Torvalds */
1572074beebSLinus WalleijSYM_FUNC_ALIAS(arm925_flush_user_cache_all, arm925_flush_kern_cache_all)
1581da177e4SLinus Torvalds
1591da177e4SLinus Torvalds/*
1601da177e4SLinus Torvalds *	flush_kern_cache_all()
1611da177e4SLinus Torvalds *
1621da177e4SLinus Torvalds *	Clean and invalidate the entire cache.
1631da177e4SLinus Torvalds */
1641036b895SLinus WalleijSYM_TYPED_FUNC_START(arm925_flush_kern_cache_all)
1651da177e4SLinus Torvalds	mov	r2, #VM_EXEC
1661da177e4SLinus Torvalds	mov	ip, #0
1671da177e4SLinus Torvalds__flush_whole_cache:
1681da177e4SLinus Torvalds#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
1691da177e4SLinus Torvalds	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
1701da177e4SLinus Torvalds#else
1711da177e4SLinus Torvalds	/* Flush entries in both segments at once, see NOTE1 above */
1721da177e4SLinus Torvalds	mov	r3, #(CACHE_DENTRIES - 1) << 4	@ 256 entries in segment
1731da177e4SLinus Torvalds2:	mcr	p15, 0, r3, c7, c14, 2		@ clean+invalidate D index
1741da177e4SLinus Torvalds	subs	r3, r3, #1 << 4
1751da177e4SLinus Torvalds	bcs	2b				@ entries 255 to 0
1761da177e4SLinus Torvalds#endif
1771da177e4SLinus Torvalds	tst	r2, #VM_EXEC
1781da177e4SLinus Torvalds	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
1791da177e4SLinus Torvalds	mcrne	p15, 0, ip, c7, c10, 4		@ drain WB
1806ebbf2ceSRussell King	ret	lr
1811036b895SLinus WalleijSYM_FUNC_END(arm925_flush_kern_cache_all)
1821da177e4SLinus Torvalds
1831da177e4SLinus Torvalds/*
1841da177e4SLinus Torvalds *	flush_user_cache_range(start, end, flags)
1851da177e4SLinus Torvalds *
1861da177e4SLinus Torvalds *	Clean and invalidate a range of cache entries in the
1871da177e4SLinus Torvalds *	specified address range.
1881da177e4SLinus Torvalds *
1891da177e4SLinus Torvalds *	- start	- start address (inclusive)
1901da177e4SLinus Torvalds *	- end	- end address (exclusive)
1911da177e4SLinus Torvalds *	- flags	- vm_flags describing address space
1921da177e4SLinus Torvalds */
1931036b895SLinus WalleijSYM_TYPED_FUNC_START(arm925_flush_user_cache_range)
1941da177e4SLinus Torvalds	mov	ip, #0
1951da177e4SLinus Torvalds	sub	r3, r1, r0			@ calculate total size
1961da177e4SLinus Torvalds	cmp	r3, #CACHE_DLIMIT
1971da177e4SLinus Torvalds	bgt	__flush_whole_cache
1981da177e4SLinus Torvalds1:	tst	r2, #VM_EXEC
1991da177e4SLinus Torvalds#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
2001da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
2011da177e4SLinus Torvalds	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
2021da177e4SLinus Torvalds	add	r0, r0, #CACHE_DLINESIZE
2031da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
2041da177e4SLinus Torvalds	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
2051da177e4SLinus Torvalds	add	r0, r0, #CACHE_DLINESIZE
2061da177e4SLinus Torvalds#else
2071da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
2081da177e4SLinus Torvalds	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
2091da177e4SLinus Torvalds	add	r0, r0, #CACHE_DLINESIZE
2101da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
2111da177e4SLinus Torvalds	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
2121da177e4SLinus Torvalds	add	r0, r0, #CACHE_DLINESIZE
2131da177e4SLinus Torvalds#endif
2141da177e4SLinus Torvalds	cmp	r0, r1
2151da177e4SLinus Torvalds	blo	1b
2161da177e4SLinus Torvalds	tst	r2, #VM_EXEC
2171da177e4SLinus Torvalds	mcrne	p15, 0, ip, c7, c10, 4		@ drain WB
2186ebbf2ceSRussell King	ret	lr
2191036b895SLinus WalleijSYM_FUNC_END(arm925_flush_user_cache_range)
2201da177e4SLinus Torvalds
2211da177e4SLinus Torvalds/*
2221da177e4SLinus Torvalds *	coherent_kern_range(start, end)
2231da177e4SLinus Torvalds *
2241da177e4SLinus Torvalds *	Ensure coherency between the Icache and the Dcache in the
2251da177e4SLinus Torvalds *	region described by start, end.  If you have non-snooping
2261da177e4SLinus Torvalds *	Harvard caches, you need to implement this function.
2271da177e4SLinus Torvalds *
2281da177e4SLinus Torvalds *	- start	- virtual start address
2291da177e4SLinus Torvalds *	- end	- virtual end address
2301da177e4SLinus Torvalds */
2311036b895SLinus WalleijSYM_TYPED_FUNC_START(arm925_coherent_kern_range)
232*7b749aadSLinus Walleij#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */
2331036b895SLinus Walleij	b	arm925_coherent_user_range
234*7b749aadSLinus Walleij#endif
2351036b895SLinus WalleijSYM_FUNC_END(arm925_coherent_kern_range)
2361da177e4SLinus Torvalds
2371da177e4SLinus Torvalds/*
2381da177e4SLinus Torvalds *	coherent_user_range(start, end)
2391da177e4SLinus Torvalds *
2401da177e4SLinus Torvalds *	Ensure coherency between the Icache and the Dcache in the
2411da177e4SLinus Torvalds *	region described by start, end.  If you have non-snooping
2421da177e4SLinus Torvalds *	Harvard caches, you need to implement this function.
2431da177e4SLinus Torvalds *
2441da177e4SLinus Torvalds *	- start	- virtual start address
2451da177e4SLinus Torvalds *	- end	- virtual end address
2461da177e4SLinus Torvalds */
2471036b895SLinus WalleijSYM_TYPED_FUNC_START(arm925_coherent_user_range)
2481da177e4SLinus Torvalds	bic	r0, r0, #CACHE_DLINESIZE - 1
2491da177e4SLinus Torvalds1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
2501da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c5, 1		@ invalidate I entry
2511da177e4SLinus Torvalds	add	r0, r0, #CACHE_DLINESIZE
2521da177e4SLinus Torvalds	cmp	r0, r1
2531da177e4SLinus Torvalds	blo	1b
2541da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
255c5102f59SWill Deacon	mov	r0, #0
2566ebbf2ceSRussell King	ret	lr
2571036b895SLinus WalleijSYM_FUNC_END(arm925_coherent_user_range)
2581da177e4SLinus Torvalds
2591da177e4SLinus Torvalds/*
2602c9b9c84SRussell King *	flush_kern_dcache_area(void *addr, size_t size)
2611da177e4SLinus Torvalds *
2621da177e4SLinus Torvalds *	Ensure no D cache aliasing occurs, either with itself or
2631da177e4SLinus Torvalds *	the I cache
2641da177e4SLinus Torvalds *
2652c9b9c84SRussell King *	- addr	- kernel address
2662c9b9c84SRussell King *	- size	- region size
2671da177e4SLinus Torvalds */
2681036b895SLinus WalleijSYM_TYPED_FUNC_START(arm925_flush_kern_dcache_area)
2692c9b9c84SRussell King	add	r1, r0, r1
2701da177e4SLinus Torvalds1:	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
2711da177e4SLinus Torvalds	add	r0, r0, #CACHE_DLINESIZE
2721da177e4SLinus Torvalds	cmp	r0, r1
2731da177e4SLinus Torvalds	blo	1b
2741da177e4SLinus Torvalds	mov	r0, #0
2751da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
2761da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
2776ebbf2ceSRussell King	ret	lr
2781036b895SLinus WalleijSYM_FUNC_END(arm925_flush_kern_dcache_area)
2791da177e4SLinus Torvalds
2801da177e4SLinus Torvalds/*
2811da177e4SLinus Torvalds *	dma_inv_range(start, end)
2821da177e4SLinus Torvalds *
2831da177e4SLinus Torvalds *	Invalidate (discard) the specified virtual address range.
2841da177e4SLinus Torvalds *	May not write back any entries.  If 'start' or 'end'
2851da177e4SLinus Torvalds *	are not cache line aligned, those lines must be written
2861da177e4SLinus Torvalds *	back.
2871da177e4SLinus Torvalds *
2881da177e4SLinus Torvalds *	- start	- virtual start address
2891da177e4SLinus Torvalds *	- end	- virtual end address
2901da177e4SLinus Torvalds *
2911da177e4SLinus Torvalds * (same as v4wb)
2921da177e4SLinus Torvalds */
293702b94bfSRussell Kingarm925_dma_inv_range:
2941da177e4SLinus Torvalds#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
2951da177e4SLinus Torvalds	tst	r0, #CACHE_DLINESIZE - 1
2961da177e4SLinus Torvalds	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
2971da177e4SLinus Torvalds	tst	r1, #CACHE_DLINESIZE - 1
2981da177e4SLinus Torvalds	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry
2991da177e4SLinus Torvalds#endif
3001da177e4SLinus Torvalds	bic	r0, r0, #CACHE_DLINESIZE - 1
3011da177e4SLinus Torvalds1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
3021da177e4SLinus Torvalds	add	r0, r0, #CACHE_DLINESIZE
3031da177e4SLinus Torvalds	cmp	r0, r1
3041da177e4SLinus Torvalds	blo	1b
3051da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
3066ebbf2ceSRussell King	ret	lr
3071da177e4SLinus Torvalds
3081da177e4SLinus Torvalds/*
3091da177e4SLinus Torvalds *	dma_clean_range(start, end)
3101da177e4SLinus Torvalds *
3111da177e4SLinus Torvalds *	Clean the specified virtual address range.
3121da177e4SLinus Torvalds *
3131da177e4SLinus Torvalds *	- start	- virtual start address
3141da177e4SLinus Torvalds *	- end	- virtual end address
3151da177e4SLinus Torvalds *
3161da177e4SLinus Torvalds * (same as v4wb)
3171da177e4SLinus Torvalds */
318702b94bfSRussell Kingarm925_dma_clean_range:
3191da177e4SLinus Torvalds#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
3201da177e4SLinus Torvalds	bic	r0, r0, #CACHE_DLINESIZE - 1
3211da177e4SLinus Torvalds1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
3221da177e4SLinus Torvalds	add	r0, r0, #CACHE_DLINESIZE
3231da177e4SLinus Torvalds	cmp	r0, r1
3241da177e4SLinus Torvalds	blo	1b
3251da177e4SLinus Torvalds#endif
3261da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
3276ebbf2ceSRussell King	ret	lr
3281da177e4SLinus Torvalds
3291da177e4SLinus Torvalds/*
3301da177e4SLinus Torvalds *	dma_flush_range(start, end)
3311da177e4SLinus Torvalds *
3321da177e4SLinus Torvalds *	Clean and invalidate the specified virtual address range.
3331da177e4SLinus Torvalds *
3341da177e4SLinus Torvalds *	- start	- virtual start address
3351da177e4SLinus Torvalds *	- end	- virtual end address
3361da177e4SLinus Torvalds */
3371036b895SLinus WalleijSYM_TYPED_FUNC_START(arm925_dma_flush_range)
3381da177e4SLinus Torvalds	bic	r0, r0, #CACHE_DLINESIZE - 1
3391da177e4SLinus Torvalds1:
3401da177e4SLinus Torvalds#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
3411da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
3421da177e4SLinus Torvalds#else
343b3a8b751SLennert Buytenhek	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
3441da177e4SLinus Torvalds#endif
3451da177e4SLinus Torvalds	add	r0, r0, #CACHE_DLINESIZE
3461da177e4SLinus Torvalds	cmp	r0, r1
3471da177e4SLinus Torvalds	blo	1b
3481da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
3496ebbf2ceSRussell King	ret	lr
3501036b895SLinus WalleijSYM_FUNC_END(arm925_dma_flush_range)
3511da177e4SLinus Torvalds
352a9c9147eSRussell King/*
353a9c9147eSRussell King *	dma_map_area(start, size, dir)
354a9c9147eSRussell King *	- start	- kernel virtual start address
355a9c9147eSRussell King *	- size	- size of region
356a9c9147eSRussell King *	- dir	- DMA direction
357a9c9147eSRussell King */
3581036b895SLinus WalleijSYM_TYPED_FUNC_START(arm925_dma_map_area)
359a9c9147eSRussell King	add	r1, r1, r0
360a9c9147eSRussell King	cmp	r2, #DMA_TO_DEVICE
361a9c9147eSRussell King	beq	arm925_dma_clean_range
362a9c9147eSRussell King	bcs	arm925_dma_inv_range
363a9c9147eSRussell King	b	arm925_dma_flush_range
3641036b895SLinus WalleijSYM_FUNC_END(arm925_dma_map_area)
365a9c9147eSRussell King
366a9c9147eSRussell King/*
367a9c9147eSRussell King *	dma_unmap_area(start, size, dir)
368a9c9147eSRussell King *	- start	- kernel virtual start address
369a9c9147eSRussell King *	- size	- size of region
370a9c9147eSRussell King *	- dir	- DMA direction
371a9c9147eSRussell King */
3721036b895SLinus WalleijSYM_TYPED_FUNC_START(arm925_dma_unmap_area)
3736ebbf2ceSRussell King	ret	lr
3741036b895SLinus WalleijSYM_FUNC_END(arm925_dma_unmap_area)
375a9c9147eSRussell King
37651db13aaSLinus WalleijSYM_TYPED_FUNC_START(cpu_arm925_dcache_clean_area)
3771da177e4SLinus Torvalds#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
3781da177e4SLinus Torvalds1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
3791da177e4SLinus Torvalds	add	r0, r0, #CACHE_DLINESIZE
3801da177e4SLinus Torvalds	subs	r1, r1, #CACHE_DLINESIZE
3811da177e4SLinus Torvalds	bhi	1b
3821da177e4SLinus Torvalds#endif
3831da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
3846ebbf2ceSRussell King	ret	lr
38551db13aaSLinus WalleijSYM_FUNC_END(cpu_arm925_dcache_clean_area)
3861da177e4SLinus Torvalds
3871da177e4SLinus Torvalds/* =============================== PageTable ============================== */
3881da177e4SLinus Torvalds
3891da177e4SLinus Torvalds/*
3901da177e4SLinus Torvalds * cpu_arm925_switch_mm(pgd)
3911da177e4SLinus Torvalds *
3921da177e4SLinus Torvalds * Set the translation base pointer to be as described by pgd.
3931da177e4SLinus Torvalds *
3941da177e4SLinus Torvalds * pgd: new page tables
3951da177e4SLinus Torvalds */
3961da177e4SLinus Torvalds	.align	5
39751db13aaSLinus WalleijSYM_TYPED_FUNC_START(cpu_arm925_switch_mm)
398d090dddaSHyok S. Choi#ifdef CONFIG_MMU
3991da177e4SLinus Torvalds	mov	ip, #0
4001da177e4SLinus Torvalds#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
4011da177e4SLinus Torvalds	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
4021da177e4SLinus Torvalds#else
4031da177e4SLinus Torvalds	/* Flush entries in bothe segments at once, see NOTE1 above */
4041da177e4SLinus Torvalds	mov	r3, #(CACHE_DENTRIES - 1) << 4	@ 256 entries in segment
4051da177e4SLinus Torvalds2:	mcr	p15, 0, r3, c7, c14, 2		@ clean & invalidate D index
4061da177e4SLinus Torvalds	subs	r3, r3, #1 << 4
4071da177e4SLinus Torvalds	bcs	2b				@ entries 255 to 0
4081da177e4SLinus Torvalds#endif
4091da177e4SLinus Torvalds	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
4101da177e4SLinus Torvalds	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
4111da177e4SLinus Torvalds	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
4121da177e4SLinus Torvalds	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
413d090dddaSHyok S. Choi#endif
4146ebbf2ceSRussell King	ret	lr
41551db13aaSLinus WalleijSYM_FUNC_END(cpu_arm925_switch_mm)
4161da177e4SLinus Torvalds
4171da177e4SLinus Torvalds/*
418ad1ae2feSRussell King * cpu_arm925_set_pte_ext(ptep, pte, ext)
4191da177e4SLinus Torvalds *
4201da177e4SLinus Torvalds * Set a PTE and flush it out
4211da177e4SLinus Torvalds */
4221da177e4SLinus Torvalds	.align	5
42351db13aaSLinus WalleijSYM_TYPED_FUNC_START(cpu_arm925_set_pte_ext)
424d090dddaSHyok S. Choi#ifdef CONFIG_MMU
425da091653SRussell King	armv3_set_pte_ext
4261da177e4SLinus Torvalds	mov	r0, r0
4271da177e4SLinus Torvalds#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
4281da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
4291da177e4SLinus Torvalds#endif
4301da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
431d090dddaSHyok S. Choi#endif /* CONFIG_MMU */
4326ebbf2ceSRussell King	ret	lr
43351db13aaSLinus WalleijSYM_FUNC_END(cpu_arm925_set_pte_ext)
4341da177e4SLinus Torvalds
4351da177e4SLinus Torvalds	.type	__arm925_setup, #function
4361da177e4SLinus Torvalds__arm925_setup:
4371da177e4SLinus Torvalds	mov	r0, #0
4381da177e4SLinus Torvalds
4391da177e4SLinus Torvalds	/* Transparent on, D-cache clean & flush mode. See  NOTE2 above */
4401da177e4SLinus Torvalds        orr     r0,r0,#1 << 1			@ transparent mode on
4411da177e4SLinus Torvalds        mcr     p15, 0, r0, c15, c1, 0          @ write TI config register
4421da177e4SLinus Torvalds
4431da177e4SLinus Torvalds	mov	r0, #0
4441da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
4451da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
446d090dddaSHyok S. Choi#ifdef CONFIG_MMU
4471da177e4SLinus Torvalds	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
448d090dddaSHyok S. Choi#endif
4491da177e4SLinus Torvalds
4501da177e4SLinus Torvalds#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
4511da177e4SLinus Torvalds	mov	r0, #4				@ disable write-back on caches explicitly
4521da177e4SLinus Torvalds	mcr	p15, 7, r0, c15, c0, 0
4531da177e4SLinus Torvalds#endif
4541da177e4SLinus Torvalds
455906243d0SRussell King	adr	r5, arm925_crval
456906243d0SRussell King	ldmia	r5, {r5, r6}
4571da177e4SLinus Torvalds	mrc	p15, 0, r0, c1, c0		@ get control register v4
4581da177e4SLinus Torvalds	bic	r0, r0, r5
45922b19086SRussell King	orr	r0, r0, r6
4601da177e4SLinus Torvalds#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
4611da177e4SLinus Torvalds	orr	r0, r0, #0x4000			@ .1.. .... .... ....
4621da177e4SLinus Torvalds#endif
4636ebbf2ceSRussell King	ret	lr
4641da177e4SLinus Torvalds	.size	__arm925_setup, . - __arm925_setup
4651da177e4SLinus Torvalds
4661da177e4SLinus Torvalds	/*
4671da177e4SLinus Torvalds	 *  R
4681da177e4SLinus Torvalds	 * .RVI ZFRS BLDP WCAM
4691da177e4SLinus Torvalds	 * .011 0001 ..11 1101
4701da177e4SLinus Torvalds	 *
4711da177e4SLinus Torvalds	 */
47222b19086SRussell King	.type	arm925_crval, #object
47322b19086SRussell Kingarm925_crval:
47422b19086SRussell King	crval	clear=0x00007f3f, mmuset=0x0000313d, ucset=0x00001130
4751da177e4SLinus Torvalds
4761da177e4SLinus Torvalds	__INITDATA
4776c240aecSDave Martin	@ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
4786c240aecSDave Martin	define_processor_functions arm925, dabort=v4t_early_abort, pabort=legacy_pabort
4791da177e4SLinus Torvalds
4801da177e4SLinus Torvalds	.section ".rodata"
4811da177e4SLinus Torvalds
4826c240aecSDave Martin	string	cpu_arch_name, "armv4t"
4836c240aecSDave Martin	string	cpu_elf_name, "v4"
4846c240aecSDave Martin	string	cpu_arm925_name, "ARM925T"
4851da177e4SLinus Torvalds
4861da177e4SLinus Torvalds	.align
4871da177e4SLinus Torvalds
488790756c7SNick Desaulniers	.section ".proc.info.init", "a"
4891da177e4SLinus Torvalds
4906c240aecSDave Martin.macro arm925_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cache
4916c240aecSDave Martin	.type	__\name\()_proc_info,#object
4926c240aecSDave Martin__\name\()_proc_info:
4936c240aecSDave Martin	.long	\cpu_val
4946c240aecSDave Martin	.long	\cpu_mask
4951da177e4SLinus Torvalds	.long   PMD_TYPE_SECT | \
496b8d8772eSRussell King		PMD_SECT_CACHEABLE | \
4971da177e4SLinus Torvalds		PMD_BIT4 | \
4981da177e4SLinus Torvalds		PMD_SECT_AP_WRITE | \
4991da177e4SLinus Torvalds		PMD_SECT_AP_READ
5008799ee9fSRussell King	.long   PMD_TYPE_SECT | \
5018799ee9fSRussell King		PMD_BIT4 | \
5028799ee9fSRussell King		PMD_SECT_AP_WRITE | \
5038799ee9fSRussell King		PMD_SECT_AP_READ
504bf35706fSArd Biesheuvel	initfn	__arm925_setup, __\name\()_proc_info
5051da177e4SLinus Torvalds	.long	cpu_arch_name
5061da177e4SLinus Torvalds	.long	cpu_elf_name
5071da177e4SLinus Torvalds	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
5081da177e4SLinus Torvalds	.long	cpu_arm925_name
5091da177e4SLinus Torvalds	.long	arm925_processor_functions
5101da177e4SLinus Torvalds	.long	v4wbi_tlb_fns
5111da177e4SLinus Torvalds	.long	v4wb_user_fns
5121da177e4SLinus Torvalds	.long	arm925_cache_fns
5136c240aecSDave Martin	.size	__\name\()_proc_info, . - __\name\()_proc_info
5146c240aecSDave Martin.endm
5151da177e4SLinus Torvalds
5166c240aecSDave Martin	arm925_proc_info arm925, 0x54029250, 0xfffffff0, cpu_arm925_name
5176c240aecSDave Martin	arm925_proc_info arm915, 0x54029150, 0xfffffff0, cpu_arm925_name
518