/* ----------------------------------------------------------------------------
* NAND Flash configuration
*/
/* NAND Flash I/O port */
#define CFG_NAND_BASE (0x02000000)
#define QT_NAND_IO (*(volatile unsigned char *)(0x02000000))
#define QT_CMD_PORT (*(volatile unsigned char *)(0x02000004))
#define QT_ADDR_PORT (*(volatile unsigned char *)(0x02000008))
#define QT_GPC_DATA (0x01D20014)
#define QT_GPE_DATA (0X01D2002C)
#define QT_READ_REG_ULONG(p) (*(volatile unsigned long *)(p))
#define QT_WRITE_REG_ULONG(p,v) (*(volatile unsigned long *)(p)) = (v)
/* Chip Enable */
#define MACRO_NAND_ENABLE_CE() \
(QT_WRITE_REG_ULONG(QT_GPE_DATA, (QT_READ_REG_ULONG(QT_GPE_DATA) & (0xFFFFFFFE))))
/* Chip Disable */
#define MACRO_NAND_DISABLE_CE() \
(QT_WRITE_REG_ULONG(QT_GPE_DATA, (QT_READ_REG_ULONG(QT_GPE_DATA) | (0x1))))
/* command latch enable */
#define MACRO_NAND_CTL_SETCLE()
/* command latch enable */
#define MACRO_NAND_CTL_CLRCLE()
/* address latch enable */
#define MACRO_NAND_CTL_SETALE()
/* address latch disable */
#define MACRO_NAND_CTL_CLRALE()
/* doc/README.nand need define */
#define NAND_MAX_CHIPS 1
#define CFG_MAX_NAND_DEVICE 1
/*
* (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
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
#include
/*
* hardware specific access to control-lines
*/
static void QT_hwcontrol(struct mtd_info *mtdinfo, int cmd)
{
switch(cmd) {
case NAND_CTL_SETCLE:
MACRO_NAND_CTL_SETCLE();
break;
case NAND_CTL_CLRCLE:
MACRO_NAND_CTL_CLRCLE();
break;
case NAND_CTL_SETALE:
MACRO_NAND_CTL_SETALE();
break;
case NAND_CTL_CLRALE:
MACRO_NAND_CTL_CLRALE();
break;
case NAND_CTL_SETNCE:
MACRO_NAND_ENABLE_CE();
break;
case NAND_CTL_CLRNCE:
MACRO_NAND_DISABLE_CE();
break;
}
}
/*
* read device ready pin
*/
static int QT_device_ready(struct mtd_info *mtdinfo)
{
if (QT_READ_REG_ULONG(QT_GPC_DATA) & (0x1<<10)){
return 1;
}
return 0;
}
static void QT_SetCommand( unsigned char command )
{
volatile int delay;
for(delay = 8; delay > 0; delay--)
delay--;
QT_CMD_PORT = command;
for(delay = 8; delay > 0; delay--)
delay--;
}
static void QT_SetAddress( unsigned char address )
{
volatile int delay;
for(delay = 8; delay > 0; delay--)
delay--;
QT_ADDR_PORT = address;
for(delay = 8; delay > 0; delay--)
delay--;
}
/**
* nand_command - [DEFAULT] Send command to NAND device
* @mtd: MTD device structure
* @command: the command to be sent
* @column: the column address for this command, -1 if none
* @page_addr: the page address for this command, -1 if none
*
* Send command to NAND device. This function is used for small page
* devices (256/512 Bytes per page)
*/
static void QT_nand_command (struct mtd_info *mtd, unsigned char command, int column, int page_addr)
{
register struct nand_chip *this = mtd->priv;
/* Begin command latch cycle */
this->hwcontrol(mtd, NAND_CTL_SETCLE);
/*
* Write out the command to the device.
*/
if (command == NAND_CMD_SEQIN) {
int readcmd;
if (column >= mtd->oobblock) {
/* OOB area */
column -= mtd->oobblock;
readcmd = NAND_CMD_READOOB;
} else if (column < 256) {
/* First 256 bytes --> READ0 */
readcmd = NAND_CMD_READ0;
} else {
column -= 256;
readcmd = NAND_CMD_READ1;
}
QT_SetCommand(readcmd);
}
QT_SetCommand(command);
/* Set ALE and clear CLE to start address cycle */
this->hwcontrol(mtd, NAND_CTL_CLRCLE);
if (column != -1 || page_addr != -1) {
this->hwcontrol(mtd, NAND_CTL_SETALE);
/* Serially input address */
if (column != -1) {
/* Adjust columns for 16 bit buswidth */
if (this->options & NAND_BUSWIDTH_16)
column >>= 1;
QT_SetAddress(column);
}
if (page_addr != -1) {
QT_SetAddress((unsigned char) (page_addr & 0xff));
QT_SetAddress((unsigned char) ((page_addr >> 8) & 0xff));
/* One more address cycle for devices > 32MiB */
if (this->chipsize > (32 << 20))
QT_SetAddress((unsigned char) ((page_addr >> 16) & 0x0f));
}
/* Latch in address */
this->hwcontrol(mtd, NAND_CTL_CLRALE);
}
/*
* program and erase have their own busy handlers
* status and sequential in needs no delay
*/
switch (command) {
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:
if (this->dev_ready)
break;
udelay(this->chip_delay);
this->hwcontrol(mtd, NAND_CTL_SETCLE);
QT_SetCommand(NAND_CMD_STATUS);
this->hwcontrol(mtd, NAND_CTL_CLRCLE);
while ( !(this->read_byte(mtd) & 0x40));
return;
/* This applies to read commands */
default:
/*
* If we don't have access to the busy pin, we apply the given
* command delay
*/
if (!this->dev_ready) {
udelay (this->chip_delay);
return;
}
}
/* Apply this short delay always to ensure that we do wait tWB in
* any case on any machine. */
ndelay (100);
/* wait until command is processed */
while (!this->dev_ready(mtd));
}
/*
* Board-specific NAND initialization. The following members of the
* argument are board-specific (per include/linux/mtd/nand.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)
{
nand->hwcontrol = QT_hwcontrol;
nand->dev_ready = QT_device_ready;
nand->eccmode = NAND_ECC_SOFT;
/* nand->chip_delay = NAND_BIG_DELAY_US; */
nand->options = NAND_SAMSUNG_LP_OPTIONS;
nand->cmdfunc = QT_nand_command;
}
#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */
大家在移植时可以根据我上面代码分析的线索然后根据自己板子的情况修改上面的代码就几乎可以达到移植的目的了.一般板子的不同之处也就是在于命令的发送和芯片的开启与关闭.还有就是状态的确认.