mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-25 06:00:43 +00:00
Merge branch 'u-boot-ti/master' into 'u-boot-arm/master'
This required manual merging drivers/mtd/nand/Makefile and adding am335x_evm support for CONFIG_SPL_NAND_DRIVERS
This commit is contained in:
commit
79f3877794
56 changed files with 1717 additions and 248 deletions
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
212
arch/arm/cpu/armv7/am33xx/elm.c
Normal file
212
arch/arm/cpu/armv7/am33xx/elm.c
Normal file
|
@ -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();
|
||||
}
|
101
arch/arm/cpu/armv7/am33xx/mem.c
Normal file
101
arch/arm/cpu/armv7/am33xx/mem.c
Normal file
|
@ -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
|
||||
}
|
|
@ -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),)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
93
arch/arm/include/asm/arch-am33xx/elm.h
Normal file
93
arch/arm/include/asm/arch-am33xx/elm.h
Normal file
|
@ -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 */
|
|
@ -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
|
||||
|
|
83
arch/arm/include/asm/arch-am33xx/mem.h
Normal file
83
arch/arm/include/asm/arch-am33xx/mem.h
Normal file
|
@ -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_ */
|
120
arch/arm/include/asm/arch-am33xx/omap_gpmc.h
Normal file
120
arch/arm/include/asm/arch-am33xx/omap_gpmc.h
Normal file
|
@ -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 */
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -91,15 +91,14 @@ int board_mmc_init(bd_t *bis)
|
|||
* provides the timing values back to the function that configures
|
||||
* the memory. We have either one or two banks of 128MB DDR.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
/* General SDRC config */
|
||||
*mcfg = MICRON_V_MCFG_165(128 << 20);
|
||||
*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
timings->mcfg = MICRON_V_MCFG_165(128 << 20);
|
||||
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
|
||||
/* AC timings */
|
||||
*ctrla = MICRON_V_ACTIMA_165;
|
||||
*ctrlb = MICRON_V_ACTIMB_165;
|
||||
*mr = MICRON_V_MR_165;
|
||||
timings->ctrla = MICRON_V_ACTIMA_165;
|
||||
timings->ctrlb = MICRON_V_ACTIMB_165;
|
||||
timings->mr = MICRON_V_MR_165;
|
||||
}
|
||||
|
|
|
@ -72,27 +72,26 @@ void omap_rev_string(void)
|
|||
* Description: If we use SPL then there is no x-loader nor config header
|
||||
* so we have to setup the DDR timings ourself on both banks.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
*mr = MICRON_V_MR_165;
|
||||
timings->mr = MICRON_V_MR_165;
|
||||
#ifdef CONFIG_BOOT_NAND
|
||||
*mcfg = MICRON_V_MCFG_200(256 << 20);
|
||||
*ctrla = MICRON_V_ACTIMA_200;
|
||||
*ctrlb = MICRON_V_ACTIMB_200;
|
||||
*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
|
||||
timings->mcfg = MICRON_V_MCFG_200(256 << 20);
|
||||
timings->ctrla = MICRON_V_ACTIMA_200;
|
||||
timings->ctrlb = MICRON_V_ACTIMB_200;
|
||||
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
|
||||
#else
|
||||
if (get_cpu_family() == CPU_OMAP34XX) {
|
||||
*mcfg = NUMONYX_V_MCFG_165(256 << 20);
|
||||
*ctrla = NUMONYX_V_ACTIMA_165;
|
||||
*ctrlb = NUMONYX_V_ACTIMB_165;
|
||||
*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
timings->mcfg = NUMONYX_V_MCFG_165(256 << 20);
|
||||
timings->ctrla = NUMONYX_V_ACTIMA_165;
|
||||
timings->ctrlb = NUMONYX_V_ACTIMB_165;
|
||||
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
|
||||
} else {
|
||||
*mcfg = NUMONYX_V_MCFG_200(256 << 20);
|
||||
*ctrla = NUMONYX_V_ACTIMA_200;
|
||||
*ctrlb = NUMONYX_V_ACTIMB_200;
|
||||
*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
|
||||
timings->mcfg = NUMONYX_V_MCFG_200(256 << 20);
|
||||
timings->ctrla = NUMONYX_V_ACTIMA_200;
|
||||
timings->ctrlb = NUMONYX_V_ACTIMB_200;
|
||||
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -59,27 +59,26 @@ void omap_rev_string(void)
|
|||
* Description: If we use SPL then there is no x-loader nor config header
|
||||
* so we have to setup the DDR timings ourself on both banks.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
*mr = MICRON_V_MR_165;
|
||||
timings->mr = MICRON_V_MR_165;
|
||||
#ifdef CONFIG_BOOT_NAND
|
||||
*mcfg = MICRON_V_MCFG_200(256 << 20);
|
||||
*ctrla = MICRON_V_ACTIMA_200;
|
||||
*ctrlb = MICRON_V_ACTIMB_200;
|
||||
*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
|
||||
timings->mcfg = MICRON_V_MCFG_200(256 << 20);
|
||||
timings->ctrla = MICRON_V_ACTIMA_200;
|
||||
timings->ctrlb = MICRON_V_ACTIMB_200;
|
||||
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
|
||||
#else
|
||||
if (get_cpu_family() == CPU_OMAP34XX) {
|
||||
*mcfg = NUMONYX_V_MCFG_165(256 << 20);
|
||||
*ctrla = NUMONYX_V_ACTIMA_165;
|
||||
*ctrlb = NUMONYX_V_ACTIMB_165;
|
||||
*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
timings->mcfg = NUMONYX_V_MCFG_165(256 << 20);
|
||||
timings->ctrla = NUMONYX_V_ACTIMA_165;
|
||||
timings->ctrlb = NUMONYX_V_ACTIMB_165;
|
||||
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
|
||||
} else {
|
||||
*mcfg = NUMONYX_V_MCFG_200(256 << 20);
|
||||
*ctrla = NUMONYX_V_ACTIMA_200;
|
||||
*ctrlb = NUMONYX_V_ACTIMB_200;
|
||||
*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
|
||||
timings->mcfg = NUMONYX_V_MCFG_200(256 << 20);
|
||||
timings->ctrla = NUMONYX_V_ACTIMA_200;
|
||||
timings->ctrlb = NUMONYX_V_ACTIMB_200;
|
||||
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -147,34 +147,33 @@ int get_board_revision(void)
|
|||
* Description: If we use SPL then there is no x-loader nor config header
|
||||
* so we have to setup the DDR timings ourself on both banks.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
*mr = MICRON_V_MR_165;
|
||||
timings->mr = MICRON_V_MR_165;
|
||||
switch (get_board_revision()) {
|
||||
case REVISION_0: /* Micron 1286MB/256MB, 1/2 banks of 128MB */
|
||||
*mcfg = MICRON_V_MCFG_165(128 << 20);
|
||||
*ctrla = MICRON_V_ACTIMA_165;
|
||||
*ctrlb = MICRON_V_ACTIMB_165;
|
||||
*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
timings->mcfg = MICRON_V_MCFG_165(128 << 20);
|
||||
timings->ctrla = MICRON_V_ACTIMA_165;
|
||||
timings->ctrlb = MICRON_V_ACTIMB_165;
|
||||
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
break;
|
||||
case REVISION_1: /* Micron 256MB/512MB, 1/2 banks of 256MB */
|
||||
*mcfg = MICRON_V_MCFG_165(256 << 20);
|
||||
*ctrla = MICRON_V_ACTIMA_165;
|
||||
*ctrlb = MICRON_V_ACTIMB_165;
|
||||
*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
timings->mcfg = MICRON_V_MCFG_165(256 << 20);
|
||||
timings->ctrla = MICRON_V_ACTIMA_165;
|
||||
timings->ctrlb = MICRON_V_ACTIMB_165;
|
||||
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
break;
|
||||
case REVISION_2: /* Hynix 256MB/512MB, 1/2 banks of 256MB */
|
||||
*mcfg = HYNIX_V_MCFG_165(256 << 20);
|
||||
*ctrla = HYNIX_V_ACTIMA_165;
|
||||
*ctrlb = HYNIX_V_ACTIMB_165;
|
||||
*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
timings->mcfg = HYNIX_V_MCFG_165(256 << 20);
|
||||
timings->ctrla = HYNIX_V_ACTIMA_165;
|
||||
timings->ctrlb = HYNIX_V_ACTIMB_165;
|
||||
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
break;
|
||||
default:
|
||||
*mcfg = MICRON_V_MCFG_165(128 << 20);
|
||||
*ctrla = MICRON_V_ACTIMA_165;
|
||||
*ctrlb = MICRON_V_ACTIMB_165;
|
||||
*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
timings->mcfg = MICRON_V_MCFG_165(128 << 20);
|
||||
timings->ctrla = MICRON_V_ACTIMA_165;
|
||||
timings->ctrlb = MICRON_V_ACTIMB_165;
|
||||
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -98,9 +98,12 @@ int board_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
int misc_init_r(void)
|
||||
{
|
||||
char *eth_addr;
|
||||
struct tam3517_module_info info;
|
||||
int ret;
|
||||
|
||||
dieid_num_r();
|
||||
|
||||
|
@ -108,12 +111,13 @@ int misc_init_r(void)
|
|||
if (eth_addr)
|
||||
return 0;
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
TAM3517_READ_MAC_FROM_EEPROM;
|
||||
#endif
|
||||
TAM3517_READ_EEPROM(&info, ret);
|
||||
if (!ret)
|
||||
TAM3517_READ_MAC_FROM_EEPROM(&info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Routine: set_muxconf_regs
|
||||
|
|
|
@ -73,10 +73,10 @@ static struct {
|
|||
|
||||
static struct panel_config lcd_cfg[] = {
|
||||
{
|
||||
.timing_h = PANEL_TIMING_H(4, 8, 41),
|
||||
.timing_v = PANEL_TIMING_V(2, 4, 10),
|
||||
.pol_freq = 0x00000000, /* Pol Freq */
|
||||
.divisor = 0x0001000d, /* 33Mhz Pixel Clock */
|
||||
.timing_h = PANEL_TIMING_H(40, 5, 2),
|
||||
.timing_v = PANEL_TIMING_V(8, 8, 2),
|
||||
.pol_freq = 0x00003000, /* Pol Freq */
|
||||
.divisor = 0x00010033, /* 9 Mhz Pixel Clock */
|
||||
.panel_type = 0x01, /* TFT */
|
||||
.data_lines = 0x03, /* 24 Bit RGB */
|
||||
.load_mode = 0x02, /* Frame Mode */
|
||||
|
@ -258,21 +258,26 @@ int board_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
int misc_init_r(void)
|
||||
{
|
||||
char *eth_addr;
|
||||
struct tam3517_module_info info;
|
||||
int ret;
|
||||
|
||||
TAM3517_READ_EEPROM(&info, ret);
|
||||
dieid_num_r();
|
||||
|
||||
eth_addr = getenv("ethaddr");
|
||||
if (eth_addr)
|
||||
if (ret)
|
||||
return 0;
|
||||
eth_addr = getenv("ethaddr");
|
||||
if (!eth_addr)
|
||||
TAM3517_READ_MAC_FROM_EEPROM(&info);
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
TAM3517_READ_MAC_FROM_EEPROM;
|
||||
#endif
|
||||
TAM3517_PRINT_SOM_INFO(&info);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Routine: set_muxconf_regs
|
||||
|
|
|
@ -44,7 +44,7 @@ static struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE;
|
|||
|
||||
/* MII mode defines */
|
||||
#define MII_MODE_ENABLE 0x0
|
||||
#define RGMII_MODE_ENABLE 0xA
|
||||
#define RGMII_MODE_ENABLE 0x3A
|
||||
|
||||
/* GPIO that controls power to DDR on EVM-SK */
|
||||
#define GPIO_DDR_VTT_EN 7
|
||||
|
@ -318,6 +318,8 @@ int board_init(void)
|
|||
|
||||
gd->bd->bi_boot_params = PHYS_DRAM_1 + 0x100;
|
||||
|
||||
gpmc_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -171,6 +171,25 @@ static struct module_pin_mux mii1_pin_mux[] = {
|
|||
{-1},
|
||||
};
|
||||
|
||||
static struct module_pin_mux nand_pin_mux[] = {
|
||||
{OFFSET(gpmc_ad0), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD0 */
|
||||
{OFFSET(gpmc_ad1), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD1 */
|
||||
{OFFSET(gpmc_ad2), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD2 */
|
||||
{OFFSET(gpmc_ad3), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD3 */
|
||||
{OFFSET(gpmc_ad4), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD4 */
|
||||
{OFFSET(gpmc_ad5), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD5 */
|
||||
{OFFSET(gpmc_ad6), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD6 */
|
||||
{OFFSET(gpmc_ad7), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD7 */
|
||||
{OFFSET(gpmc_wait0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* NAND WAIT */
|
||||
{OFFSET(gpmc_wpn), (MODE(7) | PULLUP_EN | RXACTIVE)}, /* NAND_WPN */
|
||||
{OFFSET(gpmc_csn0), (MODE(0) | PULLUDEN)}, /* NAND_CS0 */
|
||||
{OFFSET(gpmc_advn_ale), (MODE(0) | PULLUDEN)}, /* NAND_ADV_ALE */
|
||||
{OFFSET(gpmc_oen_ren), (MODE(0) | PULLUDEN)}, /* NAND_OE */
|
||||
{OFFSET(gpmc_wen), (MODE(0) | PULLUDEN)}, /* NAND_WEN */
|
||||
{OFFSET(gpmc_be0n_cle), (MODE(0) | PULLUDEN)}, /* NAND_BE_CLE */
|
||||
{-1},
|
||||
};
|
||||
|
||||
void enable_uart0_pin_mux(void)
|
||||
{
|
||||
configure_module_pin_mux(uart0_pin_mux);
|
||||
|
@ -257,6 +276,9 @@ void enable_board_pin_mux(struct am335x_baseboard_id *header)
|
|||
/* In profile #2 i2c1 and spi0 conflict. */
|
||||
if (profile & ~PROFILE_2)
|
||||
configure_module_pin_mux(i2c1_pin_mux);
|
||||
/* Profiles 2 & 3 don't have NAND */
|
||||
if (profile & ~(PROFILE_2 | PROFILE_3))
|
||||
configure_module_pin_mux(nand_pin_mux);
|
||||
else if (profile == PROFILE_2) {
|
||||
configure_module_pin_mux(mmc1_pin_mux);
|
||||
configure_module_pin_mux(spi0_pin_mux);
|
||||
|
|
|
@ -144,8 +144,7 @@ static int get_board_revision(void)
|
|||
* Description: If we use SPL then there is no x-loader nor config header
|
||||
* so we have to setup the DDR timings ourself on both banks.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
int pop_mfr, pop_id;
|
||||
|
||||
|
@ -156,29 +155,29 @@ void get_board_mem_timings(u32 *mcfg, u32 *ctrla, u32 *ctrlb, u32 *rfr_ctrl,
|
|||
*/
|
||||
identify_nand_chip(&pop_mfr, &pop_id);
|
||||
|
||||
*mr = MICRON_V_MR_165;
|
||||
timings->mr = MICRON_V_MR_165;
|
||||
switch (get_board_revision()) {
|
||||
case REVISION_C4:
|
||||
if (pop_mfr == NAND_MFR_STMICRO && pop_id == 0xba) {
|
||||
/* 512MB DDR */
|
||||
*mcfg = NUMONYX_V_MCFG_165(512 << 20);
|
||||
*ctrla = NUMONYX_V_ACTIMA_165;
|
||||
*ctrlb = NUMONYX_V_ACTIMB_165;
|
||||
*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
timings->mcfg = NUMONYX_V_MCFG_165(512 << 20);
|
||||
timings->ctrla = NUMONYX_V_ACTIMA_165;
|
||||
timings->ctrlb = NUMONYX_V_ACTIMB_165;
|
||||
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
break;
|
||||
} else if (pop_mfr == NAND_MFR_MICRON && pop_id == 0xba) {
|
||||
/* Beagleboard Rev C4, 512MB Nand/256MB DDR*/
|
||||
*mcfg = MICRON_V_MCFG_165(128 << 20);
|
||||
*ctrla = MICRON_V_ACTIMA_165;
|
||||
*ctrlb = MICRON_V_ACTIMB_165;
|
||||
*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
timings->mcfg = MICRON_V_MCFG_165(128 << 20);
|
||||
timings->ctrla = MICRON_V_ACTIMA_165;
|
||||
timings->ctrlb = MICRON_V_ACTIMB_165;
|
||||
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
break;
|
||||
} else if (pop_mfr == NAND_MFR_MICRON && pop_id == 0xbc) {
|
||||
/* Beagleboard Rev C5, 256MB DDR */
|
||||
*mcfg = MICRON_V_MCFG_200(256 << 20);
|
||||
*ctrla = MICRON_V_ACTIMA_200;
|
||||
*ctrlb = MICRON_V_ACTIMB_200;
|
||||
*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
|
||||
timings->mcfg = MICRON_V_MCFG_200(256 << 20);
|
||||
timings->ctrla = MICRON_V_ACTIMA_200;
|
||||
timings->ctrlb = MICRON_V_ACTIMB_200;
|
||||
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
|
||||
break;
|
||||
}
|
||||
case REVISION_XM_A:
|
||||
|
@ -186,24 +185,24 @@ void get_board_mem_timings(u32 *mcfg, u32 *ctrla, u32 *ctrlb, u32 *rfr_ctrl,
|
|||
case REVISION_XM_C:
|
||||
if (pop_mfr == 0) {
|
||||
/* 256MB DDR */
|
||||
*mcfg = MICRON_V_MCFG_200(256 << 20);
|
||||
*ctrla = MICRON_V_ACTIMA_200;
|
||||
*ctrlb = MICRON_V_ACTIMB_200;
|
||||
*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
|
||||
timings->mcfg = MICRON_V_MCFG_200(256 << 20);
|
||||
timings->ctrla = MICRON_V_ACTIMA_200;
|
||||
timings->ctrlb = MICRON_V_ACTIMB_200;
|
||||
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
|
||||
} else {
|
||||
/* 512MB DDR */
|
||||
*mcfg = NUMONYX_V_MCFG_165(512 << 20);
|
||||
*ctrla = NUMONYX_V_ACTIMA_165;
|
||||
*ctrlb = NUMONYX_V_ACTIMB_165;
|
||||
*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
timings->mcfg = NUMONYX_V_MCFG_165(512 << 20);
|
||||
timings->ctrla = NUMONYX_V_ACTIMA_165;
|
||||
timings->ctrlb = NUMONYX_V_ACTIMB_165;
|
||||
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Assume 128MB and Micron/165MHz timings to be safe */
|
||||
*mcfg = MICRON_V_MCFG_165(128 << 20);
|
||||
*ctrla = MICRON_V_ACTIMA_165;
|
||||
*ctrlb = MICRON_V_ACTIMB_165;
|
||||
*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
timings->mcfg = MICRON_V_MCFG_165(128 << 20);
|
||||
timings->ctrla = MICRON_V_ACTIMA_165;
|
||||
timings->ctrlb = MICRON_V_ACTIMB_165;
|
||||
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -128,8 +128,7 @@ int board_init(void)
|
|||
* provides the timing values back to the function that configures
|
||||
* the memory.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
int pop_mfr, pop_id;
|
||||
|
||||
|
@ -142,17 +141,17 @@ void get_board_mem_timings(u32 *mcfg, u32 *ctrla, u32 *ctrlb, u32 *rfr_ctrl,
|
|||
|
||||
if (pop_mfr == NAND_MFR_HYNIX && pop_id == 0xbc) {
|
||||
/* 256MB DDR */
|
||||
*mcfg = HYNIX_V_MCFG_200(256 << 20);
|
||||
*ctrla = HYNIX_V_ACTIMA_200;
|
||||
*ctrlb = HYNIX_V_ACTIMB_200;
|
||||
timings->mcfg = HYNIX_V_MCFG_200(256 << 20);
|
||||
timings->ctrla = HYNIX_V_ACTIMA_200;
|
||||
timings->ctrlb = HYNIX_V_ACTIMB_200;
|
||||
} else {
|
||||
/* 128MB DDR */
|
||||
*mcfg = MICRON_V_MCFG_165(128 << 20);
|
||||
*ctrla = MICRON_V_ACTIMA_165;
|
||||
*ctrlb = MICRON_V_ACTIMB_165;
|
||||
timings->mcfg = MICRON_V_MCFG_165(128 << 20);
|
||||
timings->ctrla = MICRON_V_ACTIMA_165;
|
||||
timings->ctrlb = MICRON_V_ACTIMB_165;
|
||||
}
|
||||
*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
*mr = MICRON_V_MR_165;
|
||||
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
timings->mr = MICRON_V_MR_165;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -188,16 +188,15 @@ int spl_start_uboot(void)
|
|||
* provides the timing values back to the function that configures
|
||||
* the memory. We have either one or two banks of 128MB DDR.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
/* General SDRC config */
|
||||
*mcfg = MICRON_V_MCFG_165(128 << 20);
|
||||
*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
timings->mcfg = MICRON_V_MCFG_165(128 << 20);
|
||||
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
|
||||
|
||||
/* AC timings */
|
||||
*ctrla = MICRON_V_ACTIMA_165;
|
||||
*ctrlb = MICRON_V_ACTIMB_165;
|
||||
timings->ctrla = MICRON_V_ACTIMA_165;
|
||||
timings->ctrlb = MICRON_V_ACTIMB_165;
|
||||
|
||||
*mr = MICRON_V_MR_165;
|
||||
timings->mr = MICRON_V_MR_165;
|
||||
}
|
||||
|
|
|
@ -53,18 +53,14 @@ static inline int get_gpio_index(int gpio)
|
|||
return gpio & 0x1f;
|
||||
}
|
||||
|
||||
static inline int gpio_valid(int gpio)
|
||||
int gpio_is_valid(int gpio)
|
||||
{
|
||||
if (gpio < 0)
|
||||
return -1;
|
||||
if (gpio < 192)
|
||||
return 0;
|
||||
return -1;
|
||||
return (gpio >= 0) && (gpio < 192);
|
||||
}
|
||||
|
||||
static int check_gpio(int gpio)
|
||||
{
|
||||
if (gpio_valid(gpio) < 0) {
|
||||
if (!gpio_is_valid(gpio)) {
|
||||
printf("ERROR : check_gpio: invalid GPIO %d\n", gpio);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||
|
||||
#define I2C_TIMEOUT 1000
|
||||
|
||||
static void wait_for_bb(void);
|
||||
static int wait_for_bb(void);
|
||||
static u16 wait_for_pin(void);
|
||||
static void flush_fifo(void);
|
||||
|
||||
|
@ -159,7 +159,8 @@ static int i2c_read_byte(u8 devaddr, u16 regoffset, u8 alen, u8 *value)
|
|||
u16 w;
|
||||
|
||||
/* wait until bus not busy */
|
||||
wait_for_bb();
|
||||
if (wait_for_bb())
|
||||
return 1;
|
||||
|
||||
/* one byte only */
|
||||
writew(alen, &i2c_base->cnt);
|
||||
|
@ -263,7 +264,8 @@ int i2c_probe(uchar chip)
|
|||
return res;
|
||||
|
||||
/* wait until bus not busy */
|
||||
wait_for_bb();
|
||||
if (wait_for_bb())
|
||||
return res;
|
||||
|
||||
/* try to read one byte */
|
||||
writew(1, &i2c_base->cnt);
|
||||
|
@ -282,7 +284,10 @@ int i2c_probe(uchar chip)
|
|||
res = 1;
|
||||
writew(0xff, &i2c_base->stat);
|
||||
writew (readw (&i2c_base->con) | I2C_CON_STP, &i2c_base->con);
|
||||
wait_for_bb ();
|
||||
|
||||
if (wait_for_bb())
|
||||
res = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
if (status & I2C_STAT_ARDY) {
|
||||
|
@ -355,7 +360,8 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
|
|||
}
|
||||
|
||||
/* wait until bus not busy */
|
||||
wait_for_bb();
|
||||
if (wait_for_bb())
|
||||
return 1;
|
||||
|
||||
/* start address phase - will write regoffset + len bytes data */
|
||||
/* TODO consider case when !CONFIG_OMAP243X/34XX/44XX */
|
||||
|
@ -399,7 +405,7 @@ write_exit:
|
|||
return i2c_error;
|
||||
}
|
||||
|
||||
static void wait_for_bb(void)
|
||||
static int wait_for_bb(void)
|
||||
{
|
||||
int timeout = I2C_TIMEOUT;
|
||||
u16 stat;
|
||||
|
@ -413,8 +419,10 @@ static void wait_for_bb(void)
|
|||
if (timeout <= 0) {
|
||||
printf("timed out in wait_for_bb: I2C_STAT=%x\n",
|
||||
readw(&i2c_base->stat));
|
||||
return 1;
|
||||
}
|
||||
writew(0xFFFF, &i2c_base->stat); /* clear delayed stuff*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u16 wait_for_pin(void)
|
||||
|
|
|
@ -33,6 +33,7 @@ ifdef CONFIG_SPL_NAND_DRIVERS
|
|||
NORMAL_DRIVERS=y
|
||||
endif
|
||||
|
||||
COBJS-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o
|
||||
COBJS-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o
|
||||
COBJS-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o
|
||||
COBJS-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o
|
||||
|
@ -78,10 +79,6 @@ COBJS-$(CONFIG_TEGRA_NAND) += tegra_nand.o
|
|||
COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
|
||||
COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o
|
||||
|
||||
else # minimal SPL drivers
|
||||
|
||||
COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_spl.o
|
||||
|
||||
endif # drivers
|
||||
endif # nand
|
||||
|
||||
|
|
238
drivers/mtd/nand/am335x_spl_bch.c
Normal file
238
drivers/mtd/nand/am335x_spl_bch.c
Normal file
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
* (C) Copyright 2012
|
||||
* Konstantin Kozhevnikov, Cogent Embedded
|
||||
*
|
||||
* based on nand_spl_simple code
|
||||
*
|
||||
* (C) Copyright 2006-2008
|
||||
* Stefan Roese, DENX Software Engineering, sr@denx.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.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <nand.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/mtd/nand_ecc.h>
|
||||
|
||||
static int nand_ecc_pos[] = CONFIG_SYS_NAND_ECCPOS;
|
||||
static nand_info_t mtd;
|
||||
static struct nand_chip nand_chip;
|
||||
|
||||
#define ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \
|
||||
CONFIG_SYS_NAND_ECCSIZE)
|
||||
#define ECCTOTAL (ECCSTEPS * CONFIG_SYS_NAND_ECCBYTES)
|
||||
|
||||
|
||||
/*
|
||||
* NAND command for large page NAND devices (2k)
|
||||
*/
|
||||
static int nand_command(int block, int page, uint32_t offs,
|
||||
u8 cmd)
|
||||
{
|
||||
struct nand_chip *this = mtd.priv;
|
||||
int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT;
|
||||
void (*hwctrl)(struct mtd_info *mtd, int cmd,
|
||||
unsigned int ctrl) = this->cmd_ctrl;
|
||||
|
||||
while (!this->dev_ready(&mtd))
|
||||
;
|
||||
|
||||
/* Emulate NAND_CMD_READOOB */
|
||||
if (cmd == NAND_CMD_READOOB) {
|
||||
offs += CONFIG_SYS_NAND_PAGE_SIZE;
|
||||
cmd = NAND_CMD_READ0;
|
||||
}
|
||||
|
||||
/* Begin command latch cycle */
|
||||
hwctrl(&mtd, cmd, NAND_CTRL_CLE | NAND_CTRL_CHANGE);
|
||||
|
||||
if (cmd == NAND_CMD_RESET) {
|
||||
hwctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
|
||||
while (!this->dev_ready(&mtd))
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Shift the offset from byte addressing to word addressing. */
|
||||
if (this->options & NAND_BUSWIDTH_16)
|
||||
offs >>= 1;
|
||||
|
||||
/* Set ALE and clear CLE to start address cycle */
|
||||
/* Column address */
|
||||
hwctrl(&mtd, offs & 0xff,
|
||||
NAND_CTRL_ALE | NAND_CTRL_CHANGE); /* A[7:0] */
|
||||
hwctrl(&mtd, (offs >> 8) & 0xff, NAND_CTRL_ALE); /* A[11:9] */
|
||||
/* Row address */
|
||||
hwctrl(&mtd, (page_addr & 0xff), NAND_CTRL_ALE); /* A[19:12] */
|
||||
hwctrl(&mtd, ((page_addr >> 8) & 0xff),
|
||||
NAND_CTRL_ALE); /* A[27:20] */
|
||||
#ifdef CONFIG_SYS_NAND_5_ADDR_CYCLE
|
||||
/* One more address cycle for devices > 128MiB */
|
||||
hwctrl(&mtd, (page_addr >> 16) & 0x0f,
|
||||
NAND_CTRL_ALE); /* A[31:28] */
|
||||
#endif
|
||||
hwctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
|
||||
|
||||
if (cmd == NAND_CMD_READ0) {
|
||||
/* Latch in address */
|
||||
hwctrl(&mtd, NAND_CMD_READSTART,
|
||||
NAND_CTRL_CLE | NAND_CTRL_CHANGE);
|
||||
hwctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
|
||||
|
||||
/*
|
||||
* Wait a while for the data to be ready
|
||||
*/
|
||||
while (!this->dev_ready(&mtd))
|
||||
;
|
||||
} else if (cmd == NAND_CMD_RNDOUT) {
|
||||
hwctrl(&mtd, NAND_CMD_RNDOUTSTART, NAND_CTRL_CLE |
|
||||
NAND_CTRL_CHANGE);
|
||||
hwctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nand_is_bad_block(int block)
|
||||
{
|
||||
struct nand_chip *this = mtd.priv;
|
||||
|
||||
nand_command(block, 0, CONFIG_SYS_NAND_BAD_BLOCK_POS,
|
||||
NAND_CMD_READOOB);
|
||||
|
||||
/*
|
||||
* Read one byte (or two if it's a 16 bit chip).
|
||||
*/
|
||||
if (this->options & NAND_BUSWIDTH_16) {
|
||||
if (readw(this->IO_ADDR_R) != 0xffff)
|
||||
return 1;
|
||||
} else {
|
||||
if (readb(this->IO_ADDR_R) != 0xff)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nand_read_page(int block, int page, void *dst)
|
||||
{
|
||||
struct nand_chip *this = mtd.priv;
|
||||
u_char ecc_calc[ECCTOTAL];
|
||||
u_char ecc_code[ECCTOTAL];
|
||||
u_char oob_data[CONFIG_SYS_NAND_OOBSIZE];
|
||||
int i;
|
||||
int eccsize = CONFIG_SYS_NAND_ECCSIZE;
|
||||
int eccbytes = CONFIG_SYS_NAND_ECCBYTES;
|
||||
int eccsteps = ECCSTEPS;
|
||||
uint8_t *p = dst;
|
||||
uint32_t data_pos = 0;
|
||||
uint8_t *oob = &oob_data[0] + nand_ecc_pos[0];
|
||||
uint32_t oob_pos = eccsize * eccsteps + nand_ecc_pos[0];
|
||||
|
||||
nand_command(block, page, 0, NAND_CMD_READ0);
|
||||
|
||||
for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
|
||||
this->ecc.hwctl(&mtd, NAND_ECC_READ);
|
||||
nand_command(block, page, data_pos, NAND_CMD_RNDOUT);
|
||||
|
||||
this->read_buf(&mtd, p, eccsize);
|
||||
|
||||
nand_command(block, page, oob_pos, NAND_CMD_RNDOUT);
|
||||
|
||||
this->read_buf(&mtd, oob, eccbytes);
|
||||
this->ecc.calculate(&mtd, p, &ecc_calc[i]);
|
||||
|
||||
data_pos += eccsize;
|
||||
oob_pos += eccbytes;
|
||||
oob += eccbytes;
|
||||
}
|
||||
|
||||
/* Pick the ECC bytes out of the oob data */
|
||||
for (i = 0; i < ECCTOTAL; i++)
|
||||
ecc_code[i] = oob_data[nand_ecc_pos[i]];
|
||||
|
||||
eccsteps = ECCSTEPS;
|
||||
p = dst;
|
||||
|
||||
for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
|
||||
/* No chance to do something with the possible error message
|
||||
* from correct_data(). We just hope that all possible errors
|
||||
* are corrected by this routine.
|
||||
*/
|
||||
this->ecc.correct(&mtd, p, &ecc_code[i], &ecc_calc[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
|
||||
{
|
||||
unsigned int block, lastblock;
|
||||
unsigned int page;
|
||||
|
||||
/*
|
||||
* offs has to be aligned to a page address!
|
||||
*/
|
||||
block = offs / CONFIG_SYS_NAND_BLOCK_SIZE;
|
||||
lastblock = (offs + size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE;
|
||||
page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE;
|
||||
|
||||
while (block <= lastblock) {
|
||||
if (!nand_is_bad_block(block)) {
|
||||
/*
|
||||
* Skip bad blocks
|
||||
*/
|
||||
while (page < CONFIG_SYS_NAND_PAGE_COUNT) {
|
||||
nand_read_page(block, page, dst);
|
||||
dst += CONFIG_SYS_NAND_PAGE_SIZE;
|
||||
page++;
|
||||
}
|
||||
|
||||
page = 0;
|
||||
} else {
|
||||
lastblock++;
|
||||
}
|
||||
|
||||
block++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* nand_init() - initialize data to make nand usable by SPL */
|
||||
void nand_init(void)
|
||||
{
|
||||
/*
|
||||
* Init board specific nand support
|
||||
*/
|
||||
mtd.priv = &nand_chip;
|
||||
nand_chip.IO_ADDR_R = nand_chip.IO_ADDR_W =
|
||||
(void __iomem *)CONFIG_SYS_NAND_BASE;
|
||||
board_nand_init(&nand_chip);
|
||||
|
||||
if (nand_chip.select_chip)
|
||||
nand_chip.select_chip(&mtd, 0);
|
||||
|
||||
/* NAND chip may require reset after power-on */
|
||||
nand_command(0, 0, 0, NAND_CMD_RESET);
|
||||
}
|
||||
|
||||
/* Unselect after operation */
|
||||
void nand_deselect(void)
|
||||
{
|
||||
if (nand_chip.select_chip)
|
||||
nand_chip.select_chip(&mtd, -1);
|
||||
}
|
|
@ -29,6 +29,9 @@
|
|||
#include <linux/mtd/nand_ecc.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <nand.h>
|
||||
#ifdef CONFIG_AM33XX
|
||||
#include <asm/arch/elm.h>
|
||||
#endif
|
||||
|
||||
static uint8_t cs;
|
||||
static __maybe_unused struct nand_ecclayout hw_nand_oob =
|
||||
|
@ -234,6 +237,370 @@ static void __maybe_unused omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* BCH8 support (needs ELM and thus AM33xx-only)
|
||||
*/
|
||||
#ifdef CONFIG_AM33XX
|
||||
struct nand_bch_priv {
|
||||
uint8_t mode;
|
||||
uint8_t type;
|
||||
uint8_t nibbles;
|
||||
};
|
||||
|
||||
/* bch types */
|
||||
#define ECC_BCH4 0
|
||||
#define ECC_BCH8 1
|
||||
#define ECC_BCH16 2
|
||||
|
||||
/* BCH nibbles for diff bch levels */
|
||||
#define NAND_ECC_HW_BCH ((uint8_t)(NAND_ECC_HW_OOB_FIRST) + 1)
|
||||
#define ECC_BCH4_NIBBLES 13
|
||||
#define ECC_BCH8_NIBBLES 26
|
||||
#define ECC_BCH16_NIBBLES 52
|
||||
|
||||
static struct nand_ecclayout hw_bch8_nand_oob = GPMC_NAND_HW_BCH8_ECC_LAYOUT;
|
||||
|
||||
static struct nand_bch_priv bch_priv = {
|
||||
.mode = NAND_ECC_HW_BCH,
|
||||
.type = ECC_BCH8,
|
||||
.nibbles = ECC_BCH8_NIBBLES
|
||||
};
|
||||
|
||||
/*
|
||||
* omap_read_bch8_result - Read BCH result for BCH8 level
|
||||
*
|
||||
* @mtd: MTD device structure
|
||||
* @big_endian: When set read register 3 first
|
||||
* @ecc_code: Read syndrome from BCH result registers
|
||||
*/
|
||||
static void omap_read_bch8_result(struct mtd_info *mtd, uint8_t big_endian,
|
||||
uint8_t *ecc_code)
|
||||
{
|
||||
uint32_t *ptr;
|
||||
int8_t i = 0, j;
|
||||
|
||||
if (big_endian) {
|
||||
ptr = &gpmc_cfg->bch_result_0_3[0].bch_result_x[3];
|
||||
ecc_code[i++] = readl(ptr) & 0xFF;
|
||||
ptr--;
|
||||
for (j = 0; j < 3; j++) {
|
||||
ecc_code[i++] = (readl(ptr) >> 24) & 0xFF;
|
||||
ecc_code[i++] = (readl(ptr) >> 16) & 0xFF;
|
||||
ecc_code[i++] = (readl(ptr) >> 8) & 0xFF;
|
||||
ecc_code[i++] = readl(ptr) & 0xFF;
|
||||
ptr--;
|
||||
}
|
||||
} else {
|
||||
ptr = &gpmc_cfg->bch_result_0_3[0].bch_result_x[0];
|
||||
for (j = 0; j < 3; j++) {
|
||||
ecc_code[i++] = readl(ptr) & 0xFF;
|
||||
ecc_code[i++] = (readl(ptr) >> 8) & 0xFF;
|
||||
ecc_code[i++] = (readl(ptr) >> 16) & 0xFF;
|
||||
ecc_code[i++] = (readl(ptr) >> 24) & 0xFF;
|
||||
ptr++;
|
||||
}
|
||||
ecc_code[i++] = readl(ptr) & 0xFF;
|
||||
ecc_code[i++] = 0; /* 14th byte is always zero */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* omap_ecc_disable - Disable H/W ECC calculation
|
||||
*
|
||||
* @mtd: MTD device structure
|
||||
*
|
||||
*/
|
||||
static void omap_ecc_disable(struct mtd_info *mtd)
|
||||
{
|
||||
writel((readl(&gpmc_cfg->ecc_config) & ~0x1),
|
||||
&gpmc_cfg->ecc_config);
|
||||
}
|
||||
|
||||
/*
|
||||
* omap_rotate_ecc_bch - Rotate the syndrome bytes
|
||||
*
|
||||
* @mtd: MTD device structure
|
||||
* @calc_ecc: ECC read from ECC registers
|
||||
* @syndrome: Rotated syndrome will be retuned in this array
|
||||
*
|
||||
*/
|
||||
static void omap_rotate_ecc_bch(struct mtd_info *mtd, uint8_t *calc_ecc,
|
||||
uint8_t *syndrome)
|
||||
{
|
||||
struct nand_chip *chip = mtd->priv;
|
||||
struct nand_bch_priv *bch = chip->priv;
|
||||
uint8_t n_bytes = 0;
|
||||
int8_t i, j;
|
||||
|
||||
switch (bch->type) {
|
||||
case ECC_BCH4:
|
||||
n_bytes = 8;
|
||||
break;
|
||||
|
||||
case ECC_BCH16:
|
||||
n_bytes = 28;
|
||||
break;
|
||||
|
||||
case ECC_BCH8:
|
||||
default:
|
||||
n_bytes = 13;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0, j = (n_bytes-1); i < n_bytes; i++, j--)
|
||||
syndrome[i] = calc_ecc[j];
|
||||
}
|
||||
|
||||
/*
|
||||
* omap_calculate_ecc_bch - Read BCH ECC result
|
||||
*
|
||||
* @mtd: MTD structure
|
||||
* @dat: unused
|
||||
* @ecc_code: ecc_code buffer
|
||||
*/
|
||||
static int omap_calculate_ecc_bch(struct mtd_info *mtd, const uint8_t *dat,
|
||||
uint8_t *ecc_code)
|
||||
{
|
||||
struct nand_chip *chip = mtd->priv;
|
||||
struct nand_bch_priv *bch = chip->priv;
|
||||
uint8_t big_endian = 1;
|
||||
int8_t ret = 0;
|
||||
|
||||
if (bch->type == ECC_BCH8)
|
||||
omap_read_bch8_result(mtd, big_endian, ecc_code);
|
||||
else /* BCH4 and BCH16 currently not supported */
|
||||
ret = -1;
|
||||
|
||||
/*
|
||||
* Stop reading anymore ECC vals and clear old results
|
||||
* enable will be called if more reads are required
|
||||
*/
|
||||
omap_ecc_disable(mtd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* omap_fix_errors_bch - Correct bch error in the data
|
||||
*
|
||||
* @mtd: MTD device structure
|
||||
* @data: Data read from flash
|
||||
* @error_count:Number of errors in data
|
||||
* @error_loc: Locations of errors in the data
|
||||
*
|
||||
*/
|
||||
static void omap_fix_errors_bch(struct mtd_info *mtd, uint8_t *data,
|
||||
uint32_t error_count, uint32_t *error_loc)
|
||||
{
|
||||
struct nand_chip *chip = mtd->priv;
|
||||
struct nand_bch_priv *bch = chip->priv;
|
||||
uint8_t count = 0;
|
||||
uint32_t error_byte_pos;
|
||||
uint32_t error_bit_mask;
|
||||
uint32_t last_bit = (bch->nibbles * 4) - 1;
|
||||
|
||||
/* Flip all bits as specified by the error location array. */
|
||||
/* FOR( each found error location flip the bit ) */
|
||||
for (count = 0; count < error_count; count++) {
|
||||
if (error_loc[count] > last_bit) {
|
||||
/* Remove the ECC spare bits from correction. */
|
||||
error_loc[count] -= (last_bit + 1);
|
||||
/* Offset bit in data region */
|
||||
error_byte_pos = ((512 * 8) -
|
||||
(error_loc[count]) - 1) / 8;
|
||||
/* Error Bit mask */
|
||||
error_bit_mask = 0x1 << (error_loc[count] % 8);
|
||||
/* Toggle the error bit to make the correction. */
|
||||
data[error_byte_pos] ^= error_bit_mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* omap_correct_data_bch - Compares the ecc read from nand spare area
|
||||
* with ECC registers values and corrects one bit error if it has occured
|
||||
*
|
||||
* @mtd: MTD device structure
|
||||
* @dat: page data
|
||||
* @read_ecc: ecc read from nand flash (ignored)
|
||||
* @calc_ecc: ecc read from ECC registers
|
||||
*
|
||||
* @return 0 if data is OK or corrected, else returns -1
|
||||
*/
|
||||
static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
|
||||
uint8_t *read_ecc, uint8_t *calc_ecc)
|
||||
{
|
||||
struct nand_chip *chip = mtd->priv;
|
||||
struct nand_bch_priv *bch = chip->priv;
|
||||
uint8_t syndrome[28];
|
||||
uint32_t error_count = 0;
|
||||
uint32_t error_loc[8];
|
||||
uint32_t i, ecc_flag;
|
||||
|
||||
ecc_flag = 0;
|
||||
for (i = 0; i < chip->ecc.bytes; i++)
|
||||
if (read_ecc[i] != 0xff)
|
||||
ecc_flag = 1;
|
||||
|
||||
if (!ecc_flag)
|
||||
return 0;
|
||||
|
||||
elm_reset();
|
||||
elm_config((enum bch_level)(bch->type));
|
||||
|
||||
/*
|
||||
* while reading ECC result we read it in big endian.
|
||||
* Hence while loading to ELM we have rotate to get the right endian.
|
||||
*/
|
||||
omap_rotate_ecc_bch(mtd, calc_ecc, syndrome);
|
||||
|
||||
/* use elm module to check for errors */
|
||||
if (elm_check_error(syndrome, bch->nibbles, &error_count,
|
||||
error_loc) != 0) {
|
||||
printf("ECC: uncorrectable.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* correct bch error */
|
||||
if (error_count > 0)
|
||||
omap_fix_errors_bch(mtd, dat, error_count, error_loc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* omap_hwecc_init_bch - Initialize the BCH Hardware ECC for NAND flash in
|
||||
* GPMC controller
|
||||
* @mtd: MTD device structure
|
||||
* @mode: Read/Write mode
|
||||
*/
|
||||
static void omap_hwecc_init_bch(struct nand_chip *chip, int32_t mode)
|
||||
{
|
||||
uint32_t val, dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1;
|
||||
uint32_t unused_length = 0;
|
||||
struct nand_bch_priv *bch = chip->priv;
|
||||
|
||||
switch (bch->nibbles) {
|
||||
case ECC_BCH4_NIBBLES:
|
||||
unused_length = 3;
|
||||
break;
|
||||
case ECC_BCH8_NIBBLES:
|
||||
unused_length = 2;
|
||||
break;
|
||||
case ECC_BCH16_NIBBLES:
|
||||
unused_length = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Clear the ecc result registers, select ecc reg as 1 */
|
||||
writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
|
||||
|
||||
switch (mode) {
|
||||
case NAND_ECC_WRITE:
|
||||
/* eccsize1 config */
|
||||
val = ((unused_length + bch->nibbles) << 22);
|
||||
break;
|
||||
|
||||
case NAND_ECC_READ:
|
||||
default:
|
||||
/* by default eccsize0 selected for ecc1resultsize */
|
||||
/* eccsize0 config */
|
||||
val = (bch->nibbles << 12);
|
||||
/* eccsize1 config */
|
||||
val |= (unused_length << 22);
|
||||
break;
|
||||
}
|
||||
/* ecc size configuration */
|
||||
writel(val, &gpmc_cfg->ecc_size_config);
|
||||
/* by default 512bytes sector page is selected */
|
||||
/* set bch mode */
|
||||
val = (1 << 16);
|
||||
/* bch4 / bch8 / bch16 */
|
||||
val |= (bch->type << 12);
|
||||
/* set wrap mode to 1 */
|
||||
val |= (1 << 8);
|
||||
val |= (dev_width << 7);
|
||||
val |= (cs << 1);
|
||||
writel(val, &gpmc_cfg->ecc_config);
|
||||
}
|
||||
|
||||
/*
|
||||
* omap_enable_ecc_bch- This function enables the bch h/w ecc functionality
|
||||
* @mtd: MTD device structure
|
||||
* @mode: Read/Write mode
|
||||
*
|
||||
*/
|
||||
static void omap_enable_ecc_bch(struct mtd_info *mtd, int32_t mode)
|
||||
{
|
||||
struct nand_chip *chip = mtd->priv;
|
||||
|
||||
omap_hwecc_init_bch(chip, mode);
|
||||
/* enable ecc */
|
||||
writel((readl(&gpmc_cfg->ecc_config) | 0x1), &gpmc_cfg->ecc_config);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap_read_page_bch - hardware ecc based page read function
|
||||
* @mtd: mtd info structure
|
||||
* @chip: nand chip info structure
|
||||
* @buf: buffer to store read data
|
||||
* @page: page number to read
|
||||
*
|
||||
*/
|
||||
static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
uint8_t *buf, int page)
|
||||
{
|
||||
int i, eccsize = chip->ecc.size;
|
||||
int eccbytes = chip->ecc.bytes;
|
||||
int eccsteps = chip->ecc.steps;
|
||||
uint8_t *p = buf;
|
||||
uint8_t *ecc_calc = chip->buffers->ecccalc;
|
||||
uint8_t *ecc_code = chip->buffers->ecccode;
|
||||
uint32_t *eccpos = chip->ecc.layout->eccpos;
|
||||
uint8_t *oob = chip->oob_poi;
|
||||
uint32_t data_pos;
|
||||
uint32_t oob_pos;
|
||||
|
||||
data_pos = 0;
|
||||
/* oob area start */
|
||||
oob_pos = (eccsize * eccsteps) + chip->ecc.layout->eccpos[0];
|
||||
oob += chip->ecc.layout->eccpos[0];
|
||||
|
||||
for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize,
|
||||
oob += eccbytes) {
|
||||
chip->ecc.hwctl(mtd, NAND_ECC_READ);
|
||||
/* read data */
|
||||
chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_pos, page);
|
||||
chip->read_buf(mtd, p, eccsize);
|
||||
|
||||
/* read respective ecc from oob area */
|
||||
chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, page);
|
||||
chip->read_buf(mtd, oob, eccbytes);
|
||||
/* read syndrome */
|
||||
chip->ecc.calculate(mtd, p, &ecc_calc[i]);
|
||||
|
||||
data_pos += eccsize;
|
||||
oob_pos += eccbytes;
|
||||
}
|
||||
|
||||
for (i = 0; i < chip->ecc.total; i++)
|
||||
ecc_code[i] = chip->oob_poi[eccpos[i]];
|
||||
|
||||
eccsteps = chip->ecc.steps;
|
||||
p = buf;
|
||||
|
||||
for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
|
||||
int stat;
|
||||
|
||||
stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
|
||||
if (stat < 0)
|
||||
mtd->ecc_stats.failed++;
|
||||
else
|
||||
mtd->ecc_stats.corrected += stat;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_AM33XX */
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
/*
|
||||
* omap_nand_switch_ecc - switch the ECC operation b/w h/w ecc and s/w ecc.
|
||||
|
@ -269,7 +636,7 @@ void omap_nand_switch_ecc(int32_t hardware)
|
|||
nand->ecc.calculate = NULL;
|
||||
|
||||
/* Setup the ecc configurations again */
|
||||
if (hardware) {
|
||||
if (hardware == 1) {
|
||||
nand->ecc.mode = NAND_ECC_HW;
|
||||
nand->ecc.layout = &hw_nand_oob;
|
||||
nand->ecc.size = 512;
|
||||
|
@ -279,6 +646,19 @@ void omap_nand_switch_ecc(int32_t hardware)
|
|||
nand->ecc.calculate = omap_calculate_ecc;
|
||||
omap_hwecc_init(nand);
|
||||
printf("HW ECC selected\n");
|
||||
#ifdef CONFIG_AM33XX
|
||||
} else if (hardware == 2) {
|
||||
nand->ecc.mode = NAND_ECC_HW;
|
||||
nand->ecc.layout = &hw_bch8_nand_oob;
|
||||
nand->ecc.size = 512;
|
||||
nand->ecc.bytes = 14;
|
||||
nand->ecc.read_page = omap_read_page_bch;
|
||||
nand->ecc.hwctl = omap_enable_ecc_bch;
|
||||
nand->ecc.correct = omap_correct_data_bch;
|
||||
nand->ecc.calculate = omap_calculate_ecc_bch;
|
||||
omap_hwecc_init_bch(nand, NAND_ECC_READ);
|
||||
printf("HW BCH8 selected\n");
|
||||
#endif
|
||||
} else {
|
||||
nand->ecc.mode = NAND_ECC_SOFT;
|
||||
/* Use mtd default settings */
|
||||
|
@ -350,7 +730,27 @@ int board_nand_init(struct nand_chip *nand)
|
|||
nand->options |= NAND_BUSWIDTH_16;
|
||||
|
||||
nand->chip_delay = 100;
|
||||
|
||||
#ifdef CONFIG_AM33XX
|
||||
/* required in case of BCH */
|
||||
elm_init();
|
||||
|
||||
/* BCH info that will be correct for SPL or overridden otherwise. */
|
||||
nand->priv = &bch_priv;
|
||||
#endif
|
||||
|
||||
/* Default ECC mode */
|
||||
#ifdef CONFIG_AM33XX
|
||||
nand->ecc.mode = NAND_ECC_HW;
|
||||
nand->ecc.layout = &hw_bch8_nand_oob;
|
||||
nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
|
||||
nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
|
||||
nand->ecc.hwctl = omap_enable_ecc_bch;
|
||||
nand->ecc.correct = omap_correct_data_bch;
|
||||
nand->ecc.calculate = omap_calculate_ecc_bch;
|
||||
nand->ecc.read_page = omap_read_page_bch;
|
||||
omap_hwecc_init_bch(nand, NAND_ECC_READ);
|
||||
#else
|
||||
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_NAND_SOFTECC)
|
||||
nand->ecc.mode = NAND_ECC_SOFT;
|
||||
#else
|
||||
|
@ -363,6 +763,7 @@ int board_nand_init(struct nand_chip *nand)
|
|||
nand->ecc.calculate = omap_calculate_ecc;
|
||||
omap_hwecc_init(nand);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
if (nand->options & NAND_BUSWIDTH_16)
|
||||
|
|
|
@ -920,7 +920,10 @@ static int cpsw_phy_init(struct eth_device *dev, struct cpsw_slave *slave)
|
|||
SUPPORTED_100baseT_Full |
|
||||
SUPPORTED_1000baseT_Full);
|
||||
|
||||
phydev = phy_connect(priv->bus, 0, dev, slave->data->phy_if);
|
||||
phydev = phy_connect(priv->bus,
|
||||
CONFIG_PHY_ADDR,
|
||||
dev,
|
||||
slave->data->phy_if);
|
||||
|
||||
phydev->supported &= supported;
|
||||
phydev->advertising = phydev->supported;
|
||||
|
|
|
@ -50,16 +50,25 @@ void twl6035_init_settings(void)
|
|||
return;
|
||||
}
|
||||
|
||||
void twl6035_mmc1_poweron_ldo(void)
|
||||
int twl6035_mmc1_poweron_ldo(void)
|
||||
{
|
||||
u8 val = 0;
|
||||
|
||||
/* set LDO9 TWL6035 to 3V */
|
||||
val = 0x2b; /* (3 -.9)*28 +1 */
|
||||
palmas_write_u8(0x48, LDO9_VOLTAGE, val);
|
||||
|
||||
if (palmas_write_u8(0x48, LDO9_VOLTAGE, val)) {
|
||||
printf("twl6035: could not set LDO9 voltage.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* TURN ON LDO9 */
|
||||
val = LDO_ON | LDO_MODE_SLEEP | LDO_MODE_ACTIVE;
|
||||
palmas_write_u8(0x48, LDO9_CTRL, val);
|
||||
return;
|
||||
|
||||
if (palmas_write_u8(0x48, LDO9_CTRL, val)) {
|
||||
printf("twl6035: could not turn on LDO9.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -57,6 +57,20 @@ static void spi_reset(struct omap3_spi_slave *ds)
|
|||
writel(OMAP3_MCSPI_WAKEUPENABLE_WKEN, &ds->regs->wakeupenable);
|
||||
}
|
||||
|
||||
static void omap3_spi_write_chconf(struct omap3_spi_slave *ds, int val)
|
||||
{
|
||||
writel(val, &ds->regs->channel[ds->slave.cs].chconf);
|
||||
/* Flash post writes to make immediate effect */
|
||||
readl(&ds->regs->channel[ds->slave.cs].chconf);
|
||||
}
|
||||
|
||||
static void omap3_spi_set_enable(struct omap3_spi_slave *ds, int enable)
|
||||
{
|
||||
writel(enable, &ds->regs->channel[ds->slave.cs].chctrl);
|
||||
/* Flash post writes to make immediate effect */
|
||||
readl(&ds->regs->channel[ds->slave.cs].chctrl);
|
||||
}
|
||||
|
||||
void spi_init()
|
||||
{
|
||||
/* do nothing */
|
||||
|
@ -212,7 +226,7 @@ int spi_claim_bus(struct spi_slave *slave)
|
|||
/* Transmit & receive mode */
|
||||
conf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
|
||||
|
||||
writel(conf, &ds->regs->channel[ds->slave.cs].chconf);
|
||||
omap3_spi_write_chconf(ds,conf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -233,14 +247,13 @@ int omap3_spi_write(struct spi_slave *slave, unsigned int len, const u8 *txp,
|
|||
int timeout = SPI_WAIT_TIMEOUT;
|
||||
int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
|
||||
|
||||
if (flags & SPI_XFER_BEGIN)
|
||||
writel(OMAP3_MCSPI_CHCTRL_EN,
|
||||
&ds->regs->channel[ds->slave.cs].chctrl);
|
||||
/* Enable the channel */
|
||||
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
|
||||
|
||||
chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
|
||||
chconf |= OMAP3_MCSPI_CHCONF_TRM_TX_ONLY;
|
||||
chconf |= OMAP3_MCSPI_CHCONF_FORCE;
|
||||
writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
|
||||
omap3_spi_write_chconf(ds,chconf);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
/* wait till TX register is empty (TXS == 1) */
|
||||
|
@ -256,15 +269,17 @@ int omap3_spi_write(struct spi_slave *slave, unsigned int len, const u8 *txp,
|
|||
writel(txp[i], &ds->regs->channel[ds->slave.cs].tx);
|
||||
}
|
||||
|
||||
/* wait to finish of transfer */
|
||||
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
|
||||
OMAP3_MCSPI_CHSTAT_EOT));
|
||||
|
||||
/* Disable the channel otherwise the next immediate RX will get affected */
|
||||
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
|
||||
|
||||
if (flags & SPI_XFER_END) {
|
||||
/* wait to finish of transfer */
|
||||
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
|
||||
OMAP3_MCSPI_CHSTAT_EOT));
|
||||
|
||||
chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
|
||||
writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
|
||||
|
||||
writel(0, &ds->regs->channel[ds->slave.cs].chctrl);
|
||||
omap3_spi_write_chconf(ds,chconf);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -277,14 +292,13 @@ int omap3_spi_read(struct spi_slave *slave, unsigned int len, u8 *rxp,
|
|||
int timeout = SPI_WAIT_TIMEOUT;
|
||||
int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
|
||||
|
||||
if (flags & SPI_XFER_BEGIN)
|
||||
writel(OMAP3_MCSPI_CHCTRL_EN,
|
||||
&ds->regs->channel[ds->slave.cs].chctrl);
|
||||
/* Enable the channel */
|
||||
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
|
||||
|
||||
chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
|
||||
chconf |= OMAP3_MCSPI_CHCONF_TRM_RX_ONLY;
|
||||
chconf |= OMAP3_MCSPI_CHCONF_FORCE;
|
||||
writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
|
||||
omap3_spi_write_chconf(ds,chconf);
|
||||
|
||||
writel(0, &ds->regs->channel[ds->slave.cs].tx);
|
||||
|
||||
|
@ -298,15 +312,18 @@ int omap3_spi_read(struct spi_slave *slave, unsigned int len, u8 *rxp,
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable the channel to prevent furher receiving */
|
||||
if(i == (len - 1))
|
||||
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
|
||||
|
||||
/* Read the data */
|
||||
rxp[i] = readl(&ds->regs->channel[ds->slave.cs].rx);
|
||||
}
|
||||
|
||||
if (flags & SPI_XFER_END) {
|
||||
chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
|
||||
writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
|
||||
|
||||
writel(0, &ds->regs->channel[ds->slave.cs].chctrl);
|
||||
omap3_spi_write_chconf(ds,chconf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -323,14 +340,12 @@ int omap3_spi_txrx(struct spi_slave *slave,
|
|||
int i=0;
|
||||
|
||||
/*Enable SPI channel*/
|
||||
if (flags & SPI_XFER_BEGIN)
|
||||
writel(OMAP3_MCSPI_CHCTRL_EN,
|
||||
&ds->regs->channel[ds->slave.cs].chctrl);
|
||||
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
|
||||
|
||||
/*set TRANSMIT-RECEIVE Mode*/
|
||||
chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
|
||||
chconf |= OMAP3_MCSPI_CHCONF_FORCE;
|
||||
writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
|
||||
omap3_spi_write_chconf(ds,chconf);
|
||||
|
||||
/*Shift in and out 1 byte at time*/
|
||||
for (i=0; i < len; i++){
|
||||
|
@ -359,13 +374,13 @@ int omap3_spi_txrx(struct spi_slave *slave,
|
|||
/* Read the data */
|
||||
rxp[i] = readl(&ds->regs->channel[ds->slave.cs].rx);
|
||||
}
|
||||
/* Disable the channel */
|
||||
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
|
||||
|
||||
/*if transfer must be terminated disable the channel*/
|
||||
if (flags & SPI_XFER_END) {
|
||||
chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
|
||||
writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
|
||||
|
||||
writel(0, &ds->regs->channel[ds->slave.cs].chctrl);
|
||||
omap3_spi_write_chconf(ds,chconf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -389,17 +404,14 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
|
|||
int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
|
||||
|
||||
if (flags & SPI_XFER_BEGIN) {
|
||||
writel(OMAP3_MCSPI_CHCTRL_EN,
|
||||
&ds->regs->channel[ds->slave.cs].chctrl);
|
||||
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
|
||||
chconf |= OMAP3_MCSPI_CHCONF_FORCE;
|
||||
writel(chconf,
|
||||
&ds->regs->channel[ds->slave.cs].chconf);
|
||||
omap3_spi_write_chconf(ds,chconf);
|
||||
}
|
||||
if (flags & SPI_XFER_END) {
|
||||
chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
|
||||
writel(chconf,
|
||||
&ds->regs->channel[ds->slave.cs].chconf);
|
||||
writel(0, &ds->regs->channel[ds->slave.cs].chctrl);
|
||||
omap3_spi_write_chconf(ds,chconf);
|
||||
omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
|
||||
}
|
||||
ret = 0;
|
||||
} else {
|
||||
|
|
|
@ -99,6 +99,7 @@ struct mcspi {
|
|||
#define OMAP3_MCSPI_CHSTAT_EOT (1 << 2)
|
||||
|
||||
#define OMAP3_MCSPI_CHCTRL_EN (1 << 0)
|
||||
#define OMAP3_MCSPI_CHCTRL_DIS (0 << 0)
|
||||
|
||||
#define OMAP3_MCSPI_WAKEUPENABLE_WKEN (1 << 0)
|
||||
|
||||
|
|
|
@ -240,6 +240,38 @@
|
|||
#define CONFIG_SYS_SPI_U_BOOT_SIZE 0x40000
|
||||
#define CONFIG_SPL_LDSCRIPT "$(CPUDIR)/omap-common/u-boot-spl.lds"
|
||||
|
||||
#define CONFIG_SPL_BOARD_INIT
|
||||
#define CONFIG_SPL_NAND_AM33XX_BCH
|
||||
#define CONFIG_SPL_NAND_SUPPORT
|
||||
#define CONFIG_SPL_NAND_BASE
|
||||
#define CONFIG_SPL_NAND_DRIVERS
|
||||
#define CONFIG_SPL_NAND_ECC
|
||||
#define CONFIG_SYS_NAND_5_ADDR_CYCLE
|
||||
#define CONFIG_SYS_NAND_PAGE_COUNT (CONFIG_SYS_NAND_BLOCK_SIZE / \
|
||||
CONFIG_SYS_NAND_PAGE_SIZE)
|
||||
#define CONFIG_SYS_NAND_PAGE_SIZE 2048
|
||||
#define CONFIG_SYS_NAND_OOBSIZE 64
|
||||
#define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024)
|
||||
#define CONFIG_SYS_NAND_BAD_BLOCK_POS NAND_LARGE_BADBLOCK_POS
|
||||
#define CONFIG_SYS_NAND_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, }
|
||||
|
||||
#define CONFIG_SYS_NAND_ECCSIZE 512
|
||||
#define CONFIG_SYS_NAND_ECCBYTES 14
|
||||
|
||||
#define CONFIG_SYS_NAND_ECCSTEPS 4
|
||||
#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \
|
||||
CONFIG_SYS_NAND_ECCSTEPS)
|
||||
|
||||
#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
|
||||
|
||||
#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
|
||||
|
||||
/*
|
||||
* 1MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM
|
||||
* 64 bytes before this address should be set aside for u-boot.img's
|
||||
|
@ -299,6 +331,24 @@
|
|||
#define CONFIG_NET_MULTI
|
||||
#define CONFIG_PHY_GIGE
|
||||
#define CONFIG_PHYLIB
|
||||
#define CONFIG_PHY_ADDR 0
|
||||
#define CONFIG_PHY_SMSC
|
||||
|
||||
#define CONFIG_NAND
|
||||
/* NAND support */
|
||||
#ifdef CONFIG_NAND
|
||||
#define CONFIG_CMD_NAND
|
||||
#define CONFIG_NAND_OMAP_GPMC
|
||||
#define GPMC_NAND_ECC_LP_x16_LAYOUT 1
|
||||
#define CONFIG_SYS_NAND_BASE (0x08000000) /* physical address */
|
||||
/* to access nand at */
|
||||
/* CS0 */
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND
|
||||
devices */
|
||||
#undef CONFIG_ENV_IS_NOWHERE
|
||||
#define CONFIG_ENV_IS_IN_NAND
|
||||
#define CONFIG_ENV_OFFSET 0x260000 /* environment starts here */
|
||||
#define CONFIG_SYS_ENV_SECT_SIZE (128 << 10) /* 128 KiB */
|
||||
#endif
|
||||
|
||||
#endif /* ! __CONFIG_AM335X_EVM_H */
|
||||
|
|
|
@ -188,6 +188,7 @@
|
|||
|
||||
/* Environment information */
|
||||
#define CONFIG_BOOTDELAY 10
|
||||
#define CONFIG_ZERO_BOOTDELAY_CHECK
|
||||
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS \
|
||||
"loadaddr=0x82000000\0" \
|
||||
|
@ -282,7 +283,6 @@
|
|||
*/
|
||||
#define CONFIG_NR_DRAM_BANKS 1 /* CS1 is never populated */
|
||||
#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0
|
||||
#define PHYS_SDRAM_1_SIZE (32 << 20) /* at least 32 MiB */
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* FLASH and environment organization
|
||||
|
|
|
@ -263,7 +263,6 @@
|
|||
*/
|
||||
#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */
|
||||
#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0
|
||||
#define PHYS_SDRAM_1_SIZE (32 << 20) /* at least 32 MiB */
|
||||
#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
|
|
|
@ -236,7 +236,6 @@
|
|||
*/
|
||||
#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */
|
||||
#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0
|
||||
#define PHYS_SDRAM_1_SIZE (32 << 20) /* at least 32 meg */
|
||||
#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1
|
||||
|
||||
/*
|
||||
|
|
|
@ -322,7 +322,6 @@
|
|||
*/
|
||||
#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */
|
||||
#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0
|
||||
#define PHYS_SDRAM_1_SIZE (32 << 20) /* at least 32 MiB */
|
||||
#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1
|
||||
|
||||
/*
|
||||
|
|
|
@ -285,7 +285,7 @@
|
|||
"else run userbutton_nonxm; fi;\0" \
|
||||
"userbutton_xm=gpio input 4;\0" \
|
||||
"userbutton_nonxm=gpio input 7;\0"
|
||||
/* "run userbutton" will return 1 (false) if is pressed and 0 (false) if not */
|
||||
/* "run userbutton" will return 1 (false) if pressed and 0 (true) if not */
|
||||
#define CONFIG_BOOTCOMMAND \
|
||||
"mmc dev ${mmcdev}; if mmc rescan; then " \
|
||||
"if run userbutton; then " \
|
||||
|
|
|
@ -251,7 +251,6 @@
|
|||
*/
|
||||
#define CONFIG_NR_DRAM_BANKS 1
|
||||
#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0
|
||||
#define PHYS_SDRAM_1_SIZE (32 << 20) /* at least 32 MiB */
|
||||
#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1
|
||||
|
||||
#define CONFIG_ENV_IS_NOWHERE 1
|
||||
|
|
|
@ -221,7 +221,6 @@
|
|||
*/
|
||||
#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */
|
||||
#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0
|
||||
#define PHYS_SDRAM_1_SIZE (32 << 20) /* at least 32 MiB */
|
||||
#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1
|
||||
|
||||
#define CONFIG_SYS_TEXT_BASE 0x80008000
|
||||
|
|
|
@ -303,7 +303,6 @@
|
|||
*/
|
||||
#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */
|
||||
#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0
|
||||
#define PHYS_SDRAM_1_SIZE (32 << 20) /* at least 32 meg */
|
||||
#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
|
|
@ -252,7 +252,6 @@
|
|||
*/
|
||||
#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */
|
||||
#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0
|
||||
#define PHYS_SDRAM_1_SIZE (32 << 20) /* at least 32 MiB */
|
||||
#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
|
|
|
@ -221,7 +221,6 @@
|
|||
*/
|
||||
#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */
|
||||
#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0
|
||||
#define PHYS_SDRAM_1_SIZE (32 << 20) /* at least 32 MiB */
|
||||
#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
|
|
|
@ -189,7 +189,6 @@
|
|||
*/
|
||||
#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */
|
||||
#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0
|
||||
#define PHYS_SDRAM_1_SIZE (32 << 20) /* at least 32 MiB */
|
||||
#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1
|
||||
|
||||
/*
|
||||
|
@ -358,7 +357,6 @@
|
|||
* I2C EEPROM
|
||||
*/
|
||||
#if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
|
||||
|
||||
/*
|
||||
* The I2C EEPROM on the TAM3517 contains
|
||||
* mac address and production data
|
||||
|
@ -384,24 +382,29 @@ struct tam3517_module_info {
|
|||
unsigned char _rev[100];
|
||||
};
|
||||
|
||||
#define TAM3517_READ_MAC_FROM_EEPROM \
|
||||
do { \
|
||||
struct tam3517_module_info info;\
|
||||
char buf[80], ethname[20]; \
|
||||
int i; \
|
||||
#define TAM3517_READ_EEPROM(info, ret) \
|
||||
do { \
|
||||
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); \
|
||||
if (eeprom_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, \
|
||||
(void *)&info, sizeof(info))) \
|
||||
break; \
|
||||
(void *)info, sizeof(*info))) \
|
||||
ret = 1; \
|
||||
else \
|
||||
ret = 0; \
|
||||
} while (0)
|
||||
|
||||
#define TAM3517_READ_MAC_FROM_EEPROM(info) \
|
||||
do { \
|
||||
char buf[80], ethname[20]; \
|
||||
int i; \
|
||||
memset(buf, 0, sizeof(buf)); \
|
||||
for (i = 0 ; i < ARRAY_SIZE(info.eth_addr); i++) { \
|
||||
for (i = 0 ; i < ARRAY_SIZE((info)->eth_addr); i++) { \
|
||||
sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", \
|
||||
info.eth_addr[i][5], \
|
||||
info.eth_addr[i][4], \
|
||||
info.eth_addr[i][3], \
|
||||
info.eth_addr[i][2], \
|
||||
info.eth_addr[i][1], \
|
||||
info.eth_addr[i][0]); \
|
||||
(info)->eth_addr[i][5], \
|
||||
(info)->eth_addr[i][4], \
|
||||
(info)->eth_addr[i][3], \
|
||||
(info)->eth_addr[i][2], \
|
||||
(info)->eth_addr[i][1], \
|
||||
(info)->eth_addr[i][0]); \
|
||||
\
|
||||
if (i) \
|
||||
sprintf(ethname, "eth%daddr", i); \
|
||||
|
@ -411,6 +414,30 @@ do { \
|
|||
setenv(ethname, buf); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* The following macros are taken from Technexion's documentation */
|
||||
#define TAM3517_sequence_number(info) \
|
||||
((info)->sequence_number % 0x1000000000000LL)
|
||||
#define TAM3517_week_of_year(info) (((info)->sequence_number >> 48) % 0x100)
|
||||
#define TAM3517_year(info) ((info)->sequence_number >> 56)
|
||||
#define TAM3517_revision_fixed(info) ((info)->revision % 0x100)
|
||||
#define TAM3517_revision_major(info) (((info)->revision >> 8) % 0x100)
|
||||
#define TAM3517_revision_tn(info) ((info)->revision >> 16)
|
||||
|
||||
#define TAM3517_PRINT_SOM_INFO(info) \
|
||||
do { \
|
||||
printf("Vendor:%s\n", (info)->customer); \
|
||||
printf("SOM: %s\n", (info)->product); \
|
||||
printf("SeqNr: %02llu%02llu%012llu\n", \
|
||||
TAM3517_year(info), \
|
||||
TAM3517_week_of_year(info), \
|
||||
TAM3517_sequence_number(info)); \
|
||||
printf("Rev: TN%u %u.%u\n", \
|
||||
TAM3517_revision_tn(info), \
|
||||
TAM3517_revision_major(info), \
|
||||
TAM3517_revision_fixed(info)); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __TAM3517_H */
|
||||
|
|
|
@ -247,7 +247,6 @@
|
|||
/* Physical Memory Map */
|
||||
#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */
|
||||
#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0
|
||||
#define PHYS_SDRAM_1_SIZE (128 << 20) /* at least 128 MiB */
|
||||
#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1
|
||||
|
||||
/* NAND and environment organization */
|
||||
|
|
|
@ -39,4 +39,4 @@
|
|||
int twl6035_i2c_write_u8(u8 chip_no, u8 val, u8 reg);
|
||||
int twl6035_i2c_read_u8(u8 chip_no, u8 *val, u8 reg);
|
||||
void twl6035_init_settings(void);
|
||||
void twl6035_mmc1_poweron_ldo(void);
|
||||
int twl6035_mmc1_poweron_ldo(void);
|
||||
|
|
Loading…
Reference in a new issue