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