Fix OneNAND build break

Since page size field is changed from oobblock to writesize. But OneNAND is not updated.
- fix bufferram management at erase operation
This patch includes the NAND/OneNAND state filed too.

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Scott Wood <scottwood@freescale.com>
master
Kyungmin Park 16 years ago committed by Scott Wood
parent 8641ff266a
commit d438d50848
  1. 10
      common/env_onenand.c
  2. 131
      drivers/mtd/onenand/onenand_base.c
  3. 4
      drivers/mtd/onenand/onenand_bbt.c
  4. 16
      include/linux/mtd/mtd.h
  5. 16
      include/linux/mtd/nand.h
  6. 12
      include/linux/mtd/nand_legacy.h
  7. 19
      include/linux/mtd/onenand.h

@ -40,7 +40,7 @@ extern struct onenand_chip onenand_chip;
/* References to names in env_common.c */
extern uchar default_environment[];
#define ONENAND_ENV_SIZE(mtd) (mtd.oobblock - ENV_HEADER_SIZE)
#define ONENAND_ENV_SIZE(mtd) (mtd.writesize - ENV_HEADER_SIZE)
char *env_name_spec = "OneNAND";
@ -68,12 +68,12 @@ void env_relocate_spec(void)
env_addr = CFG_ENV_ADDR;
/* Check OneNAND exist */
if (onenand_mtd.oobblock)
if (onenand_mtd.writesize)
/* Ignore read fail */
onenand_read(&onenand_mtd, env_addr, onenand_mtd.oobblock,
onenand_read(&onenand_mtd, env_addr, onenand_mtd.writesize,
&retlen, (u_char *) env_ptr);
else
onenand_mtd.oobblock = MAX_ONENAND_PAGESIZE;
onenand_mtd.writesize = MAX_ONENAND_PAGESIZE;
if (crc32(0, env_ptr->data, ONENAND_ENV_SIZE(onenand_mtd)) !=
env_ptr->crc)
@ -109,7 +109,7 @@ int saveenv(void)
env_ptr->crc =
crc32(0, env_ptr->data, ONENAND_ENV_SIZE(onenand_mtd));
if (onenand_write(&onenand_mtd, env_addr, onenand_mtd.oobblock, &retlen,
if (onenand_write(&onenand_mtd, env_addr, onenand_mtd.writesize, &retlen,
(u_char *) env_ptr)) {
printf("OneNAND: write failed at 0x%08x\n", instr.addr);
return 2;

@ -331,7 +331,7 @@ static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
if (ONENAND_CURRENT_BUFFERRAM(this)) {
if (area == ONENAND_DATARAM)
return mtd->oobblock;
return mtd->writesize;
if (area == ONENAND_SPARERAM)
return mtd->oobsize;
}
@ -482,6 +482,30 @@ static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
}
/**
* onenand_invalidate_bufferram - [GENERIC] Invalidate BufferRAM information
* @param mtd MTD data structure
* @param addr start address to invalidate
* @param len length to invalidate
*
* Invalidate BufferRAM information
*/
static void onenand_invalidate_bufferram(struct mtd_info *mtd, loff_t addr,
unsigned int len)
{
struct onenand_chip *this = mtd->priv;
int i;
loff_t end_addr = addr + len;
/* Invalidate BufferRAM */
for (i = 0; i < MAX_BUFFERRAM; i++) {
loff_t buf_addr = this->bufferram[i].block << this->erase_shift;
if (buf_addr >= addr && buf_addr < end_addr)
this->bufferram[i].valid = 0;
}
}
/**
* onenand_get_device - [GENERIC] Get chip for selected access
* @param mtd MTD device structure
* @param new_state the state which is requested
@ -541,15 +565,15 @@ static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
onenand_get_device(mtd, FL_READING);
while (read < len) {
thislen = min_t(int, mtd->oobblock, len - read);
thislen = min_t(int, mtd->writesize, len - read);
column = from & (mtd->oobblock - 1);
if (column + thislen > mtd->oobblock)
thislen = mtd->oobblock - column;
column = from & (mtd->writesize - 1);
if (column + thislen > mtd->writesize)
thislen = mtd->writesize - column;
if (!onenand_check_bufferram(mtd, from)) {
this->command(mtd, ONENAND_CMD_READ, from,
mtd->oobblock);
mtd->writesize);
ret = this->wait(mtd, FL_READING);
/* First copy data and check return value for ECC handling */
onenand_update_bufferram(mtd, from, 1);
@ -664,7 +688,7 @@ int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
/* Read more? */
if (read < len) {
/* Page size */
from += mtd->oobblock;
from += mtd->writesize;
column = 0;
}
}
@ -691,7 +715,7 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,
void __iomem *dataram0, *dataram1;
int ret = 0;
this->command(mtd, ONENAND_CMD_READ, addr, mtd->oobblock);
this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);
ret = this->wait(mtd, FL_READING);
if (ret)
@ -701,9 +725,9 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,
/* Check, if the two dataram areas are same */
dataram0 = this->base + ONENAND_DATARAM;
dataram1 = dataram0 + mtd->oobblock;
dataram1 = dataram0 + mtd->writesize;
if (memcmp(dataram0, dataram1, mtd->oobblock))
if (memcmp(dataram0, dataram1, mtd->writesize))
return -EBADMSG;
return 0;
@ -712,7 +736,7 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,
#define onenand_verify_page(...) (0)
#endif
#define NOTALIGNED(x) ((x & (mtd->oobblock - 1)) != 0)
#define NOTALIGNED(x) ((x & (mtd->writesize - 1)) != 0)
/**
* onenand_write_ecc - [MTD Interface] OneNAND write with ECC
@ -760,15 +784,15 @@ static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
/* Loop until all data write */
while (written < len) {
int thislen = min_t(int, mtd->oobblock, len - written);
int thislen = min_t(int, mtd->writesize, len - written);
this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->writesize);
this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen);
this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0,
mtd->oobsize);
this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
onenand_update_bufferram(mtd, to, 1);
@ -893,6 +917,25 @@ int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
}
/**
* onenand_block_isbad_nolock - [GENERIC] Check if a block is marked bad
* @param mtd MTD device structure
* @param ofs offset from device start
* @param allowbbt 1, if its allowed to access the bbt area
*
* Check, if the block is bad, Either by reading the bad block table or
* calling of the scan function.
*/
static int onenand_block_isbad_nolock(struct mtd_info *mtd, loff_t ofs, int allowbbt)
{
struct onenand_chip *this = mtd->priv;
struct bbm_info *bbm = this->bbm;
/* Return info from the table */
return bbm->isbad_bbt(mtd, ofs, allowbbt);
}
/**
* onenand_erase - [MTD Interface] erase block(s)
* @param mtd MTD device structure
* @param instr erase instruction
@ -950,6 +993,8 @@ int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
onenand_invalidate_bufferram(mtd, addr, block_size);
ret = this->wait(mtd, FL_ERASING);
/* Check, if it is write protected */
if (ret) {
@ -1005,30 +1050,45 @@ void onenand_sync(struct mtd_info *mtd)
* onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
* @param mtd MTD device structure
* @param ofs offset relative to mtd start
*
* Check whether the block is bad
*/
int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
{
/*
* TODO
* 1. Bad block table (BBT)
* -> using NAND BBT to support JFFS2
* 2. Bad block management (BBM)
* -> bad block replace scheme
*
* Currently we do nothing
*/
return 0;
int ret;
/* Check for invalid offset */
if (ofs > mtd->size)
return -EINVAL;
onenand_get_device(mtd, FL_READING);
ret = onenand_block_isbad_nolock(mtd,ofs, 0);
onenand_release_device(mtd);
return ret;
}
/**
* onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
* @param mtd MTD device structure
* @param ofs offset relative to mtd start
*
* Mark the block as bad
*/
int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
{
/* see above */
return 0;
struct onenand_chip *this = mtd->priv;
int ret;
ret = onenand_block_isbad(mtd, ofs);
if (ret) {
/* If it was bad already, return success and do nothing */
if (ret > 0)
return 0;
return ret;
}
ret = this->block_markbad(mtd, ofs);
return ret;
}
/**
@ -1184,10 +1244,8 @@ static int onenand_probe(struct mtd_info *mtd)
/* Reset OneNAND to read default register values */
this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
{
int i;
for (i = 0; i < 10000; i++) ;
}
/* Wait reset */
this->wait(mtd, FL_RESETING);
/* Read manufacturer and device IDs from Register */
maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
@ -1212,16 +1270,16 @@ static int onenand_probe(struct mtd_info *mtd)
/* OneNAND page size & block size */
/* The data buffer size is equal to page size */
mtd->oobblock =
mtd->writesize =
this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
mtd->oobsize = mtd->oobblock >> 5;
mtd->oobsize = mtd->writesize >> 5;
/* Pagers per block is always 64 in OneNAND */
mtd->erasesize = mtd->oobblock << 6;
mtd->erasesize = mtd->writesize << 6;
this->erase_shift = ffs(mtd->erasesize) - 1;
this->page_shift = ffs(mtd->oobblock) - 1;
this->page_shift = ffs(mtd->writesize) - 1;
this->ppb_shift = (this->erase_shift - this->page_shift);
this->page_mask = (mtd->erasesize / mtd->oobblock) - 1;
this->page_mask = (mtd->erasesize / mtd->writesize) - 1;
/* REVIST: Multichip handling */
@ -1240,11 +1298,10 @@ static int onenand_probe(struct mtd_info *mtd)
this->options |= ONENAND_CONT_LOCK;
}
mtd->flags = MTD_CAP_NANDFLASH;
mtd->erase = onenand_erase;
mtd->read = onenand_read;
mtd->write = onenand_write;
mtd->read_ecc = onenand_read_ecc;
mtd->write_ecc = onenand_write_ecc;
mtd->read_oob = onenand_read_oob;
mtd->write_oob = onenand_write_oob;
mtd->sync = onenand_sync;

