/* * Memory Setup stuff - taken from blob memsetup.S * * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) * * Modified for the Samsung SMDK2410 by * (C) Copyright 2002 * David Mueller, ELSOFT AG, * * (C) Copyright 2008 * Guennadi Liakhovetki, DENX Software Engineering, * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #include #include #include #ifdef CONFIG_SERIAL1 #define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART0_OFFSET) #elif defined(CONFIG_SERIAL2) #define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART1_OFFSET) #else #define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART2_OFFSET) #endif _TEXT_BASE: .word TEXT_BASE .globl lowlevel_init lowlevel_init: mov r12, lr /* LED on only #8 */ ldr r0, =ELFIN_GPIO_BASE ldr r1, =0x55540000 str r1, [r0, #GPNCON_OFFSET] ldr r1, =0x55555555 str r1, [r0, #GPNPUD_OFFSET] ldr r1, =0xf000 str r1, [r0, #GPNDAT_OFFSET] /* Disable Watchdog */ ldr r0, =0x7e000000 @0x7e004000 orr r0, r0, #0x4000 mov r1, #0 str r1, [r0] /* External interrupt pending clear */ ldr r0, =(ELFIN_GPIO_BASE+EINTPEND_OFFSET) /*EINTPEND*/ ldr r1, [r0] str r1, [r0] ldr r0, =ELFIN_VIC0_BASE_ADDR @0x71200000 ldr r1, =ELFIN_VIC1_BASE_ADDR @0x71300000 /* Disable all interrupts (VIC0 and VIC1) */ mvn r3, #0x0 str r3, [r0, #oINTMSK] str r3, [r1, #oINTMSK] /* Set all interrupts as IRQ */ mov r3, #0x0 str r3, [r0, #oINTMOD] str r3, [r1, #oINTMOD] /* Pending Interrupt Clear */ mov r3, #0x0 str r3, [r0, #oVECTADDR] str r3, [r1, #oVECTADDR] /* init system clock */ bl system_clock_init #ifndef CONFIG_NAND_SPL /* for UART */ bl uart_asm_init #endif #ifdef CONFIG_BOOT_NAND /* simple init for NAND */ bl nand_asm_init #endif /* Memory subsystem address 0x7e00f120 */ ldr r0, =ELFIN_MEM_SYS_CFG /* Xm0CSn2 = NFCON CS0, Xm0CSn3 = NFCON CS1 */ mov r1, #S3C64XX_MEM_SYS_CFG_NAND str r1, [r0] bl mem_ctrl_asm_init /* Wakeup support. Don't know if it's going to be used, untested. */ ldr r0, =(ELFIN_CLOCK_POWER_BASE + RST_STAT_OFFSET) ldr r1, [r0] bic r1, r1, #0xfffffff7 cmp r1, #0x8 beq wakeup_reset 1: mov lr, r12 mov pc, lr wakeup_reset: /* Clear wakeup status register */ ldr r0, =(ELFIN_CLOCK_POWER_BASE + WAKEUP_STAT_OFFSET) ldr r1, [r0] str r1, [r0] /* LED test */ ldr r0, =ELFIN_GPIO_BASE ldr r1, =0x3000 str r1, [r0, #GPNDAT_OFFSET] /* Load return address and jump to kernel */ ldr r0, =(ELFIN_CLOCK_POWER_BASE + INF_REG0_OFFSET) /* r1 = physical address of s3c6400_cpu_resume function */ ldr r1, [r0] /* Jump to kernel (sleep-s3c6400.S) */ mov pc, r1 nop nop /* * system_clock_init: Initialize core clock and bus clock. * void system_clock_init(void) */ system_clock_init: ldr r0, =ELFIN_CLOCK_POWER_BASE /* 0x7e00f000 */ #ifdef CONFIG_SYNC_MODE ldr r1, [r0, #OTHERS_OFFSET] mov r2, #0x40 orr r1, r1, r2 str r1, [r0, #OTHERS_OFFSET] nop nop nop nop nop ldr r2, =0x80 orr r1, r1, r2 str r1, [r0, #OTHERS_OFFSET] check_syncack: ldr r1, [r0, #OTHERS_OFFSET] ldr r2, =0xf00 and r1, r1, r2 cmp r1, #0xf00 bne check_syncack #else /* ASYNC Mode */ nop nop nop nop nop /* * This was unconditional in original Samsung sources, but it doesn't * seem to make much sense on S3C6400. */ #ifndef CONFIG_S3C6400 ldr r1, [r0, #OTHERS_OFFSET] bic r1, r1, #0xC0 orr r1, r1, #0x40 str r1, [r0, #OTHERS_OFFSET] wait_for_async: ldr r1, [r0, #OTHERS_OFFSET] and r1, r1, #0xf00 cmp r1, #0x0 bne wait_for_async #endif ldr r1, [r0, #OTHERS_OFFSET] bic r1, r1, #0x40 str r1, [r0, #OTHERS_OFFSET] #endif mov r1, #0xff00 orr r1, r1, #0xff str r1, [r0, #APLL_LOCK_OFFSET] str r1, [r0, #MPLL_LOCK_OFFSET] /* Set Clock Divider */ ldr r1, [r0, #CLK_DIV0_OFFSET] bic r1, r1, #0x30000 bic r1, r1, #0xff00 bic r1, r1, #0xff ldr r2, =CLK_DIV_VAL orr r1, r1, r2 str r1, [r0, #CLK_DIV0_OFFSET] ldr r1, =APLL_VAL str r1, [r0, #APLL_CON_OFFSET] ldr r1, =MPLL_VAL str r1, [r0, #MPLL_CON_OFFSET] /* FOUT of EPLL is 96MHz */ ldr r1, =0x200203 str r1, [r0, #EPLL_CON0_OFFSET] ldr r1, =0x0 str r1, [r0, #EPLL_CON1_OFFSET] /* APLL, MPLL, EPLL select to Fout */ ldr r1, [r0, #CLK_SRC_OFFSET] orr r1, r1, #0x7 str r1, [r0, #CLK_SRC_OFFSET] /* wait at least 200us to stablize all clock */ mov r1, #0x10000 1: subs r1, r1, #1 bne 1b /* Synchronization for VIC port */ #if defined(CONFIG_SYNC_MODE) ldr r1, [r0, #OTHERS_OFFSET] orr r1, r1, #0x20 str r1, [r0, #OTHERS_OFFSET] #elif !defined(CONFIG_S3C6400) /* According to 661558um_S3C6400X_rev10.pdf 0x20 is reserved */ ldr r1, [r0, #OTHERS_OFFSET] bic r1, r1, #0x20 str r1, [r0, #OTHERS_OFFSET] #endif mov pc, lr #ifndef CONFIG_NAND_SPL /* * uart_asm_init: Initialize UART's pins */ uart_asm_init: /* set GPIO to enable UART */ ldr r0, =ELFIN_GPIO_BASE ldr r1, =0x220022 str r1, [r0, #GPACON_OFFSET] mov pc, lr #endif #ifdef CONFIG_BOOT_NAND /* * NAND Interface init for SMDK6400 */ nand_asm_init: ldr r0, =ELFIN_NAND_BASE ldr r1, [r0, #NFCONF_OFFSET] orr r1, r1, #0x70 orr r1, r1, #0x7700 str r1, [r0, #NFCONF_OFFSET] ldr r1, [r0, #NFCONT_OFFSET] orr r1, r1, #0x07 str r1, [r0, #NFCONT_OFFSET] mov pc, lr #endif #ifdef CONFIG_ENABLE_MMU /* * MMU Table for SMDK6400 */ /* form a first-level section entry */ .macro FL_SECTION_ENTRY base,ap,d,c,b .word (\base << 20) | (\ap << 10) | \ (\d << 5) | (1<<4) | (\c << 3) | (\b << 2) | (1<<1) .endm .section .mmudata, "a" .align 14 /* the following alignment creates the mmu table at address 0x4000. */ .globl mmu_table mmu_table: .set __base, 0 /* 1:1 mapping for debugging */ .rept 0xA00 FL_SECTION_ENTRY __base, 3, 0, 0, 0 .set __base, __base + 1 .endr /* access is not allowed. */ .rept 0xC00 - 0xA00 .word 0x00000000 .endr /* 128MB for SDRAM 0xC0000000 -> 0x50000000 */ .set __base, 0x500 .rept 0xC80 - 0xC00 FL_SECTION_ENTRY __base, 3, 0, 1, 1 .set __base, __base + 1 .endr /* access is not allowed. */ .rept 0x1000 - 0xc80 .word 0x00000000 .endr #endif