u-boot-brain/arch/arm/mach-uniphier/arm32/lowlevel_init.S
Masahiro Yamada bcc51c1512 ARM: uniphier: move lowlevel debug init code after page table switch
As the sLD3 Boot ROM has a complex page table, it is difficult to
set up the debug UART with enabling it.  It will be much easier to
initialize the UART port after switching over to the straight-mapped
page table.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
2016-08-11 17:49:20 +09:00

146 lines
4.0 KiB
ArmAsm

/*
* Copyright (C) 2012-2015 Panasonic Corporation
* Copyright (C) 2015-2016 Socionext Inc.
* Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <config.h>
#include <linux/linkage.h>
#include <linux/sizes.h>
#include <asm/system.h>
ENTRY(lowlevel_init)
mov r8, lr @ persevere link reg across call
/*
* The UniPhier Boot ROM loads SPL code to the L2 cache.
* But CPUs can only do instruction fetch now because start.S has
* cleared C and M bits.
* First we need to turn on MMU and Dcache again to get back
* data access to L2.
*/
mrc p15, 0, r0, c1, c0, 0 @ SCTLR (System Control Register)
orr r0, r0, #(CR_C | CR_M) @ enable MMU and Dcache
mcr p15, 0, r0, c1, c0, 0
bl setup_init_ram @ RAM area for stack and page table
/*
* Now we are using the page table embedded in the Boot ROM.
* It is not handy since it is not a straight mapped table for sLD3.
* Also, the access to the external bus is prohibited. What we need
* to do next is to create a page table and switch over to it.
*/
bl create_page_table
bl __v7_flush_dcache_all
/* Disable MMU and Dcache before switching Page Table */
mrc p15, 0, r0, c1, c0, 0 @ SCTLR (System Control Register)
bic r0, r0, #(CR_C | CR_M) @ disable MMU and Dcache
mcr p15, 0, r0, c1, c0, 0
bl enable_mmu
#ifdef CONFIG_DEBUG_LL
bl debug_ll_init
#endif
mov lr, r8 @ restore link
mov pc, lr @ back to my caller
ENDPROC(lowlevel_init)
ENTRY(enable_mmu)
mrc p15, 0, r0, c2, c0, 2 @ TTBCR (Translation Table Base Control Register)
bic r0, r0, #0x37
orr r0, r0, #0x20 @ disable TTBR1
mcr p15, 0, r0, c2, c0, 2
orr r0, r12, #0x8 @ Outer Cacheability for table walks: WBWA
mcr p15, 0, r0, c2, c0, 0 @ TTBR0
mov r0, #0
mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
mov r0, #-1 @ manager for all domains (No permission check)
mcr p15, 0, r0, c3, c0, 0 @ DACR (Domain Access Control Register)
dsb
isb
/*
* MMU on:
* TLBs was already invalidated in "../start.S"
* So, we don't need to invalidate it here.
*/
mrc p15, 0, r0, c1, c0, 0 @ SCTLR (System Control Register)
orr r0, r0, #(CR_C | CR_M) @ MMU and Dcache enable
mcr p15, 0, r0, c1, c0, 0
mov pc, lr
ENDPROC(enable_mmu)
/*
* For PH1-Pro4 or older SoCs, the size of WAY is 32KB.
* It is large enough for tmp RAM.
*/
#define BOOT_RAM_SIZE (SZ_32K)
#define BOOT_RAM_BASE ((CONFIG_SPL_STACK) - (BOOT_RAM_SIZE))
#define BOOT_RAM_WAYS (0x00000100) @ way 8
#define SSCO_BASE 0x506c0000
#define SSCOPE 0x244
#define SSCOQM 0x248
#define SSCOQAD 0x24c
#define SSCOQSZ 0x250
#define SSCOQWN 0x258
#define SSCOPPQSEF 0x25c
#define SSCOLPQS 0x260
ENTRY(setup_init_ram)
ldr r1, = SSCO_BASE
mrc p15, 0, r0, c2, c0, 0 @ TTBR0
ldr r0, [r0, #0x400] @ entry for virtual address 0x100*****
bfc r0, #0, #20
cmp r0, #0x50000000 @ is sLD3 page table?
biceq r1, r1, #0xc0000000 @ sLD3 ROM maps 0x5******* to 0x1*******
/* Touch to zero for the boot way */
0: ldr r0, = 0x00408006 @ touch to zero with address range
str r0, [r1, #SSCOQM]
ldr r0, = BOOT_RAM_BASE
str r0, [r1, #SSCOQAD]
ldr r0, = BOOT_RAM_SIZE
str r0, [r1, #SSCOQSZ]
ldr r0, = BOOT_RAM_WAYS
str r0, [r1, #SSCOQWN]
ldr r0, [r1, #SSCOPPQSEF]
cmp r0, #0 @ check if the command is successfully set
bne 0b @ try again if an error occurs
1: ldr r0, [r1, #SSCOLPQS]
cmp r0, #0x4
bne 1b @ wait until the operation is completed
str r0, [r1, #SSCOLPQS] @ clear the complete notification flag
mov pc, lr
ENDPROC(setup_init_ram)
#define DEVICE 0x00002002 /* Non-shareable Device */
#define NORMAL 0x0000000e /* Normal Memory Write-Back, No Write-Allocate */
ENTRY(create_page_table)
ldr r0, = DEVICE
ldr r1, = BOOT_RAM_BASE
mov r12, r1 @ r12 is preserved during D-cache flush
0: str r0, [r1], #4 @ specify all the sections as Device
adds r0, r0, #0x00100000
bcc 0b
ldr r0, = NORMAL
str r0, [r12] @ mark the first section as Normal
add r0, r0, #0x00100000
str r0, [r12, #4] @ mark the second section as Normal
mov pc, lr
ENDPROC(create_page_table)