aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/nand/mxc_nand.c72
1 files changed, 44 insertions, 28 deletions
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index b6aa7e3a967a..5130a8531024 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -115,6 +115,13 @@ struct mxc_nand_host {
115 uint8_t *data_buf; 115 uint8_t *data_buf;
116 unsigned int buf_start; 116 unsigned int buf_start;
117 int spare_len; 117 int spare_len;
118
119 void (*preset)(struct mtd_info *);
120 void (*send_cmd)(struct mxc_nand_host *, uint16_t, int);
121 void (*send_addr)(struct mxc_nand_host *, uint16_t, int);
122 void (*send_page)(struct mtd_info *, unsigned int);
123 void (*send_read_id)(struct mxc_nand_host *);
124 uint16_t (*get_dev_status)(struct mxc_nand_host *);
118}; 125};
119 126
120/* OOB placement block for use with hardware ecc generation */ 127/* OOB placement block for use with hardware ecc generation */
@@ -212,7 +219,7 @@ static void wait_op_done(struct mxc_nand_host *host, int useirq)
212 219
213/* This function issues the specified command to the NAND device and 220/* This function issues the specified command to the NAND device and
214 * waits for completion. */ 221 * waits for completion. */
215static void send_cmd(struct mxc_nand_host *host, uint16_t cmd, int useirq) 222static void send_cmd_v1_v2(struct mxc_nand_host *host, uint16_t cmd, int useirq)
216{ 223{
217 DEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x, %d)\n", cmd, useirq); 224 DEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x, %d)\n", cmd, useirq);
218 225
@@ -241,7 +248,7 @@ static void send_cmd(struct mxc_nand_host *host, uint16_t cmd, int useirq)
241/* This function sends an address (or partial address) to the 248/* This function sends an address (or partial address) to the
242 * NAND device. The address is used to select the source/destination for 249 * NAND device. The address is used to select the source/destination for
243 * a NAND command. */ 250 * a NAND command. */
244static void send_addr(struct mxc_nand_host *host, uint16_t addr, int islast) 251static void send_addr_v1_v2(struct mxc_nand_host *host, uint16_t addr, int islast)
245{ 252{
246 DEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x %d)\n", addr, islast); 253 DEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x %d)\n", addr, islast);
247 254
@@ -252,7 +259,7 @@ static void send_addr(struct mxc_nand_host *host, uint16_t addr, int islast)
252 wait_op_done(host, islast); 259 wait_op_done(host, islast);
253} 260}
254 261
255static void send_page(struct mtd_info *mtd, unsigned int ops) 262static void send_page_v1_v2(struct mtd_info *mtd, unsigned int ops)
256{ 263{
257 struct nand_chip *nand_chip = mtd->priv; 264 struct nand_chip *nand_chip = mtd->priv;
258 struct mxc_nand_host *host = nand_chip->priv; 265 struct mxc_nand_host *host = nand_chip->priv;
@@ -276,7 +283,7 @@ static void send_page(struct mtd_info *mtd, unsigned int ops)
276} 283}
277 284
278/* Request the NANDFC to perform a read of the NAND device ID. */ 285/* Request the NANDFC to perform a read of the NAND device ID. */
279static void send_read_id(struct mxc_nand_host *host) 286static void send_read_id_v1_v2(struct mxc_nand_host *host)
280{ 287{
281 struct nand_chip *this = &host->nand; 288 struct nand_chip *this = &host->nand;
282 289
@@ -302,7 +309,7 @@ static void send_read_id(struct mxc_nand_host *host)
302 309
303/* This function requests the NANDFC to perform a read of the 310/* This function requests the NANDFC to perform a read of the
304 * NAND device status and returns the current status. */ 311 * NAND device status and returns the current status. */
305static uint16_t get_dev_status(struct mxc_nand_host *host) 312static uint16_t get_dev_status_v1_v2(struct mxc_nand_host *host)
306{ 313{
307 void __iomem *main_buf = host->main_area0; 314 void __iomem *main_buf = host->main_area0;
308 uint32_t store; 315 uint32_t store;
@@ -381,7 +388,7 @@ static u_char mxc_nand_read_byte(struct mtd_info *mtd)
381 388
382 /* Check for status request */ 389 /* Check for status request */
383 if (host->status_request) 390 if (host->status_request)
384 return get_dev_status(host) & 0xFF; 391 return host->get_dev_status(host) & 0xFF;
385 392
386 ret = *(uint8_t *)(host->data_buf + host->buf_start); 393 ret = *(uint8_t *)(host->data_buf + host->buf_start);
387 host->buf_start++; 394 host->buf_start++;
@@ -517,39 +524,39 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
517 * we will used the saved column address to index into 524 * we will used the saved column address to index into
518 * the full page. 525 * the full page.
519 */ 526 */
520 send_addr(host, 0, page_addr == -1); 527 host->send_addr(host, 0, page_addr == -1);
521 if (mtd->writesize > 512) 528 if (mtd->writesize > 512)
522 /* another col addr cycle for 2k page */ 529 /* another col addr cycle for 2k page */
523 send_addr(host, 0, false); 530 host->send_addr(host, 0, false);
524 } 531 }
525 532
526 /* Write out page address, if necessary */ 533 /* Write out page address, if necessary */
527 if (page_addr != -1) { 534 if (page_addr != -1) {
528 /* paddr_0 - p_addr_7 */ 535 /* paddr_0 - p_addr_7 */
529 send_addr(host, (page_addr & 0xff), false); 536 host->send_addr(host, (page_addr & 0xff), false);
530 537
531 if (mtd->writesize > 512) { 538 if (mtd->writesize > 512) {
532 if (mtd->size >= 0x10000000) { 539 if (mtd->size >= 0x10000000) {
533 /* paddr_8 - paddr_15 */ 540 /* paddr_8 - paddr_15 */
534 send_addr(host, (page_addr >> 8) & 0xff, false); 541 host->send_addr(host, (page_addr >> 8) & 0xff, false);
535 send_addr(host, (page_addr >> 16) & 0xff, true); 542 host->send_addr(host, (page_addr >> 16) & 0xff, true);
536 } else 543 } else
537 /* paddr_8 - paddr_15 */ 544 /* paddr_8 - paddr_15 */
538 send_addr(host, (page_addr >> 8) & 0xff, true); 545 host->send_addr(host, (page_addr >> 8) & 0xff, true);
539 } else { 546 } else {
540 /* One more address cycle for higher density devices */ 547 /* One more address cycle for higher density devices */
541 if (mtd->size >= 0x4000000) { 548 if (mtd->size >= 0x4000000) {
542 /* paddr_8 - paddr_15 */ 549 /* paddr_8 - paddr_15 */
543 send_addr(host, (page_addr >> 8) & 0xff, false); 550 host->send_addr(host, (page_addr >> 8) & 0xff, false);
544 send_addr(host, (page_addr >> 16) & 0xff, true); 551 host->send_addr(host, (page_addr >> 16) & 0xff, true);
545 } else 552 } else
546 /* paddr_8 - paddr_15 */ 553 /* paddr_8 - paddr_15 */
547 send_addr(host, (page_addr >> 8) & 0xff, true); 554 host->send_addr(host, (page_addr >> 8) & 0xff, true);
548 } 555 }
549 } 556 }
550} 557}
551 558
552static void preset(struct mtd_info *mtd) 559static void preset_v1_v2(struct mtd_info *mtd)
553{ 560{
554 struct nand_chip *nand_chip = mtd->priv; 561 struct nand_chip *nand_chip = mtd->priv;
555 struct mxc_nand_host *host = nand_chip->priv; 562 struct mxc_nand_host *host = nand_chip->priv;
@@ -602,15 +609,15 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
602 /* Command pre-processing step */ 609 /* Command pre-processing step */
603 switch (command) { 610 switch (command) {
604 case NAND_CMD_RESET: 611 case NAND_CMD_RESET:
605 preset(mtd); 612 host->preset(mtd);
606 send_cmd(host, command, false); 613 host->send_cmd(host, command, false);
607 break; 614 break;
608 615
609 case NAND_CMD_STATUS: 616 case NAND_CMD_STATUS:
610 host->buf_start = 0; 617 host->buf_start = 0;
611 host->status_request = true; 618 host->status_request = true;
612 619
613 send_cmd(host, command, true); 620 host->send_cmd(host, command, true);
614 mxc_do_addr_cycle(mtd, column, page_addr); 621 mxc_do_addr_cycle(mtd, column, page_addr);
615 break; 622 break;
616 623
@@ -623,13 +630,13 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
623 630
624 command = NAND_CMD_READ0; /* only READ0 is valid */ 631 command = NAND_CMD_READ0; /* only READ0 is valid */
625 632
626 send_cmd(host, command, false); 633 host->send_cmd(host, command, false);
627 mxc_do_addr_cycle(mtd, column, page_addr); 634 mxc_do_addr_cycle(mtd, column, page_addr);
628 635
629 if (mtd->writesize > 512) 636 if (mtd->writesize > 512)
630 send_cmd(host, NAND_CMD_READSTART, true); 637 host->send_cmd(host, NAND_CMD_READSTART, true);
631 638
632 send_page(mtd, NFC_OUTPUT); 639 host->send_page(mtd, NFC_OUTPUT);
633 640
634 memcpy(host->data_buf, host->main_area0, mtd->writesize); 641 memcpy(host->data_buf, host->main_area0, mtd->writesize);
635 copy_spare(mtd, true); 642 copy_spare(mtd, true);
@@ -642,28 +649,28 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
642 649
643 host->buf_start = column; 650 host->buf_start = column;
644 651
645 send_cmd(host, command, false); 652 host->send_cmd(host, command, false);
646 mxc_do_addr_cycle(mtd, column, page_addr); 653 mxc_do_addr_cycle(mtd, column, page_addr);
647 break; 654 break;
648 655
649 case NAND_CMD_PAGEPROG: 656 case NAND_CMD_PAGEPROG:
650 memcpy(host->main_area0, host->data_buf, mtd->writesize); 657 memcpy(host->main_area0, host->data_buf, mtd->writesize);
651 copy_spare(mtd, false); 658 copy_spare(mtd, false);
652 send_page(mtd, NFC_INPUT); 659 host->send_page(mtd, NFC_INPUT);
653 send_cmd(host, command, true); 660 host->send_cmd(host, command, true);
654 mxc_do_addr_cycle(mtd, column, page_addr); 661 mxc_do_addr_cycle(mtd, column, page_addr);
655 break; 662 break;
656 663
657 case NAND_CMD_READID: 664 case NAND_CMD_READID:
658 send_cmd(host, command, true); 665 host->send_cmd(host, command, true);
659 mxc_do_addr_cycle(mtd, column, page_addr); 666 mxc_do_addr_cycle(mtd, column, page_addr);
660 send_read_id(host); 667 host->send_read_id(host);
661 host->buf_start = column; 668 host->buf_start = column;
662 break; 669 break;
663 670
664 case NAND_CMD_ERASE1: 671 case NAND_CMD_ERASE1:
665 case NAND_CMD_ERASE2: 672 case NAND_CMD_ERASE2:
666 send_cmd(host, command, false); 673 host->send_cmd(host, command, false);
667 mxc_do_addr_cycle(mtd, column, page_addr); 674 mxc_do_addr_cycle(mtd, column, page_addr);
668 675
669 break; 676 break;
@@ -760,6 +767,15 @@ static int __init mxcnd_probe(struct platform_device *pdev)
760 767
761 host->main_area0 = host->base; 768 host->main_area0 = host->base;
762 769
770 if (nfc_is_v1() || nfc_is_v21()) {
771 host->preset = preset_v1_v2;
772 host->send_cmd = send_cmd_v1_v2;
773 host->send_addr = send_addr_v1_v2;
774 host->send_page = send_page_v1_v2;
775 host->send_read_id = send_read_id_v1_v2;
776 host->get_dev_status = get_dev_status_v1_v2;
777 }
778
763 if (nfc_is_v21()) { 779 if (nfc_is_v21()) {
764 host->regs = host->base + 0x1e00; 780 host->regs = host->base + 0x1e00;
765 host->spare0 = host->base + 0x1000; 781 host->spare0 = host->base + 0x1000;