xref: /openbmc/linux/arch/arm/mm/proc-sa1100.S (revision 4b4193256c8d3bc3a5397b5cd9494c2ad386317d)
1d2912cb1SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */
21da177e4SLinus Torvalds/*
31da177e4SLinus Torvalds *  linux/arch/arm/mm/proc-sa1100.S
41da177e4SLinus Torvalds *
51da177e4SLinus Torvalds *  Copyright (C) 1997-2002 Russell King
6d090dddaSHyok S. Choi *  hacked for non-paged-MM by Hyok S. Choi, 2003.
71da177e4SLinus Torvalds *
81da177e4SLinus Torvalds *  MMU functions for SA110
91da177e4SLinus Torvalds *
101da177e4SLinus Torvalds *  These are the low level assembler for performing cache and TLB
111da177e4SLinus Torvalds *  functions on the StrongARM-1100 and StrongARM-1110.
121da177e4SLinus Torvalds *
131da177e4SLinus Torvalds *  Note that SA1100 and SA1110 share everything but their name and CPU ID.
141da177e4SLinus Torvalds *
151da177e4SLinus Torvalds *  12-jun-2000, Erik Mouw (J.A.K.Mouw@its.tudelft.nl):
161da177e4SLinus Torvalds *    Flush the read buffer at context switches
171da177e4SLinus Torvalds */
181da177e4SLinus Torvalds#include <linux/linkage.h>
191da177e4SLinus Torvalds#include <linux/init.h>
20*65fddcfcSMike Rapoport#include <linux/pgtable.h>
211da177e4SLinus Torvalds#include <asm/assembler.h>
22e6ae744dSSam Ravnborg#include <asm/asm-offsets.h>
235ec9407dSRussell King#include <asm/hwcap.h>
24a09e64fbSRussell King#include <mach/hardware.h>
2574945c86SRussell King#include <asm/pgtable-hwdef.h>
261da177e4SLinus Torvalds
27bb8d5a55SThomas Gleixner#include "proc-macros.S"
28bb8d5a55SThomas Gleixner
291da177e4SLinus Torvalds/*
301da177e4SLinus Torvalds * the cache line size of the I and D cache
311da177e4SLinus Torvalds */
321da177e4SLinus Torvalds#define DCACHELINESIZE	32
331da177e4SLinus Torvalds
34b69874e4SRussell King	.section .text
351da177e4SLinus Torvalds
361da177e4SLinus Torvalds/*
371da177e4SLinus Torvalds * cpu_sa1100_proc_init()
381da177e4SLinus Torvalds */
391da177e4SLinus TorvaldsENTRY(cpu_sa1100_proc_init)
401da177e4SLinus Torvalds	mov	r0, #0
411da177e4SLinus Torvalds	mcr	p15, 0, r0, c15, c1, 2		@ Enable clock switching
421da177e4SLinus Torvalds	mcr	p15, 0, r0, c9, c0, 5		@ Allow read-buffer operations from userland
436ebbf2ceSRussell King	ret	lr
441da177e4SLinus Torvalds
451da177e4SLinus Torvalds/*
461da177e4SLinus Torvalds * cpu_sa1100_proc_fin()
471da177e4SLinus Torvalds *
481da177e4SLinus Torvalds * Prepare the CPU for reset:
491da177e4SLinus Torvalds *  - Disable interrupts
501da177e4SLinus Torvalds *  - Clean and turn off caches.
511da177e4SLinus Torvalds */
521da177e4SLinus TorvaldsENTRY(cpu_sa1100_proc_fin)
5395f3df6bSRussell King	mcr	p15, 0, ip, c15, c2, 2		@ Disable clock switching
541da177e4SLinus Torvalds	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
551da177e4SLinus Torvalds	bic	r0, r0, #0x1000			@ ...i............
561da177e4SLinus Torvalds	bic	r0, r0, #0x000e			@ ............wca.
571da177e4SLinus Torvalds	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
586ebbf2ceSRussell King	ret	lr
591da177e4SLinus Torvalds
601da177e4SLinus Torvalds/*
611da177e4SLinus Torvalds * cpu_sa1100_reset(loc)
621da177e4SLinus Torvalds *
631da177e4SLinus Torvalds * Perform a soft reset of the system.  Put the CPU into the
641da177e4SLinus Torvalds * same state as it would be if it had been reset, and branch
651da177e4SLinus Torvalds * to what would be the reset vector.
661da177e4SLinus Torvalds *
671da177e4SLinus Torvalds * loc: location to jump to for soft reset
681da177e4SLinus Torvalds */
691da177e4SLinus Torvalds	.align	5
701a4baafaSWill Deacon	.pushsection	.idmap.text, "ax"
711da177e4SLinus TorvaldsENTRY(cpu_sa1100_reset)
721da177e4SLinus Torvalds	mov	ip, #0
731da177e4SLinus Torvalds	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
741da177e4SLinus Torvalds	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
75d090dddaSHyok S. Choi#ifdef CONFIG_MMU
761da177e4SLinus Torvalds	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
77d090dddaSHyok S. Choi#endif
781da177e4SLinus Torvalds	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
791da177e4SLinus Torvalds	bic	ip, ip, #0x000f			@ ............wcam
801da177e4SLinus Torvalds	bic	ip, ip, #0x1100			@ ...i...s........
811da177e4SLinus Torvalds	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
826ebbf2ceSRussell King	ret	r0
831a4baafaSWill DeaconENDPROC(cpu_sa1100_reset)
841a4baafaSWill Deacon	.popsection
851da177e4SLinus Torvalds
861da177e4SLinus Torvalds/*
871da177e4SLinus Torvalds * cpu_sa1100_do_idle(type)
881da177e4SLinus Torvalds *
891da177e4SLinus Torvalds * Cause the processor to idle
901da177e4SLinus Torvalds *
911da177e4SLinus Torvalds * type: call type:
921da177e4SLinus Torvalds *   0 = slow idle
931da177e4SLinus Torvalds *   1 = fast idle
941da177e4SLinus Torvalds *   2 = switch to slow processor clock
951da177e4SLinus Torvalds *   3 = switch to fast processor clock
961da177e4SLinus Torvalds */
971da177e4SLinus Torvalds	.align	5
981da177e4SLinus TorvaldsENTRY(cpu_sa1100_do_idle)
991da177e4SLinus Torvalds	mov	r0, r0				@ 4 nop padding
1001da177e4SLinus Torvalds	mov	r0, r0
1011da177e4SLinus Torvalds	mov	r0, r0
1021da177e4SLinus Torvalds	mov	r0, r0				@ 4 nop padding
1031da177e4SLinus Torvalds	mov	r0, r0
1041da177e4SLinus Torvalds	mov	r0, r0
1051da177e4SLinus Torvalds	mov	r0, #0
1061da177e4SLinus Torvalds	ldr	r1, =UNCACHEABLE_ADDR		@ ptr to uncacheable address
1071da177e4SLinus Torvalds	@ --- aligned to a cache line
1081da177e4SLinus Torvalds	mcr	p15, 0, r0, c15, c2, 2		@ disable clock switching
1091da177e4SLinus Torvalds	ldr	r1, [r1, #0]			@ force switch to MCLK
1101da177e4SLinus Torvalds	mcr	p15, 0, r0, c15, c8, 2		@ wait for interrupt
1111da177e4SLinus Torvalds	mov	r0, r0				@ safety
1121da177e4SLinus Torvalds	mcr	p15, 0, r0, c15, c1, 2		@ enable clock switching
1136ebbf2ceSRussell King	ret	lr
1141da177e4SLinus Torvalds
1151da177e4SLinus Torvalds/* ================================= CACHE ================================ */
1161da177e4SLinus Torvalds
1171da177e4SLinus Torvalds/*
1181da177e4SLinus Torvalds * cpu_sa1100_dcache_clean_area(addr,sz)
1191da177e4SLinus Torvalds *
1201da177e4SLinus Torvalds * Clean the specified entry of any caches such that the MMU
1211da177e4SLinus Torvalds * translation fetches will obtain correct data.
1221da177e4SLinus Torvalds *
1231da177e4SLinus Torvalds * addr: cache-unaligned virtual address
1241da177e4SLinus Torvalds */
1251da177e4SLinus Torvalds	.align	5
1261da177e4SLinus TorvaldsENTRY(cpu_sa1100_dcache_clean_area)
1271da177e4SLinus Torvalds1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
1281da177e4SLinus Torvalds	add	r0, r0, #DCACHELINESIZE
1291da177e4SLinus Torvalds	subs	r1, r1, #DCACHELINESIZE
1301da177e4SLinus Torvalds	bhi	1b
1316ebbf2ceSRussell King	ret	lr
1321da177e4SLinus Torvalds
1331da177e4SLinus Torvalds/* =============================== PageTable ============================== */
1341da177e4SLinus Torvalds
1351da177e4SLinus Torvalds/*
1361da177e4SLinus Torvalds * cpu_sa1100_switch_mm(pgd)
1371da177e4SLinus Torvalds *
1381da177e4SLinus Torvalds * Set the translation base pointer to be as described by pgd.
1391da177e4SLinus Torvalds *
1401da177e4SLinus Torvalds * pgd: new page tables
1411da177e4SLinus Torvalds */
1421da177e4SLinus Torvalds	.align	5
1431da177e4SLinus TorvaldsENTRY(cpu_sa1100_switch_mm)
144d090dddaSHyok S. Choi#ifdef CONFIG_MMU
14595f3df6bSRussell King	str	lr, [sp, #-4]!
14695f3df6bSRussell King	bl	v4wb_flush_kern_cache_all	@ clears IP
1471da177e4SLinus Torvalds	mcr	p15, 0, ip, c9, c0, 0		@ invalidate RB
1481da177e4SLinus Torvalds	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
1491da177e4SLinus Torvalds	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
15095f3df6bSRussell King	ldr	pc, [sp], #4
151d090dddaSHyok S. Choi#else
1526ebbf2ceSRussell King	ret	lr
153d090dddaSHyok S. Choi#endif
1541da177e4SLinus Torvalds
1551da177e4SLinus Torvalds/*
156ad1ae2feSRussell King * cpu_sa1100_set_pte_ext(ptep, pte, ext)
1571da177e4SLinus Torvalds *
1581da177e4SLinus Torvalds * Set a PTE and flush it out
1591da177e4SLinus Torvalds */
1601da177e4SLinus Torvalds	.align	5
161ad1ae2feSRussell KingENTRY(cpu_sa1100_set_pte_ext)
162d090dddaSHyok S. Choi#ifdef CONFIG_MMU
163da091653SRussell King	armv3_set_pte_ext wc_disable=0
1641da177e4SLinus Torvalds	mov	r0, r0
1651da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
1661da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
167d090dddaSHyok S. Choi#endif
1686ebbf2ceSRussell King	ret	lr
1691da177e4SLinus Torvalds
170f6b0fa02SRussell King.globl	cpu_sa1100_suspend_size
171de8e71caSRussell King.equ	cpu_sa1100_suspend_size, 4 * 3
172b6c7aabdSRussell King#ifdef CONFIG_ARM_CPU_SUSPEND
173f6b0fa02SRussell KingENTRY(cpu_sa1100_do_suspend)
174de8e71caSRussell King	stmfd	sp!, {r4 - r6, lr}
175f6b0fa02SRussell King	mrc	p15, 0, r4, c3, c0, 0		@ domain ID
176de8e71caSRussell King	mrc	p15, 0, r5, c13, c0, 0		@ PID
177de8e71caSRussell King	mrc	p15, 0, r6, c1, c0, 0		@ control reg
178de8e71caSRussell King	stmia	r0, {r4 - r6}			@ store cp regs
179de8e71caSRussell King	ldmfd	sp!, {r4 - r6, pc}
180f6b0fa02SRussell KingENDPROC(cpu_sa1100_do_suspend)
181f6b0fa02SRussell King
182f6b0fa02SRussell KingENTRY(cpu_sa1100_do_resume)
183de8e71caSRussell King	ldmia	r0, {r4 - r6}			@ load cp regs
1846f354e5fSRussell King	mov	ip, #0
1856f354e5fSRussell King	mcr	p15, 0, ip, c8, c7, 0		@ flush I+D TLBs
1866f354e5fSRussell King	mcr	p15, 0, ip, c7, c7, 0		@ flush I&D cache
1876f354e5fSRussell King	mcr	p15, 0, ip, c9, c0, 0		@ invalidate RB
1886f354e5fSRussell King	mcr	p15, 0, ip, c9, c0, 5		@ allow user space to use RB
189f6b0fa02SRussell King
190f6b0fa02SRussell King	mcr	p15, 0, r4, c3, c0, 0		@ domain ID
191de8e71caSRussell King	mcr	p15, 0, r1, c2, c0, 0		@ translation table base addr
192de8e71caSRussell King	mcr	p15, 0, r5, c13, c0, 0		@ PID
193de8e71caSRussell King	mov	r0, r6				@ control register
194f6b0fa02SRussell King	b	cpu_resume_mmu
195f6b0fa02SRussell KingENDPROC(cpu_sa1100_do_resume)
196f6b0fa02SRussell King#endif
197f6b0fa02SRussell King
1981da177e4SLinus Torvalds	.type	__sa1100_setup, #function
1991da177e4SLinus Torvalds__sa1100_setup:
2001da177e4SLinus Torvalds	mov	r0, #0
2011da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
2021da177e4SLinus Torvalds	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
203d090dddaSHyok S. Choi#ifdef CONFIG_MMU
2041da177e4SLinus Torvalds	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
205d090dddaSHyok S. Choi#endif
20622b19086SRussell King	adr	r5, sa1100_crval
20722b19086SRussell King	ldmia	r5, {r5, r6}
2081da177e4SLinus Torvalds	mrc	p15, 0, r0, c1, c0		@ get control register v4
2091da177e4SLinus Torvalds	bic	r0, r0, r5
21022b19086SRussell King	orr	r0, r0, r6
2116ebbf2ceSRussell King	ret	lr
2121da177e4SLinus Torvalds	.size	__sa1100_setup, . - __sa1100_setup
2131da177e4SLinus Torvalds
2141da177e4SLinus Torvalds	/*
2151da177e4SLinus Torvalds	 *  R
2161da177e4SLinus Torvalds	 * .RVI ZFRS BLDP WCAM
2171da177e4SLinus Torvalds	 * ..11 0001 ..11 1101
2181da177e4SLinus Torvalds	 *
2191da177e4SLinus Torvalds	 */
22022b19086SRussell King	.type	sa1100_crval, #object
22122b19086SRussell Kingsa1100_crval:
22222b19086SRussell King	crval	clear=0x00003f3f, mmuset=0x0000313d, ucset=0x00001130
2231da177e4SLinus Torvalds
2241da177e4SLinus Torvalds	__INITDATA
2251da177e4SLinus Torvalds
2261da177e4SLinus Torvalds/*
2271da177e4SLinus Torvalds * SA1100 and SA1110 share the same function calls
2281da177e4SLinus Torvalds */
229f58d59f6SDave Martin
230f58d59f6SDave Martin	@ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
231f58d59f6SDave Martin	define_processor_functions sa1100, dabort=v4_early_abort, pabort=legacy_pabort, suspend=1
2321da177e4SLinus Torvalds
2331da177e4SLinus Torvalds	.section ".rodata"
2341da177e4SLinus Torvalds
235f58d59f6SDave Martin	string	cpu_arch_name, "armv4"
236f58d59f6SDave Martin	string	cpu_elf_name, "v4"
237f58d59f6SDave Martin	string	cpu_sa1100_name, "StrongARM-1100"
238f58d59f6SDave Martin	string	cpu_sa1110_name, "StrongARM-1110"
2391da177e4SLinus Torvalds
2401da177e4SLinus Torvalds	.align
2411da177e4SLinus Torvalds
242790756c7SNick Desaulniers	.section ".proc.info.init", "a"
2431da177e4SLinus Torvalds
244f58d59f6SDave Martin.macro sa1100_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req
245f58d59f6SDave Martin	.type	__\name\()_proc_info,#object
246f58d59f6SDave Martin__\name\()_proc_info:
247f58d59f6SDave Martin	.long	\cpu_val
248f58d59f6SDave Martin	.long	\cpu_mask
2491da177e4SLinus Torvalds	.long   PMD_TYPE_SECT | \
2501da177e4SLinus Torvalds		PMD_SECT_BUFFERABLE | \
2511da177e4SLinus Torvalds		PMD_SECT_CACHEABLE | \
2521da177e4SLinus Torvalds		PMD_SECT_AP_WRITE | \
2531da177e4SLinus Torvalds		PMD_SECT_AP_READ
2548799ee9fSRussell King	.long   PMD_TYPE_SECT | \
2558799ee9fSRussell King		PMD_SECT_AP_WRITE | \
2568799ee9fSRussell King		PMD_SECT_AP_READ
257bf35706fSArd Biesheuvel	initfn	__sa1100_setup, __\name\()_proc_info
2581da177e4SLinus Torvalds	.long	cpu_arch_name
2591da177e4SLinus Torvalds	.long	cpu_elf_name
2601da177e4SLinus Torvalds	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
261f58d59f6SDave Martin	.long	\cpu_name
2621da177e4SLinus Torvalds	.long	sa1100_processor_functions
2631da177e4SLinus Torvalds	.long	v4wb_tlb_fns
2641da177e4SLinus Torvalds	.long	v4_mc_user_fns
2651da177e4SLinus Torvalds	.long	v4wb_cache_fns
266f58d59f6SDave Martin	.size	__\name\()_proc_info, . - __\name\()_proc_info
267f58d59f6SDave Martin.endm
2681da177e4SLinus Torvalds
269f58d59f6SDave Martin	sa1100_proc_info sa1100, 0x4401a110, 0xfffffff0, cpu_sa1100_name
270f58d59f6SDave Martin	sa1100_proc_info sa1110, 0x6901b110, 0xfffffff0, cpu_sa1110_name
271