@ -97,7 +97,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
/* No need to read pages fully,
* just read required OOB bytes */
ret = onenand_read_oob(mtd,
from + j * mtd->oobblock +
from + j * mtd->writesize +
bd->offs, readlen, &retlen,
&buf[0]);
@ -107,7 +107,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
}
if (check_short_pattern
(&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
(&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
printk(KERN_WARNING
"Bad eraseblock %d at 0x%08x\n", i >> 1,

@ -22,6 +22,22 @@
#define MTD_ERASE_DONE 0x08
#define MTD_ERASE_FAILED 0x10
/*
* Enumeration for NAND/OneNAND flash chip state
*/
enum {
FL_READY,
FL_READING,
FL_WRITING,
FL_ERASING,
FL_SYNCING,
FL_CACHEDPRG,
FL_RESETING,
FL_UNLOCKING,
FL_LOCKING,
FL_PM_SUSPENDED,
};
/* If the erase fails, fail_addr might indicate exactly which block failed. If
fail_addr = 0xffffffff, the failure was not at the device level or was not
specific to any particular block. */

@ -213,20 +213,6 @@ typedef enum {
#define NAND_CI_CHIPNR_MSK 0x03
#define NAND_CI_CELLTYPE_MSK 0x0C
/*
* nand_state_t - chip states
* Enumeration for NAND flash chip state
*/
typedef enum {
FL_READY,
FL_READING,
FL_WRITING,
FL_ERASING,
FL_SYNCING,
FL_CACHEDPRG,
FL_PM_SUSPENDED,
} nand_state_t;
/* Keep gcc happy */
struct nand_chip;
@ -416,7 +402,7 @@ struct nand_chip {
uint8_t cellinfo;
int badblockpos;
nand_state_t state;
int state;
uint8_t *oob_poi;
struct nand_hw_control *controller;

@ -55,18 +55,6 @@
#define NAND_CMD_RESET 0xff
/*
* Enumeration for NAND flash chip state
*/
typedef enum {
FL_READY,
FL_READING,
FL_WRITING,
FL_ERASING,
FL_SYNCING
} nand_state_t;
/*
* NAND Private Flash Chip Data
*
* Structure overview:

@ -17,6 +17,7 @@
/* Note: The header order is impoertant */
#include <onenand_uboot.h>
#include <linux/mtd/compat.h>
#include <linux/mtd/bbm.h>
#define MAX_BUFFERRAM 2
@ -28,20 +29,6 @@ extern int onenand_scan (struct mtd_info *mtd, int max_chips);
extern void onenand_release (struct mtd_info *mtd);
/**
* onenand_state_t - chip states
* Enumeration for OneNAND flash chip state
*/
typedef enum {
FL_READY,
FL_READING,
FL_WRITING,
FL_ERASING,
FL_SYNCING,
FL_UNLOCKING,
FL_LOCKING,
} onenand_state_t;
/**
* struct onenand_bufferram - OneNAND BufferRAM Data
* @param block block address in BufferRAM
* @param page page address in BufferRAM
@ -103,10 +90,12 @@ struct onenand_chip {
unsigned short (*read_word) (void __iomem * addr);
void (*write_word) (unsigned short value, void __iomem * addr);
void (*mmcontrol) (struct mtd_info * mtd, int sync_read);
int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
int (*scan_bbt)(struct mtd_info *mtd);
spinlock_t chip_lock;
wait_queue_head_t wq;
onenand_state_t state;
int state;
struct nand_oobinfo *autooob;

Loading…
Cancel
Save