This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
TI的工程师您好,
我正在移植 ti-processor-sdk-linux-am335x-evm-01.00.00.00 中的 u-boot-2014.07-g7e537bf nand驱动,make am335x_evm_nandboot_config,根据板子配置nand的pinmux,nand芯片型号是S34ML08G101TF100
启动后不断打印nand: bit-flip corrected @oob=0
这里应该是正在读取nand中的环境变量,问题是每个页都在oob[0]发生位翻转???并且执行save命令是正常的:
U-Boot# sa
Saving Environment to NAND...
Erasing NAND...
Erasing at 0x1c0000 -- 100% complete.
Writing to NAND... OK
以下是启动信息:
U-Boot 2014.07-00107-ga6ef75a-dirty (Dec 01 2015 - 14:07:04)
I2C: ready
DRAM: 512 MiB
NAND: ONFI flash detected
NAND device: Manufacturer ID: 0x01, Chip ID: 0xd3 (AMD/Spansion S34ML08G1)
1024 MiB
nand: bit-flip corrected @oob=0
nand: bit-flip corrected @oob=0
nand: bit-flip corrected @oob=0
nand: bit-flip corrected @oob=0
nand: bit-flip corrected @oob=0
nand: bit-flip corrected @oob=0
nand: bit-flip corrected @oob=0
nand: bit-flip corrected @oob=0
nand: bit-flip corrected @oob=0
nand: bit-flip corrected @oob=0
问题查出来了,随机读函数不能传递参数page,在uboot源码中搜索NAND_CMD_RNDOUT,只有TI的omap_read_page_bch函数传递了page参数,其他厂家的代码都是传-1的,所以将page改成-1就好了。由此猜测,TI的BSP是否对ONFI规范的flash存在不兼容的情况?
cmdfunc最终调用nand_base.c中的nand_command函数,
static void nand_command(struct mtd_info *mtd, unsigned int command,
int column, int page_addr)
{
register struct nand_chip *chip = mtd->priv;
int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE;
uint32_t rst_sts_cnt = CONFIG_SYS_NAND_RESET_CNT;
/* Write out the command to the device */
if (command == NAND_CMD_SEQIN) {
int readcmd;
if (column >= mtd->writesize) {
/* OOB area */
column -= mtd->writesize;
readcmd = NAND_CMD_READOOB;
} else if (column < 256) {
/* First 256 bytes --> READ0 */
readcmd = NAND_CMD_READ0;
} else {
column -= 256;
readcmd = NAND_CMD_READ1;
}
chip->cmd_ctrl(mtd, readcmd, ctrl);
ctrl &= ~NAND_CTRL_CHANGE;
}
chip->cmd_ctrl(mtd, command, ctrl);
/* Address cycle, when necessary */
ctrl = NAND_CTRL_ALE | NAND_CTRL_CHANGE;
/* Serially input address */
if (column != -1) {
/* Adjust columns for 16 bit buswidth */
if ((chip->options & NAND_BUSWIDTH_16) &&
!nand_opcode_8bits(command))
column >>= 1;
chip->cmd_ctrl(mtd, column, ctrl);
ctrl &= ~NAND_CTRL_CHANGE;
}
if (page_addr != -1) {
chip->cmd_ctrl(mtd, page_addr, ctrl);
ctrl &= ~NAND_CTRL_CHANGE;
chip->cmd_ctrl(mtd, page_addr >> 8, ctrl);
/* One more address cycle for devices > 32MiB */
if (chip->chipsize > (32 << 20))
chip->cmd_ctrl(mtd, page_addr >> 16, ctrl);
}
chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
/*
* 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 (chip->dev_ready)
break;
udelay(chip->chip_delay);
chip->cmd_ctrl(mtd, NAND_CMD_STATUS,
NAND_CTRL_CLE | NAND_CTRL_CHANGE);
chip->cmd_ctrl(mtd,
NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
while (!(chip->read_byte(mtd) & NAND_STATUS_READY) &&
(rst_sts_cnt--));
return;
/* This applies to read commands */
default:
/*
* If we don't have access to the busy pin, we apply the given
* command delay
*/
if (!chip->dev_ready) {
udelay(chip->chip_delay);
return;
}
}
/*
* Apply this short delay always to ensure that we do wait tWB in
* any case on any machine.
*/
ndelay(100);
nand_wait_ready(mtd);
}