diff options
author | Tom Rini <trini@ti.com> | 2013-01-08 08:28:27 -0700 |
---|---|---|
committer | Tom Rini <trini@ti.com> | 2013-01-08 14:26:42 -0700 |
commit | 91c038f087d7f643c85609897af3710d5f8b42a9 (patch) | |
tree | e96b3c73031aafdd000a253e6dcf5ae6966e8c65 /arch/arm | |
parent | e56cdd778ca08fc8c32ffc3ddebbb6102519f344 (diff) | |
parent | 7528cf5f016b5b8b8b12b373f6f31a10bf89233d (diff) | |
download | u-boot-imx-91c038f087d7f643c85609897af3710d5f8b42a9.zip u-boot-imx-91c038f087d7f643c85609897af3710d5f8b42a9.tar.gz u-boot-imx-91c038f087d7f643c85609897af3710d5f8b42a9.tar.bz2 |
Merge branch 'master' of git://git.denx.de/u-boot-arm
Diffstat (limited to 'arch/arm')
22 files changed, 762 insertions, 52 deletions
diff --git a/arch/arm/cpu/arm926ejs/davinci/reset.c b/arch/arm/cpu/arm926ejs/davinci/reset.c index 968fb03..80f1ce9 100644 --- a/arch/arm/cpu/arm926ejs/davinci/reset.c +++ b/arch/arm/cpu/arm926ejs/davinci/reset.c @@ -16,7 +16,7 @@ void reset_cpu(unsigned long a) { struct davinci_timer *const wdttimer = - (struct davinci_timer *)DAVINCI_TIMER1_BASE; + (struct davinci_timer *)DAVINCI_WDOG_BASE; writel(0x08, &wdttimer->tgcr); writel(readl(&wdttimer->tgcr) | 0x03, &wdttimer->tgcr); writel(0, &wdttimer->tim12); diff --git a/arch/arm/cpu/armv7/am33xx/Makefile b/arch/arm/cpu/armv7/am33xx/Makefile index 74875b3..70c443e 100644 --- a/arch/arm/cpu/armv7/am33xx/Makefile +++ b/arch/arm/cpu/armv7/am33xx/Makefile @@ -18,10 +18,12 @@ LIB = $(obj)lib$(SOC).o COBJS += clock.o COBJS += sys_info.o +COBJS += mem.o COBJS += ddr.o COBJS += emif4.o COBJS += board.o COBJS += mux.o +COBJS-$(CONFIG_NAND_OMAP_GPMC) += elm.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(COBJS-y) $(SOBJS)) diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c index da5bc73..ab31326 100644 --- a/arch/arm/cpu/armv7/am33xx/board.c +++ b/arch/arm/cpu/armv7/am33xx/board.c @@ -25,6 +25,7 @@ #include <asm/arch/ddr_defs.h> #include <asm/arch/clock.h> #include <asm/arch/gpio.h> +#include <asm/arch/mem.h> #include <asm/arch/mmc_host_def.h> #include <asm/arch/sys_proto.h> #include <asm/io.h> diff --git a/arch/arm/cpu/armv7/am33xx/clock.c b/arch/arm/cpu/armv7/am33xx/clock.c index 0b4cb4e..d7d98d1 100644 --- a/arch/arm/cpu/armv7/am33xx/clock.c +++ b/arch/arm/cpu/armv7/am33xx/clock.c @@ -151,6 +151,16 @@ static void enable_per_clocks(void) ; #endif /* CONFIG_SERIAL6 */ + /* GPMC */ + writel(PRCM_MOD_EN, &cmper->gpmcclkctrl); + while (readl(&cmper->gpmcclkctrl) != PRCM_MOD_EN) + ; + + /* ELM */ + writel(PRCM_MOD_EN, &cmper->elmclkctrl); + while (readl(&cmper->elmclkctrl) != PRCM_MOD_EN) + ; + /* MMC0*/ writel(PRCM_MOD_EN, &cmper->mmc0clkctrl); while (readl(&cmper->mmc0clkctrl) != PRCM_MOD_EN) diff --git a/arch/arm/cpu/armv7/am33xx/elm.c b/arch/arm/cpu/armv7/am33xx/elm.c new file mode 100644 index 0000000..9eed23d --- /dev/null +++ b/arch/arm/cpu/armv7/am33xx/elm.c @@ -0,0 +1,212 @@ +/* + * (C) Copyright 2010-2011 Texas Instruments, <www.ti.com> + * Mansoor Ahamed <mansoor.ahamed@ti.com> + * + * BCH Error Location Module (ELM) support. + * + * NOTE: + * 1. Supports only continuous mode. Dont see need for page mode in uboot + * 2. Supports only syndrome polynomial 0. i.e. poly local variable is + * always set to ELM_DEFAULT_POLY. Dont see need for other polynomial + * sets in uboot + * + * 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 <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/cpu.h> +#include <asm/arch/omap_gpmc.h> +#include <asm/arch/elm.h> + +#define ELM_DEFAULT_POLY (0) + +struct elm *elm_cfg; + +/** + * elm_load_syndromes - Load BCH syndromes based on nibble selection + * @syndrome: BCH syndrome + * @nibbles: + * @poly: Syndrome Polynomial set to use + * + * Load BCH syndromes based on nibble selection + */ +static void elm_load_syndromes(u8 *syndrome, u32 nibbles, u8 poly) +{ + u32 *ptr; + u32 val; + + /* reg 0 */ + ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[0]; + val = syndrome[0] | (syndrome[1] << 8) | (syndrome[2] << 16) | + (syndrome[3] << 24); + writel(val, ptr); + /* reg 1 */ + ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[1]; + val = syndrome[4] | (syndrome[5] << 8) | (syndrome[6] << 16) | + (syndrome[7] << 24); + writel(val, ptr); + + /* BCH 8-bit with 26 nibbles (4*8=32) */ + if (nibbles > 13) { + /* reg 2 */ + ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[2]; + val = syndrome[8] | (syndrome[9] << 8) | (syndrome[10] << 16) | + (syndrome[11] << 24); + writel(val, ptr); + /* reg 3 */ + ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[3]; + val = syndrome[12] | (syndrome[13] << 8) | + (syndrome[14] << 16) | (syndrome[15] << 24); + writel(val, ptr); + } + + /* BCH 16-bit with 52 nibbles (7*8=56) */ + if (nibbles > 26) { + /* reg 4 */ + ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[4]; + val = syndrome[16] | (syndrome[17] << 8) | + (syndrome[18] << 16) | (syndrome[19] << 24); + writel(val, ptr); + + /* reg 5 */ + ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[5]; + val = syndrome[20] | (syndrome[21] << 8) | + (syndrome[22] << 16) | (syndrome[23] << 24); + writel(val, ptr); + + /* reg 6 */ + ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6]; + val = syndrome[24] | (syndrome[25] << 8) | + (syndrome[26] << 16) | (syndrome[27] << 24); + writel(val, ptr); + } +} + +/** + * elm_check_errors - Check for BCH errors and return error locations + * @syndrome: BCH syndrome + * @nibbles: + * @error_count: Returns number of errrors in the syndrome + * @error_locations: Returns error locations (in decimal) in this array + * + * Check the provided syndrome for BCH errors and return error count + * and locations in the array passed. Returns -1 if error is not correctable, + * else returns 0 + */ +int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count, + u32 *error_locations) +{ + u8 poly = ELM_DEFAULT_POLY; + s8 i; + u32 location_status; + + elm_load_syndromes(syndrome, nibbles, poly); + + /* start processing */ + writel((readl(&elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6]) + | ELM_SYNDROME_FRAGMENT_6_SYNDROME_VALID), + &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6]); + + /* wait for processing to complete */ + while ((readl(&elm_cfg->irqstatus) & (0x1 << poly)) != 0x1) + ; + /* clear status */ + writel((readl(&elm_cfg->irqstatus) | (0x1 << poly)), + &elm_cfg->irqstatus); + + /* check if correctable */ + location_status = readl(&elm_cfg->error_location[poly].location_status); + if (!(location_status & ELM_LOCATION_STATUS_ECC_CORRECTABLE_MASK)) + return -1; + + /* get error count */ + *error_count = readl(&elm_cfg->error_location[poly].location_status) & + ELM_LOCATION_STATUS_ECC_NB_ERRORS_MASK; + + for (i = 0; i < *error_count; i++) { + error_locations[i] = + readl(&elm_cfg->error_location[poly].error_location_x[i]); + } + + return 0; +} + + +/** + * elm_config - Configure ELM module + * @level: 4 / 8 / 16 bit BCH + * + * Configure ELM module based on BCH level. + * Set mode as continuous mode. + * Currently we are using only syndrome 0 and syndromes 1 to 6 are not used. + * Also, the mode is set only for syndrome 0 + */ +int elm_config(enum bch_level level) +{ + u32 val; + u8 poly = ELM_DEFAULT_POLY; + u32 buffer_size = 0x7FF; + + /* config size and level */ + val = (u32)(level) & ELM_LOCATION_CONFIG_ECC_BCH_LEVEL_MASK; + val |= ((buffer_size << ELM_LOCATION_CONFIG_ECC_SIZE_POS) & + ELM_LOCATION_CONFIG_ECC_SIZE_MASK); + writel(val, &elm_cfg->location_config); + + /* config continous mode */ + /* enable interrupt generation for syndrome polynomial set */ + writel((readl(&elm_cfg->irqenable) | (0x1 << poly)), + &elm_cfg->irqenable); + /* set continuous mode for the syndrome polynomial set */ + writel((readl(&elm_cfg->page_ctrl) & ~(0x1 << poly)), + &elm_cfg->page_ctrl); + + return 0; +} + +/** + * elm_reset - Do a soft reset of ELM + * + * Perform a soft reset of ELM and return after reset is done. + */ +void elm_reset(void) +{ + /* initiate reset */ + writel((readl(&elm_cfg->sysconfig) | ELM_SYSCONFIG_SOFTRESET), + &elm_cfg->sysconfig); + + /* wait for reset complete and normal operation */ + while ((readl(&elm_cfg->sysstatus) & ELM_SYSSTATUS_RESETDONE) != + ELM_SYSSTATUS_RESETDONE) + ; +} + +/** + * elm_init - Initialize ELM module + * + * Initialize ELM support. Currently it does only base address init + * and ELM reset. + */ +void elm_init(void) +{ + elm_cfg = (struct elm *)ELM_BASE; + elm_reset(); +} diff --git a/arch/arm/cpu/armv7/am33xx/mem.c b/arch/arm/cpu/armv7/am33xx/mem.c new file mode 100644 index 0000000..b8f54ab --- /dev/null +++ b/arch/arm/cpu/armv7/am33xx/mem.c @@ -0,0 +1,101 @@ +/* + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Author : + * Mansoor Ahamed <mansoor.ahamed@ti.com> + * + * Initial Code from: + * Manikandan Pillai <mani.pillai@ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * Syed Mohammed Khasim <khasim@ti.com> + * + * 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/cpu.h> +#include <asm/arch/mem.h> +#include <asm/arch/sys_proto.h> +#include <command.h> + +struct gpmc *gpmc_cfg; + +#if defined(CONFIG_CMD_NAND) +static const 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 +}; +#endif + + +void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base, + u32 size) +{ + writel(0, &cs->config7); + sdelay(1000); + /* Delay for settling */ + writel(gpmc_config[0], &cs->config1); + writel(gpmc_config[1], &cs->config2); + writel(gpmc_config[2], &cs->config3); + writel(gpmc_config[3], &cs->config4); + writel(gpmc_config[4], &cs->config5); + writel(gpmc_config[5], &cs->config6); + /* Enable the config */ + writel((((size & 0xF) << 8) | ((base >> 24) & 0x3F) | + (1 << 6)), &cs->config7); + 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 */ + gpmc_cfg = (struct gpmc *)GPMC_BASE; + +#ifdef CONFIG_CMD_NAND + const u32 *gpmc_config = NULL; + u32 base = 0; + u32 size = 0; +#endif + /* global settings */ + writel(0x00000008, &gpmc_cfg->sysconfig); + writel(0x00000100, &gpmc_cfg->irqstatus); + writel(0x00000200, &gpmc_cfg->irqenable); + writel(0x00000012, &gpmc_cfg->config); + /* + * Disable the GPMC0 config set by ROM code + */ + writel(0, &gpmc_cfg->cs[0].config7); + sdelay(1000); + +#ifdef CONFIG_CMD_NAND + gpmc_config = gpmc_m_nand; + + base = PISMO1_NAND_BASE; + size = PISMO1_NAND_SIZE; + enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size); +#endif +} diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index 1f2fa02..0efc80d 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -25,9 +25,8 @@ include $(TOPDIR)/config.mk LIB = $(obj)libomap-common.o -SOBJS := reset.o - -COBJS := timer.o +COBJS := reset.o +COBJS += timer.o COBJS += utils.o ifneq ($(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),) diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c index 0f19141..2b584e0 100644 --- a/arch/arm/cpu/armv7/omap-common/boot-common.c +++ b/arch/arm/cpu/armv7/omap-common/boot-common.c @@ -21,6 +21,7 @@ #include <asm/omap_common.h> #include <asm/arch/omap.h> #include <asm/arch/mmc_host_def.h> +#include <asm/arch/sys_proto.h> /* * This is used to verify if the configuration header diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c index 30dcf1b..88253cf 100644 --- a/arch/arm/cpu/armv7/omap-common/emif-common.c +++ b/arch/arm/cpu/armv7/omap-common/emif-common.c @@ -33,6 +33,8 @@ #include <asm/utils.h> #include <linux/compiler.h> +static int emif1_enabled = -1, emif2_enabled = -1; + void set_lpmode_selfrefresh(u32 base) { struct emif_reg_struct *emif = (struct emif_reg_struct *)base; @@ -1109,6 +1111,7 @@ void emif_post_init_config(u32 base) void dmm_init(u32 base) { const struct dmm_lisa_map_regs *lisa_map_regs; + u32 i, section, valid; #ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS emif_get_dmm_regs(&lisa_map_regs); @@ -1216,6 +1219,29 @@ void dmm_init(u32 base) writel(lisa_map_regs->dmm_lisa_map_0, &hw_lisa_map_regs->dmm_lisa_map_0); } + + /* + * EMIF should be configured only when + * memory is mapped on it. Using emif1_enabled + * and emif2_enabled variables for this. + */ + emif1_enabled = 0; + emif2_enabled = 0; + for (i = 0; i < 4; i++) { + section = __raw_readl(DMM_BASE + i*4); + valid = (section & EMIF_SDRC_MAP_MASK) >> + (EMIF_SDRC_MAP_SHIFT); + if (valid == 3) { + emif1_enabled = 1; + emif2_enabled = 1; + break; + } else if (valid == 1) { + emif1_enabled = 1; + } else if (valid == 2) { + emif2_enabled = 1; + } + } + } /* @@ -1255,15 +1281,20 @@ void sdram_init(void) writel(CM_DLL_CTRL_NO_OVERRIDE, &prcm->cm_dll_ctrl); } - do_sdram_init(EMIF1_BASE); - do_sdram_init(EMIF2_BASE); - if (!in_sdram) dmm_init(DMM_BASE); + if (emif1_enabled) + do_sdram_init(EMIF1_BASE); + + if (emif2_enabled) + do_sdram_init(EMIF2_BASE); + if (!(in_sdram || warm_reset())) { - emif_post_init_config(EMIF1_BASE); - emif_post_init_config(EMIF2_BASE); + if (emif1_enabled) + emif_post_init_config(EMIF1_BASE); + if (emif2_enabled) + emif_post_init_config(EMIF2_BASE); } /* for the shadow registers to take effect */ diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index f3cd81a..89c587e 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -478,7 +478,7 @@ void omap3_outer_cache_disable(void) */ omap3_update_aux_cr(0, 0x2); } -#endif +#endif /* !CONFIG_SYS_L2CACHE_OFF */ #ifndef CONFIG_SYS_DCACHE_OFF void enable_caches(void) @@ -486,4 +486,4 @@ void enable_caches(void) /* Enable D-cache. I-cache is already enabled in start.S */ dcache_enable(); } -#endif +#endif /* !CONFIG_SYS_DCACHE_OFF */ diff --git a/arch/arm/cpu/armv7/omap3/mem.c b/arch/arm/cpu/armv7/omap3/mem.c index 2fe5ac7..d04a5a1 100644 --- a/arch/arm/cpu/armv7/omap3/mem.c +++ b/arch/arm/cpu/armv7/omap3/mem.c @@ -42,14 +42,7 @@ static const u32 gpmc_m_nand[GPMC_MAX_REG] = { M_NAND_GPMC_CONFIG5, M_NAND_GPMC_CONFIG6, 0 }; - -#if defined(CONFIG_ENV_IS_IN_NAND) -#define GPMC_CS 0 -#else -#define GPMC_CS 1 -#endif - -#endif +#endif /* CONFIG_CMD_NAND */ #if defined(CONFIG_CMD_ONENAND) static const u32 gpmc_onenand[GPMC_MAX_REG] = { @@ -60,14 +53,7 @@ static const u32 gpmc_onenand[GPMC_MAX_REG] = { ONENAND_GPMC_CONFIG5, ONENAND_GPMC_CONFIG6, 0 }; - -#if defined(CONFIG_ENV_IS_IN_ONENAND) -#define GPMC_CS 0 -#else -#define GPMC_CS 1 -#endif - -#endif +#endif /* CONFIG_CMD_ONENAND */ /******************************************************** * mem_ok() - test used to see if timings are correct diff --git a/arch/arm/cpu/armv7/omap3/sdrc.c b/arch/arm/cpu/armv7/omap3/sdrc.c index f6d9b97..e32bf11 100644 --- a/arch/arm/cpu/armv7/omap3/sdrc.c +++ b/arch/arm/cpu/armv7/omap3/sdrc.c @@ -113,18 +113,18 @@ u32 get_sdr_cs_offset(u32 cs) * - Test CS to make sure it's OK for use */ static void write_sdrc_timings(u32 cs, struct sdrc_actim *sdrc_actim_base, - u32 mcfg, u32 ctrla, u32 ctrlb, u32 rfr_ctrl, u32 mr) + struct board_sdrc_timings *timings) { /* Setup timings we got from the board. */ - writel(mcfg, &sdrc_base->cs[cs].mcfg); - writel(ctrla, &sdrc_actim_base->ctrla); - writel(ctrlb, &sdrc_actim_base->ctrlb); - writel(rfr_ctrl, &sdrc_base->cs[cs].rfr_ctrl); + writel(timings->mcfg, &sdrc_base->cs[cs].mcfg); + writel(timings->ctrla, &sdrc_actim_base->ctrla); + writel(timings->ctrlb, &sdrc_actim_base->ctrlb); + writel(timings->rfr_ctrl, &sdrc_base->cs[cs].rfr_ctrl); writel(CMD_NOP, &sdrc_base->cs[cs].manual); writel(CMD_PRECHARGE, &sdrc_base->cs[cs].manual); writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); - writel(mr, &sdrc_base->cs[cs].mr); + writel(timings->mr, &sdrc_base->cs[cs].mr); /* * Test ram in this bank @@ -143,7 +143,7 @@ static void write_sdrc_timings(u32 cs, struct sdrc_actim *sdrc_actim_base, void do_sdrc_init(u32 cs, u32 early) { struct sdrc_actim *sdrc_actim_base0, *sdrc_actim_base1; - u32 mcfg, ctrla, ctrlb, rfr_ctrl, mr; + struct board_sdrc_timings timings; sdrc_actim_base0 = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE; sdrc_actim_base1 = (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE; @@ -158,7 +158,7 @@ void do_sdrc_init(u32 cs, u32 early) * setup CS1. */ #ifdef CONFIG_SPL_BUILD - get_board_mem_timings(&mcfg, &ctrla, &ctrlb, &rfr_ctrl, &mr); + get_board_mem_timings(&timings); #endif if (early) { /* reset sdrc controller */ @@ -177,11 +177,9 @@ void do_sdrc_init(u32 cs, u32 early) writel(ENADLL | DLLPHASE_90, &sdrc_base->dlla_ctrl); sdelay(0x20000); #ifdef CONFIG_SPL_BUILD - write_sdrc_timings(CS0, sdrc_actim_base0, mcfg, ctrla, ctrlb, - rfr_ctrl, mr); + write_sdrc_timings(CS0, sdrc_actim_base0, &timings); make_cs1_contiguous(); - write_sdrc_timings(CS1, sdrc_actim_base1, mcfg, ctrla, ctrlb, - rfr_ctrl, mr); + write_sdrc_timings(CS1, sdrc_actim_base1, &timings); #endif } @@ -193,14 +191,12 @@ void do_sdrc_init(u32 cs, u32 early) * so we may be asked now to setup CS1. */ if (cs == CS1) { - mcfg = readl(&sdrc_base->cs[CS0].mcfg), - rfr_ctrl = readl(&sdrc_base->cs[CS0].rfr_ctrl); - ctrla = readl(&sdrc_actim_base0->ctrla), - ctrlb = readl(&sdrc_actim_base0->ctrlb); - mr = readl(&sdrc_base->cs[CS0].mr); - write_sdrc_timings(cs, sdrc_actim_base1, mcfg, ctrla, ctrlb, - rfr_ctrl, mr); - + timings.mcfg = readl(&sdrc_base->cs[CS0].mcfg), + timings.rfr_ctrl = readl(&sdrc_base->cs[CS0].rfr_ctrl); + timings.ctrla = readl(&sdrc_actim_base0->ctrla); + timings.ctrlb = readl(&sdrc_actim_base0->ctrlb); + timings.mr = readl(&sdrc_base->cs[CS0].mr); + write_sdrc_timings(cs, sdrc_actim_base1, &timings); } } diff --git a/arch/arm/cpu/armv7/omap4/clocks.c b/arch/arm/cpu/armv7/omap4/clocks.c index 5bd0a88..12c5803 100644 --- a/arch/arm/cpu/armv7/omap4/clocks.c +++ b/arch/arm/cpu/armv7/omap4/clocks.c @@ -44,7 +44,7 @@ */ #define printf(fmt, args...) #define puts(s) -#endif +#endif /* !CONFIG_SPL_BUILD */ struct omap4_prcm_regs *const prcm = (struct omap4_prcm_regs *)0x4A004100; diff --git a/arch/arm/cpu/armv7/omap4/hwinit.c b/arch/arm/cpu/armv7/omap4/hwinit.c index 2c34e48..f4123aa 100644 --- a/arch/arm/cpu/armv7/omap4/hwinit.c +++ b/arch/arm/cpu/armv7/omap4/hwinit.c @@ -116,7 +116,7 @@ void do_io_settings(void) if ((omap4_rev < OMAP4460_ES1_0) || !readl(&ctrl->control_efuse_2)) writel(CONTROL_EFUSE_2_OVERRIDE, &ctrl->control_efuse_2); } -#endif +#endif /* CONFIG_SPL_BUILD */ /* dummy fuction for omap4 */ void config_data_eye_leveling_samples(u32 emif_base) @@ -182,4 +182,4 @@ void v7_outer_cache_disable(void) { set_pl310_ctrl_reg(0); } -#endif +#endif /* !CONFIG_SYS_L2CACHE_OFF */ diff --git a/arch/arm/include/asm/arch-am33xx/cpu.h b/arch/arm/include/asm/arch-am33xx/cpu.h index d6c038e..16e8a80 100644 --- a/arch/arm/include/asm/arch-am33xx/cpu.h +++ b/arch/arm/include/asm/arch-am33xx/cpu.h @@ -60,6 +60,59 @@ #ifndef __KERNEL_STRICT_NAMES #ifndef __ASSEMBLY__ +struct gpmc_cs { + u32 config1; /* 0x00 */ + u32 config2; /* 0x04 */ + u32 config3; /* 0x08 */ + u32 config4; /* 0x0C */ + u32 config5; /* 0x10 */ + u32 config6; /* 0x14 */ + u32 config7; /* 0x18 */ + u32 nand_cmd; /* 0x1C */ + u32 nand_adr; /* 0x20 */ + u32 nand_dat; /* 0x24 */ + u8 res[8]; /* blow up to 0x30 byte */ +}; + +struct bch_res_0_3 { + u32 bch_result_x[4]; +}; + +struct gpmc { + u8 res1[0x10]; + u32 sysconfig; /* 0x10 */ + u8 res2[0x4]; + u32 irqstatus; /* 0x18 */ + u32 irqenable; /* 0x1C */ + u8 res3[0x20]; + u32 timeout_control; /* 0x40 */ + u8 res4[0xC]; + u32 config; /* 0x50 */ + u32 status; /* 0x54 */ + u8 res5[0x8]; /* 0x58 */ + struct gpmc_cs cs[8]; /* 0x60, 0x90, .. */ + u8 res6[0x14]; /* 0x1E0 */ + u32 ecc_config; /* 0x1F4 */ + u32 ecc_control; /* 0x1F8 */ + u32 ecc_size_config; /* 0x1FC */ + u32 ecc1_result; /* 0x200 */ + u32 ecc2_result; /* 0x204 */ + u32 ecc3_result; /* 0x208 */ + u32 ecc4_result; /* 0x20C */ + u32 ecc5_result; /* 0x210 */ + u32 ecc6_result; /* 0x214 */ + u32 ecc7_result; /* 0x218 */ + u32 ecc8_result; /* 0x21C */ + u32 ecc9_result; /* 0x220 */ + u8 res7[12]; /* 0x224 */ + u32 testmomde_ctrl; /* 0x230 */ + u8 res8[12]; /* 0x234 */ + struct bch_res_0_3 bch_result_0_3[2]; /* 0x240 */ +}; + +/* Used for board specific gpmc initialization */ +extern struct gpmc *gpmc_cfg; + /* Encapsulating core pll registers */ struct cm_wkuppll { unsigned int wkclkstctrl; /* offset 0x00 */ diff --git a/arch/arm/include/asm/arch-am33xx/elm.h b/arch/arm/include/asm/arch-am33xx/elm.h new file mode 100644 index 0000000..e80f7d4 --- /dev/null +++ b/arch/arm/include/asm/arch-am33xx/elm.h @@ -0,0 +1,93 @@ +/* + * (C) Copyright 2010-2011 Texas Instruments, <www.ti.com> + * Mansoor Ahamed <mansoor.ahamed@ti.com> + * + * Derived from work done by Rohit Choraria <rohitkc@ti.com> for omap3 + * + * 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 + */ +#ifndef __ASM_ARCH_ELM_H +#define __ASM_ARCH_ELM_H +/* + * ELM Module Registers + */ + +/* ELM registers bit fields */ +#define ELM_SYSCONFIG_SOFTRESET_MASK (0x2) +#define ELM_SYSCONFIG_SOFTRESET (0x2) +#define ELM_SYSSTATUS_RESETDONE_MASK (0x1) +#define ELM_SYSSTATUS_RESETDONE (0x1) +#define ELM_LOCATION_CONFIG_ECC_BCH_LEVEL_MASK (0x3) +#define ELM_LOCATION_CONFIG_ECC_SIZE_MASK (0x7FF0000) +#define ELM_LOCATION_CONFIG_ECC_SIZE_POS (16) +#define ELM_SYNDROME_FRAGMENT_6_SYNDROME_VALID (0x00010000) +#define ELM_LOCATION_STATUS_ECC_CORRECTABLE_MASK (0x100) +#define ELM_LOCATION_STATUS_ECC_NB_ERRORS_MASK (0x1F) + +#ifndef __ASSEMBLY__ + +enum bch_level { + BCH_4_BIT = 0, + BCH_8_BIT, + BCH_16_BIT +}; + + +/* BCH syndrome registers */ +struct syndrome { + u32 syndrome_fragment_x[7]; /* 0x400, 0x404.... 0x418 */ + u8 res1[36]; /* 0x41c */ +}; + +/* BCH error status & location register */ +struct location { + u32 location_status; /* 0x800 */ + u8 res1[124]; /* 0x804 */ + u32 error_location_x[16]; /* 0x880.... */ + u8 res2[64]; /* 0x8c0 */ +}; + +/* BCH ELM register map - do not try to allocate memmory for this structure. + * We have used plenty of reserved variables to fill the slots in the ELM + * register memory map. + * Directly initialize the struct pointer to ELM base address. + */ +struct elm { + u32 rev; /* 0x000 */ + u8 res1[12]; /* 0x004 */ + u32 sysconfig; /* 0x010 */ + u32 sysstatus; /* 0x014 */ + u32 irqstatus; /* 0x018 */ + u32 irqenable; /* 0x01c */ + u32 location_config; /* 0x020 */ + u8 res2[92]; /* 0x024 */ + u32 page_ctrl; /* 0x080 */ + u8 res3[892]; /* 0x084 */ + struct syndrome syndrome_fragments[8]; /* 0x400 */ + u8 res4[512]; /* 0x600 */ + struct location error_location[8]; /* 0x800 */ +}; + +int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count, + u32 *error_locations); +int elm_config(enum bch_level level); +void elm_reset(void); +void elm_init(void); +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_ARCH_ELM_H */ diff --git a/arch/arm/include/asm/arch-am33xx/hardware.h b/arch/arm/include/asm/arch-am33xx/hardware.h index 24ab365..6dd3296 100644 --- a/arch/arm/include/asm/arch-am33xx/hardware.h +++ b/arch/arm/include/asm/arch-am33xx/hardware.h @@ -80,6 +80,9 @@ #define DDRPHY_0_CONFIG_BASE (CTRL_BASE + 0x1400) #define DDRPHY_CONFIG_BASE DDRPHY_0_CONFIG_BASE +/* GPMC Base address */ +#define GPMC_BASE 0x50000000 + /* CPSW Config space */ #define AM335X_CPSW_BASE 0x4A100000 #define AM335X_CPSW_MDIO_BASE 0x4A101000 diff --git a/arch/arm/include/asm/arch-am33xx/mem.h b/arch/arm/include/asm/arch-am33xx/mem.h new file mode 100644 index 0000000..c3bf74e --- /dev/null +++ b/arch/arm/include/asm/arch-am33xx/mem.h @@ -0,0 +1,83 @@ +/* + * (C) Copyright 2006-2008 + * Texas Instruments, <www.ti.com> + * + * Author + * Mansoor Ahamed <mansoor.ahamed@ti.com> + * + * Initial Code from: + * Richard Woodruff <r-woodruff2@ti.com> + * + * 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 + */ + +#ifndef _MEM_H_ +#define _MEM_H_ + +/* + * GPMC settings - + * Definitions is as per the following format + * #define <PART>_GPMC_CONFIG<x> <value> + * Where: + * PART is the part name e.g. STNOR - Intel Strata Flash + * x is GPMC config registers from 1 to 6 (there will be 6 macros) + * Value is corresponding value + * + * For every valid PRCM configuration there should be only one definition of + * the same. if values are independent of the board, this definition will be + * present in this file if values are dependent on the board, then this should + * go into corresponding mem-boardName.h file + * + * Currently valid part Names are (PART): + * M_NAND - Micron NAND + */ +#define GPMC_SIZE_256M 0x0 +#define GPMC_SIZE_128M 0x8 +#define GPMC_SIZE_64M 0xC +#define GPMC_SIZE_32M 0xE +#define GPMC_SIZE_16M 0xF + +#define M_NAND_GPMC_CONFIG1 0x00000800 +#define M_NAND_GPMC_CONFIG2 0x001e1e00 +#define M_NAND_GPMC_CONFIG3 0x001e1e00 +#define M_NAND_GPMC_CONFIG4 0x16051807 +#define M_NAND_GPMC_CONFIG5 0x00151e1e +#define M_NAND_GPMC_CONFIG6 0x16000f80 +#define M_NAND_GPMC_CONFIG7 0x00000008 + +/* max number of GPMC Chip Selects */ +#define GPMC_MAX_CS 8 +/* max number of GPMC regs */ +#define GPMC_MAX_REG 7 + +#define PISMO1_NOR 1 +#define PISMO1_NAND 2 +#define PISMO2_CS0 3 +#define PISMO2_CS1 4 +#define PISMO1_ONENAND 5 +#define DBG_MPDB 6 +#define PISMO2_NAND_CS0 7 +#define PISMO2_NAND_CS1 8 + +/* make it readable for the gpmc_init */ +#define PISMO1_NOR_BASE FLASH_BASE +#define PISMO1_NAND_BASE CONFIG_SYS_NAND_BASE +#define PISMO1_NAND_SIZE GPMC_SIZE_256M + +#endif /* endif _MEM_H_ */ diff --git a/arch/arm/include/asm/arch-am33xx/omap_gpmc.h b/arch/arm/include/asm/arch-am33xx/omap_gpmc.h new file mode 100644 index 0000000..572f9d0 --- /dev/null +++ b/arch/arm/include/asm/arch-am33xx/omap_gpmc.h @@ -0,0 +1,120 @@ +/* + * (C) Copyright 2004-2008 Texas Instruments, <www.ti.com> + * Rohit Choraria <rohitkc@ti.com> + * + * 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 + */ +#ifndef __ASM_ARCH_OMAP_GPMC_H +#define __ASM_ARCH_OMAP_GPMC_H + +#define GPMC_BUF_EMPTY 0 +#define GPMC_BUF_FULL 1 + +#define ECCCLEAR (0x1 << 8) +#define ECCRESULTREG1 (0x1 << 0) +#define ECCSIZE512BYTE 0xFF +#define ECCSIZE1 (ECCSIZE512BYTE << 22) +#define ECCSIZE0 (ECCSIZE512BYTE << 12) +#define ECCSIZE0SEL (0x000 << 0) + +/* Generic ECC Layouts */ +/* Large Page x8 NAND device Layout */ +#ifdef GPMC_NAND_ECC_LP_x8_LAYOUT +#define GPMC_NAND_HW_ECC_LAYOUT {\ + .eccbytes = 12,\ + .eccpos = {1, 2, 3, 4, 5, 6, 7, 8,\ + 9, 10, 11, 12},\ + .oobfree = {\ + {.offset = 13,\ + .length = 51 } } \ +} +#endif + +/* Large Page x16 NAND device Layout */ +#ifdef GPMC_NAND_ECC_LP_x16_LAYOUT +#define GPMC_NAND_HW_ECC_LAYOUT {\ + .eccbytes = 12,\ + .eccpos = {2, 3, 4, 5, 6, 7, 8, 9,\ + 10, 11, 12, 13},\ + .oobfree = {\ + {.offset = 14,\ + .length = 50 } } \ +} +#endif + +/* Small Page x8 NAND device Layout */ +#ifdef GPMC_NAND_ECC_SP_x8_LAYOUT +#define GPMC_NAND_HW_ECC_LAYOUT {\ + .eccbytes = 3,\ + .eccpos = {1, 2, 3},\ + .oobfree = {\ + {.offset = 4,\ + .length = 12 } } \ +} +#endif + +/* Small Page x16 NAND device Layout */ +#ifdef GPMC_NAND_ECC_SP_x16_LAYOUT +#define GPMC_NAND_HW_ECC_LAYOUT {\ + .eccbytes = 3,\ + .eccpos = {2, 3, 4},\ + .oobfree = {\ + {.offset = 5,\ + .length = 11 } } \ +} +#endif + +#define GPMC_NAND_HW_BCH4_ECC_LAYOUT {\ + .eccbytes = 32,\ + .eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\ + 28, 29, 30, 31, 32, 33},\ + .oobfree = {\ + {.offset = 34,\ + .length = 30 } } \ +} + +#define GPMC_NAND_HW_BCH8_ECC_LAYOUT {\ + .eccbytes = 56,\ + .eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\ + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\ + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\ + 52, 53, 54, 55, 56, 57},\ + .oobfree = {\ + {.offset = 58,\ + .length = 6 } } \ +} + +#define GPMC_NAND_HW_BCH16_ECC_LAYOUT {\ + .eccbytes = 104,\ + .eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\ + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\ + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\ + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,\ + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,\ + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,\ + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,\ + 100, 101, 102, 103, 104, 105},\ + .oobfree = {\ + {.offset = 106,\ + .length = 8 } } \ +} +#endif /* __ASM_ARCH_OMAP_GPMC_H */ diff --git a/arch/arm/include/asm/arch-am33xx/sys_proto.h b/arch/arm/include/asm/arch-am33xx/sys_proto.h index 9cf35e0..588d8de 100644 --- a/arch/arm/include/asm/arch-am33xx/sys_proto.h +++ b/arch/arm/include/asm/arch-am33xx/sys_proto.h @@ -33,4 +33,7 @@ u32 get_device_type(void); void setup_clocks_for_console(void); void ddr_pll_config(unsigned int ddrpll_M); +void sdelay(unsigned long); +void gpmc_init(void); +void omap_nand_switch_ecc(int); #endif diff --git a/arch/arm/include/asm/arch-omap3/sys_proto.h b/arch/arm/include/asm/arch-omap3/sys_proto.h index 9e52b12..d60f2ad 100644 --- a/arch/arm/include/asm/arch-omap3/sys_proto.h +++ b/arch/arm/include/asm/arch-omap3/sys_proto.h @@ -32,6 +32,15 @@ struct emu_hal_params { u32 param1; }; +/* Board SDRC timing values */ +struct board_sdrc_timings { + u32 mcfg; + u32 ctrla; + u32 ctrlb; + u32 rfr_ctrl; + u32 mr; +}; + void prcm_init(void); void per_clocks_enable(void); void ehci_clocks_enable(void); @@ -39,8 +48,8 @@ void ehci_clocks_enable(void); void memif_init(void); void sdrc_init(void); void do_sdrc_init(u32, u32); -void get_board_mem_timings(u32 *mcfg, u32 *ctrla, u32 *ctrlb, u32 *rfr_ctrl, - u32 *mr); + +void get_board_mem_timings(struct board_sdrc_timings *timings); void identify_nand_chip(int *mfr, int *id); void emif4_init(void); void gpmc_init(void); diff --git a/arch/arm/include/asm/omap_gpio.h b/arch/arm/include/asm/omap_gpio.h index 516cc42..1ebfa86 100644 --- a/arch/arm/include/asm/omap_gpio.h +++ b/arch/arm/include/asm/omap_gpio.h @@ -49,4 +49,11 @@ extern const struct gpio_bank *const omap_gpio_bank; #define METHOD_GPIO_24XX 4 +/** + * Check if gpio is valid. + * + * @param gpio GPIO number + * @return 1 if ok, 0 on error + */ +int gpio_is_valid(int gpio); #endif /* _GPIO_H_ */ |