Subject: [PATCH 07/13 v3] ARM: OMAP3: Add memory and syslib common files From: Dirk Behme <[EMAIL PROTECTED]>
Add memory and syslib common files. Signed-off-by: Dirk Behme <[EMAIL PROTECTED]> --- Changes in version v3: - Add detection and support for 128MB/256MB RAM by Mans Rullgard Changes in version v2: - Move common ARM Cortex A8 code to cpu/arm_cortexa8/ and OMAP3 SoC specific common code to cpu/arm_cortexa8/omap3 as proposed by Wolfgang. cpu/arm_cortexa8/omap3/Makefile | 2 cpu/arm_cortexa8/omap3/mem.c | 298 ++++++++++++++++++++++++++++++++++++++++ cpu/arm_cortexa8/omap3/syslib.c | 72 +++++++++ examples/Makefile | 6 4 files changed, 375 insertions(+), 3 deletions(-) Index: u-boot-arm/cpu/arm_cortexa8/omap3/mem.c =================================================================== --- /dev/null +++ u-boot-arm/cpu/arm_cortexa8/omap3/mem.c @@ -0,0 +1,298 @@ +/* + * (C) Copyright 2008 + * Texas Instruments, <www.ti.com> + * + * Author : + * Manikandan Pillai <[EMAIL PROTECTED]> + * + * Initial Code from: + * Richard Woodruff <[EMAIL PROTECTED]> + * Syed Mohammed Khasim <[EMAIL PROTECTED]> + * + * 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 <common.h> +#include <asm/io.h> +#include <asm/arch/bits.h> +#include <asm/arch/mem.h> +#include <asm/arch/sys_proto.h> +#include <command.h> + +/* Only One NAND allowed on board at a time. + * The GPMC CS Base for the same + */ +unsigned int boot_flash_base; +unsigned int boot_flash_off; +unsigned int boot_flash_sec; +unsigned int boot_flash_type; +volatile unsigned int boot_flash_env_addr; + +/* help common/env_flash.c */ +#ifdef ENV_IS_VARIABLE + +uchar(*boot_env_get_char_spec) (int index); +int (*boot_env_init) (void); +int (*boot_saveenv) (void); +void (*boot_env_relocate_spec) (void); + +/* 16 bit NAND */ +uchar env_get_char_spec(int index); +int env_init(void); +int saveenv(void); +void env_relocate_spec(void); +extern char *env_name_spec; + +#if defined(CONFIG_CMD_NAND) +u8 is_nand; +#endif + +#if defined(CONFIG_CMD_ONENAND) +u8 is_onenand; +#endif + +#endif /* ENV_IS_VARIABLE */ + +#if defined(CONFIG_CMD_NAND) +static u32 gpmc_m_nand[GPMC_MAX_REG] = { + M_NAND_GPMC_CONFIG1, + M_NAND_GPMC_CONFIG2, + M_NAND_GPMC_CONFIG3, + M_NAND_GPMC_CONFIG4, + M_NAND_GPMC_CONFIG5, + M_NAND_GPMC_CONFIG6, 0 +}; +unsigned int nand_cs_base; +#endif + +#if defined(CONFIG_CMD_ONENAND) +static u32 gpmc_onenand[GPMC_MAX_REG] = { + ONENAND_GPMC_CONFIG1, + ONENAND_GPMC_CONFIG2, + ONENAND_GPMC_CONFIG3, + ONENAND_GPMC_CONFIG4, + ONENAND_GPMC_CONFIG5, + ONENAND_GPMC_CONFIG6, 0 +}; +unsigned int onenand_cs_base; + +#endif + +/************************************************************************** + * make_cs1_contiguous() - for es2 and above remap cs1 behind cs0 to allow + * command line mem=xyz use all memory with out discontinuous support + * compiled in. Could do it at the ATAG, but there really is two banks... + * Called as part of 2nd phase DDR init. + **************************************************************************/ +void make_cs1_contiguous(void) +{ + u32 size, a_add_low, a_add_high; + + size = get_sdr_cs_size(SDRC_CS0_OSET); + size /= SZ_32M; /* find size to offset CS1 */ + a_add_high = (size & 3) << 8; /* set up low field */ + a_add_low = (size & 0x3C) >> 2; /* set up high field */ + writel((a_add_high | a_add_low), SDRC_CS_CFG); + +} + +/******************************************************** + * mem_ok() - test used to see if timings are correct + * for a part. Helps in guessing which part + * we are currently using. + *******************************************************/ +u32 mem_ok(u32 cs) +{ + u32 val1, val2, addr; + u32 pattern = 0x12345678; + + addr = OMAP34XX_SDRC_CS0 + get_sdr_cs_offset(cs); + + writel(0x0, addr + 0x400); /* clear pos A */ + writel(pattern, addr); /* pattern to pos B */ + writel(0x0, addr + 4); /* remove pattern off the bus */ + val1 = readl(addr + 0x400); /* get pos A value */ + val2 = readl(addr); /* get val2 */ + + if ((val1 != 0) || (val2 != pattern)) /* see if pos A value changed */ + return 0; + else + return 1; +} + +/******************************************************** + * sdrc_init() - init the sdrc chip selects CS0 and CS1 + * - early init routines, called from flash or + * SRAM. + *******************************************************/ +void sdrc_init(void) +{ + /* only init up first bank here */ + do_sdrc_init(SDRC_CS0_OSET, EARLY_INIT); +} + +/************************************************************************* + * do_sdrc_init(): initialize the SDRAM for use. + * -code sets up SDRAM basic SDRC timings for CS0 + * -optimal settings can be placed here, or redone after i2c + * inspection of board info + * + * - code called ones in C-Stack only context for CS0 and a possible 2nd + * time depending on memory configuration from stack+global context + **************************************************************************/ + +void do_sdrc_init(u32 offset, u32 early) +{ + u32 actim_offs = offset? 0x28: 0; + + if (early) { + /* reset sdrc controller */ + writel(SOFTRESET, SDRC_SYSCONFIG); + wait_on_value(BIT0, BIT0, SDRC_STATUS, 12000000); + writel(0, SDRC_SYSCONFIG); + + /* setup sdrc to ball mux */ + writel(SDP_SDRC_SHARING, SDRC_SHARING); + + /* Disble Power Down of CKE cuz of 1 CKE on combo part */ + writel(0x00000081, SDRC_POWER); + + writel(0x0000A, SDRC_DLLA_CTRL); + sdelay(0x20000); + } + + writel(0x02584099, SDRC_MCFG_0 + offset); + writel(0x4e201, SDRC_RFR_CTRL + offset); + writel(0xaa9db4c6, SDRC_ACTIM_CTRLA_0 + actim_offs); + writel(0x11517, SDRC_ACTIM_CTRLB_0 + actim_offs); + + writel(CMD_NOP, SDRC_MANUAL_0 + offset); + writel(CMD_PRECHARGE, SDRC_MANUAL_0 + offset); + writel(CMD_AUTOREFRESH, SDRC_MANUAL_0 + offset); + writel(CMD_AUTOREFRESH, SDRC_MANUAL_0 + offset); + + /* CAS latency 3, Write Burst = Read Burst, Serial Mode, + Burst length = 4 */ + writel(0x00000032, SDRC_MR_0 + offset); + + if (!mem_ok(offset)) + writel(0, SDRC_MCFG_0 + offset); +} + +void enable_gpmc_config(u32 *gpmc_config, u32 gpmc_base, u32 base, u32 size) +{ + writel(0, GPMC_CONFIG7 + gpmc_base); + sdelay(1000); + /* Delay for settling */ + writel(gpmc_config[0], GPMC_CONFIG1 + gpmc_base); + writel(gpmc_config[1], GPMC_CONFIG2 + gpmc_base); + writel(gpmc_config[2], GPMC_CONFIG3 + gpmc_base); + writel(gpmc_config[3], GPMC_CONFIG4 + gpmc_base); + writel(gpmc_config[4], GPMC_CONFIG5 + gpmc_base); + writel(gpmc_config[5], GPMC_CONFIG6 + gpmc_base); + /* Enable the config */ + writel((((size & 0xF) << 8) | ((base >> 24) & 0x3F) | + (1 << 6)), GPMC_CONFIG7 + gpmc_base); + sdelay(2000); +} + +/***************************************************** + * gpmc_init(): init gpmc bus + * Init GPMC for x16, MuxMode (SDRAM in x32). + * This code can only be executed from SRAM or SDRAM. + *****************************************************/ +void gpmc_init(void) +{ + /* putting a blanket check on GPMC based on ZeBu for now */ + u32 mux = 0, mwidth; + u32 *gpmc_config = NULL; + u32 gpmc_base = 0; + u32 base = 0; + u32 size = 0; + u32 f_off = CONFIG_SYS_MONITOR_LEN; + u32 f_sec = 0; + u32 config = 0; + + mux = BIT9; + mwidth = get_gpmc0_width(); + + /* global settings */ + writel(0x0, GPMC_IRQENABLE); /* isr's sources masked */ + writel(0, GPMC_TIMEOUT_CONTROL); /* timeout disable */ + + config = readl(GPMC_CONFIG); + config &= (~0xf00); + writel(config, GPMC_CONFIG); + + /* Disable the GPMC0 config set by ROM code + * It conflicts with our MPDB (both at 0x08000000) + */ + writel(0, GPMC_CONFIG7 + GPMC_CONFIG_CS0); + sdelay(1000); + +#if defined(CONFIG_CMD_NAND) /* CS 0 */ + gpmc_config = gpmc_m_nand; +#if defined(CONFIG_ENV_IS_IN_NAND) + gpmc_base = GPMC_CONFIG_CS0 + (0 * GPMC_CONFIG_WIDTH); +#else + gpmc_base = GPMC_CONFIG_CS0 + (1 * GPMC_CONFIG_WIDTH); +#endif + base = PISMO1_NAND_BASE; + size = PISMO1_NAND_SIZE; + enable_gpmc_config(gpmc_config, gpmc_base, base, size); + is_nand = 1; + nand_cs_base = gpmc_base; +#if defined(CONFIG_ENV_IS_IN_NAND) + f_off = SMNAND_ENV_OFFSET; + f_sec = SZ_128K; + /* env setup */ + boot_flash_base = base; + boot_flash_off = f_off; + boot_flash_sec = f_sec; + boot_flash_env_addr = f_off; +#endif +#endif + +#if defined(CONFIG_CMD_ONENAND) + gpmc_config = gpmc_onenand; +#if defined(CONFIG_ENV_IS_IN_ONENAND) + gpmc_base = GPMC_CONFIG_CS0 + (0 * GPMC_CONFIG_WIDTH); +#else + gpmc_base = GPMC_CONFIG_CS0 + (1 * GPMC_CONFIG_WIDTH); +#endif + base = PISMO1_ONEN_BASE; + size = PISMO1_ONEN_SIZE; + enable_gpmc_config(gpmc_config, gpmc_base, base, size); + is_onenand = 1; + onenand_cs_base = gpmc_base; +#if defined(CONFIG_ENV_IS_IN_ONENAND) + f_off = ONENAND_ENV_OFFSET; + f_sec = SZ_128K; + /* env setup */ + boot_flash_base = base; + boot_flash_off = f_off; + boot_flash_sec = f_sec; + boot_flash_env_addr = f_off; +#endif +#endif + +#ifdef ENV_IS_VARIABLE + boot_env_get_char_spec = env_get_char_spec; + boot_env_init = env_init; + boot_saveenv = saveenv; + boot_env_relocate_spec = env_relocate_spec; +#endif +} Index: u-boot-arm/cpu/arm_cortexa8/omap3/syslib.c =================================================================== --- /dev/null +++ u-boot-arm/cpu/arm_cortexa8/omap3/syslib.c @@ -0,0 +1,72 @@ +/* + * (C) Copyright 2008 + * Texas Instruments, <www.ti.com> + * + * Richard Woodruff <[EMAIL PROTECTED]> + * Syed Mohammed Khasim <[EMAIL PROTECTED]> + * + * 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 <common.h> +#include <asm/io.h> +#include <asm/arch/bits.h> +#include <asm/arch/mem.h> +#include <asm/arch/clocks.h> +#include <asm/arch/sys_proto.h> + +/************************************************************ + * sdelay() - simple spin loop. Will be constant time as + * its generally used in bypass conditions only. This + * is necessary until timers are accessible. + * + * not inline to increase chances its in cache when called + *************************************************************/ +void sdelay(unsigned long loops) +{ + __asm__ volatile ("1:\n" "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0"(loops)); +} + +/***************************************************************** + * sr32 - clear & set a value in a bit range for a 32 bit address + *****************************************************************/ +void sr32(u32 addr, u32 start_bit, u32 num_bits, u32 value) +{ + u32 tmp, msk = 0; + msk = 1 << num_bits; + --msk; + tmp = readl(addr) & ~(msk << start_bit); + tmp |= value << start_bit; + writel(tmp, addr); +} + +/********************************************************************* + * wait_on_value() - common routine to allow waiting for changes in + * volatile regs. + *********************************************************************/ +u32 wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound) +{ + u32 i = 0, val; + do { + ++i; + val = readl(read_addr) & read_bit_mask; + if (val == match_value) + return 1; + if (i == bound) + return 0; + } while (1); +} Index: u-boot-arm/cpu/arm_cortexa8/omap3/Makefile =================================================================== --- u-boot-arm.orig/cpu/arm_cortexa8/omap3/Makefile +++ u-boot-arm/cpu/arm_cortexa8/omap3/Makefile @@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk LIB = lib$(SOC).a SOBJS := lowlevel_init.o -OBJS := sys_info.o board.o clock.o interrupts.o +OBJS := sys_info.o board.o clock.o interrupts.o mem.o syslib.o all: .depend $(LIB) Index: u-boot-arm/examples/Makefile =================================================================== --- u-boot-arm.orig/examples/Makefile +++ u-boot-arm/examples/Makefile @@ -30,10 +30,12 @@ LOAD_ADDR = 0x40000 endif ifeq ($(ARCH),arm) +LOAD_ADDR = 0xc100000 ifeq ($(BOARD),omap2420h4) LOAD_ADDR = 0x80300000 -else -LOAD_ADDR = 0xc100000 +endif +ifeq ($(CPU),omap3) +LOAD_ADDR = 0x80300000 endif endif _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot