First steps implementing NAND support. Not working, fails to read ID.
This commit is contained in:
parent
0377dca227
commit
6949328d7d
5
Makefile
5
Makefile
|
@ -208,6 +208,9 @@ etags:
|
|||
net disk rtc dtt drivers drivers/sk98lin common \
|
||||
\( -name CVS -prune \) -o \( -name '*.[ch]' -print \)`
|
||||
|
||||
ctags:
|
||||
ctags -Re
|
||||
|
||||
System.map: u-boot
|
||||
@$(NM) $< | \
|
||||
grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \
|
||||
|
@ -1874,7 +1877,7 @@ clobber: clean
|
|||
-o -name '*.srec' -o -name '*.bin' -o -name u-boot.img \) \
|
||||
-print0 \
|
||||
| xargs -0 rm -f
|
||||
rm -f $(OBJS) *.bak tags TAGS include/version_autogenerated.h
|
||||
rm -f $(OBJS) *.bak tags include/version_autogenerated.h
|
||||
|
||||
rm -fr *.*~
|
||||
rm -f u-boot u-boot.map u-boot.hex $(ALL)
|
||||
|
|
|
@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
|
|||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
OBJS := delta.o flash.o
|
||||
OBJS := delta.o nand.o
|
||||
SOBJS := lowlevel_init.o
|
||||
|
||||
$(LIB): $(OBJS) $(SOBJS)
|
||||
|
|
|
@ -4,3 +4,6 @@
|
|||
#TEXT_BASE = 0x9ffe0000
|
||||
TEXT_BASE = 0xa3008000
|
||||
|
||||
# Compile the new NAND code (needed iff #ifdef CONFIG_NEW_NAND_CODE)
|
||||
BOARDLIBS = drivers/nand/libnand.a
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ int board_init (void)
|
|||
/* memory and cpu-speed are setup before relocation */
|
||||
/* so we do _nothing_ here */
|
||||
|
||||
/* arch number of Lubbock-Board */
|
||||
/* arch number of Lubbock-Board mk@tbd: fix this! */
|
||||
gd->bd->bi_arch_number = MACH_TYPE_LUBBOCK;
|
||||
|
||||
/* adress of boot parameters */
|
||||
|
|
|
@ -1,434 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2001
|
||||
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
|
||||
*
|
||||
* (C) Copyright 2001
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* 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 <linux/byteorder/swab.h>
|
||||
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
|
||||
/* Board support for 1 or 2 flash devices */
|
||||
#define FLASH_PORT_WIDTH32
|
||||
#undef FLASH_PORT_WIDTH16
|
||||
|
||||
#ifdef FLASH_PORT_WIDTH16
|
||||
#define FLASH_PORT_WIDTH ushort
|
||||
#define FLASH_PORT_WIDTHV vu_short
|
||||
#define SWAP(x) __swab16(x)
|
||||
#else
|
||||
#define FLASH_PORT_WIDTH ulong
|
||||
#define FLASH_PORT_WIDTHV vu_long
|
||||
#define SWAP(x) __swab32(x)
|
||||
#endif
|
||||
|
||||
#define FPW FLASH_PORT_WIDTH
|
||||
#define FPWV FLASH_PORT_WIDTHV
|
||||
|
||||
#define mb() __asm__ __volatile__ ("" : : : "memory")
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
static ulong flash_get_size (FPW *addr, flash_info_t *info);
|
||||
static int write_data (flash_info_t *info, ulong dest, FPW data);
|
||||
static void flash_get_offsets (ulong base, flash_info_t *info);
|
||||
void inline spin_wheel (void);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
unsigned long flash_init (void)
|
||||
{
|
||||
#if 0
|
||||
int i;
|
||||
ulong size = 0;
|
||||
|
||||
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]);
|
||||
flash_get_offsets (PHYS_FLASH_1, &flash_info[i]);
|
||||
break;
|
||||
case 1:
|
||||
flash_get_size ((FPW *) PHYS_FLASH_2, &flash_info[i]);
|
||||
flash_get_offsets (PHYS_FLASH_2, &flash_info[i]);
|
||||
break;
|
||||
default:
|
||||
panic ("configured too many flash banks!\n");
|
||||
break;
|
||||
}
|
||||
size += flash_info[i].size;
|
||||
}
|
||||
|
||||
/* Protect monitor and environment sectors
|
||||
*/
|
||||
flash_protect ( FLAG_PROTECT_SET,
|
||||
CFG_FLASH_BASE,
|
||||
CFG_FLASH_BASE + monitor_flash_len - 1,
|
||||
&flash_info[0] );
|
||||
|
||||
flash_protect ( FLAG_PROTECT_SET,
|
||||
CFG_ENV_ADDR,
|
||||
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] );
|
||||
|
||||
return size;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
static void flash_get_offsets (ulong base, flash_info_t *info)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
|
||||
for (i = 0; i < info->sector_count; i++) {
|
||||
info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE);
|
||||
info->protect[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
void flash_print_info (flash_info_t *info)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("missing or unknown FLASH type\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_INTEL:
|
||||
printf ("INTEL ");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Vendor ");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_28F128J3A:
|
||||
printf ("28F128J3A\n");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Chip Type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
printf (" Size: %ld MB in %d Sectors\n",
|
||||
info->size >> 20, info->sector_count);
|
||||
|
||||
printf (" Sector Start Addresses:");
|
||||
for (i = 0; i < info->sector_count; ++i) {
|
||||
if ((i % 5) == 0)
|
||||
printf ("\n ");
|
||||
printf (" %08lX%s",
|
||||
info->start[i],
|
||||
info->protect[i] ? " (RO)" : " ");
|
||||
}
|
||||
printf ("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following code cannot be run from FLASH!
|
||||
*/
|
||||
static ulong flash_get_size (FPW *addr, flash_info_t *info)
|
||||
{
|
||||
volatile FPW value;
|
||||
|
||||
/* Write auto select command: read Manufacturer ID */
|
||||
addr[0x5555] = (FPW) 0x00AA00AA;
|
||||
addr[0x2AAA] = (FPW) 0x00550055;
|
||||
addr[0x5555] = (FPW) 0x00900090;
|
||||
|
||||
mb ();
|
||||
value = addr[0];
|
||||
|
||||
switch (value) {
|
||||
|
||||
case (FPW) INTEL_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_INTEL;
|
||||
break;
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
return (0); /* no or unknown flash */
|
||||
}
|
||||
|
||||
mb ();
|
||||
value = addr[1]; /* device ID */
|
||||
|
||||
switch (value) {
|
||||
|
||||
case (FPW) INTEL_ID_28F128J3A:
|
||||
info->flash_id += FLASH_28F128J3A;
|
||||
info->sector_count = 128;
|
||||
info->size = 0x02000000;
|
||||
break; /* => 16 MB */
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (info->sector_count > CFG_MAX_FLASH_SECT) {
|
||||
printf ("** ERROR: sector count %d > max (%d) **\n",
|
||||
info->sector_count, CFG_MAX_FLASH_SECT);
|
||||
info->sector_count = CFG_MAX_FLASH_SECT;
|
||||
}
|
||||
|
||||
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
|
||||
return (info->size);
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||
{
|
||||
int flag, prot, sect;
|
||||
ulong type, start, last;
|
||||
int rcode = 0;
|
||||
|
||||
if ((s_first < 0) || (s_first > s_last)) {
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("- missing\n");
|
||||
} else {
|
||||
printf ("- no sectors to erase\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
type = (info->flash_id & FLASH_VENDMASK);
|
||||
if ((type != FLASH_MAN_INTEL)) {
|
||||
printf ("Can't erase unknown flash type %08lx - aborted\n",
|
||||
info->flash_id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
prot = 0;
|
||||
for (sect = s_first; sect <= s_last; ++sect) {
|
||||
if (info->protect[sect]) {
|
||||
prot++;
|
||||
}
|
||||
}
|
||||
|
||||
if (prot) {
|
||||
printf ("- Warning: %d protected sectors will not be erased!\n",
|
||||
prot);
|
||||
} else {
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
start = get_timer (0);
|
||||
last = start;
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts ();
|
||||
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect <= s_last; sect++) {
|
||||
if (info->protect[sect] == 0) { /* not protected */
|
||||
FPWV *addr = (FPWV *) (info->start[sect]);
|
||||
FPW status;
|
||||
|
||||
printf ("Erasing sector %2d ... ", sect);
|
||||
|
||||
/* arm simple, non interrupt dependent timer */
|
||||
reset_timer_masked ();
|
||||
|
||||
*addr = (FPW) 0x00500050; /* clear status register */
|
||||
*addr = (FPW) 0x00200020; /* erase setup */
|
||||
*addr = (FPW) 0x00D000D0; /* erase confirm */
|
||||
|
||||
while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
|
||||
if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
|
||||
printf ("Timeout\n");
|
||||
*addr = (FPW) 0x00B000B0; /* suspend erase */
|
||||
*addr = (FPW) 0x00FF00FF; /* reset to read mode */
|
||||
rcode = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*addr = 0x00500050; /* clear status register cmd. */
|
||||
*addr = 0x00FF00FF; /* resest to read mode */
|
||||
|
||||
printf (" done\n");
|
||||
}
|
||||
}
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
* 4 - Flash not identified
|
||||
*/
|
||||
|
||||
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
{
|
||||
ulong cp, wp;
|
||||
FPW data;
|
||||
int count, i, l, rc, port_width;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
return 4;
|
||||
}
|
||||
/* get lower word aligned address */
|
||||
#ifdef FLASH_PORT_WIDTH16
|
||||
wp = (addr & ~1);
|
||||
port_width = 2;
|
||||
#else
|
||||
wp = (addr & ~3);
|
||||
port_width = 4;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* handle unaligned start bytes
|
||||
*/
|
||||
if ((l = addr - wp) != 0) {
|
||||
data = 0;
|
||||
for (i = 0, cp = wp; i < l; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *) cp);
|
||||
}
|
||||
for (; i < port_width && cnt > 0; ++i) {
|
||||
data = (data << 8) | *src++;
|
||||
--cnt;
|
||||
++cp;
|
||||
}
|
||||
for (; cnt == 0 && i < port_width; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *) cp);
|
||||
}
|
||||
|
||||
if ((rc = write_data (info, wp, SWAP (data))) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
wp += port_width;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle word aligned part
|
||||
*/
|
||||
count = 0;
|
||||
while (cnt >= port_width) {
|
||||
data = 0;
|
||||
for (i = 0; i < port_width; ++i) {
|
||||
data = (data << 8) | *src++;
|
||||
}
|
||||
if ((rc = write_data (info, wp, SWAP (data))) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
wp += port_width;
|
||||
cnt -= port_width;
|
||||
if (count++ > 0x800) {
|
||||
spin_wheel ();
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (cnt == 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* handle unaligned tail bytes
|
||||
*/
|
||||
data = 0;
|
||||
for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
|
||||
data = (data << 8) | *src++;
|
||||
--cnt;
|
||||
}
|
||||
for (; i < port_width; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *) cp);
|
||||
}
|
||||
|
||||
return (write_data (info, wp, SWAP (data)));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Write a word or halfword to Flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
static int write_data (flash_info_t *info, ulong dest, FPW data)
|
||||
{
|
||||
FPWV *addr = (FPWV *) dest;
|
||||
ulong status;
|
||||
int flag;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*addr & data) != data) {
|
||||
printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr);
|
||||
return (2);
|
||||
}
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts ();
|
||||
|
||||
*addr = (FPW) 0x00400040; /* write setup */
|
||||
*addr = data;
|
||||
|
||||
/* arm simple, non interrupt dependent timer */
|
||||
reset_timer_masked ();
|
||||
|
||||
/* wait while polling the status register */
|
||||
while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
|
||||
if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
|
||||
*addr = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
*addr = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void inline spin_wheel (void)
|
||||
{
|
||||
static int p = 0;
|
||||
static char w[] = "\\/-";
|
||||
|
||||
printf ("\010%c", w[p]);
|
||||
(++p == 3) ? (p = 0) : 0;
|
||||
}
|
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
* (C) Copyright 2006 DENX Software Engineering
|
||||
*
|
||||
* 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>
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
|
||||
#ifdef CONFIG_NEW_NAND_CODE
|
||||
|
||||
#include <nand.h>
|
||||
#include <asm/arch/pxa-regs.h>
|
||||
|
||||
/*
|
||||
* hardware specific access to control-lines
|
||||
* function borrowed from Linux 2.6 (drivers/mtd/nand/ppchameleonevb.c)
|
||||
*/
|
||||
static void delta_hwcontrol(struct mtd_info *mtdinfo, int cmd)
|
||||
{
|
||||
#if 0
|
||||
struct nand_chip *this = mtdinfo->priv;
|
||||
ulong base = (ulong) this->IO_ADDR_W;
|
||||
|
||||
switch(cmd) {
|
||||
case NAND_CTL_SETCLE:
|
||||
MACRO_NAND_CTL_SETCLE((unsigned long)base);
|
||||
break;
|
||||
case NAND_CTL_CLRCLE:
|
||||
MACRO_NAND_CTL_CLRCLE((unsigned long)base);
|
||||
break;
|
||||
case NAND_CTL_SETALE:
|
||||
MACRO_NAND_CTL_SETALE((unsigned long)base);
|
||||
break;
|
||||
case NAND_CTL_CLRALE:
|
||||
MACRO_NAND_CTL_CLRALE((unsigned long)base);
|
||||
break;
|
||||
case NAND_CTL_SETNCE:
|
||||
MACRO_NAND_ENABLE_CE((unsigned long)base);
|
||||
break;
|
||||
case NAND_CTL_CLRNCE:
|
||||
MACRO_NAND_DISABLE_CE((unsigned long)base);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* read device ready pin */
|
||||
static int delta_device_ready(struct mtd_info *mtdinfo)
|
||||
{
|
||||
if(NDSR & NDSR_RDY)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
#if 0
|
||||
struct nand_chip *this = mtdinfo->priv;
|
||||
ulong rb_gpio_pin;
|
||||
|
||||
/* use the base addr to find out which chip are we dealing with */
|
||||
switch((ulong) this->IO_ADDR_W) {
|
||||
case CFG_NAND0_BASE:
|
||||
rb_gpio_pin = CFG_NAND0_RDY;
|
||||
break;
|
||||
case CFG_NAND1_BASE:
|
||||
rb_gpio_pin = CFG_NAND1_RDY;
|
||||
break;
|
||||
default: /* this should never happen */
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (in32(GPIO0_IR) & rb_gpio_pin)
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u_char delta_read_byte(struct mtd_info *mtd)
|
||||
{
|
||||
/* struct nand_chip *this = mtd->priv; */
|
||||
unsigned long tmp;
|
||||
|
||||
/* wait for read request */
|
||||
while(1) {
|
||||
if(NDSR & NDSR_RDDREQ) {
|
||||
NDSR |= NDSR_RDDREQ;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tmp = NDDB;
|
||||
printk("delta_read_byte: 0x%x.\n", tmp);
|
||||
return (u_char) tmp;
|
||||
}
|
||||
|
||||
/* this is really monahans, not board specific ... */
|
||||
static void delta_cmdfunc(struct mtd_info *mtd, unsigned command,
|
||||
int column, int page_addr)
|
||||
{
|
||||
/* register struct nand_chip *this = mtd->priv; */
|
||||
unsigned long ndcb0=0, ndcb1=0, ndcb2=0;
|
||||
uchar command2;
|
||||
|
||||
/* Clear NDSR */
|
||||
NDSR = 0xFFF;
|
||||
|
||||
/* apparently NDCR[NDRUN] needs to be set before writing to NDCBx */
|
||||
NDCR |= NDCR_ND_RUN;
|
||||
|
||||
/* wait for write command request
|
||||
* hmm, might be nice if this could time-out. mk@tbd
|
||||
*/
|
||||
while(1) {
|
||||
if(NDSR & NDSR_WRCMDREQ) {
|
||||
NDSR |= NDSR_WRCMDREQ; /* Ack */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if command is a double byte cmd, we set bit double cmd bit 19 */
|
||||
command2 = (command>>8) & 0xFF;
|
||||
ndcb0 = command | ((command2 ? 1 : 0) << 19);
|
||||
|
||||
switch (command) {
|
||||
case NAND_CMD_READID:
|
||||
printk("delta_cmdfunc: NAND_CMD_READID.\n");
|
||||
ndcb0 |= ((3 << 21) | (2 << 16));
|
||||
break;
|
||||
case NAND_CMD_PAGEPROG:
|
||||
case NAND_CMD_ERASE1:
|
||||
case NAND_CMD_ERASE2:
|
||||
case NAND_CMD_SEQIN:
|
||||
case NAND_CMD_STATUS:
|
||||
return;
|
||||
case NAND_CMD_RESET:
|
||||
return;
|
||||
default:
|
||||
printk("delta_cmdfunc: error, unkown command issued.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
NDCB0 = ndcb0;
|
||||
NDCB1 = ndcb1;
|
||||
NDCB2 = ndcb2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Board-specific NAND initialization. The following members of the
|
||||
* argument are board-specific (per include/linux/mtd/nand_new.h):
|
||||
* - IO_ADDR_R?: address to read the 8 I/O lines of the flash device
|
||||
* - IO_ADDR_W?: address to write the 8 I/O lines of the flash device
|
||||
* - hwcontrol: hardwarespecific function for accesing control-lines
|
||||
* - dev_ready: hardwarespecific function for accesing device ready/busy line
|
||||
* - enable_hwecc?: function to enable (reset) hardware ecc generator. Must
|
||||
* only be provided if a hardware ECC is available
|
||||
* - eccmode: mode of ecc, see defines
|
||||
* - chip_delay: chip dependent delay for transfering data from array to
|
||||
* read regs (tR)
|
||||
* - options: various chip options. They can partly be set to inform
|
||||
* nand_scan about special functionality. See the defines for further
|
||||
* explanation
|
||||
* Members with a "?" were not set in the merged testing-NAND branch,
|
||||
* so they are not set here either.
|
||||
*/
|
||||
void board_nand_init(struct nand_chip *nand)
|
||||
{
|
||||
unsigned long tCH, tCS, tWH, tWP, tRH, tRP, tRP_high, tR, tWHR, tAR;
|
||||
|
||||
/* set up GPIO Control Registers */
|
||||
|
||||
/* turn on the NAND Controller Clock (104 MHz @ D0) */
|
||||
CKENA |= (CKENA_4_NAND | CKENA_9_SMC);
|
||||
|
||||
/* NAND Timing Parameters (in ns) */
|
||||
#define NAND_TIMING_tCH 10
|
||||
#define NAND_TIMING_tCS 0
|
||||
#define NAND_TIMING_tWH 20
|
||||
#define NAND_TIMING_tWP 40
|
||||
#define NAND_TIMING_tRH 20
|
||||
#define NAND_TIMING_tRP 40
|
||||
#define NAND_TIMING_tR 11123
|
||||
#define NAND_TIMING_tWHR 110
|
||||
#define NAND_TIMING_tAR 10
|
||||
|
||||
/* Maximum values for NAND Interface Timing Registers in DFC clock
|
||||
* periods */
|
||||
#define DFC_MAX_tCH 7
|
||||
#define DFC_MAX_tCS 7
|
||||
#define DFC_MAX_tWH 7
|
||||
#define DFC_MAX_tWP 7
|
||||
#define DFC_MAX_tRH 7
|
||||
#define DFC_MAX_tRP 15
|
||||
#define DFC_MAX_tR 65535
|
||||
#define DFC_MAX_tWHR 15
|
||||
#define DFC_MAX_tAR 15
|
||||
|
||||
#define DFC_CLOCK 104 /* DFC Clock is 104 MHz */
|
||||
#define DFC_CLK_PER_US DFC_CLOCK/1000 /* clock period in ns */
|
||||
#define MIN(x, y) ((x < y) ? x : y)
|
||||
|
||||
|
||||
tCH = MIN(((unsigned long) (NAND_TIMING_tCH * DFC_CLK_PER_US) + 1),
|
||||
DFC_MAX_tCH);
|
||||
tCS = MIN(((unsigned long) (NAND_TIMING_tCS * DFC_CLK_PER_US) + 1),
|
||||
DFC_MAX_tCS);
|
||||
tWH = MIN(((unsigned long) (NAND_TIMING_tWH * DFC_CLK_PER_US) + 1),
|
||||
DFC_MAX_tWH);
|
||||
tWP = MIN(((unsigned long) (NAND_TIMING_tWP * DFC_CLK_PER_US) + 1),
|
||||
DFC_MAX_tWP);
|
||||
tRH = MIN(((unsigned long) (NAND_TIMING_tRH * DFC_CLK_PER_US) + 1),
|
||||
DFC_MAX_tRH);
|
||||
tRP = MIN(((unsigned long) (NAND_TIMING_tRP * DFC_CLK_PER_US) + 1),
|
||||
DFC_MAX_tRP);
|
||||
tR = MIN(((unsigned long) (NAND_TIMING_tR * DFC_CLK_PER_US) + 1),
|
||||
DFC_MAX_tR);
|
||||
tWHR = MIN(((unsigned long) (NAND_TIMING_tWHR * DFC_CLK_PER_US) + 1),
|
||||
DFC_MAX_tWHR);
|
||||
tAR = MIN(((unsigned long) (NAND_TIMING_tAR * DFC_CLK_PER_US) + 1),
|
||||
DFC_MAX_tAR);
|
||||
|
||||
|
||||
/* tRP value is split in the register */
|
||||
if(tRP & (1 << 4)) {
|
||||
tRP_high = 1;
|
||||
tRP &= ~(1 << 4);
|
||||
} else {
|
||||
tRP_high = 0;
|
||||
}
|
||||
|
||||
NDTR0CS0 = (tCH << 19) |
|
||||
(tCS << 16) |
|
||||
(tWH << 11) |
|
||||
(tWP << 8) |
|
||||
(tRP_high << 6) |
|
||||
(tRH << 3) |
|
||||
(tRP << 0);
|
||||
|
||||
NDTR1CS0 = (tR << 16) |
|
||||
(tWHR << 4) |
|
||||
(tAR << 0);
|
||||
|
||||
|
||||
|
||||
/* If it doesn't work (unlikely) think about:
|
||||
* - ecc enable
|
||||
* - chip select don't care
|
||||
* - read id byte count
|
||||
*
|
||||
* Intentionally enabled by not setting bits:
|
||||
* - dma (DMA_EN)
|
||||
* - page size = 512
|
||||
* - cs don't care, see if we can enable later!
|
||||
* - row address start position (after second cycle)
|
||||
* - pages per block = 32
|
||||
*/
|
||||
NDCR = (NDCR_ND_ARB_EN | /* enable bus arbiter */
|
||||
NDCR_SPARE_EN | /* use the spare area */
|
||||
NDCR_DWIDTH_C | /* 16bit DFC data bus width */
|
||||
NDCR_DWIDTH_M | /* 16 bit Flash device data bus width */
|
||||
(2 << 16) | /* read id count = 7 ???? mk@tbd */
|
||||
NDCE_RDYM | /* flash device ready ir masked */
|
||||
NDCE_CS0_PAGEDM | /* ND_nCSx page done ir masked */
|
||||
NDCE_CS1_PAGEDM |
|
||||
NDCE_CS0_CMDDM | /* ND_CSx command done ir masked */
|
||||
NDCE_CS1_CMDDM |
|
||||
NDCE_CS0_BBDM | /* ND_CSx bad block detect ir masked */
|
||||
NDCE_CS1_BBDM |
|
||||
NDCE_DBERRM | /* double bit error ir masked */
|
||||
NDCE_SBERRM | /* single bit error ir masked */
|
||||
NDCE_WRDREQM | /* write data request ir masked */
|
||||
NDCE_RDDREQM | /* read data request ir masked */
|
||||
NDCE_WRCMDREQM); /* write command request ir masked */
|
||||
|
||||
|
||||
|
||||
nand->hwcontrol = delta_hwcontrol;
|
||||
nand->dev_ready = delta_device_ready;
|
||||
nand->eccmode = NAND_ECC_SOFT;
|
||||
nand->chip_delay = NAND_DELAY_US;
|
||||
nand->options = NAND_BUSWIDTH_16;
|
||||
nand->read_byte = delta_read_byte;
|
||||
nand->cmdfunc = delta_cmdfunc;
|
||||
/* nand->options = NAND_SAMSUNG_LP_OPTIONS; */
|
||||
}
|
||||
|
||||
#else
|
||||
#error "U-Boot legacy NAND support not available for delta board."
|
||||
#endif
|
||||
#endif
|
|
@ -1003,12 +1003,51 @@ typedef void (*ExcpHndlr) (void) ;
|
|||
#define GSDR(x) __REG2(0x40E00400, ((x) & 0x60) >> 3)
|
||||
#define GCDR(x) __REG2(0x40300420, ((x) & 0x60) >> 3)
|
||||
|
||||
/* Multi-funktion Pin Registers, uncomplete, only GPIO relevant pins for now */
|
||||
/* Multi-funktion Pin Registers, uncomplete, only:
|
||||
* - GPIO
|
||||
* - Data Flash DF_* pins defined.
|
||||
*/
|
||||
#define GPIO0 __REG(0x40e10124)
|
||||
#define GPIO1 __REG(0x40e10128)
|
||||
#define GPIO2 __REG(0x40e1012c)
|
||||
#define GPIO3 __REG(0x40e10130)
|
||||
#define GPIO4 __REG(0x40e10134)
|
||||
#define nXCVREN __REG(0x40e10138)
|
||||
|
||||
#define DF_CLE_NOE __REG(0x40e10204)
|
||||
#define DF_ALE_WE1 __REG(0x40e10208)
|
||||
|
||||
#define DF_SCLK_E __REG(0x40e10210)
|
||||
#define nBE0 __REG(0x40e10214)
|
||||
#define nBE1 __REG(0x40e10218)
|
||||
#define DF_ALE_WE2 __REG(0x40e1021c)
|
||||
#define DF_INT_RnB __REG(0x40e10220)
|
||||
#define DF_nCS0 __REG(0x40e10224)
|
||||
#define DF_nCS1 __REG(0x40e10228)
|
||||
#define DF_nWE __REG(0x40e1022c)
|
||||
#define DF_nRE __REG(0x40e10230)
|
||||
#define nLUA __REG(0x40e10234)
|
||||
#define nLLA __REG(0x40e10238)
|
||||
#define DF_ADDR0 __REG(0x40e1023c)
|
||||
#define DF_ADDR1 __REG(0x40e10240)
|
||||
#define DF_ADDR2 __REG(0x40e10244)
|
||||
#define DF_ADDR3 __REG(0x40e10248)
|
||||
#define DF_IO0 __REG(0x40e1024c)
|
||||
#define DF_IO8 __REG(0x40e10250)
|
||||
#define DF_IO1 __REG(0x40e10254)
|
||||
#define DF_IO9 __REG(0x40e10258)
|
||||
#define DF_IO2 __REG(0x40e1025c)
|
||||
#define DF_IO10 __REG(0x40e10260)
|
||||
#define DF_IO3 __REG(0x40e10264)
|
||||
#define DF_IO11 __REG(0x40e10268)
|
||||
#define DF_IO4 __REG(0x40e1026c)
|
||||
#define DF_IO12 __REG(0x40e10270)
|
||||
#define DF_IO5 __REG(0x40e10274)
|
||||
#define DF_IO13 __REG(0x40e10278)
|
||||
#define DF_IO6 __REG(0x40e1027c)
|
||||
#define DF_IO14 __REG(0x40e10280)
|
||||
#define DF_IO7 __REG(0x40e10284)
|
||||
#define DF_IO15 __REG(0x40e10288)
|
||||
|
||||
#define GPIO5 __REG(0x40e1028c)
|
||||
#define GPIO6 __REG(0x40e10290)
|
||||
|
@ -2022,19 +2061,19 @@ typedef void (*ExcpHndlr) (void) ;
|
|||
|
||||
/* Data Flash Controller Registers */
|
||||
|
||||
#define NDCR __REG_2(0x43100000) /* Data Flash Control register */
|
||||
#define NDTR0CS0 __REG_2(0x43100004) /* Data Controller Timing Parameter 0 Register for ND_nCS0 */
|
||||
#define NDTR0CS1 __REG_2(0x43100008) /* Data Controller Timing Parameter 0 Register for ND_nCS1 */
|
||||
#define NDTR1CS0 __REG_2(0x4310000C) /* Data Controller Timing Parameter 1 Register for ND_nCS0 */
|
||||
#define NDTR1CS1 __REG_2(0x43100010) /* Data Controller Timing Parameter 1 Register for ND_nCS1 */
|
||||
#define NDSR __REG_2(0x43100014) /* Data Controller Status Register */
|
||||
#define NDPCR __REG_2(0x43100018) /* Data Controller Page Count Register */
|
||||
#define NDBDR0 __REG_2(0x4310001C) /* Data Controller Bad Block Register 0 */
|
||||
#define NDBDR1 __REG_2(0x43100020) /* Data Controller Bad Block Register 1 */
|
||||
#define NDDB __REG_2(0x43100040) /* Data Controller Data Buffer */
|
||||
#define NDCB0 __REG_2(0x43100048) /* Data Controller Command Buffer0 */
|
||||
#define NDCB1 __REG_2(0x4310004C) /* Data Controller Command Buffer1 */
|
||||
#define NDCB2 __REG_2(0x43100050) /* Data Controller Command Buffer2 */
|
||||
#define NDCR __REG(0x43100000) /* Data Flash Control register */
|
||||
#define NDTR0CS0 __REG(0x43100004) /* Data Controller Timing Parameter 0 Register for ND_nCS0 */
|
||||
/* #define NDTR0CS1 __REG(0x43100008) /\* Data Controller Timing Parameter 0 Register for ND_nCS1 *\/ */
|
||||
#define NDTR1CS0 __REG(0x4310000C) /* Data Controller Timing Parameter 1 Register for ND_nCS0 */
|
||||
/* #define NDTR1CS1 __REG(0x43100010) /\* Data Controller Timing Parameter 1 Register for ND_nCS1 *\/ */
|
||||
#define NDSR __REG(0x43100014) /* Data Controller Status Register */
|
||||
#define NDPCR __REG(0x43100018) /* Data Controller Page Count Register */
|
||||
#define NDBDR0 __REG(0x4310001C) /* Data Controller Bad Block Register 0 */
|
||||
#define NDBDR1 __REG(0x43100020) /* Data Controller Bad Block Register 1 */
|
||||
#define NDDB __REG(0x43100040) /* Data Controller Data Buffer */
|
||||
#define NDCB0 __REG(0x43100048) /* Data Controller Command Buffer0 */
|
||||
#define NDCB1 __REG(0x4310004C) /* Data Controller Command Buffer1 */
|
||||
#define NDCB2 __REG(0x43100050) /* Data Controller Command Buffer2 */
|
||||
|
||||
#define NDCR_SPARE_EN (0x1<<31)
|
||||
#define NDCR_ECC_EN (0x1<<30)
|
||||
|
@ -2052,6 +2091,18 @@ typedef void (*ExcpHndlr) (void) ;
|
|||
#define NDCR_RA_START (0x1<<15)
|
||||
#define NDCR_PG_PER_BLK (0x1<<14)
|
||||
#define NDCR_ND_ARB_EN (0x1<<12)
|
||||
#define NDCE_RDYM (0x1<<11)
|
||||
#define NDCE_CS0_PAGEDM (0x1<<10)
|
||||
#define NDCE_CS1_PAGEDM (0x1<<9)
|
||||
#define NDCE_CS0_CMDDM (0x1<<8)
|
||||
#define NDCE_CS1_CMDDM (0x1<<7)
|
||||
#define NDCE_CS0_BBDM (0x1<<6)
|
||||
#define NDCE_CS1_BBDM (0x1<<5)
|
||||
#define NDCE_DBERRM (0x1<<4)
|
||||
#define NDCE_SBERRM (0x1<<3)
|
||||
#define NDCE_WRDREQM (0x1<<2)
|
||||
#define NDCE_RDDREQM (0x1<<1)
|
||||
#define NDCE_WRCMDREQM (0x1)
|
||||
|
||||
#define NDSR_RDY (0x1<<11)
|
||||
#define NDSR_CS0_PAGED (0x1<<10)
|
||||
|
|
|
@ -73,7 +73,9 @@
|
|||
#ifdef TURN_ON_ETHERNET
|
||||
# define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_PING)
|
||||
#else
|
||||
# define CONFIG_COMMANDS (CONFIG_CMD_DFL & ~CFG_CMD_NET)
|
||||
# define CONFIG_COMMANDS ((CONFIG_CMD_DFL | CFG_CMD_NAND) \
|
||||
& ~(CFG_CMD_NET | CFG_CMD_FLASH | \
|
||||
CFG_CMD_ENV | CFG_CMD_IMLS))
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -152,20 +154,41 @@
|
|||
#define PHYS_SDRAM_4 0xa3000000 /* SDRAM Bank #4 */
|
||||
#define PHYS_SDRAM_4_SIZE 0x1000000 /* 64 MB */
|
||||
|
||||
#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */
|
||||
#define PHYS_FLASH_2 0x04000000 /* Flash Bank #2 */
|
||||
#define PHYS_FLASH_SIZE 0x02000000 /* 32 MB */
|
||||
#define PHYS_FLASH_BANK_SIZE 0x02000000 /* 32 MB Banks */
|
||||
#define PHYS_FLASH_SECT_SIZE 0x00040000 /* 256 KB sectors (x2) */
|
||||
|
||||
#define CFG_DRAM_BASE 0xa0000000 /* at CS0 */
|
||||
#define CFG_DRAM_SIZE 0x04000000 /* 64 MB Ram */
|
||||
|
||||
#define CFG_SKIP_DRAM_SCRUB 1
|
||||
|
||||
#define CFG_FLASH_BASE PHYS_FLASH_1
|
||||
/*
|
||||
* NAND Flash
|
||||
*/
|
||||
/* Use the new NAND code. (BOARDLIBS = drivers/nand/libnand.a required) */
|
||||
#define CONFIG_NEW_NAND_CODE
|
||||
#define CFG_NAND0_BASE 0x10000000
|
||||
#undef CFG_NAND1_BASE
|
||||
|
||||
#define FPGA_REGS_BASE_PHYSICAL 0x08000000
|
||||
#define CFG_NAND_BASE_LIST { CFG_NAND0_BASE }
|
||||
#define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */
|
||||
#define SECTORSIZE 512
|
||||
/* #define NAND_NO_RB */
|
||||
#define NAND_DELAY_US 25 /* mk@tbd: could be 0, I guess */
|
||||
|
||||
#define ADDR_COLUMN 1
|
||||
#define ADDR_PAGE 2
|
||||
#define ADDR_COLUMN_PAGE 3
|
||||
|
||||
#define NAND_ChipID_UNKNOWN 0x00
|
||||
#define NAND_MAX_FLOORS 1
|
||||
#define NAND_MAX_CHIPS 1
|
||||
|
||||
#define CFG_NO_FLASH 1
|
||||
#ifndef CGF_NO_FLASH
|
||||
/* these are required by the environment code */
|
||||
#define PHYS_FLASH_1 CFG_NAND0_BASE /* Flash Bank #1 */
|
||||
#define PHYS_FLASH_SIZE 0x04000000 /* 64 MB */
|
||||
#define PHYS_FLASH_BANK_SIZE 0x04000000 /* 64 MB Banks */
|
||||
#define PHYS_FLASH_SECT_SIZE (SECTORSIZE*1024) /* KB sectors (x2) */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* GPIO settings
|
||||
|
@ -215,6 +238,7 @@
|
|||
/*
|
||||
* FLASH and environment organization
|
||||
*/
|
||||
#ifndef CFG_NO_FLASH
|
||||
#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */
|
||||
#define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */
|
||||
|
||||
|
@ -222,30 +246,16 @@
|
|||
#define CFG_FLASH_ERASE_TOUT (25*CFG_HZ) /* Timeout for Flash Erase */
|
||||
#define CFG_FLASH_WRITE_TOUT (25*CFG_HZ) /* Timeout for Flash Write */
|
||||
|
||||
|
||||
/* NOTE: many default partitioning schemes assume the kernel starts at the
|
||||
* second sector, not an environment. You have been warned!
|
||||
*/
|
||||
#define CFG_MONITOR_LEN PHYS_FLASH_SECT_SIZE
|
||||
#endif /* #ifndef CFG_NO_FLASH */
|
||||
|
||||
#define CFG_ENV_IS_IN_FLASH 1
|
||||
#define CFG_ENV_ADDR (PHYS_FLASH_1 + PHYS_FLASH_SECT_SIZE)
|
||||
#define CFG_ENV_SECT_SIZE PHYS_FLASH_SECT_SIZE
|
||||
#define CFG_ENV_SIZE (PHYS_FLASH_SECT_SIZE / 16)
|
||||
|
||||
|
||||
/*
|
||||
* FPGA Offsets
|
||||
*/
|
||||
#define WHOAMI_OFFSET 0x00
|
||||
#define HEXLED_OFFSET 0x10
|
||||
#define BLANKLED_OFFSET 0x40
|
||||
#define DISCRETELED_OFFSET 0x40
|
||||
#define CNFG_SWITCHES_OFFSET 0x50
|
||||
#define USER_SWITCHES_OFFSET 0x60
|
||||
#define MISC_WR_OFFSET 0x80
|
||||
#define MISC_RD_OFFSET 0x90
|
||||
#define INT_MASK_OFFSET 0xC0
|
||||
#define INT_CLEAR_OFFSET 0xD0
|
||||
#define GP_OFFSET 0x100
|
||||
#define CFG_ENV_IS_NOWHERE
|
||||
/* #define CFG_ENV_IS_IN_NAND 1 */
|
||||
#define CFG_ENV_OFFSET 0x40000
|
||||
#define CFG_ENV_SIZE 0x4000
|
||||
|
||||
#endif /* __CONFIG_H */
|
||||
|
|
|
@ -179,11 +179,13 @@ static int display_dram_config (void)
|
|||
return (0);
|
||||
}
|
||||
|
||||
#ifndef CFG_NO_FLASH
|
||||
static void display_flash_config (ulong size)
|
||||
{
|
||||
puts ("Flash: ");
|
||||
print_size (size, "\n");
|
||||
}
|
||||
#endif /* CFG_NO_FLASH */
|
||||
|
||||
|
||||
/*
|
||||
|
@ -259,9 +261,11 @@ void start_armboot (void)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef CFG_NO_FLASH
|
||||
/* configure available FLASH banks */
|
||||
size = flash_init ();
|
||||
display_flash_config (size);
|
||||
#endif /* CFG_NO_FLASH */
|
||||
|
||||
#ifdef CONFIG_VFD
|
||||
# ifndef PAGE_SIZE
|
||||
|
|
Loading…
Reference in New Issue