Commit 05038925 authored by Anton Protopopov's avatar Anton Protopopov

RT #101966. EA-LPC1788: NAND and ENVM support

parent 8575e947
......@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
COBJS := board.o
COBJS := board.o nand.o
SRCS := $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
......
......@@ -117,6 +117,9 @@
/* EMC data pins (DQ0..DQ31) */
#define LPC178X_EMC_DATA_PINS 31
#ifdef CONFIG_SYS_NAND_CS
#define LPC178X_EMC_ADDR_PINS 31
#else
#if !defined(CONFIG_SYS_FLASH_CS)
/* EMC row/column address pins (A0..A11) */
#define LPC178X_EMC_ADDR_PINS 12
......@@ -124,6 +127,7 @@
/* ..and NOR Flash pins up to A22 */
#define LPC178X_EMC_ADDR_PINS 22
#endif
#endif
/*
* Dynamic Memory Control register
......@@ -366,6 +370,10 @@ static const struct lpc178x_gpio_pin_config ea_lpc1788_gpio[] = {
{{4, 27}, LPC178X_GPIO_CONFIG_D(1, LPC178X_NO_PULLUP, 0, 0, 1, 0)},
#endif
#ifdef CONFIG_SYS_NAND_CS
{{2, 21}, LPC178X_GPIO_CONFIG_D(0, LPC178X_NO_PULLUP, 0, 0, 0, 0)},
#endif
};
/*
......@@ -449,6 +457,19 @@ int board_init(void)
st->wr = CONFIG_SYS_FLASH_WR;
st->ta = CONFIG_SYS_FLASH_TA;
#endif
#ifdef CONFIG_SYS_NAND_CS
/* Set timing for flash */
st = &LPC178X_EMC->st[CONFIG_SYS_NAND_CS];
st->cfg = CONFIG_SYS_NAND_CFG;
st->we = CONFIG_SYS_NAND_WE;
st->oe = CONFIG_SYS_NAND_OE;
st->rd = CONFIG_SYS_NAND_RD;
st->page = CONFIG_SYS_NAND_PAGE;
st->wr = CONFIG_SYS_NAND_WR;
st->ta = CONFIG_SYS_NAND_TA;
#endif
return 0;
}
......
/*
* Copyright (C) 2011 by NXP Semiconductors
* All rights reserved.
*
* @Author: Kevin Wells
* @Descr: Simple NAND interface driver
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <common.h>
#if defined(CONFIG_CMD_NAND)
#include <nand.h>
#include <asm/io.h>
#if 1
#define LPC17_AHB_BASE 0x20080000
#define LPC17_GPIO(x) (LPC17_AHB_BASE + 0x00018000 + (x))
#define LPC17_FIODIR(grp) LPC17_GPIO((0x00 + (grp) * 0x20))
#define LPC17_FIOSET(grp) LPC17_GPIO((0x18 + (grp) * 0x20))
#define LPC17_FIOCLR(grp) LPC17_GPIO((0x1C + (grp) * 0x20))
#define LPC17_FIOPIN(grp) LPC17_GPIO((0x14 + (grp) * 0x20))
/* Set a GPIO as an input */
void lpc17xx_gpio_set_input(unsigned char grp, unsigned char pin)
{
unsigned long gd;
gd = __raw_readl(LPC17_FIODIR(grp));
gd &= ~(1 << pin);
__raw_writel(gd, LPC17_FIODIR(grp));
}
/* Set a GPIO as an output */
void lpc17xx_gpio_set_output(unsigned char grp, unsigned char pin)
{
unsigned long gd;
gd = __raw_readl(LPC17_FIODIR(grp));
gd |= (1 << pin);
__raw_writel(gd, LPC17_FIODIR(grp));
}
/* Set a output GPIO to a specific state */
void lpc17xx_gpio_set_state(unsigned char grp, unsigned char pin, int st)
{
if (st)
__raw_writel((1 << pin), LPC17_FIOSET(grp));
else
__raw_writel((1 << pin), LPC17_FIOCLR(grp));
}
/* Return the state of an input GPIO */
int lpc17xx_gpio_get_state(unsigned char grp, unsigned char pin)
{
return ((__raw_readl(LPC17_FIOPIN(grp)) & (1 << pin)) != 0);
}
#endif
/* Set this define to 0 to use hardware detection */
#define USE_NAND_DELAY 25
/*
* EA1788 board setup with CS1 as chip select. ALE uses A19, CLE uses A21,
* and NAND RDY/BUSY is read on GPIO P2.21. CS1 is controlled as a GPIO
* instead of a CS on GPIO P4.31 to lock the CS state during NAND transfers.
*/
#define NAND_ALE_OFFS (1 << 19)
#define NAND_CLE_OFFS (1 << 20)
static void ea1788_set_nand_cs(unsigned int set)
{
if (set)
lpc17xx_gpio_set_state(4, 31, 1);
else
lpc17xx_gpio_set_state(4, 31, 0);
}
static void ea1788_nand_hwcontrol(struct mtd_info *mtd, int cmd,
unsigned int ctrl)
{
struct nand_chip *this = mtd->priv;
char *pCMD;
long IO_ADDR_W;
if (ctrl & NAND_CTRL_CHANGE) {
IO_ADDR_W = (long) this->IO_ADDR_W &
~(NAND_CLE_OFFS | NAND_ALE_OFFS);
if (ctrl & NAND_CLE)
IO_ADDR_W |= NAND_CLE_OFFS;
else if (ctrl & NAND_ALE)
IO_ADDR_W |= NAND_ALE_OFFS;
if (ctrl & NAND_NCE)
ea1788_set_nand_cs(0);
else
ea1788_set_nand_cs(1);
this->IO_ADDR_W = (void *) IO_ADDR_W;
}
if (cmd != NAND_CMD_NONE) {
pCMD = (char *) this->IO_ADDR_W;
*pCMD = cmd;
}
return;
}
#if USE_NAND_DELAY == 0
static int ea1788_nand_device_ready(struct mtd_info *mtd)
{
/* If NAND doesn't work, check jumper JP2-3-4 on base board */
return lpc17xx_gpio_get_state(2, 21);
}
#endif
/*
* Setup NAND timing and standard NAND functions
*/
int board_nand_init(struct nand_chip *nand)
{
/* Setup CS1 on p4.31 for GPIO output instead of CS1 */
lpc17xx_gpio_set_output(4, 31);
ea1788_set_nand_cs(1);
/* P2.21 for NAND ready configured as GPIO input */
lpc17xx_gpio_set_input(2, 21);
nand->cmd_ctrl = ea1788_nand_hwcontrol;
#if USE_NAND_DELAY == 0
nand->dev_ready = ea1788_nand_device_ready;
#else
nand->chip_delay = USE_NAND_DELAY;
#endif
nand->ecc.mode = NAND_ECC_SOFT;
nand->options = NAND_USE_FLASH_BBT;
return 0;
}
#endif
......@@ -244,6 +244,11 @@ int saveenv(void)
if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE)
return 1;
/* we will erase the block anyway, so prevent warning */
if (nand_erase_options.length < nand_info[0].erasesize)
nand_erase_options.length = nand_info[0].erasesize;
puts ("Erasing Nand...\n");
if (nand_erase_opts(&nand_info[0], &nand_erase_options))
return 1;
......
......@@ -998,7 +998,11 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
/* Allocate a temporary buffer for one eraseblock incl. oob */
len = (1 << this->bbt_erase_shift);
len += (len >> this->page_shift) * mtd->oobsize;
#ifdef CONFIG_NAND_BBT_BLOCK_BUFFER
buf = (uint8_t *) CONFIG_NAND_BBT_BLOCK_BUFFER;
#else
buf = vmalloc(len);
#endif
if (!buf) {
printk(KERN_ERR "nand_bbt: Out of memory\n");
kfree(this->bbt);
......@@ -1022,7 +1026,9 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
if (md)
mark_bbt_region(mtd, md);
#ifndef CONFIG_NAND_BBT_BLOCK_BUFFER
vfree(buf);
#endif
return res;
}
......
......@@ -182,8 +182,8 @@
#define CONFIG_MEM_RAM_BASE 0x10000000
#define CONFIG_MEM_RAM_LEN (32 * 1024)
#define CONFIG_MEM_RAM_BUF_LEN (16 * 1024)
#define CONFIG_MEM_MALLOC_LEN (12 * 1024)
#define CONFIG_MEM_RAM_BUF_LEN (12 * 1024)
#define CONFIG_MEM_MALLOC_LEN (16 * 1024)
#define CONFIG_MEM_STACK_LEN (4 * 1024)
/*
......@@ -234,22 +234,70 @@
#define CONFIG_SYS_MAX_FLASH_BANKS 1
#define CONFIG_SYS_MAX_FLASH_SECT 1024
/*
* Store env in flash.
*/
#define CONFIG_ENV_IS_IN_FLASH
#else
/*
* Store env in memory only, if no flash.
*/
#define CONFIG_ENV_IS_NOWHERE
#define CONFIG_SYS_NO_FLASH
#endif
/* NAND */
#define CONFIG_CMD_NAND 1
#ifdef CONFIG_CMD_NAND
#define CONFIG_SYS_MAX_NAND_DEVICE 1
#define CONFIG_SYS_NAND_BASE 0x90000000
#define CONFIG_SYS_NAND_CS 1
#define CONFIG_SYS_NAND_CFG 0x80
#define CONFIG_SYS_NAND_WE 0x2
#define CONFIG_SYS_NAND_OE 0x2
#define CONFIG_SYS_NAND_RD 0x1f
#define CONFIG_SYS_NAND_PAGE 0x1f
#define CONFIG_SYS_NAND_WR 0x1f
#define CONFIG_SYS_NAND_TA 0x1f
#define CONFIG_NAND_BBT_BLOCK_BUFFER \
(CONFIG_SYS_RAM_BASE + (16 * 1024 * 1024))
#endif
/* ENVM */
#define CONFIG_ENVM 1
#ifdef CONFIG_ENVM
#define CONFIG_SYS_ENVM_BASE CONFIG_MEM_NVM_BASE
#define CONFIG_SYS_ENVM_LEN CONFIG_MEM_NVM_LEN
#endif
/*
* Environment
*/
#define CONFIG_ENV_IS_IN_FLASH
#ifdef CONFIG_ENV_IS_IN_FLASH
#define CONFIG_ENV_SIZE (4 * 1024)
#define CONFIG_ENV_OVERWRITE 1
#define CONFIG_ENV_ADDR CONFIG_SYS_FLASH_BANK1_BASE
#define CONFIG_INFERNO 1
#endif
#undef CONFIG_ENV_IS_IN_NAND
#ifdef CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_SIZE (4 * 1024)
#define CONFIG_ENV_OVERWRITE 1
#define CONFIG_ENV_OFFSET 0
#endif
#undef CONFIG_ENV_IS_IN_ENVM
#ifdef CONFIG_ENV_IS_IN_ENVM
#define CONFIG_ENV_SIZE (4 * 1024)
#define CONFIG_ENV_ADDR \
(CONFIG_SYS_ENVM_BASE + CONFIG_SYS_ENVM_LEN - (128 * 1024))
#endif
#if !defined(CONFIG_ENV_IS_IN_FLASH) && \
!defined(CONFIG_ENV_IS_IN_NAND) && \
!defined(CONFIG_ENV_IS_IN_ENVM)
#define CONFIG_ENV_IS_NOWHERE
#endif
/*
* Serial console configuration
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment