summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-samsung/lowlevel-s3c24x0.S
diff options
context:
space:
mode:
authorAlexey Galakhov <agalakhov@gmail.com>2012-05-18 15:43:26 +0600
committerSascha Hauer <s.hauer@pengutronix.de>2012-05-21 21:58:26 +0200
commit7a05b45b4b4890d72841d8afa9ed0ca3f775577f (patch)
treee6bd92083dbf89d8e195daed087a9e926f955d68 /arch/arm/mach-samsung/lowlevel-s3c24x0.S
parent5ef3ecd922e459b50b7a2e4c61d8b876ee1c146a (diff)
downloadbarebox-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.S317
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.
+
+*/