@board/samsung/smdkc100/lowlevel_init.S
#include <config.h>
#include <version.h>#include <asm/arch/cpu.h>#include <asm/arch/power.h>/*
* Register usages: * * r5 has zero always */_TEXT_BASE:
.word TEXT_BASE.globl lowlevel_init
lowlevel_init: mov r9, lr/* r5 has always zero */
mov r5, #0ldr r8, =S5PC100_GPIO_BASE
/* Disable Watchdog */ @关看门狗
ldr r0, =S5PC100_WATCHDOG_BASE @0xEA200000 Watchdog Timer WTCON地址 orr r0, r0, #0x0 str r5, [r0] @看门狗控制器的最低位为0时,看门狗不输出复位信号@向看门狗控制寄存器写入0,关闭看门狗。否则在U-Boot启动过程中,CPU将不断重启
#ifndef CONFIG_ONENAND_IPL
/* setting SRAM */ ldr r0, =S5PC100_SROMC_BASE ldr r1, =0x9 str r1, [r0]#endif/* S5PC100 has 3 groups of interrupt sources */
ldr r0, =S5PC100_VIC0_BASE @0xE4000000 ldr r1, =S5PC100_VIC1_BASE @0xE4100000 ldr r2, =S5PC100_VIC2_BASE @0xE4200000/* Disable all interrupts (VIC0, VIC1 and VIC2) */
mvn r3, #0x0 str r3, [r0, #0x14] @INTENCLEAR Interrupt Enable Clear Register中断使能清除寄存器 str r3, [r1, #0x14] @INTENCLEAR str r3, [r2, #0x14] @INTENCLEAR#ifndef CONFIG_ONENAND_IPL
/* Set all interrupts as IRQ */ str r5, [r0, #0xc] @INTSELECT Interrupt Select Register中断选择寄存器 str r5, [r1, #0xc] @INTSELECT str r5, [r2, #0xc] @INTSELECT/* Pending Interrupt Clear */
str r5, [r0, #0xf00] @INTADDRESS Vector Address Register向量地址寄存器 str r5, [r1, #0xf00] @INTADDRESS str r5, [r2, #0xf00] @INTADDRESS#endif#ifndef CONFIG_ONENAND_IPL
/* for UART */ bl uart_asm_init/* for TZPC */
bl tzpc_asm_init#endif#ifdef CONFIG_ONENAND_IPL
/* init system clock */ bl system_clock_initbl mem_ctrl_asm_init
/* Wakeup support. Don't know if it's going to be used, untested. */
ldr r0, =S5PC100_RST_STAT ldr r1, [r0] bic r1, r1, #0xfffffff7 cmp r1, #0x8 beq wakeup_reset#endif1:
mov lr, r9 mov pc, lr#ifdef CONFIG_ONENAND_IPL
wakeup_reset:/* Clear wakeup status register */
ldr r0, =S5PC100_WAKEUP_STAT ldr r1, [r0] str r1, [r0]/* Load return address and jump to kernel */
ldr r0, =S5PC100_INFORM0/* r1 = physical address of s5pc100_cpu_resume function */
ldr r1, [r0]/* Jump to kernel (sleep.S) */
mov pc, r1 nop nop @NOP指令为单周期指令,延时很短@nop指令的作用:
1)就是通过nop指令的填充(nop指令一个字节),使指令按字对齐,从而减少取指令时的内存访问次数。(一般用来内存地址偶数对齐,比如有一条指令,占3字节,这时候使用nop指令,cpu 就可以从第四个字节处读取指令了。)2)通过nop指令产生一定的延迟,但是对于快速的CPU来说效果不明显,可以使用rep前缀,多延迟几个时钟;-->具体应该说是占用了3个时钟脉冲! 3)i/o传输时,也会用一下 nop,等待缓冲区清空,总线恢复; 4)清除由上一个算术逻辑指令设置的flag位; #endif/*
* system_clock_init: Initialize core clock and bus clock. * void system_clock_init(void) */system_clock_init: ldr r8, =S5PC1XX_CLOCK_BASE @ 0xE0100000/* Set Clock divider */ 设置时钟分频值
ldr r1, =0x00011110 str r1, [r8, #0x304] @Set clock divider ratio 1 (Main D1 domain) ldr r1, =0x1 str r1, [r8, #0x308] @Set clock divider ratio 2 (Connectivity) ldr r1, =0x00011301 str r1, [r8, #0x300] @Set clock divider ratio 0 (Main D0 domain)/* Set Lock Time */
ldr r1, =0xe10 @ Locktime : 0xe10 = 3600 str r1, [r8, #0x000] @ APLL_LOCK Control PLL masking period for APLL str r1, [r8, #0x004] @ MPLL_LOCK str r1, [r8, #0x008] @ EPLL_LOCK str r1, [r8, #0x00C] @ HPLL_LOCK/* APLL_CON */
ldr r1, =0x81bc0400 @ SDIV 0, PDIV 4, MDIV 444 (1332MHz)@FOUT = MDIV X FIN / (PDIV X 2SDIV)
@FOUT = 444 * 12MHz / 4 = 1332MHz
/*
The output frequency is calculated by the following equation:
FOUT = MDIV X FIN / (PDIV X 2SDIV)where, MDIV, PDIV, SDIV for APLL and MPLL must meet the following conditions :PDIV: 1 ≤ PDIV ≤ 63MDIV: 64 ≤ MDIV ≤ 1023SDIV: 0 ≤ SDIV ≤ 5Fref (=FIN / PDIV): 3MHz ≤ Fref ≤ 6MHzFVCO (=MDIV X FIN / PDIV): 1000MHz ≤ FVCO ≤ 2000MHzFOUT: 50MHz ≤ FVCO ≤ 2000MHz*/
str r1, [r8, #0x100] /* MPLL_CON */ ldr r1, =0x80590201 @ SDIV 1, PDIV 2, MDIV 89 (267MHz) str r1, [r8, #0x104] /* EPLL_CON */ ldr r1, =0x80870303 @ SDIV 3, PDIV 3, MDIV 135 (67.5MHz) str r1, [r8, #0x108] /* HPLL_CON */ ldr r1, =0x80600603 str r1, [r8, #0x10C]/* Set Source Clock */
ldr r1, =0x1111 @ A, M, E, HPLL Muxing str r1, [r8, #0x200] @ CLK_SRC0ldr r1, =0x1000001 @ Uart Clock & CLK48M Muxing
str r1, [r8, #0x204] @ CLK_SRC1ldr r1, =0x9000 @ ARMCLK/4
str r1, [r8, #0x400] @ CLK_OUT/* wait at least 200us to stablize all clock */
mov r2, #0x100001: subs r2, r2, #1 bne 1bmov pc, lr
#ifndef CONFIG_ONENAND_IPL
/* * uart_asm_init: Initialize UART's pins */uart_asm_init: mov r0, r8 ldr r1, =0x22222222 str r1, [r0, #0x0] @ GPA0_CON 0xE030_0000 配置UART_0/UART_1 ldr r1, =0x00022222 str r1, [r0, #0x20] @ GPA1_CON 配置UART_2/UART_3/UARTCLKmov pc, lr
/*
* tzpc_asm_init: Initialize TZPC */tzpc_asm_init: ldr r0, =0xE3800000 @TZPC0 SECURE RAM REGION SIZE REGISTER mov r1, #0x0 str r1, [r0] mov r1, #0xff str r1, [r0, #0x804] str r1, [r0, #0x810]ldr r0, =0xE2800000 @TZPC1
str r1, [r0, #0x804] str r1, [r0, #0x810] str r1, [r0, #0x81C]ldr r0, =0xE2900000 @TZPC2
str r1, [r0, #0x804] str r1, [r0, #0x810]mov pc, lr
#endif