diff options
author | Alexey Galakhov <agalakhov@gmail.com> | 2012-05-18 15:43:26 +0600 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-05-21 21:58:26 +0200 |
commit | 7a05b45b4b4890d72841d8afa9ed0ca3f775577f (patch) | |
tree | e6bd92083dbf89d8e195daed087a9e926f955d68 /arch/arm/mach-samsung/lowlevel-s3c24x0.S | |
parent | 5ef3ecd922e459b50b7a2e4c61d8b876ee1c146a (diff) | |
download | barebox-7a05b45b4b4890d72841d8afa9ed0ca3f775577f.tar.gz barebox-7a05b45b4b4890d72841d8afa9ed0ca3f775577f.tar.xz |
Split S3C generic and S3C24xx specific code
Signed-off-by: Alexey Galakhov <agalakhov@gmail.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/mach-samsung/lowlevel-s3c24x0.S')
-rw-r--r-- | arch/arm/mach-samsung/lowlevel-s3c24x0.S | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/arch/arm/mach-samsung/lowlevel-s3c24x0.S b/arch/arm/mach-samsung/lowlevel-s3c24x0.S new file mode 100644 index 0000000000..e9471a5a17 --- /dev/null +++ b/arch/arm/mach-samsung/lowlevel-s3c24x0.S @@ -0,0 +1,317 @@ +/* + * (C) Copyright 2009 + * Juergen Beisert <kernel@pengutronix.de> + * + * 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 <config.h> +#include <mach/s3c-iomap.h> + + .section ".text_bare_init.s3c24x0_disable_wd","ax" + +/* + * Disable the watchdog, else it continues to bark + */ +.globl s3c24x0_disable_wd +s3c24x0_disable_wd: + + ldr r0, =S3C_WATCHDOG_BASE + mov r1, #0x0 + str r1, [r0] + mov pc, lr + +/** +@page dev_s3c24xx_wd_handling Watchdog handling + +The watchdog must be disabled very early, because if it resets the system +it is still active and will continue to reset the system. So, call this +routine very early in your board_init_lowlevel routine. +*/ + +/* + * S3C2410 PLL configuration + * ------------------------- + * + * Basic frequency calculation + * + * m * REFclk s = SDIV + * PLLclk = ------------ p = PDIV + 2 + * p * 2^s m = MDIV + 8 + * + * After reset the PLL of the s3c2410 processor uses: + * + * MPLL UPLL + * MDIV 0x5c 0x28 + * PDIV 0x08 0x08 + * SDIV 0x0 0x0 + * + * 100 * 12MHz 1200MHz + * MPLLclk = ------------- = -------- = 120MHz + * 10 * 2^0 10 + * + * 48 * 12MHz 576MHz + * UPLLclk = ------------- = -------- = 57,6MHz + * 10 * 2^0 10 + * + * Note: Do not use "r10" here in this code + */ + +#ifdef CONFIG_S3C_PLL_INIT + + .section ".text_bare_init.s3c24x0_pll_init","ax" + +.globl s3c24x0_pll_init +s3c24x0_pll_init: + + mov r0, #S3C_CLOCK_POWER_BASE + + /* configure internal clock ratio */ + mov r1, #BOARD_SPECIFIC_CLKDIVN + str r1, [r0, #20] + + /* enable all devices on this chip */ + mov r1, #0xFFFFFFF0 + str r1, [r0, #12] + + /* ??????? */ +#ifdef CONFIG_CPU_S3C2440 + mov r1, #0xFFFFFFFF +#endif +#ifdef CONFIG_CPU_S3C2410 + mov r1, #0x00FFFFFF +#endif + str r1, [r0, #0] + +#ifdef CONFIG_CPU_S3C2440 + /* + * Most of the time HDIVN is not 0, so we must use the + * asynchronous bus mode (refer datasheet "Clock and Power Management") + */ + mrc p15, 0, r1, c1, c0, 0 + orr r1, r1, #0xc0000000 + mcr p15, 0, r1, c1, c0, 0 +#endif + + /* configure UPLL */ + ldr r1, =BOARD_SPECIFIC_UPLL + str r1, [r0, #8] + + nop + nop + nop + nop + nop + nop + nop + nop + + /* configure MPLL */ + ldr r1, =BOARD_SPECIFIC_MPLL + str r1, [r0, #4] + + nop + nop + nop + nop + nop + nop + nop + nop + + mov pc, lr + +#endif + +/** +@page dev_s3c24xx_pll_handling PLL clock handling + +To control the speed of your machine the PLLs must be reconfigured after reset. + +For example the S3C2410 CPU wakes up after reset at 120MHz main PLL speed, +shared with all other system on chip components. Most of the time this +configuration is to slow for the CPU and to fast for the other components. + +PLL reprogramming can be done in the machine specific manner very early when +the CONFIG_S3C_PLL_INIT and CONFIG_MACH_HAS_LOWLEVEL_INIT symbols are +defined. The board must provide a board_init_lowlevel() assembler function in +this case and calling the s3c24x0_pll_init() assembler function. + +If the s3c24x0_pll_init() is called a few further symbols must be defined to +setup the correct values for the machine. + +Define in the machine specific config.h the following symbols: + +- S3C24XX_CLOCK_REFERENCE with the frequency in Hz of your reference crystal. +- BOARD_SPECIFIC_CLKDIVN with the value for the main clock ratio register (CLKDIVN) +- BOARD_SPECIFIC_MPLL with the value for the main PLL setup register +- BOARD_SPECIFIC_UPLL with the value for the USB PLL setup register + +@note Valid values for the PLL settings can be found in the CPU manual. + +@par Background: PLL frequency calculation for the S3C2410 CPU (both PLLs) and S3C2440 (UPLL only) + +@f[ + f_{PLL} = \frac{m * f_{Ref}}{p * 2^s} +@f] + +With m = MDIV + 8, p = PDIV + 2 and s = SDIV. + +@par Background: PLL frequency calculation for the S3C2440 CPU (MPLL only) + +@f[ + f_{PLL} = \frac{2 * m * f_{Ref}}{p * 2^s} +@f] + +With m = MDIV + 8, p = PDIV + 2 and s = SDIV. + +@note This routine can be used for the S3C2410 and the S3C2440 CPU. + +*/ + +/* ----------------------------------------------------------------------- */ + +#ifdef CONFIG_S3C_SDRAM_INIT + + .section ".text_bare_init.s3c24x0_sdram_init","ax" + + .globl s3c24x0_sdram_init +s3c24x0_sdram_init: + + adr r0, SDRAMDATA /* get the current relative address of the table */ + mov r1, #S3C_MEMCTL_BASE + mov r2, #6 /* we *know* it contains 6 entries */ + + ldr r3, [r0], #4 /* write BSWCON first */ + str r3, [r1], #0x1c /* post add register offset for bank6 */ +/* + * Initializing the SDRAM controller is very simple: + * Just write some useful values into the SDRAM controller. + */ +0: ldr r3, [r0], #4 + str r3, [r1], #4 + subs r2, r2, #1 + bne 0b + + mov pc, lr + +SDRAMDATA: + .word BOARD_SPECIFIC_BWSCON + .word BOARD_SPECIFIC_BANKCON6 + .word BOARD_SPECIFIC_BANKCON7 + .word BOARD_SPECIFIC_REFRESH + .word BOARD_SPECIFIC_BANKSIZE + .word BOARD_SPECIFIC_MRSRB6 + .word BOARD_SPECIFIC_MRSRB7 + +#endif + +/** +@page dev_s3c24xx_sdram_handling SDRAM controller initialisation + +The SDRAM controller is very simple and its initialisation requires only a +few steps. barebox provides a generic routine to do this step. + +Enable CONFIG_S3C_SDRAM_INIT and CONFIG_MACH_HAS_LOWLEVEL_INIT to be able +to call the generic s3c24x0_sdram_init() assembler function from within the +machine specific board_init_lowlevel() assembler function. + +To use the s3c24x0_sdram_init() assembler function a few symbols must be +defined to setup correct values for the machine. + +Define in the machine specific config.h the following list of symbols: + +- BOARD_SPECIFIC_BWSCON with the values for SDRAM banks 6 and 7 +- BOARD_SPECIFIC_BANKCON6 with the value for the BANKCON6 register +- BOARD_SPECIFIC_BANKCON7 with the value for the BANKCON7 register +- BOARD_SPECIFIC_REFRESH with the value for the REFRESH register +- BOARD_SPECIFIC_BANKSIZE with the value for the BANKSIZE register +- BOARD_SPECIFIC_MRSRB6 with the value for the MRSRB6 register +- BOARD_SPECIFIC_MRSRB7 with the value for the MRSRB7 register +*/ + +/* ----------------------------------------------------------------------- */ + +#ifdef CONFIG_S3C_NAND_BOOT + + .section ".text_bare_init.s3c24x0_nand_boot","ax" + + .globl s3c24x0_nand_boot +s3c24x0_nand_boot: +/* + * In the case of NOR boot we are running from the same address space. + * Detect this case to handle it correctly. + */ + mov r1, #S3C_MEMCTL_BASE + ldr r3, [r1] + and r3, r3, #0x6 + cmp r3, #0x0 /* check for NAND case */ + beq 2f + mov pc, lr /* NOR case: nothing to do here */ + +2: ldr sp, =TEXT_BASE /* Setup a temporary stack in SDRAM */ +/* + * We still run at a location we are not linked to. But lets still running + * from the internal SRAM, this may speed up the boot + */ + push {lr} + bl nand_boot + pop {lr} +/* + * Adjust the return address to the correct address in SDRAM + */ + ldr r1, =TEXT_BASE + add lr, lr, r1 + + mov pc, lr + +#endif + +/** +@page dev_s3c24xx_nandboot_handling Booting from NAND + +To be able to boot from NAND memory only, enable the S3C24x0 NAND driver. Also +enable CONFIG_S3C_NAND_BOOT and CONFIG_MACH_HAS_LOWLEVEL_INIT to be +able to call the s3c24x0_nand_boot() assembler routine from within the +machine specific board_init_lowlevel() assembler function. + +@note This routine assumes an already working SDRAM controller and +an initialized stack pointer. + +@note Basicly this routine runs from inside the internal SRAM. After load of +the whole barebox image from the NAND flash memory into the SDRAM it adjusts +the link register to the final SDRAM adress and returns. + +@note In the NAND boot mode, ECC is not checked. So, the first x KBytes used +by barebox should have no bit error. + +Due to the fact the code to load the whole barebox from NAND must fit into +the first 4kiB of the barebox image, the shrinked NAND driver is very +minimalistic. Setup the NAND access timing is done in a safe manner, what +means: Slowest possible values are used. If you want to increase the speed you +should define the BOARD_DEFAULT_NAND_TIMING to a valid setting into the +NFCONF register and add it to your board specific config.h. Refer S3C24x0's +datasheet for further details. The macro #CALC_NFCONF_TIMING could help to +calculate the register setting in a hardware independent manner. + +@note The regular NAND driver uses a platform data structure to define the +NAND access timings. + +@note Its still possible to boot this image from NOR memory. If this routine +detects it is running from NOR instead of the internal SRAM it skips any +loading and returns immediately. + +*/ |