xref: /linux/arch/arm/mm/proc-arm925.S (revision c8c90860cd3592fac83a349f84a20360a6498727)
11da177e4SLinus Torvalds/*
21da177e4SLinus Torvalds *  linux/arch/arm/mm/arm925.S: MMU functions for ARM925
31da177e4SLinus Torvalds *
41da177e4SLinus Torvalds *  Copyright (C) 1999,2000 ARM Limited
51da177e4SLinus Torvalds *  Copyright (C) 2000 Deep Blue Solutions Ltd.
61da177e4SLinus Torvalds *  Copyright (C) 2002 RidgeRun, Inc.
71da177e4SLinus Torvalds *  Copyright (C) 2002-2003 MontaVista Software, Inc.
81da177e4SLinus Torvalds *
91da177e4SLinus Torvalds *  Update for Linux-2.6 and cache flush improvements
101da177e4SLinus Torvalds *  Copyright (C) 2004 Nokia Corporation by Tony Lindgren <tony@atomide.com>
111da177e4SLinus Torvalds *
12d090dddaSHyok S. Choi *  hacked for non-paged-MM by Hyok S. Choi, 2004.
13d090dddaSHyok S. Choi *
141da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify
151da177e4SLinus Torvalds * it under the terms of the GNU General Public License as published by
161da177e4SLinus Torvalds * the Free Software Foundation; either version 2 of the License, or
171da177e4SLinus Torvalds * (at your option) any later version.
181da177e4SLinus Torvalds *
191da177e4SLinus Torvalds * This program is distributed in the hope that it will be useful,
201da177e4SLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of
211da177e4SLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
221da177e4SLinus Torvalds * GNU General Public License for more details.
231da177e4SLinus Torvalds *
241da177e4SLinus Torvalds * You should have received a copy of the GNU General Public License
251da177e4SLinus Torvalds * along with this program; if not, write to the Free Software
261da177e4SLinus Torvalds * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
271da177e4SLinus Torvalds *
281da177e4SLinus Torvalds *
291da177e4SLinus Torvalds * These are the low level assembler for performing cache and TLB
301da177e4SLinus Torvalds * functions on the arm925.
311da177e4SLinus Torvalds *
321da177e4SLinus Torvalds *  CONFIG_CPU_ARM925_CPU_IDLE -> nohlt
331da177e4SLinus Torvalds *
341da177e4SLinus Torvalds * Some additional notes based on deciphering the TI TRM on OMAP-5910:
351da177e4SLinus Torvalds *
361da177e4SLinus Torvalds * NOTE1: The TI925T Configuration Register bit "D-cache clean and flush
371da177e4SLinus Torvalds *	  entry mode" must be 0 to flush the entries in both segments
381da177e4SLinus Torvalds *	  at once. This is the default value. See TRM 2-20 and 2-24 for
391da177e4SLinus Torvalds *	  more information.
401da177e4SLinus Torvalds *
411da177e4SLinus Torvalds * NOTE2: Default is the "D-cache clean and flush entry mode". It looks
421da177e4SLinus Torvalds *	  like the "Transparent mode" must be on for partial cache flushes
431da177e4SLinus Torvalds *	  to work in this mode. This mode only works with 16-bit external
441da177e4SLinus Torvalds *	  memory. See TRM 2-24 for more information.
451da177e4SLinus Torvalds *
461da177e4SLinus Torvalds * NOTE3: Write-back cache flushing seems to be flakey with devices using
471da177e4SLinus Torvalds *        direct memory access, such as USB OHCI. The workaround is to use
481da177e4SLinus Torvalds *        write-through cache with CONFIG_CPU_DCACHE_WRITETHROUGH (this is
491da177e4SLinus Torvalds *        the default for OMAP-1510).
501da177e4SLinus Torvalds */
511da177e4SLinus Torvalds
521da177e4SLinus Torvalds#include <linux/linkage.h>
531da177e4SLinus Torvalds#include <linux/init.h>
541da177e4SLinus Torvalds#include <asm/assembler.h>
555ec9407dSRussell King#include <asm/hwcap.h>
5674945c86SRussell King#include <asm/pgtable-hwdef.h>
571da177e4SLinus Torvalds#include <asm/pgtable.h>
581da177e4SLinus Torvalds#include <asm/page.h>
591da177e4SLinus Torvalds#include <asm/ptrace.h>
601da177e4SLinus Torvalds#include "proc-macros.S"
611da177e4SLinus Torvalds
621da177e4SLinus Torvalds/*
631da177e4SLinus Torvalds * The size of one data cache line.
641da177e4SLinus Torvalds */
651da177e4SLinus Torvalds#define CACHE_DLINESIZE	16
661da177e4SLinus Torvalds
671da177e4SLinus Torvalds/*
681da177e4SLinus Torvalds * The number of data cache segments.
691da177e4SLinus Torvalds */
701da177e4SLinus Torvalds#define CACHE_DSEGMENTS	2
711da177e4SLinus Torvalds
721da177e4SLinus Torvalds/*
731da177e4SLinus Torvalds * The number of lines in a cache segment.
741da177e4SLinus Torvalds */
751da177e4SLinus Torvalds#define CACHE_DENTRIES	256
761da177e4SLinus Torvalds
771da177e4SLinus Torvalds/*
781da177e4SLinus Torvalds * This is the size at which it becomes more efficient to
791da177e4SLinus Torvalds * clean the whole cache, rather than using the individual
801da177e4SLinus Torvalds * cache line maintainence instructions.
811da177e4SLinus Torvalds */
821da177e4SLinus Torvalds#define CACHE_DLIMIT	8192
831da177e4SLinus Torvalds
841da177e4SLinus Torvalds	.text
851da177e4SLinus Torvalds/*
861da177e4SLinus Torvalds * cpu_arm925_proc_init()
871da177e4SLinus Torvalds */
881da177e4SLinus TorvaldsENTRY(cpu_arm925_proc_init)
891da177e4SLinus Torvalds	mov	pc, lr
901da177e4SLinus Torvalds
911da177e4SLinus Torvalds/*
921da177e4SLinus Torvalds * cpu_arm925_proc_fin()
931da177e4SLinus Torvalds */
941da177e4SLinus TorvaldsENTRY(cpu_arm925_proc_fin)
951da177e4SLinus Torvalds	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
961da177e4SLinus Torvalds	bic	r0, r0, #0x1000			@ ...i............
971da177e4SLinus Torvalds	bic	r0, r0, #0x000e			@ ............wca.
981da177e4SLinus Torvalds	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
999ca03a21SRussell King	mov	pc, lr
1001da177e4SLinus Torvalds
1011da177e4SLinus Torvalds/*
1021da177e4SLinus Torvalds * cpu_arm925_reset(loc)
1031da177e4SLinus Torvalds *
1041da177e4SLinus Torvalds * Perform a soft reset of the system.  Put the CPU into the
1051da177e4SLinus Torvalds * same state as it would be if it had been reset, and branch
1061da177e4SLinus Torvalds * to what would be the reset vector.
1071da177e4SLinus Torvalds *
1081da177e4SLinus Torvalds * loc: location to jump to for soft reset
1091da177e4SLinus Torvalds */
1101da177e4SLinus Torvalds	.align	5
1111da177e4SLinus TorvaldsENTRY(cpu_arm925_reset)
1121da177e4SLinus Torvalds	/* Send software reset to MPU and DSP */
1131da177e4SLinus Torvalds	mov	ip, #0xff000000
1141da177e4SLinus Torvalds	orr	ip, ip, #0x00fe0000
1151da177e4SLinus Torvalds	orr	ip, ip, #0x0000ce00
1161da177e4SLinus Torvalds	mov	r4, #1
1171da177e4SLinus Torvalds	strh	r4, [ip, #0x10]
1181da177e4SLinus Torvalds
1191da177e4SLinus Torvalds	mov	ip, #0
1201da177e4SLinus Torvalds	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
1211da177e4SLinus Torvalds	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
122d090dddaSHyok S. Choi#ifdef CONFIG_MMU
1231da177e4SLinus Torvalds	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
124d090dddaSHyok S. Choi#endif
1251da177e4SLinus Torvalds	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
1261da177e4SLinus Torvalds	bic	ip, ip, #0x000f			@ ............wcam
1271da177e4SLinus Torvalds	bic	ip, ip, #0x1100			@ ...i...s........
1281da177e4SLinus Torvalds	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
1291da177e4SLinus Torvalds	mov	pc, r0
1301da177e4SLinus Torvalds
1311da177e4SLinus Torvalds/*
1321da177e4SLinus Torvalds * cpu_arm925_do_idle()
1331da177e4SLinus Torvalds *
1341da177e4SLinus Torvalds * Called with IRQs disabled
1351da177e4SLinus Torvalds */
1361da177e4SLinus Torvalds	.align	10
1371da177e4SLinus TorvaldsENTRY(cpu_arm925_do_idle)
1381da177e4SLinus Torvalds	mov	r0, #0
1391da177e4SLinus Torvalds	mrc	p15, 0, r1, c1, c0, 0		@ Read control register
1401da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 4		@ Drain write buffer
1411da177e4SLinus Torvalds	bic	r2, r1, #1 << 12
1421da177e4SLinus Torvalds	mcr	p15, 0, r2, c1, c0, 0		@ Disable I cache
1431da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
1441da177e4SLinus Torvalds	mcr	p15, 0, r1, c1, c0, 0		@ Restore ICache enable
1451da177e4SLinus Torvalds	mov	pc, lr
1461da177e4SLinus Torvalds
1471da177e4SLinus Torvalds/*
148*c8c90860SMika Westerberg *	flush_icache_all()
149*c8c90860SMika Westerberg *
150*c8c90860SMika Westerberg *	Unconditionally clean and invalidate the entire icache.
151*c8c90860SMika Westerberg */
152*c8c90860SMika WesterbergENTRY(arm925_flush_icache_all)
153*c8c90860SMika Westerberg	mov	r0, #0
154*c8c90860SMika Westerberg	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
155*c8c90860SMika Westerberg	mov	pc, lr
156*c8c90860SMika WesterbergENDPROC(arm925_flush_icache_all)
157*c8c90860SMika Westerberg
158*c8c90860SMika Westerberg/*
1591da177e4SLinus Torvalds *	flush_user_cache_all()
1601da177e4SLinus Torvalds *
1611da177e4SLinus Torvalds *	Clean and invalidate all cache entries in a particular
1621da177e4SLinus Torvalds *	address space.
1631da177e4SLinus Torvalds */
1641da177e4SLinus TorvaldsENTRY(arm925_flush_user_cache_all)
1651da177e4SLinus Torvalds	/* FALLTHROUGH */
1661da177e4SLinus Torvalds
1671da177e4SLinus Torvalds/*
1681da177e4SLinus Torvalds *	flush_kern_cache_all()
1691da177e4SLinus Torvalds *
1701da177e4SLinus Torvalds *	Clean and invalidate the entire cache.
1711da177e4SLinus Torvalds */
1721da177e4SLinus TorvaldsENTRY(arm925_flush_kern_cache_all)
1731da177e4SLinus Torvalds	mov	r2, #VM_EXEC
1741da177e4SLinus Torvalds	mov	ip, #0
1751da177e4SLinus Torvalds__flush_whole_cache:
1761da177e4SLinus Torvalds#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
1771da177e4SLinus Torvalds	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
1781da177e4SLinus Torvalds#else
1791da177e4SLinus Torvalds	/* Flush entries in both segments at once, see NOTE1 above */
1801da177e4SLinus Torvalds	mov	r3, #(CACHE_DENTRIES - 1) << 4	@ 256 entries in segment
1811da177e4SLinus Torvalds2:	mcr	p15, 0, r3, c7, c14, 2		@ clean+invalidate D index
1821da177e4SLinus Torvalds	subs	r3, r3, #1 << 4
1831da177e4SLinus Torvalds	bcs	2b				@ entries 255 to 0
1841da177e4SLinus Torvalds#endif
1851da177e4SLinus Torvalds	tst	r2, #VM_EXEC
1861da177e4SLinus Torvalds	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
1871da177e4SLinus Torvalds	mcrne	p15, 0, ip, c7, c10, 4		@ drain WB
1881da177e4SLinus Torvalds	mov	pc, lr
1891da177e4SLinus Torvalds
1901da177e4SLinus Torvalds/*
1911da177e4SLinus Torvalds *	flush_user_cache_range(start, end, flags)
1921da177e4SLinus Torvalds *
1931da177e4SLinus Torvalds *	Clean and invalidate a range of cache entries in the
1941da177e4SLinus Torvalds *	specified address range.
1951da177e4SLinus Torvalds *
1961da177e4SLinus Torvalds *	- start	- start address (inclusive)
1971da177e4SLinus Torvalds *	- end	- end address (exclusive)
1981da177e4SLinus Torvalds *	- flags	- vm_flags describing address space
1991da177e4SLinus Torvalds */
2001da177e4SLinus TorvaldsENTRY(arm925_flush_user_cache_range)
2011da177e4SLinus Torvalds	mov	ip, #0
2021da177e4SLinus Torvalds	sub	r3, r1, r0			@ calculate total size
2031da177e4SLinus Torvalds	cmp	r3, #CACHE_DLIMIT
2041da177e4SLinus Torvalds	bgt	__flush_whole_cache
2051da177e4SLinus Torvalds1:	tst	r2, #VM_EXEC
2061da177e4SLinus Torvalds#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
2071da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c6, 1		@ 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, c6, 1		@ invalidate D entry
2111da177e4SLinus Torvalds	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
2121da177e4SLinus Torvalds	add	r0, r0, #CACHE_DLINESIZE
2131da177e4SLinus Torvalds#else
2141da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
2151da177e4SLinus Torvalds	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
2161da177e4SLinus Torvalds	add	r0, r0, #CACHE_DLINESIZE
2171da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
2181da177e4SLinus Torvalds	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
2191da177e4SLinus Torvalds	add	r0, r0, #CACHE_DLINESIZE
2201da177e4SLinus Torvalds#endif
2211da177e4SLinus Torvalds	cmp	r0, r1
2221da177e4SLinus Torvalds	blo	1b
2231da177e4SLinus Torvalds	tst	r2, #VM_EXEC
2241da177e4SLinus Torvalds	mcrne	p15, 0, ip, c7, c10, 4		@ drain WB
2251da177e4SLinus Torvalds	mov	pc, lr
2261da177e4SLinus Torvalds
2271da177e4SLinus Torvalds/*
2281da177e4SLinus Torvalds *	coherent_kern_range(start, end)
2291da177e4SLinus Torvalds *
2301da177e4SLinus Torvalds *	Ensure coherency between the Icache and the Dcache in the
2311da177e4SLinus Torvalds *	region described by start, end.  If you have non-snooping
2321da177e4SLinus Torvalds *	Harvard caches, you need to implement this function.
2331da177e4SLinus Torvalds *
2341da177e4SLinus Torvalds *	- start	- virtual start address
2351da177e4SLinus Torvalds *	- end	- virtual end address
2361da177e4SLinus Torvalds */
2371da177e4SLinus TorvaldsENTRY(arm925_coherent_kern_range)
2381da177e4SLinus Torvalds	/* FALLTHROUGH */
2391da177e4SLinus Torvalds
2401da177e4SLinus Torvalds/*
2411da177e4SLinus Torvalds *	coherent_user_range(start, end)
2421da177e4SLinus Torvalds *
2431da177e4SLinus Torvalds *	Ensure coherency between the Icache and the Dcache in the
2441da177e4SLinus Torvalds *	region described by start, end.  If you have non-snooping
2451da177e4SLinus Torvalds *	Harvard caches, you need to implement this function.
2461da177e4SLinus Torvalds *
2471da177e4SLinus Torvalds *	- start	- virtual start address
2481da177e4SLinus Torvalds *	- end	- virtual end address
2491da177e4SLinus Torvalds */
2501da177e4SLinus TorvaldsENTRY(arm925_coherent_user_range)
2511da177e4SLinus Torvalds	bic	r0, r0, #CACHE_DLINESIZE - 1
2521da177e4SLinus Torvalds1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
2531da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c5, 1		@ invalidate I entry
2541da177e4SLinus Torvalds	add	r0, r0, #CACHE_DLINESIZE
2551da177e4SLinus Torvalds	cmp	r0, r1
2561da177e4SLinus Torvalds	blo	1b
2571da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
2581da177e4SLinus Torvalds	mov	pc, lr
2591da177e4SLinus Torvalds
2601da177e4SLinus Torvalds/*
2612c9b9c84SRussell King *	flush_kern_dcache_area(void *addr, size_t size)
2621da177e4SLinus Torvalds *
2631da177e4SLinus Torvalds *	Ensure no D cache aliasing occurs, either with itself or
2641da177e4SLinus Torvalds *	the I cache
2651da177e4SLinus Torvalds *
2662c9b9c84SRussell King *	- addr	- kernel address
2672c9b9c84SRussell King *	- size	- region size
2681da177e4SLinus Torvalds */
2692c9b9c84SRussell KingENTRY(arm925_flush_kern_dcache_area)
2702c9b9c84SRussell King	add	r1, r0, r1
2711da177e4SLinus Torvalds1:	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
2721da177e4SLinus Torvalds	add	r0, r0, #CACHE_DLINESIZE
2731da177e4SLinus Torvalds	cmp	r0, r1
2741da177e4SLinus Torvalds	blo	1b
2751da177e4SLinus Torvalds	mov	r0, #0
2761da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
2771da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
2781da177e4SLinus Torvalds	mov	pc, lr
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
3061da177e4SLinus Torvalds	mov	pc, 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
3271da177e4SLinus Torvalds	mov	pc, 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 */
3371da177e4SLinus TorvaldsENTRY(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
3491da177e4SLinus Torvalds	mov	pc, lr
3501da177e4SLinus Torvalds
351a9c9147eSRussell King/*
352a9c9147eSRussell King *	dma_map_area(start, size, dir)
353a9c9147eSRussell King *	- start	- kernel virtual start address
354a9c9147eSRussell King *	- size	- size of region
355a9c9147eSRussell King *	- dir	- DMA direction
356a9c9147eSRussell King */
357a9c9147eSRussell KingENTRY(arm925_dma_map_area)
358a9c9147eSRussell King	add	r1, r1, r0
359a9c9147eSRussell King	cmp	r2, #DMA_TO_DEVICE
360a9c9147eSRussell King	beq	arm925_dma_clean_range
361a9c9147eSRussell King	bcs	arm925_dma_inv_range
362a9c9147eSRussell King	b	arm925_dma_flush_range
363a9c9147eSRussell KingENDPROC(arm925_dma_map_area)
364a9c9147eSRussell King
365a9c9147eSRussell King/*
366a9c9147eSRussell King *	dma_unmap_area(start, size, dir)
367a9c9147eSRussell King *	- start	- kernel virtual start address
368a9c9147eSRussell King *	- size	- size of region
369a9c9147eSRussell King *	- dir	- DMA direction
370a9c9147eSRussell King */
371a9c9147eSRussell KingENTRY(arm925_dma_unmap_area)
372a9c9147eSRussell King	mov	pc, lr
373a9c9147eSRussell KingENDPROC(arm925_dma_unmap_area)
374a9c9147eSRussell King
3751da177e4SLinus TorvaldsENTRY(arm925_cache_fns)
376*c8c90860SMika Westerberg	.long	arm925_flush_icache_all
3771da177e4SLinus Torvalds	.long	arm925_flush_kern_cache_all
3781da177e4SLinus Torvalds	.long	arm925_flush_user_cache_all
3791da177e4SLinus Torvalds	.long	arm925_flush_user_cache_range
3801da177e4SLinus Torvalds	.long	arm925_coherent_kern_range
3811da177e4SLinus Torvalds	.long	arm925_coherent_user_range
3822c9b9c84SRussell King	.long	arm925_flush_kern_dcache_area
383a9c9147eSRussell King	.long	arm925_dma_map_area
384a9c9147eSRussell King	.long	arm925_dma_unmap_area
3851da177e4SLinus Torvalds	.long	arm925_dma_flush_range
3861da177e4SLinus Torvalds
3871da177e4SLinus TorvaldsENTRY(cpu_arm925_dcache_clean_area)
3881da177e4SLinus Torvalds#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
3891da177e4SLinus Torvalds1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
3901da177e4SLinus Torvalds	add	r0, r0, #CACHE_DLINESIZE
3911da177e4SLinus Torvalds	subs	r1, r1, #CACHE_DLINESIZE
3921da177e4SLinus Torvalds	bhi	1b
3931da177e4SLinus Torvalds#endif
3941da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
3951da177e4SLinus Torvalds	mov	pc, lr
3961da177e4SLinus Torvalds
3971da177e4SLinus Torvalds/* =============================== PageTable ============================== */
3981da177e4SLinus Torvalds
3991da177e4SLinus Torvalds/*
4001da177e4SLinus Torvalds * cpu_arm925_switch_mm(pgd)
4011da177e4SLinus Torvalds *
4021da177e4SLinus Torvalds * Set the translation base pointer to be as described by pgd.
4031da177e4SLinus Torvalds *
4041da177e4SLinus Torvalds * pgd: new page tables
4051da177e4SLinus Torvalds */
4061da177e4SLinus Torvalds	.align	5
4071da177e4SLinus TorvaldsENTRY(cpu_arm925_switch_mm)
408d090dddaSHyok S. Choi#ifdef CONFIG_MMU
4091da177e4SLinus Torvalds	mov	ip, #0
4101da177e4SLinus Torvalds#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
4111da177e4SLinus Torvalds	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
4121da177e4SLinus Torvalds#else
4131da177e4SLinus Torvalds	/* Flush entries in bothe segments at once, see NOTE1 above */
4141da177e4SLinus Torvalds	mov	r3, #(CACHE_DENTRIES - 1) << 4	@ 256 entries in segment
4151da177e4SLinus Torvalds2:	mcr	p15, 0, r3, c7, c14, 2		@ clean & invalidate D index
4161da177e4SLinus Torvalds	subs	r3, r3, #1 << 4
4171da177e4SLinus Torvalds	bcs	2b				@ entries 255 to 0
4181da177e4SLinus Torvalds#endif
4191da177e4SLinus Torvalds	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
4201da177e4SLinus Torvalds	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
4211da177e4SLinus Torvalds	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
4221da177e4SLinus Torvalds	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
423d090dddaSHyok S. Choi#endif
4241da177e4SLinus Torvalds	mov	pc, lr
4251da177e4SLinus Torvalds
4261da177e4SLinus Torvalds/*
427ad1ae2feSRussell King * cpu_arm925_set_pte_ext(ptep, pte, ext)
4281da177e4SLinus Torvalds *
4291da177e4SLinus Torvalds * Set a PTE and flush it out
4301da177e4SLinus Torvalds */
4311da177e4SLinus Torvalds	.align	5
432ad1ae2feSRussell KingENTRY(cpu_arm925_set_pte_ext)
433d090dddaSHyok S. Choi#ifdef CONFIG_MMU
434da091653SRussell King	armv3_set_pte_ext
4351da177e4SLinus Torvalds	mov	r0, r0
4361da177e4SLinus Torvalds#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
4371da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
4381da177e4SLinus Torvalds#endif
4391da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
440d090dddaSHyok S. Choi#endif /* CONFIG_MMU */
4411da177e4SLinus Torvalds	mov	pc, lr
4421da177e4SLinus Torvalds
4435085f3ffSRussell King	__CPUINIT
4441da177e4SLinus Torvalds
4451da177e4SLinus Torvalds	.type	__arm925_setup, #function
4461da177e4SLinus Torvalds__arm925_setup:
4471da177e4SLinus Torvalds	mov	r0, #0
4481da177e4SLinus Torvalds#if defined(CONFIG_CPU_ICACHE_STREAMING_DISABLE)
4491da177e4SLinus Torvalds        orr     r0,r0,#1 << 7
4501da177e4SLinus Torvalds#endif
4511da177e4SLinus Torvalds
4521da177e4SLinus Torvalds	/* Transparent on, D-cache clean & flush mode. See  NOTE2 above */
4531da177e4SLinus Torvalds        orr     r0,r0,#1 << 1			@ transparent mode on
4541da177e4SLinus Torvalds        mcr     p15, 0, r0, c15, c1, 0          @ write TI config register
4551da177e4SLinus Torvalds
4561da177e4SLinus Torvalds	mov	r0, #0
4571da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
4581da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
459d090dddaSHyok S. Choi#ifdef CONFIG_MMU
4601da177e4SLinus Torvalds	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
461d090dddaSHyok S. Choi#endif
4621da177e4SLinus Torvalds
4631da177e4SLinus Torvalds#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
4641da177e4SLinus Torvalds	mov	r0, #4				@ disable write-back on caches explicitly
4651da177e4SLinus Torvalds	mcr	p15, 7, r0, c15, c0, 0
4661da177e4SLinus Torvalds#endif
4671da177e4SLinus Torvalds
468906243d0SRussell King	adr	r5, arm925_crval
469906243d0SRussell King	ldmia	r5, {r5, r6}
4701da177e4SLinus Torvalds	mrc	p15, 0, r0, c1, c0		@ get control register v4
4711da177e4SLinus Torvalds	bic	r0, r0, r5
47222b19086SRussell King	orr	r0, r0, r6
4731da177e4SLinus Torvalds#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
4741da177e4SLinus Torvalds	orr	r0, r0, #0x4000			@ .1.. .... .... ....
4751da177e4SLinus Torvalds#endif
4761da177e4SLinus Torvalds	mov	pc, lr
4771da177e4SLinus Torvalds	.size	__arm925_setup, . - __arm925_setup
4781da177e4SLinus Torvalds
4791da177e4SLinus Torvalds	/*
4801da177e4SLinus Torvalds	 *  R
4811da177e4SLinus Torvalds	 * .RVI ZFRS BLDP WCAM
4821da177e4SLinus Torvalds	 * .011 0001 ..11 1101
4831da177e4SLinus Torvalds	 *
4841da177e4SLinus Torvalds	 */
48522b19086SRussell King	.type	arm925_crval, #object
48622b19086SRussell Kingarm925_crval:
48722b19086SRussell King	crval	clear=0x00007f3f, mmuset=0x0000313d, ucset=0x00001130
4881da177e4SLinus Torvalds
4891da177e4SLinus Torvalds	__INITDATA
4901da177e4SLinus Torvalds
4911da177e4SLinus Torvalds/*
4921da177e4SLinus Torvalds * Purpose : Function pointers used to access above functions - all calls
4931da177e4SLinus Torvalds *	     come through these
4941da177e4SLinus Torvalds */
4951da177e4SLinus Torvalds	.type	arm925_processor_functions, #object
4961da177e4SLinus Torvaldsarm925_processor_functions:
4971da177e4SLinus Torvalds	.word	v4t_early_abort
4984fb28474SKirill A. Shutemov	.word	legacy_pabort
4991da177e4SLinus Torvalds	.word	cpu_arm925_proc_init
5001da177e4SLinus Torvalds	.word	cpu_arm925_proc_fin
5011da177e4SLinus Torvalds	.word	cpu_arm925_reset
5021da177e4SLinus Torvalds	.word   cpu_arm925_do_idle
5031da177e4SLinus Torvalds	.word	cpu_arm925_dcache_clean_area
5041da177e4SLinus Torvalds	.word	cpu_arm925_switch_mm
505ad1ae2feSRussell King	.word	cpu_arm925_set_pte_ext
5061da177e4SLinus Torvalds	.size	arm925_processor_functions, . - arm925_processor_functions
5071da177e4SLinus Torvalds
5081da177e4SLinus Torvalds	.section ".rodata"
5091da177e4SLinus Torvalds
5101da177e4SLinus Torvalds	.type	cpu_arch_name, #object
5111da177e4SLinus Torvaldscpu_arch_name:
5121da177e4SLinus Torvalds	.asciz	"armv4t"
5131da177e4SLinus Torvalds	.size	cpu_arch_name, . - cpu_arch_name
5141da177e4SLinus Torvalds
5151da177e4SLinus Torvalds	.type	cpu_elf_name, #object
5161da177e4SLinus Torvaldscpu_elf_name:
5171da177e4SLinus Torvalds	.asciz	"v4"
5181da177e4SLinus Torvalds	.size	cpu_elf_name, . - cpu_elf_name
5191da177e4SLinus Torvalds
5201da177e4SLinus Torvalds	.type	cpu_arm925_name, #object
5211da177e4SLinus Torvaldscpu_arm925_name:
522264edb35SRussell King	.asciz	"ARM925T"
5231da177e4SLinus Torvalds	.size	cpu_arm925_name, . - cpu_arm925_name
5241da177e4SLinus Torvalds
5251da177e4SLinus Torvalds	.align
5261da177e4SLinus Torvalds
52702b7dd12SBen Dooks	.section ".proc.info.init", #alloc, #execinstr
5281da177e4SLinus Torvalds
5291da177e4SLinus Torvalds	.type	__arm925_proc_info,#object
5301da177e4SLinus Torvalds__arm925_proc_info:
5311da177e4SLinus Torvalds	.long	0x54029250
5321da177e4SLinus Torvalds	.long	0xfffffff0
5331da177e4SLinus Torvalds	.long   PMD_TYPE_SECT | \
5341da177e4SLinus Torvalds		PMD_BIT4 | \
5351da177e4SLinus Torvalds		PMD_SECT_AP_WRITE | \
5361da177e4SLinus Torvalds		PMD_SECT_AP_READ
5378799ee9fSRussell King	.long   PMD_TYPE_SECT | \
5388799ee9fSRussell King		PMD_BIT4 | \
5398799ee9fSRussell King		PMD_SECT_AP_WRITE | \
5408799ee9fSRussell King		PMD_SECT_AP_READ
5411da177e4SLinus Torvalds	b	__arm925_setup
5421da177e4SLinus Torvalds	.long	cpu_arch_name
5431da177e4SLinus Torvalds	.long	cpu_elf_name
5441da177e4SLinus Torvalds	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
5451da177e4SLinus Torvalds	.long	cpu_arm925_name
5461da177e4SLinus Torvalds	.long	arm925_processor_functions
5471da177e4SLinus Torvalds	.long	v4wbi_tlb_fns
5481da177e4SLinus Torvalds	.long	v4wb_user_fns
5491da177e4SLinus Torvalds	.long	arm925_cache_fns
5501da177e4SLinus Torvalds	.size	__arm925_proc_info, . - __arm925_proc_info
5511da177e4SLinus Torvalds
5521da177e4SLinus Torvalds	.type	__arm915_proc_info,#object
5531da177e4SLinus Torvalds__arm915_proc_info:
5541da177e4SLinus Torvalds	.long	0x54029150
5551da177e4SLinus Torvalds	.long	0xfffffff0
5561da177e4SLinus Torvalds	.long   PMD_TYPE_SECT | \
5571da177e4SLinus Torvalds		PMD_BIT4 | \
5581da177e4SLinus Torvalds		PMD_SECT_AP_WRITE | \
5591da177e4SLinus Torvalds		PMD_SECT_AP_READ
5608799ee9fSRussell King	.long   PMD_TYPE_SECT | \
5618799ee9fSRussell King		PMD_BIT4 | \
5628799ee9fSRussell King		PMD_SECT_AP_WRITE | \
5638799ee9fSRussell King		PMD_SECT_AP_READ
5641da177e4SLinus Torvalds	b	__arm925_setup
5651da177e4SLinus Torvalds	.long	cpu_arch_name
5661da177e4SLinus Torvalds	.long	cpu_elf_name
5671da177e4SLinus Torvalds	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
5681da177e4SLinus Torvalds	.long	cpu_arm925_name
5691da177e4SLinus Torvalds	.long	arm925_processor_functions
5701da177e4SLinus Torvalds	.long	v4wbi_tlb_fns
5711da177e4SLinus Torvalds	.long	v4wb_user_fns
5721da177e4SLinus Torvalds	.long	arm925_cache_fns
5731da177e4SLinus Torvalds	.size	__arm925_proc_info, . - __arm925_proc_info
574