@@ -29,6 +29,7 @@
#define CHIP_DELAY_TIMEOUT (2 * HZ/10)
#define NAND_STOP_DELAY (2 * HZ/50)
#define PAGE_CHUNK_SIZE (2048)
+#define BCH_THRESHOLD (8)
/* registers and bit definitions */
#define NDCR (0x00) /* Control register */
@@ -38,12 +39,15 @@
#define NDPCR (0x18) /* Page Count Register */
#define NDBDR0 (0x1C) /* Bad Block Register 0 */
#define NDBDR1 (0x20) /* Bad Block Register 1 */
+#define NDECCCTRL (0x28) /* ECC Control Register */
#define NDDB (0x40) /* Data Buffer */
#define NDCB0 (0x48) /* Command Buffer0 */
#define NDCB1 (0x4C) /* Command Buffer1 */
#define NDCB2 (0x50) /* Command Buffer2 */
#define NDCR_SPARE_EN (0x1 << 31)
+#define NDSR_ERR_CNT_MASK (0x1F << 16)
+#define NDSR_ERR_CNT(x) (((x) << 16) & NDSR_ERR_CNT_MASK)
#define NDCR_ECC_EN (0x1 << 30)
#define NDCR_DMA_EN (0x1 << 29)
#define NDCR_ND_RUN (0x1 << 28)
@@ -92,6 +96,13 @@
#define NDCB0_CMD1_MASK (0xff)
#define NDCB0_ADDR_CYC_SHIFT (16)
+/* ECC Control Register */
+#define NDECCCTRL_ECC_SPARE_MSK (0xFF << 7)
+#define NDECCCTRL_ECC_SPARE(x) (((x) << 7) & NDECCCTRL_ECC_SPARE_MSK)
+#define NDECCCTRL_ECC_THR_MSK (0x3F << 1)
+#define NDECCCTRL_ECC_THRESH(x) (((x) << 1) & NDECCCTRL_ECC_THR_MSK)
+#define NDECCCTRL_BCH_EN (0x1)
+
/* macros for registers read/write */
#define nand_writel(info, off, val) \
__raw_writel((val), (info)->mmio_base + (off))
@@ -122,6 +133,13 @@ enum {
STATE_IS_WRITE = (1 << 7),
};
+/* error code and state */
+enum {
+ ECC_NONE = 0,
+ ECC_HAMMIN,
+ ECC_BCH,
+};
+
struct pxa3xx_nand_timing {
uint32_t tCH; /* Enable signal hold time */
uint32_t tCS; /* Enable signal setup time */
@@ -149,10 +167,11 @@ struct pxa3xx_nand_cmdset {
struct pxa3xx_nand_flash {
uint32_t chip_id;
- uint16_t page_per_block; /* Pages per block (PG_PER_BLK) */
- uint16_t page_size; /* Page size in bytes (PAGE_SZ) */
+ uint16_t page_per_block; /* Pages per block */
+ uint16_t page_size; /* Page size in bytes */
uint8_t flash_width; /* Width of Flash memory (DWIDTH_M) */
uint8_t dfc_width; /* Width of flash controller(DWIDTH_C) */
+ uint8_t ecc_type; /* Which ECC is applied */
uint32_t num_blocks; /* Number of physical blocks in Flash */
struct pxa3xx_nand_timing timing; /* NAND Flash timing */
};
@@ -172,7 +191,10 @@ struct pxa3xx_nand_info {
dma_addr_t data_desc_addr;
struct pxa_dma_desc *data_desc;
uint8_t chip_select;
- uint8_t use_ecc; /* use HW ECC ? */
+
+ /* use HW ECC ? */
+ /* 0:off, 1:Hammin ECC 2: BCH ECC */
+ uint8_t use_ecc;
/* calculated from pxa3xx_nand_flash data */
uint8_t col_addr_cycles;
@@ -241,16 +263,25 @@ const static struct pxa3xx_nand_cmdset cmdset = {
* detect the chip id before we know how to optimize further
*/
static struct pxa3xx_nand_flash __devinitdata builtin_flash_types[] = {
-{ 0, 0, 0, 0, 0, 0, { 40, 80, 60, 100, 80, 100, 90000, 400, 40, }, },
-{ 0x46ec, 32, 512, 16, 16, 4096, { 10, 0, 20, 40, 30, 40, 11123, 110, 10, }, },
-{ 0xdaec, 64, 2048, 8, 8, 2048, { 10, 0, 20, 40, 30, 40, 11123, 110, 10, }, },
-{ 0xd3ec, 128, 2048, 8, 8, 4096, { 10, 0, 20, 40, 30, 40, 11123, 110, 10, }, },
-{ 0xd7ec, 128, 4096, 8, 8, 8192, { 10, 0, 20, 40, 30, 40, 11123, 110, 10, }, },
-{ 0xa12c, 64, 2048, 8, 8, 1024, { 10, 25, 15, 25, 15, 30, 25000, 60, 10, }, },
-{ 0xb12c, 64, 2048, 16, 16, 1024, { 10, 25, 15, 25, 15, 30, 25000,
60, 10, }, },
-{ 0xdc2c, 64, 2048, 8, 8, 4096, { 10, 25, 15, 25, 15, 30, 25000, 60, 10, }, },
-{ 0xcc2c, 64, 2048, 16, 16, 4096, { 10, 25, 15, 25, 15, 30, 25000,
60, 10, }, },
-{ 0xba20, 64, 2048, 16, 16, 2048, { 10, 35, 15, 25, 15, 25, 25000,
60, 10, }, },
+{ 0, 0, 0, 0, 0, 0, 0, { 40, 80, 60, 100, 80, 100, 90000, 400, 40, }, },
+{ 0x46ec, 32, 512, 16, 16, ECC_HAMMIN, 4096, \
+ { 10, 0, 20, 40, 30, 40, 11123, 110, 10, }, },
+{ 0xdaec, 64, 2048, 8, 8, ECC_HAMMIN, 2048, \
+ { 10, 0, 20, 40, 30, 40, 11123, 110, 10, }, },
+{ 0xd3ec, 128, 2048, 8, 8, ECC_BCH, 4096, \
+ { 10, 0, 20, 40, 30, 40, 11123, 110, 10, }, },
+{ 0xd7ec, 128, 4096, 8, 8, ECC_BCH, 8192, \
+ { 10, 0, 20, 40, 30, 40, 11123, 110, 10, }, },
+{ 0xa12c, 64, 2048, 8, 8, ECC_HAMMIN, 1024, \
+ { 10, 25, 15, 25, 15, 30, 25000, 60, 10, }, },
+{ 0xb12c, 64, 2048, 16, 16, ECC_HAMMIN, 1024, \
+ { 10, 25, 15, 25, 15, 30, 25000, 60, 10, }, },
+{ 0xdc2c, 64, 2048, 8, 8, ECC_HAMMIN, 4096, \
+ { 10, 25, 15, 25, 15, 30, 25000, 60, 10, }, },
+{ 0xcc2c, 64, 2048, 16, 16, ECC_HAMMIN, 4096, \
+ { 10, 25, 15, 25, 15, 30, 25000, 60, 10, }, },
+{ 0xba20, 64, 2048, 16, 16, ECC_HAMMIN, 2048, \
+ { 10, 35, 15, 25, 15, 25, 25000, 60, 10, }, },