diff options
Diffstat (limited to 'arch/arm/boards/a9m2440')
-rw-r--r-- | arch/arm/boards/a9m2440/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/boards/a9m2440/a9m2410dev.c | 95 | ||||
-rw-r--r-- | arch/arm/boards/a9m2440/a9m2440.c | 271 | ||||
-rw-r--r-- | arch/arm/boards/a9m2440/baseboards.h | 23 | ||||
-rw-r--r-- | arch/arm/boards/a9m2440/config.h | 73 | ||||
-rw-r--r-- | arch/arm/boards/a9m2440/env/bin/_update | 34 | ||||
-rw-r--r-- | arch/arm/boards/a9m2440/env/bin/boot | 40 | ||||
-rw-r--r-- | arch/arm/boards/a9m2440/env/bin/hush_hack | 1 | ||||
-rw-r--r-- | arch/arm/boards/a9m2440/env/bin/init | 34 | ||||
-rw-r--r-- | arch/arm/boards/a9m2440/env/bin/update_kernel | 13 | ||||
-rw-r--r-- | arch/arm/boards/a9m2440/env/bin/update_root | 13 | ||||
-rw-r--r-- | arch/arm/boards/a9m2440/env/config | 26 | ||||
-rw-r--r-- | arch/arm/boards/a9m2440/lowlevel_init.S | 240 |
13 files changed, 867 insertions, 0 deletions
diff --git a/arch/arm/boards/a9m2440/Makefile b/arch/arm/boards/a9m2440/Makefile new file mode 100644 index 0000000000..779e83dc03 --- /dev/null +++ b/arch/arm/boards/a9m2440/Makefile @@ -0,0 +1,4 @@ + +obj-y += lowlevel_init.o +obj-y += a9m2440.o +obj-$(CONFIG_MACH_A9M2410DEV) += a9m2410dev.o diff --git a/arch/arm/boards/a9m2440/a9m2410dev.c b/arch/arm/boards/a9m2440/a9m2410dev.c new file mode 100644 index 0000000000..1220bd9777 --- /dev/null +++ b/arch/arm/boards/a9m2440/a9m2410dev.c @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2009 Juergen Beisert + * + * 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 + * + */ + +/** + * @file + * @brief a9m2410dev Baseboad specific initialization routines + * + */ + +#include <common.h> +#include <driver.h> +#include <init.h> +#include <asm/io.h> +#include <mach/s3c24x0-iomap.h> + +/** + * Initialize the CPU to be able to work with the a9m2410dev evaluation board + */ +int a9m2410dev_devices_init(void) +{ + unsigned int reg; + + /* ---------- configure the GPIOs ------------- */ + writel(0x007FFFFF, GPACON); + writel(0x00000000, GPCCON); + writel(0x00000000, GPCUP); + writel(0x00000000, GPDCON); + writel(0x00000000, GPDUP); + writel(0xAAAAAAAA, GPECON); + writel(0x0000E03F, GPEUP); + writel(0x00000000, GPBCON); /* all inputs */ + writel(0x00000007, GPBUP); /* pullup disabled for GPB0..3 */ + writel(0x00009000, GPFCON); /* GPF7 CLK_INT#, GPF6 Debug-LED */ + writel(0x000000FF, GPFUP); + writel(readl(GPGDAT) | 0x1010, GPGDAT); /* switch off IDLE_SW#, switch off LCD backlight */ + writel(0x0100A93A, GPGCON); /* switch on USB device */ + writel(0x0000F000, GPGUP); + writel(0x0029FAAA, GPHCON); + + writel((1 << 12) | (0 << 11), GPJDAT); + writel(0x0016aaaa, GPJCON); + writel(~((0<<12)| (1<<11)), GPJUP); + + writel((0 << 12) | (0 << 11), GPJDAT); + writel(0x0016aaaa, GPJCON); + writel(0x00001fff, GPJUP); + + writel(0x00000000, DSC0); + writel(0x00000000, DSC1); + + /* + * USB port1 normal, USB port0 normal, USB1 pads for device + * PCLK output on CLKOUT0, UPLL CLK output on CLKOUT1, + */ + writel((readl(MISCCR) & ~0xFFFF) | 0x0140, MISCCR); + + /* ----------- configure the access to the outer space ---------- */ + reg = readl(BWSCON); + + /* CS#1 to access the network controller */ + reg &= ~0xf0; + reg |= 0xe0; + writel(0x1350, BANKCON1); + + /* CS#2 to the dual 16550 UART */ + reg &= ~0xf00; + reg |= 0x400; + writel(0x0d50, BANKCON2); + + writel(reg, BWSCON); + + /* release the reset signal to the network and UART device */ + reg = readl(MISCCR); + reg |= 0x10000; + writel(reg, MISCCR); + + return 0; +} diff --git a/arch/arm/boards/a9m2440/a9m2440.c b/arch/arm/boards/a9m2440/a9m2440.c new file mode 100644 index 0000000000..2567f5ed13 --- /dev/null +++ b/arch/arm/boards/a9m2440/a9m2440.c @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2009 Juergen Beisert, Pengutronix + * + * 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 + * + */ + +/** + * @file + * @brief a9m2440 Specific Board Initialization routines + * + */ + +#include <common.h> +#include <driver.h> +#include <init.h> +#include <asm/armlinux.h> +#include <asm/mach-types.h> +#include <partition.h> +#include <nand.h> +#include <asm/io.h> +#include <mach/s3c24x0-iomap.h> +#include <mach/s3c24x0-nand.h> +#include <mach/s3c24xx-generic.h> + +#include "baseboards.h" + +static struct memory_platform_data ram_pdata = { + .name = "ram0", + .flags = DEVFS_RDWR, +}; + +static struct device_d sdram_dev = { + .name = "mem", + .map_base = CS6_BASE, + .platform_data = &ram_pdata, +}; + +static struct s3c24x0_nand_platform_data nand_info = { + .nand_timing = CALC_NFCONF_TIMING(A9M2440_TACLS, A9M2440_TWRPH0, A9M2440_TWRPH1) +}; + +static struct device_d nand_dev = { + .name = "s3c24x0_nand", + .map_base = S3C24X0_NAND_BASE, + .platform_data = &nand_info, +}; + +/* + * cs8900 network controller onboard + * Connected to CS line 5 + A24 and interrupt line EINT9, + * data width is 16 bit + */ +static struct device_d network_dev = { + .name = "cs8900", + .map_base = CS5_BASE + (1 << 24) + 0x300, + .size = 16, +}; + +static int a9m2440_check_for_ram(uint32_t addr) +{ + uint32_t tmp1, tmp2; + int rc = 0; + + tmp1 = readl(addr); + tmp2 = readl(addr + sizeof(uint32_t)); + + writel(0xaaaaaaaa, addr); + writel(0x55555555, addr + sizeof(uint32_t)); + if ((readl(addr) != 0xaaaaaaaa) || (readl(addr + sizeof(uint32_t)) != 0x55555555)) + rc = 1; /* seems no RAM */ + + writel(0x55555555, addr); + writel(0xaaaaaaaa, addr + sizeof(uint32_t)); + if ((readl(addr) != 0x55555555) || (readl(addr + sizeof(uint32_t)) != 0xaaaaaaaa)) + rc = 1; /* seems no RAM */ + + writel(tmp1, addr); + writel(tmp2, addr + sizeof(uint32_t)); + + return rc; +} + +static void a9m2440_disable_second_sdram_bank(void) +{ + writel(readl(BANKCON7) & ~(0x3 << 15),BANKCON7); + writel(readl(MISCCR) | (1 << 18), MISCCR); /* disable clock */ +} + +static int a9m2440_devices_init(void) +{ + uint32_t reg; + + /* + * The special SDRAM setup code for this machine will always enable + * both SDRAM banks. But the second SDRAM device may not exists! + * So we must check here, if the second bank is populated to get the + * correct RAM size. + */ + switch (readl(BANKSIZE) & 0x7) { + case 0: + if (a9m2440_check_for_ram(S3C24X0_SDRAM_BASE + 32 * 1024 * 1024)) + a9m2440_disable_second_sdram_bank(); + break; + case 1: + if (a9m2440_check_for_ram(S3C24X0_SDRAM_BASE + 64 * 1024 * 1024)) + a9m2440_disable_second_sdram_bank(); + break; + case 2: + if (a9m2440_check_for_ram(S3C24X0_SDRAM_BASE + 128 * 1024 * 1024)) + a9m2440_disable_second_sdram_bank(); + break; + case 4: + case 5: + case 6: /* not supported on this machine */ + break; + default: + if (a9m2440_check_for_ram(S3C24X0_SDRAM_BASE + 16 * 1024 * 1024)) + a9m2440_disable_second_sdram_bank(); + break; + } + + sdram_dev.size = s3c24x0_get_memory_size(); + + /* ----------- configure the access to the outer space ---------- */ + reg = readl(BWSCON); + + /* CS#5 to access the network controller */ + reg &= ~0x00f00000; + reg |= 0x00d00000; /* 16 bit */ + writel(0x1f4c, BANKCON5); + + writel(reg, BWSCON); + +#ifdef CONFIG_MACH_A9M2410DEV + a9m2410dev_devices_init(); +#endif + + /* release the reset signal to external devices */ + reg = readl(MISCCR); + reg |= 0x10000; + writel(reg, MISCCR); + + /* ----------- the devices the boot loader should work with -------- */ + register_device(&nand_dev); + register_device(&sdram_dev); + register_device(&network_dev); + +#ifdef CONFIG_NAND + /* ----------- add some vital partitions -------- */ + devfs_add_partition("nand0", 0x00000, 0x40000, PARTITION_FIXED, "self_raw"); + dev_add_bb_dev("self_raw", "self0"); + + devfs_add_partition("nand0", 0x40000, 0x20000, PARTITION_FIXED, "env_raw"); + dev_add_bb_dev("env_raw", "env0"); +#endif + armlinux_add_dram(&sdram_dev); + armlinux_set_bootparams((void *)sdram_dev.map_base + 0x100); + armlinux_set_architecture(MACH_TYPE_A9M2440); + + return 0; +} + +device_initcall(a9m2440_devices_init); + +#ifdef CONFIG_S3C24XX_NAND_BOOT +void __bare_init nand_boot(void) +{ + s3c24x0_nand_load_image((void *)TEXT_BASE, 256 * 1024, 0, 512); +} +#endif + +static struct device_d a9m2440_serial_device = { + .name = "s3c24x0_serial", + .map_base = UART1_BASE, + .size = UART1_SIZE, +}; + +static int a9m2440_console_init(void) +{ + register_device(&a9m2440_serial_device); + return 0; +} + +console_initcall(a9m2440_console_init); + +/** @page a9m2440 DIGI's a9m2440 + +This CPU card is based on a Samsung S3C2440 CPU. The card is shipped with: + +- S3C2440\@400 MHz or 533 MHz (ARM920T/ARMv4T) +- 16.9344 MHz crystal reference +- SDRAM 32/64/128 MiB + - Samsung K4M563233E-EE1H (one or two devices for 32 MiB or 64 MiB) + - 2M x 32bit x 4 Banks Mobile SDRAM + - CL2\@100 MHz (CAS/RAS delay 19ns) + - 105 MHz max + - collumn address size is 9 bits + - Row cycle time: 69ns + - Samsung K4M513233C-DG75 (one or two devices for 64 MiB or 128 MiB) + - 4M x 32bit x 4 Banks Mobile SDRAM + - CL2\@100MHz (CAS/RAS delay 18ns) + - 111 MHz max + - collumn address size is 9 bits + - Row cycle time: 63ns + - 64ms refresh period (4k) + - 90 pin FBGA + - 32 bit data bits + - Extended temperature range (-25°C...85°C) +- NAND Flash 32/64/128 MiB + - Samsung KM29U512T (NAND01GW3A0AN6) + - 64 MiB 3,3V 8-bit + - ID: 0xEC, 0x76, 0x??, 0xBD + - Samsung KM29U256T + - 32 MiB 3,3V 8-bit + - ID: 0xEC, 0x75, 0x??, 0xBD + - ST Micro + - 128 MiB 3,3V 8-bit + - ID: 0x20, 0x79 + - 30ns/40ns/20ns +- I2C interface, 100 KHz and 400 KHz + - Real Time Clock + - Dallas DS1337 + - address 0x68 + - EEPROM + - ST M24LC64 + - address 0x50 + - 16bit addressing +- LCD interface +- Touch Screen interface +- Camera interface +- I2S interface +- AC97 Audio-CODEC interface +- SD card interface +- 3 serial RS232 interfaces +- Host and device USB interface, USB1.1 compliant +- Ethernet interface + - 10Mbps, Cirrus Logic, CS8900A (on the CPU card) +- SPI interface +- JTAG interface + +How to get the binary image: + +Using the default configuration: + +@code +make ARCH=arm a9m2440_defconfig +@endcode + +Build the binary image: + +@code +make ARCH=arm CROSS_COMPILE=armv4compiler +@endcode + +@note replace the armv4compiler with your ARM v4 cross compiler. + +*/ diff --git a/arch/arm/boards/a9m2440/baseboards.h b/arch/arm/boards/a9m2440/baseboards.h new file mode 100644 index 0000000000..ec80312b69 --- /dev/null +++ b/arch/arm/boards/a9m2440/baseboards.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2009 Juergen Beisert + * + * 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 + * + */ + +#ifdef CONFIG_MACH_A9M2410DEV +extern int a9m2410dev_devices_init(void); +#endif diff --git a/arch/arm/boards/a9m2440/config.h b/arch/arm/boards/a9m2440/config.h new file mode 100644 index 0000000000..43cb6ab934 --- /dev/null +++ b/arch/arm/boards/a9m2440/config.h @@ -0,0 +1,73 @@ +/** + * @file + * @brief Global defintions for the ARM S3C2440 based a9m2440 CPU card + */ +/* 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 + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/** + * The external clock reference is a 16.9344 MHz crystal + */ +#define S3C24XX_CLOCK_REFERENCE 16934400 + +/** + * Define the main clock configuration to be used in register CLKDIVN + * + * We must limit the frequency of the connected SDRAMs with the clock ratio + * setup to 1:4:8. This will result into FCLK:HCLK:PCLK = 400Mhz:100MHz:50MHz + */ +#define BOARD_SPECIFIC_CLKDIVN 0x05 + +/** + * Define the MPLL configuration to be used in register MPLLCON + * + * We want the MPLL to run at 399.65 MHz + */ +#define BOARD_SPECIFIC_MPLL ((0x6e << 12) + (3 << 4) + 1) + +/** + * Define the UPLL configuration to be used in register UPLLCON + * + * We want the UPLL to run at 47.98 MHz + */ +#define BOARD_SPECIFIC_UPLL ((0x3c << 12) + (4 << 4) + 2) + +/* + * Flash access timings + * Tacls = 0ns (but 20ns data setup time) + * Twrph0 = 25ns (write) 35ns (read) + * Twrph1 = 10ns (10ns data hold time) + * Read cycle time = 50ns + * + * Assumed HCLK is 100MHz + * Tacls = 1 (-> 20ns) + * Twrph0 = 3 (-> 40ns) + * Twrph1 = 1 (-> 20ns) + * Cycle time = 80ns + */ +#define A9M2440_TACLS 1 +#define A9M2440_TWRPH0 3 +#define A9M2440_TWRPH1 1 + +/* needed in the generic NAND boot code only */ +#ifdef CONFIG_S3C24XX_NAND_BOOT +# define BOARD_DEFAULT_NAND_TIMING CALC_NFCONF_TIMING(A9M2440_TACLS, A9M2440_TWRPH0, A9M2440_TWRPH1) +#endif + +#endif /* __CONFIG_H */ diff --git a/arch/arm/boards/a9m2440/env/bin/_update b/arch/arm/boards/a9m2440/env/bin/_update new file mode 100644 index 0000000000..b10682ece4 --- /dev/null +++ b/arch/arm/boards/a9m2440/env/bin/_update @@ -0,0 +1,34 @@ +#!/bin/sh + +if [ -z "$part" -o -z "$image" ]; then + echo "define \$part and \$image" + exit 1 +fi + +if [ ! -e "$part" ]; then + echo "Partition $part does not exist" + exit 1 +fi + +if [ $# = 1 ]; then + image=$1 +fi + +if [ x$ip = xdhcp ]; then + dhcp +fi + +ping $eth0.serverip +if [ $? -ne 0 ] ; then + echo "update aborted" + exit 1 +fi + +echo +echo "erasing partition $part" +erase $part + +echo +echo "flashing $image to $part" +echo +tftp $image $part diff --git a/arch/arm/boards/a9m2440/env/bin/boot b/arch/arm/boards/a9m2440/env/bin/boot new file mode 100644 index 0000000000..86e22cf9ff --- /dev/null +++ b/arch/arm/boards/a9m2440/env/bin/boot @@ -0,0 +1,40 @@ +#!/bin/sh + +. /env/config + +if [ x$1 = xnand ]; then + root=nand + kernel=nand +fi + +if [ x$1 = xnet ]; then + root=net + kernel=net +fi + +if [ x$root = xnand ]; then + bootargs="$bootargs root=$rootpart_nand rootfstype=jffs2" +fi +if [ x$root = xnet ]; then + bootargs="$bootargs root=/dev/nfs nfsroot=$eth0.serverip:$nfsroot,v3,tcp" + if [ x$ip = xdhcp ]; then + bootargs="$bootargs ip=dhcp" + else + bootargs="$bootargs ip=$eth0.ipaddr:$eth0.serverip:$eth0.gateway:$eth0.netmask:::" + fi +fi + +bootargs="$bootargs mtdparts=\"NAND 32MiB 3,3V 8-bit:$nand_parts\"" + +bootargs="$bootargs cs89x0_media=rj45 cs89x0_mac=$eth0.ethaddr" + +if [ x$kernel = xnet ]; then + if [ x$ip = xdhcp ]; then + dhcp + fi + tftp $uimage uImage || exit 1 + bootm uImage +else + bootm /dev/nand0.kernel.bb +fi + diff --git a/arch/arm/boards/a9m2440/env/bin/hush_hack b/arch/arm/boards/a9m2440/env/bin/hush_hack new file mode 100644 index 0000000000..5fffa92ecd --- /dev/null +++ b/arch/arm/boards/a9m2440/env/bin/hush_hack @@ -0,0 +1 @@ +nand -a /dev/nand0.* diff --git a/arch/arm/boards/a9m2440/env/bin/init b/arch/arm/boards/a9m2440/env/bin/init new file mode 100644 index 0000000000..5ae44dd455 --- /dev/null +++ b/arch/arm/boards/a9m2440/env/bin/init @@ -0,0 +1,34 @@ +#!/bin/sh + +PATH=/env/bin +export PATH + +. /env/config + +if [ -e /dev/nand0 ]; then + addpart /dev/nand0 $nand_parts + + # Uh, oh, hush first expands wildcards and then starts executing + # commands. What a bug! + source /env/bin/hush_hack +fi + +if [ -z $eth0.ethaddr ]; then + while [ -z $eth0.ethaddr ]; do + readline "no MAC address set for eth0. please enter the one found on your board: " eth0.ethaddr + done + echo -a /env/config "eth0.ethaddr=$eth0.ethaddr" +fi + +echo +echo -n "Hit any key to stop autoboot: " +timeout -a $autoboot_timeout +if [ $? != 0 ]; then + echo + echo "type update_kernel [<imagename>] to update kernel into flash" + echo "type update_root [<imagename>] to update rootfs into flash" + echo + exit +fi + +boot diff --git a/arch/arm/boards/a9m2440/env/bin/update_kernel b/arch/arm/boards/a9m2440/env/bin/update_kernel new file mode 100644 index 0000000000..c43a55785b --- /dev/null +++ b/arch/arm/boards/a9m2440/env/bin/update_kernel @@ -0,0 +1,13 @@ +#!/bin/sh + +. /env/config + +part=/dev/nand0.kernel.bb + +if [ x$1 = x ]; then + image=$uimage +else + image=$1 +fi + +. /env/bin/_update $image diff --git a/arch/arm/boards/a9m2440/env/bin/update_root b/arch/arm/boards/a9m2440/env/bin/update_root new file mode 100644 index 0000000000..46cbca5beb --- /dev/null +++ b/arch/arm/boards/a9m2440/env/bin/update_root @@ -0,0 +1,13 @@ +#!/bin/sh + +. /env/config + +part=/dev/nand0.root.bb + +if [ x$1 = x ]; then + image=$jffs2 +else + image=$1 +fi + +. /env/bin/_update $image diff --git a/arch/arm/boards/a9m2440/env/config b/arch/arm/boards/a9m2440/env/config new file mode 100644 index 0000000000..936c35f9a9 --- /dev/null +++ b/arch/arm/boards/a9m2440/env/config @@ -0,0 +1,26 @@ +#!/bin/sh + +# can be either 'net' or 'nand'' +kernel=net +root=net + +uimage=uImage-a9m2440 +jffs2=root-a9m2440.jffs2 + +autoboot_timeout=3 + +nfsroot="/nfsexport/OSELAS.BSP-Hesch-TMU-1/platform-FS_A9M2440/root" +bootargs="console=ttySAC0,38400" + +nand_parts="256k(barebox)ro,128k(bareboxenv),1536k(kernel),-(root)" +rootpart_nand="/dev/mtdblock3" + +# use 'dhcp' to do dhcp in barebox and in kernel +#ip=dhcp + +# or set your networking parameters here +eth0.ipaddr=192.168.42.32 +eth0.netmask=255.255.0.0 +eth0.gateway=192.168.23.1 +eth0.serverip=192.168.23.2 +eth0.ethaddr=00:04:f3:00:06:35 diff --git a/arch/arm/boards/a9m2440/lowlevel_init.S b/arch/arm/boards/a9m2440/lowlevel_init.S new file mode 100644 index 0000000000..4b5c596076 --- /dev/null +++ b/arch/arm/boards/a9m2440/lowlevel_init.S @@ -0,0 +1,240 @@ +/* + * + */ + +#include <config.h> +#include <mach/s3c24x0-iomap.h> + + .section ".text_bare_init.board_init_lowlevel","ax" + +/* + * To be able to setup the SDRAM interface correctly, we need some + * external information about the connected SDRAM devices. + * + * When we set GPH8, we can read at GPB: + * Bit 0..1: Memory device size -> 00=16M, 01=64M, 10=32M, 11=128M + * Bit 2: CL setting + * + * Some remarks: The CL setting seems useless. It always signals a CL3 + * requirement, but the SDRAM types I found on the cards are supporting + * CL2 @ 100 MHz. But also these SDRAM types are only support 105 MHz max. + * So, we never need CL3 because we can't run the CPU at 533 MHz (which + * implies an 133 MHz SDRAM clock). + * All devices are connected via 32 bit databus + * + * Note: I was able to check the 32 MiB and 64 MiB configuration only. I didn't + * had access to a 16 MiB nor 128 MiB config. + * + */ + +sdram_init: + /* + * Read the configuration. After reset until any GPIO port is + * configured yet, these pins show external settings, to detect + * the SDRAM size. + */ + ldr r1, =GPBDAT + ldr r4, [r1] + and r4, r4, #0x3 + + ldr r1, =S3C24X0_MEMCTL_BASE + /* configure both SDRAM areas with 32 bit data bus width */ + ldr r0, =((0x2 << 24) + (0x2 << 28)) + str r0, [r1], #0x1c /* post add register offset for bank6 */ + + /* + * With the configuration we simply need to calculate an offset into + * our table with the predefined SDRAM settings + */ + adr r0, SDRAMDATA + mov r2, #6*4 /* # of bytes per table entry */ + mul r3, r4, r2 + add r0, r0, r3 /* start address of the entry */ + + /* + * store the table entry data into the registers + */ +1: + ldr r3, [r0], #4 + str r3, [r1], #4 + subs r2, r2, #4 + bne 1b + +/* TODO: Check if the second bank is populated, and switch it off if not */ + + mov pc, lr + +/* + * we need 4 sets of memory settings per main CPU clock speed + * + * 400MHz main speed: + * - 16 MiB in the first bank, maybe 16 MiB in the second bank (untested!) + * - 32 MiB in the first bank, maybe 32 MiB in the second bank (CL=2) + * - 64 MiB in the first bank, maybe 64 MiB in the second bank (CL=2) + * - 128 MiB in the first bank, maybe 128 MiB in the second bank (untested!) + * + * Note: SDRAM clock runs at 100MHz + */ + +SDRAMDATA: +/* --------------------------- 16 MiB @ 100MHz --------------------------- */ + /* + * - MT = 11 (= sync dram type) + * - Trcd = 01 (= CL3) + * - SCAN = 00 (= 8 bit collumns) + */ + .word ((0x3 << 15) + (0x1 << 2) + (0x0)) + .word ((0x3 << 15) + (0x1 << 2) + (0x0)) + /* + * SDRAM refresh settings + * - REFEN = 1 (= refresh enabled) + * - TREFMD = 0 (= auto refresh) + * - Trp = 00 (= 2 RAS precharge clocks) + * - Tsrc = 11 (= 7 clocks -> row cycle time @100MHz 2+5=7 -> 70ns) + * - Refrsh = 2^11 + 1 - 100 * 15.6 = 2049 - 1560 = FIXME + */ + .word ((0x1 << 23) + (0x0 << 22) + (0x0 << 20) + (0x3 << 18) + 468) + /* + * SDRAM banksize + * - BURST_EN = 0 (= burst mode disabled) + * - SCKE_EN = 1 (= SDRAM SCKE enabled) + * - SCLK_EN = 1 (= clock active only during accesses) + * - BK67MAP = 010 (= 128MiB) FIXME????? + */ + .word ((0 << 7) + (1 << 5) + (1 << 4) + 2) + /* + * SDRAM mode register + * CL = 010 (= 2 clocks) + */ + .word (0x2 << 4) + .word (0x2 << 4) + +/* ------------- one or two banks with 64 MiB @ 100MHz -------------------- */ + + /* + * - MT = 11 (= sync dram type) + * - Trcd = 00 (= CL2) + * - SCAN = 01 (= 9 bit collumns) + */ + .word ((0x3 << 15) + (0x0 << 2) + (0x1)) + .word ((0x3 << 15) + (0x0 << 2) + (0x1)) + /* + * SDRAM refresh settings + * - REFEN = 1 (= refresh enabled) + * - TREFMD = 0 (= auto refresh) + * - Trp = 00 (= 2 RAS precharge clocks) + * - Tsrc = 01 (= 5 clocks -> row cycle time @100MHz 2+5=7 -> 70ns) + * - Refrsh = 2^11 + 1 - 100 * 15.6 = 2049 - 1560 = 489 + */ + .word ((0x1 << 23) + (0x0 << 22) + (0x0 << 20) + (0x1 << 18) + 489) + /* + * SDRAM banksize + * - BURST_EN = 1 (= burst mode enabled) + * - SCKE_EN = 1 (= SDRAM SCKE enabled) + * - SCLK_EN = 1 (= clock active only during accesses) + * - BK67MAP = 001 (= 64 MiB) + */ + .word ((1 << 7) + (1 << 5) + (1 << 4) + 1) + /* + * SDRAM mode register + * CL = 010 (= 2 clocks) + */ + .word (0x2 << 4) + .word (0x2 << 4) + +/* ------------- one or two banks with 32 MiB @ 100MHz -------------------- */ + + /* + * - MT = 11 (= sync dram type) + * - Trcd = 00 (= CL2) + * - SCAN = 01 (= 9 bit collumns) + */ + .word ((0x3 << 15) + (0x0 << 2) + (0x1)) + .word ((0x3 << 15) + (0x0 << 2) + (0x1)) + /* + * SDRAM refresh settings + * - REFEN = 1 (= refresh enabled) + * - TREFMD = 0 (= auto refresh) + * - Trp = 00 (= 2 RAS precharge clocks) + * - Tsrc = 01 (= 5 clocks -> row cycle time @100MHz 2+5=7 -> 70ns) + * - Refrsh = 2^11 + 1 - 100 * 15.6 = 2049 - 1560 = 489 + */ + .word ((0x1 << 23) + (0x0 << 22) + (0x0 << 20) + (0x1 << 18) + 489) + /* + * SDRAM banksize + * - BURST_EN = 1 (= burst mode enabled) + * - SCKE_EN = 1 (= SDRAM SCKE enabled) + * - SCLK_EN = 1 (= clock active only during accesses) + * - BK67MAP = 000 (= 32 MiB) + */ + .word ((1 << 7) + (1 << 5) + (1 << 4) + 0) + /* + * SDRAM mode register + * CL = 010 (= 2 clocks) + */ + .word (0x2 << 4) + .word (0x2 << 4) + +/* ------------ one or two banks with 128 MiB @ 100MHz -------------------- */ + + /* + * - MT = 11 (= sync dram type) + * - Trcd = 00 (= CL2) + * - SCAN = 01 (= 9 bit collumns) + */ + .word ((0x3 << 15) + (0x0 << 2) + (0x1)) + .word ((0x3 << 15) + (0x0 << 2) + (0x1)) + /* + * SDRAM refresh settings + * - REFEN = 1 (= refresh enabled) + * - TREFMD = 0 (= auto refresh) + * - Trp = 00 (= 2 RAS precharge clocks) + * - Tsrc = 01 (= 5 clocks -> row cycle time @100MHz 2+5=7 -> 70ns) + * - Refrsh = 2^11 + 1 - 100 * 7.5 = 2049 - FIXME = 1259 + */ + .word ((0x1 << 23) + (0x0 << 22) + (0x1 << 20) + (0x3 << 18) + 1259) + /* + * SDRAM banksize + * - BURST_EN = 0 (= burst mode disabled) + * - SCKE_EN = 1 (= SDRAM SCKE enabled) + * - SCLK_EN = 1 (= clock active only during accesses) + * - BK67MAP = 010 (= 128MiB) + */ + .word (0x32) + /* + * SDRAM mode register + * CL = 010 (= 2 clocks) + */ + .word (0x2 << 4) + .word (0x2 << 4) + +/* ------------------------------------------------------------------------ */ + +.globl board_init_lowlevel +board_init_lowlevel: + + mov r10, lr /* save the link register */ + + bl s3c24x0_disable_wd + + /* skip everything here if we are already running from SDRAM */ + cmp pc, #S3C24X0_SDRAM_BASE + blo 1f + cmp pc, #S3C24X0_SDRAM_END + bhs 1f + + mov pc, r10 + +/* we are running from NOR or NAND/SRAM memory. Do further initialisation */ +1: + bl s3c24x0_pll_init + + bl sdram_init + +#ifdef CONFIG_S3C24XX_NAND_BOOT + mov lr, r10 /* restore the link register */ +/* up to here we are running from the internal SRAM area */ + b s3c24x0_nand_boot /* does return directly to our caller into SDRAM */ +#else + mov pc, r10 +#endif |