1/* 2 * Copyright (C) 2012-2015 Masahiro Yamada <yamada.masahiro@socionext.com> 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7#include <config.h> 8#include <linux/linkage.h> 9#include <linux/sizes.h> 10#include <asm/system.h> 11 12#include "ssc-regs.h" 13 14ENTRY(lowlevel_init) 15 mov r8, lr @ persevere link reg across call 16 17 /* 18 * The UniPhier Boot ROM loads SPL code to the L2 cache. 19 * But CPUs can only do instruction fetch now because start.S has 20 * cleared C and M bits. 21 * First we need to turn on MMU and Dcache again to get back 22 * data access to L2. 23 */ 24 mrc p15, 0, r0, c1, c0, 0 @ SCTLR (System Control Register) 25 orr r0, r0, #(CR_C | CR_M) @ enable MMU and Dcache 26 mcr p15, 0, r0, c1, c0, 0 27 28#ifdef CONFIG_DEBUG_LL 29 bl debug_ll_init 30#endif 31 32 bl setup_init_ram @ RAM area for stack and page talbe 33 34 /* 35 * Now we are using the page table embedded in the Boot ROM. 36 * It is not handy since it is not a straight mapped table for sLD3. 37 * Also, the access to the external bus is prohibited. What we need 38 * to do next is to create a page table and switch over to it. 39 */ 40 bl create_page_table 41 bl v7_flush_dcache_all 42 43 /* Disable MMU and Dcache before switching Page Table */ 44 mrc p15, 0, r0, c1, c0, 0 @ SCTLR (System Control Register) 45 bic r0, r0, #(CR_C | CR_M) @ disable MMU and Dcache 46 mcr p15, 0, r0, c1, c0, 0 47 48 bl enable_mmu 49 50 mov lr, r8 @ restore link 51 mov pc, lr @ back to my caller 52ENDPROC(lowlevel_init) 53 54ENTRY(enable_mmu) 55 mrc p15, 0, r0, c2, c0, 2 @ TTBCR (Translation Table Base Control Register) 56 bic r0, r0, #0x37 57 orr r0, r0, #0x20 @ disable TTBR1 58 mcr p15, 0, r0, c2, c0, 2 59 60 orr r0, r12, #0x8 @ Outer Cacheability for table walks: WBWA 61 mcr p15, 0, r0, c2, c0, 0 @ TTBR0 62 63 mov r0, #0 64 mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs 65 66 mov r0, #-1 @ manager for all domains (No permission check) 67 mcr p15, 0, r0, c3, c0, 0 @ DACR (Domain Access Control Register) 68 69 dsb 70 isb 71 /* 72 * MMU on: 73 * TLBs was already invalidated in "../start.S" 74 * So, we don't need to invalidate it here. 75 */ 76 mrc p15, 0, r0, c1, c0, 0 @ SCTLR (System Control Register) 77 orr r0, r0, #(CR_C | CR_M) @ MMU and Dcache enable 78 mcr p15, 0, r0, c1, c0, 0 79 80 mov pc, lr 81ENDPROC(enable_mmu) 82 83/* 84 * For PH1-Pro4 or older SoCs, the size of WAY is 32KB. 85 * It is large enough for tmp RAM. 86 */ 87#define BOOT_RAM_SIZE (SZ_32K) 88#define BOOT_RAM_BASE ((CONFIG_SPL_STACK) - (BOOT_RAM_SIZE)) 89#define BOOT_WAY_BITS (0x00000100) /* way 8 */ 90 91ENTRY(setup_init_ram) 92 /* 93 * Touch to zero for the boot way 94 */ 950: 96 /* 97 * set SSCOQM, SSCOQAD, SSCOQSZ, SSCOQWN in this order 98 */ 99 ldr r0, = 0x00408006 @ touch to zero with address range 100 ldr r1, = SSCOQM 101 str r0, [r1] 102 ldr r0, = BOOT_RAM_BASE 103 ldr r1, = SSCOQAD 104 str r0, [r1] 105 ldr r0, = BOOT_RAM_SIZE 106 ldr r1, = SSCOQSZ 107 str r0, [r1] 108 ldr r0, = BOOT_WAY_BITS 109 ldr r1, = SSCOQWN 110 str r0, [r1] 111 ldr r1, = SSCOPPQSEF 112 ldr r0, [r1] 113 cmp r0, #0 @ check if the command is successfully set 114 bne 0b @ try again if an error occurs 115 116 ldr r1, = SSCOLPQS 1171: 118 ldr r0, [r1] 119 cmp r0, #0x4 120 bne 1b @ wait until the operation is completed 121 str r0, [r1] @ clear the complete notification flag 122 123 mov pc, lr 124ENDPROC(setup_init_ram) 125 126#define DEVICE 0x00002002 /* Non-shareable Device */ 127#define NORMAL 0x0000000e /* Normal Memory Write-Back, No Write-Allocate */ 128 129ENTRY(create_page_table) 130 ldr r0, = DEVICE 131 ldr r1, = BOOT_RAM_BASE 132 mov r12, r1 @ r12 is preserved during D-cache flush 1330: str r0, [r1], #4 @ specify all the sections as Device 134 adds r0, r0, #0x00100000 135 bcc 0b 136 137 ldr r0, = NORMAL 138 str r0, [r12] @ mark the first section as Normal 139 add r0, r0, #0x00100000 140 str r0, [r12, #4] @ mark the second section as Normal 141 mov pc, lr 142ENDPROC(create_page_table) 143 144/* We don't use Thumb instructions for now */ 145#define ARM(x...) x 146#define THUMB(x...) 147 148/* 149 * v7_flush_dcache_all() 150 * 151 * Flush the whole D-cache. 152 * 153 * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode) 154 * 155 * - mm - mm_struct describing address space 156 * 157 * Note: copied from arch/arm/mm/cache-v7.S of Linux 4.4 158 */ 159ENTRY(v7_flush_dcache_all) 160 dmb @ ensure ordering with previous memory accesses 161 mrc p15, 1, r0, c0, c0, 1 @ read clidr 162 mov r3, r0, lsr #23 @ move LoC into position 163 ands r3, r3, #7 << 1 @ extract LoC*2 from clidr 164 beq finished @ if loc is 0, then no need to clean 165start_flush_levels: 166 mov r10, #0 @ start clean at cache level 0 167flush_levels: 168 add r2, r10, r10, lsr #1 @ work out 3x current cache level 169 mov r1, r0, lsr r2 @ extract cache type bits from clidr 170 and r1, r1, #7 @ mask of the bits for current cache only 171 cmp r1, #2 @ see what cache we have at this level 172 blt skip @ skip if no cache, or just i-cache 173 mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr 174 isb @ isb to sych the new cssr&csidr 175 mrc p15, 1, r1, c0, c0, 0 @ read the new csidr 176 and r2, r1, #7 @ extract the length of the cache lines 177 add r2, r2, #4 @ add 4 (line length offset) 178 movw r4, #0x3ff 179 ands r4, r4, r1, lsr #3 @ find maximum number on the way size 180 clz r5, r4 @ find bit position of way size increment 181 movw r7, #0x7fff 182 ands r7, r7, r1, lsr #13 @ extract max number of the index size 183loop1: 184 mov r9, r7 @ create working copy of max index 185loop2: 186 ARM( orr r11, r10, r4, lsl r5 ) @ factor way and cache number into r11 187 THUMB( lsl r6, r4, r5 ) 188 THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11 189 ARM( orr r11, r11, r9, lsl r2 ) @ factor index number into r11 190 THUMB( lsl r6, r9, r2 ) 191 THUMB( orr r11, r11, r6 ) @ factor index number into r11 192 mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way 193 subs r9, r9, #1 @ decrement the index 194 bge loop2 195 subs r4, r4, #1 @ decrement the way 196 bge loop1 197skip: 198 add r10, r10, #2 @ increment cache number 199 cmp r3, r10 200 bgt flush_levels 201finished: 202 mov r10, #0 @ swith back to cache level 0 203 mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr 204 dsb st 205 isb 206 mov pc, lr 207ENDPROC(v7_flush_dcache_all) 208