diff options
Diffstat (limited to 'drivers/mtd/nand/mxc_nand.c')
-rw-r--r-- | drivers/mtd/nand/mxc_nand.c | 141 |
1 files changed, 63 insertions, 78 deletions
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index ea491140e552..6d0fa4cd1ddf 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c | |||
@@ -41,58 +41,43 @@ | |||
41 | #define nfc_is_v1() (cpu_is_mx31() || cpu_is_mx27() || cpu_is_mx21()) | 41 | #define nfc_is_v1() (cpu_is_mx31() || cpu_is_mx27() || cpu_is_mx21()) |
42 | 42 | ||
43 | /* Addresses for NFC registers */ | 43 | /* Addresses for NFC registers */ |
44 | #define NFC_BUF_SIZE 0x00 | 44 | #define NFC_V1_V2_BUF_SIZE (host->regs + 0x00) |
45 | #define NFC_BUF_ADDR 0x04 | 45 | #define NFC_V1_V2_BUF_ADDR (host->regs + 0x04) |
46 | #define NFC_FLASH_ADDR 0x06 | 46 | #define NFC_V1_V2_FLASH_ADDR (host->regs + 0x06) |
47 | #define NFC_FLASH_CMD 0x08 | 47 | #define NFC_V1_V2_FLASH_CMD (host->regs + 0x08) |
48 | #define NFC_CONFIG 0x0a | 48 | #define NFC_V1_V2_CONFIG (host->regs + 0x0a) |
49 | #define NFC_ECC_STATUS_RESULT 0x0c | 49 | #define NFC_V1_V2_ECC_STATUS_RESULT (host->regs + 0x0c) |
50 | #define NFC_RSLTMAIN_AREA 0x0e | 50 | #define NFC_V1_V2_RSLTMAIN_AREA (host->regs + 0x0e) |
51 | #define NFC_RSLTSPARE_AREA 0x10 | 51 | #define NFC_V1_V2_RSLTSPARE_AREA (host->regs + 0x10) |
52 | #define NFC_WRPROT 0x12 | 52 | #define NFC_V1_V2_WRPROT (host->regs + 0x12) |
53 | #define NFC_V1_UNLOCKSTART_BLKADDR 0x14 | 53 | #define NFC_V1_UNLOCKSTART_BLKADDR (host->regs + 0x14) |
54 | #define NFC_V1_UNLOCKEND_BLKADDR 0x16 | 54 | #define NFC_V1_UNLOCKEND_BLKADDR (host->regs + 0x16) |
55 | #define NFC_V21_UNLOCKSTART_BLKADDR 0x20 | 55 | #define NFC_V21_UNLOCKSTART_BLKADDR (host->regs + 0x20) |
56 | #define NFC_V21_UNLOCKEND_BLKADDR 0x22 | 56 | #define NFC_V21_UNLOCKEND_BLKADDR (host->regs + 0x22) |
57 | #define NFC_NF_WRPRST 0x18 | 57 | #define NFC_V1_V2_NF_WRPRST (host->regs + 0x18) |
58 | #define NFC_CONFIG1 0x1a | 58 | #define NFC_V1_V2_CONFIG1 (host->regs + 0x1a) |
59 | #define NFC_CONFIG2 0x1c | 59 | #define NFC_V1_V2_CONFIG2 (host->regs + 0x1c) |
60 | 60 | ||
61 | /* Set INT to 0, FCMD to 1, rest to 0 in NFC_CONFIG2 Register | 61 | #define NFC_V1_V2_CONFIG1_SP_EN (1 << 2) |
62 | * for Command operation */ | 62 | #define NFC_V1_V2_CONFIG1_ECC_EN (1 << 3) |
63 | #define NFC_CMD 0x1 | 63 | #define NFC_V1_V2_CONFIG1_INT_MSK (1 << 4) |
64 | 64 | #define NFC_V1_V2_CONFIG1_BIG (1 << 5) | |
65 | /* Set INT to 0, FADD to 1, rest to 0 in NFC_CONFIG2 Register | 65 | #define NFC_V1_V2_CONFIG1_RST (1 << 6) |
66 | * for Address operation */ | 66 | #define NFC_V1_V2_CONFIG1_CE (1 << 7) |
67 | #define NFC_ADDR 0x2 | 67 | #define NFC_V1_V2_CONFIG1_ONE_CYCLE (1 << 8) |
68 | 68 | ||
69 | /* Set INT to 0, FDI to 1, rest to 0 in NFC_CONFIG2 Register | 69 | #define NFC_V1_V2_CONFIG2_INT (1 << 15) |
70 | * for Input operation */ | 70 | |
71 | #define NFC_INPUT 0x4 | 71 | /* |
72 | 72 | * Operation modes for the NFC. Valid for v1, v2 and v3 | |
73 | /* Set INT to 0, FDO to 001, rest to 0 in NFC_CONFIG2 Register | 73 | * type controllers. |
74 | * for Data Output operation */ | 74 | */ |
75 | #define NFC_OUTPUT 0x8 | 75 | #define NFC_CMD (1 << 0) |
76 | 76 | #define NFC_ADDR (1 << 1) | |
77 | /* Set INT to 0, FD0 to 010, rest to 0 in NFC_CONFIG2 Register | 77 | #define NFC_INPUT (1 << 2) |
78 | * for Read ID operation */ | 78 | #define NFC_OUTPUT (1 << 3) |
79 | #define NFC_ID 0x10 | 79 | #define NFC_ID (1 << 4) |
80 | 80 | #define NFC_STATUS (1 << 5) | |
81 | /* Set INT to 0, FDO to 100, rest to 0 in NFC_CONFIG2 Register | ||
82 | * for Read Status operation */ | ||
83 | #define NFC_STATUS 0x20 | ||
84 | |||
85 | /* Set INT to 1, rest to 0 in NFC_CONFIG2 Register for Read | ||
86 | * Status operation */ | ||
87 | #define NFC_INT 0x8000 | ||
88 | |||
89 | #define NFC_SP_EN (1 << 2) | ||
90 | #define NFC_ECC_EN (1 << 3) | ||
91 | #define NFC_INT_MSK (1 << 4) | ||
92 | #define NFC_BIG (1 << 5) | ||
93 | #define NFC_RST (1 << 6) | ||
94 | #define NFC_CE (1 << 7) | ||
95 | #define NFC_ONE_CYCLE (1 << 8) | ||
96 | 81 | ||
97 | struct mxc_nand_host { | 82 | struct mxc_nand_host { |
98 | struct mtd_info mtd; | 83 | struct mtd_info mtd; |
@@ -186,11 +171,11 @@ static int check_int_v1_v2(struct mxc_nand_host *host) | |||
186 | { | 171 | { |
187 | uint32_t tmp; | 172 | uint32_t tmp; |
188 | 173 | ||
189 | tmp = readw(host->regs + NFC_CONFIG2); | 174 | tmp = readw(NFC_V1_V2_CONFIG2); |
190 | if (!(tmp & NFC_INT)) | 175 | if (!(tmp & NFC_V1_V2_CONFIG2_INT)) |
191 | return 0; | 176 | return 0; |
192 | 177 | ||
193 | writew(tmp & ~NFC_INT, NFC_CONFIG2); | 178 | writew(tmp & ~NFC_V1_V2_CONFIG2_INT, NFC_V1_V2_CONFIG2); |
194 | 179 | ||
195 | return 1; | 180 | return 1; |
196 | } | 181 | } |
@@ -228,15 +213,15 @@ static void send_cmd_v1_v2(struct mxc_nand_host *host, uint16_t cmd, int useirq) | |||
228 | { | 213 | { |
229 | DEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x, %d)\n", cmd, useirq); | 214 | DEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x, %d)\n", cmd, useirq); |
230 | 215 | ||
231 | writew(cmd, host->regs + NFC_FLASH_CMD); | 216 | writew(cmd, NFC_V1_V2_FLASH_CMD); |
232 | writew(NFC_CMD, host->regs + NFC_CONFIG2); | 217 | writew(NFC_CMD, NFC_V1_V2_CONFIG2); |
233 | 218 | ||
234 | if (cpu_is_mx21() && (cmd == NAND_CMD_RESET)) { | 219 | if (cpu_is_mx21() && (cmd == NAND_CMD_RESET)) { |
235 | int max_retries = 100; | 220 | int max_retries = 100; |
236 | /* Reset completion is indicated by NFC_CONFIG2 */ | 221 | /* Reset completion is indicated by NFC_CONFIG2 */ |
237 | /* being set to 0 */ | 222 | /* being set to 0 */ |
238 | while (max_retries-- > 0) { | 223 | while (max_retries-- > 0) { |
239 | if (readw(host->regs + NFC_CONFIG2) == 0) { | 224 | if (readw(NFC_V1_V2_CONFIG2) == 0) { |
240 | break; | 225 | break; |
241 | } | 226 | } |
242 | udelay(1); | 227 | udelay(1); |
@@ -257,8 +242,8 @@ static void send_addr_v1_v2(struct mxc_nand_host *host, uint16_t addr, int islas | |||
257 | { | 242 | { |
258 | DEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x %d)\n", addr, islast); | 243 | DEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x %d)\n", addr, islast); |
259 | 244 | ||
260 | writew(addr, host->regs + NFC_FLASH_ADDR); | 245 | writew(addr, NFC_V1_V2_FLASH_ADDR); |
261 | writew(NFC_ADDR, host->regs + NFC_CONFIG2); | 246 | writew(NFC_ADDR, NFC_V1_V2_CONFIG2); |
262 | 247 | ||
263 | /* Wait for operation to complete */ | 248 | /* Wait for operation to complete */ |
264 | wait_op_done(host, islast); | 249 | wait_op_done(host, islast); |
@@ -278,9 +263,9 @@ static void send_page_v1_v2(struct mtd_info *mtd, unsigned int ops) | |||
278 | for (i = 0; i < bufs; i++) { | 263 | for (i = 0; i < bufs; i++) { |
279 | 264 | ||
280 | /* NANDFC buffer 0 is used for page read/write */ | 265 | /* NANDFC buffer 0 is used for page read/write */ |
281 | writew(i, host->regs + NFC_BUF_ADDR); | 266 | writew(i, NFC_V1_V2_BUF_ADDR); |
282 | 267 | ||
283 | writew(ops, host->regs + NFC_CONFIG2); | 268 | writew(ops, NFC_V1_V2_CONFIG2); |
284 | 269 | ||
285 | /* Wait for operation to complete */ | 270 | /* Wait for operation to complete */ |
286 | wait_op_done(host, true); | 271 | wait_op_done(host, true); |
@@ -293,9 +278,9 @@ static void send_read_id_v1_v2(struct mxc_nand_host *host) | |||
293 | struct nand_chip *this = &host->nand; | 278 | struct nand_chip *this = &host->nand; |
294 | 279 | ||
295 | /* NANDFC buffer 0 is used for device ID output */ | 280 | /* NANDFC buffer 0 is used for device ID output */ |
296 | writew(0x0, host->regs + NFC_BUF_ADDR); | 281 | writew(0x0, NFC_V1_V2_BUF_ADDR); |
297 | 282 | ||
298 | writew(NFC_ID, host->regs + NFC_CONFIG2); | 283 | writew(NFC_ID, NFC_V1_V2_CONFIG2); |
299 | 284 | ||
300 | /* Wait for operation to complete */ | 285 | /* Wait for operation to complete */ |
301 | wait_op_done(host, true); | 286 | wait_op_done(host, true); |
@@ -329,7 +314,7 @@ static uint16_t get_dev_status_v1_v2(struct mxc_nand_host *host) | |||
329 | */ | 314 | */ |
330 | store = readl(main_buf); | 315 | store = readl(main_buf); |
331 | 316 | ||
332 | writew(NFC_STATUS, host->regs + NFC_CONFIG2); | 317 | writew(NFC_STATUS, NFC_V1_V2_CONFIG2); |
333 | wait_op_done(host, true); | 318 | wait_op_done(host, true); |
334 | 319 | ||
335 | ret = readw(main_buf); | 320 | ret = readw(main_buf); |
@@ -368,7 +353,7 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat, | |||
368 | * additional correction. 2-Bit errors cannot be corrected by | 353 | * additional correction. 2-Bit errors cannot be corrected by |
369 | * HW ECC, so we need to return failure | 354 | * HW ECC, so we need to return failure |
370 | */ | 355 | */ |
371 | uint16_t ecc_status = readw(host->regs + NFC_ECC_STATUS_RESULT); | 356 | uint16_t ecc_status = readw(NFC_V1_V2_ECC_STATUS_RESULT); |
372 | 357 | ||
373 | if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) { | 358 | if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) { |
374 | DEBUG(MTD_DEBUG_LEVEL0, | 359 | DEBUG(MTD_DEBUG_LEVEL0, |
@@ -568,32 +553,32 @@ static void preset_v1_v2(struct mtd_info *mtd) | |||
568 | uint16_t tmp; | 553 | uint16_t tmp; |
569 | 554 | ||
570 | /* enable interrupt, disable spare enable */ | 555 | /* enable interrupt, disable spare enable */ |
571 | tmp = readw(host->regs + NFC_CONFIG1); | 556 | tmp = readw(NFC_V1_V2_CONFIG1); |
572 | tmp &= ~NFC_INT_MSK; | 557 | tmp &= ~NFC_V1_V2_CONFIG1_INT_MSK; |
573 | tmp &= ~NFC_SP_EN; | 558 | tmp &= ~NFC_V1_V2_CONFIG1_SP_EN; |
574 | if (nand_chip->ecc.mode == NAND_ECC_HW) { | 559 | if (nand_chip->ecc.mode == NAND_ECC_HW) { |
575 | tmp |= NFC_ECC_EN; | 560 | tmp |= NFC_V1_V2_CONFIG1_ECC_EN; |
576 | } else { | 561 | } else { |
577 | tmp &= ~NFC_ECC_EN; | 562 | tmp &= ~NFC_V1_V2_CONFIG1_ECC_EN; |
578 | } | 563 | } |
579 | writew(tmp, host->regs + NFC_CONFIG1); | 564 | writew(tmp, NFC_V1_V2_CONFIG1); |
580 | /* preset operation */ | 565 | /* preset operation */ |
581 | 566 | ||
582 | /* Unlock the internal RAM Buffer */ | 567 | /* Unlock the internal RAM Buffer */ |
583 | writew(0x2, host->regs + NFC_CONFIG); | 568 | writew(0x2, NFC_V1_V2_CONFIG); |
584 | 569 | ||
585 | /* Blocks to be unlocked */ | 570 | /* Blocks to be unlocked */ |
586 | if (nfc_is_v21()) { | 571 | if (nfc_is_v21()) { |
587 | writew(0x0, host->regs + NFC_V21_UNLOCKSTART_BLKADDR); | 572 | writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR); |
588 | writew(0xffff, host->regs + NFC_V21_UNLOCKEND_BLKADDR); | 573 | writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR); |
589 | } else if (nfc_is_v1()) { | 574 | } else if (nfc_is_v1()) { |
590 | writew(0x0, host->regs + NFC_V1_UNLOCKSTART_BLKADDR); | 575 | writew(0x0, NFC_V1_UNLOCKSTART_BLKADDR); |
591 | writew(0x4000, host->regs + NFC_V1_UNLOCKEND_BLKADDR); | 576 | writew(0x4000, NFC_V1_UNLOCKEND_BLKADDR); |
592 | } else | 577 | } else |
593 | BUG(); | 578 | BUG(); |
594 | 579 | ||
595 | /* Unlock Block Command for given address range */ | 580 | /* Unlock Block Command for given address range */ |
596 | writew(0x4, host->regs + NFC_WRPROT); | 581 | writew(0x4, NFC_V1_V2_WRPROT); |
597 | } | 582 | } |
598 | 583 | ||
599 | /* Used by the upper layer to write command to NAND Flash for | 584 | /* Used by the upper layer to write command to NAND Flash for |