Skip to content

Commit

Permalink
[MTD] [NAND] S3C2410 Large page NAND support
Browse files Browse the repository at this point in the history
This adds support for using large page NAND devices
with the S3C24XX NAND controller. This also adds the
file Documentation/arm/Samsung-S3C24XX/NAND.txt to
describe the differences.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
  • Loading branch information
Ben Dooks authored and David Woodhouse committed Apr 22, 2008
1 parent 0916083 commit 71d54f3
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 5 deletions.
30 changes: 30 additions & 0 deletions Documentation/arm/Samsung-S3C24XX/NAND.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
S3C24XX NAND Support
====================

Introduction
------------

Small Page NAND
---------------

The driver uses a 512 byte (1 page) ECC code for this setup. The
ECC code is not directly compatible with the default kernel ECC
code, so the driver enforces its own OOB layout and ECC parameters

Large Page NAND
---------------

The driver is capable of handling NAND flash with a 2KiB page
size, with support for hardware ECC generation and correction.

Unlike the 512byte page mode, the driver generates ECC data for
each 256 byte block in an 2KiB page. This means that more than
one error in a page can be rectified. It also means that the
OOB layout remains the default kernel layout for these flashes.


Document Author
---------------

Ben Dooks, Copyright 2007 Simtec Electronics

2 changes: 2 additions & 0 deletions Documentation/arm/Samsung-S3C24XX/Overview.txt
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ NAND
controller. If there are any problems the latest linux-mtd
code can be found from http://www.linux-mtd.infradead.org/

For more information see Documentation/arm/Samsung-S3C24XX/NAND.txt


Serial
------
Expand Down
38 changes: 33 additions & 5 deletions drivers/mtd/nand/s3c2410.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u
ecc_code[1] = ecc >> 8;
ecc_code[2] = ecc >> 16;

pr_debug("%s: returning ecc %06lx\n", __func__, ecc);
pr_debug("%s: returning ecc %06lx\n", __func__, ecc & 0xffffff);

return 0;
}
Expand Down Expand Up @@ -643,9 +643,6 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
chip->ecc.calculate = s3c2410_nand_calculate_ecc;
chip->ecc.correct = s3c2410_nand_correct_data;
chip->ecc.mode = NAND_ECC_HW;
chip->ecc.size = 512;
chip->ecc.bytes = 3;
chip->ecc.layout = &nand_hw_eccoob;

switch (info->cpu_type) {
case TYPE_S3C2410:
Expand All @@ -669,6 +666,34 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
}
}

/* s3c2410_nand_update_chip
*
* post-probe chip update, to change any items, such as the
* layout for large page nand
*/

static void s3c2410_nand_update_chip(struct s3c2410_nand_info *info,
struct s3c2410_nand_mtd *nmtd)
{
struct nand_chip *chip = &nmtd->chip;

printk("%s: chip %p: %d\n", __func__, chip, chip->page_shift);

if (hardware_ecc) {
/* change the behaviour depending on wether we are using
* the large or small page nand device */

if (chip->page_shift > 10) {
chip->ecc.size = 256;
chip->ecc.bytes = 3;
} else {
chip->ecc.size = 512;
chip->ecc.bytes = 3;
chip->ecc.layout = &nand_hw_eccoob;
}
}
}

/* s3c2410_nand_probe
*
* called by device layer when it finds a device matching
Expand Down Expand Up @@ -775,9 +800,12 @@ static int s3c24xx_nand_probe(struct platform_device *pdev,

s3c2410_nand_init_chip(info, nmtd, sets);

nmtd->scan_res = nand_scan(&nmtd->mtd, (sets) ? sets->nr_chips : 1);
nmtd->scan_res = nand_scan_ident(&nmtd->mtd,
(sets) ? sets->nr_chips : 1);

if (nmtd->scan_res == 0) {
s3c2410_nand_update_chip(info, nmtd);
nand_scan_tail(&nmtd->mtd);
s3c2410_nand_add_partition(info, nmtd, sets);
}

Expand Down

0 comments on commit 71d54f3

Please sign in to comment.