Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 207785
b: refs/heads/master
c: 4429917
h: refs/heads/master
i:
  207783: 5c61950
v: v3
  • Loading branch information
Barry Song authored and David Woodhouse committed Aug 5, 2010
1 parent 3afb879 commit 5de2734
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 42 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 752b957a37ee1cc09fccb39a8bc5843edf32119b
refs/heads/master: 44299179c0e87cc6d8b753c1ca8c97b1cf9340e1
3 changes: 0 additions & 3 deletions trunk/arch/blackfin/include/asm/nand.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
* partitions = mtd partition list
*/

#define NFC_PG_SIZE_256 0
#define NFC_PG_SIZE_512 1
#define NFC_PG_SIZE_OFFSET 9

#define NFC_NWIDTH_8 0
Expand All @@ -30,7 +28,6 @@

struct bf5xx_nand_platform {
/* NAND chip information */
unsigned short page_size;
unsigned short data_width;

/* RD/WR strobe delay timing information, all times in SCLK cycles */
Expand Down
86 changes: 48 additions & 38 deletions trunk/drivers/mtd/nand/bf5xx_nand.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,18 +314,16 @@ static int bf5xx_nand_correct_data_256(struct mtd_info *mtd, u_char *dat,
static int bf5xx_nand_correct_data(struct mtd_info *mtd, u_char *dat,
u_char *read_ecc, u_char *calc_ecc)
{
struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
struct bf5xx_nand_platform *plat = info->platform;
unsigned short page_size = (plat->page_size ? 512 : 256);
struct nand_chip *chip = mtd->priv;
int ret;

ret = bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc);

/* If page size is 512, correct second 256 bytes */
if (page_size == 512) {
/* If ecc size is 512, correct second 256 bytes */
if (chip->ecc.size == 512) {
dat += 256;
read_ecc += 8;
calc_ecc += 8;
read_ecc += 3;
calc_ecc += 3;
ret |= bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc);
}

Expand All @@ -341,26 +339,24 @@ static int bf5xx_nand_calculate_ecc(struct mtd_info *mtd,
const u_char *dat, u_char *ecc_code)
{
struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
struct bf5xx_nand_platform *plat = info->platform;
u16 page_size = (plat->page_size ? 512 : 256);
struct nand_chip *chip = mtd->priv;
u16 ecc0, ecc1;
u32 code[2];
u8 *p;

/* first 4 bytes ECC code for 256 page size */
/* first 3 bytes ECC code for 256 page size */
ecc0 = bfin_read_NFC_ECC0();
ecc1 = bfin_read_NFC_ECC1();

code[0] = (ecc0 & 0x7ff) | ((ecc1 & 0x7ff) << 11);

dev_dbg(info->device, "returning ecc 0x%08x\n", code[0]);

/* first 3 bytes in ecc_code for 256 page size */
p = (u8 *) code;
memcpy(ecc_code, p, 3);

/* second 4 bytes ECC code for 512 page size */
if (page_size == 512) {
/* second 3 bytes ECC code for 512 ecc size */
if (chip->ecc.size == 512) {
ecc0 = bfin_read_NFC_ECC2();
ecc1 = bfin_read_NFC_ECC3();
code[1] = (ecc0 & 0x7ff) | ((ecc1 & 0x7ff) << 11);
Expand Down Expand Up @@ -480,8 +476,7 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd,
uint8_t *buf, int is_read)
{
struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
struct bf5xx_nand_platform *plat = info->platform;
unsigned short page_size = (plat->page_size ? 512 : 256);
struct nand_chip *chip = mtd->priv;
unsigned short val;

dev_dbg(info->device, " mtd->%p, buf->%p, is_read %d\n",
Expand All @@ -495,10 +490,10 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd,
*/
if (is_read)
invalidate_dcache_range((unsigned int)buf,
(unsigned int)(buf + page_size));
(unsigned int)(buf + chip->ecc.size));
else
flush_dcache_range((unsigned int)buf,
(unsigned int)(buf + page_size));
(unsigned int)(buf + chip->ecc.size));

/*
* This register must be written before each page is
Expand All @@ -519,13 +514,13 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd,

/* The DMAs have different size on BF52x and BF54x */
#ifdef CONFIG_BF52x
set_dma_x_count(CH_NFC, (page_size >> 1));
set_dma_x_count(CH_NFC, (chip->ecc.size >> 1));
set_dma_x_modify(CH_NFC, 2);
val = DI_EN | WDSIZE_16;
#endif

#ifdef CONFIG_BF54x
set_dma_x_count(CH_NFC, (page_size >> 2));
set_dma_x_count(CH_NFC, (chip->ecc.size >> 2));
set_dma_x_modify(CH_NFC, 4);
val = DI_EN | WDSIZE_32;
#endif
Expand All @@ -547,12 +542,11 @@ static void bf5xx_nand_dma_read_buf(struct mtd_info *mtd,
uint8_t *buf, int len)
{
struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
struct bf5xx_nand_platform *plat = info->platform;
unsigned short page_size = (plat->page_size ? 512 : 256);
struct nand_chip *chip = mtd->priv;

dev_dbg(info->device, "mtd->%p, buf->%p, int %d\n", mtd, buf, len);

if (len == page_size)
if (len == chip->ecc.size)
bf5xx_nand_dma_rw(mtd, buf, 1);
else
bf5xx_nand_read_buf(mtd, buf, len);
Expand All @@ -562,12 +556,11 @@ static void bf5xx_nand_dma_write_buf(struct mtd_info *mtd,
const uint8_t *buf, int len)
{
struct bf5xx_nand_info *info = mtd_to_nand_info(mtd);
struct bf5xx_nand_platform *plat = info->platform;
unsigned short page_size = (plat->page_size ? 512 : 256);
struct nand_chip *chip = mtd->priv;

dev_dbg(info->device, "mtd->%p, buf->%p, len %d\n", mtd, buf, len);

if (len == page_size)
if (len == chip->ecc.size)
bf5xx_nand_dma_rw(mtd, (uint8_t *)buf, 0);
else
bf5xx_nand_write_buf(mtd, buf, len);
Expand Down Expand Up @@ -642,12 +635,11 @@ static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info)

/* setup NFC_CTL register */
dev_info(info->device,
"page_size=%d, data_width=%d, wr_dly=%d, rd_dly=%d\n",
(plat->page_size ? 512 : 256),
"data_width=%d, wr_dly=%d, rd_dly=%d\n",
(plat->data_width ? 16 : 8),
plat->wr_dly, plat->rd_dly);

val = (plat->page_size << NFC_PG_SIZE_OFFSET) |
val = (1 << NFC_PG_SIZE_OFFSET) |
(plat->data_width << NFC_NWIDTH_OFFSET) |
(plat->rd_dly << NFC_RDDLY_OFFSET) |
(plat->wr_dly << NFC_WRDLY_OFFSET);
Expand Down Expand Up @@ -713,6 +705,33 @@ static int __devexit bf5xx_nand_remove(struct platform_device *pdev)
return 0;
}

static int bf5xx_nand_scan(struct mtd_info *mtd)
{
struct nand_chip *chip = mtd->priv;
int ret;

ret = nand_scan_ident(mtd, 1);
if (ret)
return ret;

if (hardware_ecc) {
/*
* for nand with page size > 512B, think it as several sections with 512B
*/
if (likely(mtd->writesize >= 512)) {
chip->ecc.size = 512;
chip->ecc.bytes = 6;
} else {
chip->ecc.size = 256;
chip->ecc.bytes = 3;
bfin_write_NFC_CTL(bfin_read_NFC_CTL() & ~(1 << NFC_PG_SIZE_OFFSET));
SSYNC();
}
}

return nand_scan_tail(mtd);
}

/*
* bf5xx_nand_probe
*
Expand Down Expand Up @@ -798,15 +817,6 @@ static int __devinit bf5xx_nand_probe(struct platform_device *pdev)
chip->badblock_pattern = &bootrom_bbt;
chip->ecc.layout = &bootrom_ecclayout;
#endif

if (plat->page_size == NFC_PG_SIZE_256) {
chip->ecc.bytes = 3;
chip->ecc.size = 256;
} else if (plat->page_size == NFC_PG_SIZE_512) {
chip->ecc.bytes = 6;
chip->ecc.size = 512;
}

chip->read_buf = bf5xx_nand_dma_read_buf;
chip->write_buf = bf5xx_nand_dma_write_buf;
chip->ecc.calculate = bf5xx_nand_calculate_ecc;
Expand All @@ -820,7 +830,7 @@ static int __devinit bf5xx_nand_probe(struct platform_device *pdev)
}

/* scan hardware nand chip and setup mtd info data struct */
if (nand_scan(mtd, 1)) {
if (bf5xx_nand_scan(mtd)) {
err = -ENXIO;
goto out_err_nand_scan;
}
Expand Down

0 comments on commit 5de2734

Please sign in to comment.