aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/mxc_nand.c
diff options
context:
space:
mode:
authorBaruch Siach <baruch@tkos.co.il>2011-03-14 03:01:56 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2011-05-24 20:47:08 -0400
commitd178e3e88f538323eb483df1563c8edfb71fdb39 (patch)
treec22ccf56a1910eab2688e2d68e70ccaac24cdfea /drivers/mtd/nand/mxc_nand.c
parent61c4f2c81c61f73549928dfd9f3e8f26aa36a8cf (diff)
mtd: mxc_nand: add support for multiple chips on V21 devices
Do the following to add support for up to 4 chips on V21 devices (i.MX25 and i.MX35): * implement .select_chip for V21 * adjust existing NFC_V1_V2_BUF_ADDR writes to take chip select into account * unlock all chip selects at preset_v1_v2() * scan up to 4 devices at .probe This has been tested on i.MX25 with two attached NAND chip (on one die). Signed-off-by: Baruch Siach <baruch@tkos.co.il> Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/nand/mxc_nand.c')
-rw-r--r--drivers/mtd/nand/mxc_nand.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 42a95fb4150..b4efdb704ed 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -56,8 +56,14 @@
56#define NFC_V1_V2_WRPROT (host->regs + 0x12) 56#define NFC_V1_V2_WRPROT (host->regs + 0x12)
57#define NFC_V1_UNLOCKSTART_BLKADDR (host->regs + 0x14) 57#define NFC_V1_UNLOCKSTART_BLKADDR (host->regs + 0x14)
58#define NFC_V1_UNLOCKEND_BLKADDR (host->regs + 0x16) 58#define NFC_V1_UNLOCKEND_BLKADDR (host->regs + 0x16)
59#define NFC_V21_UNLOCKSTART_BLKADDR (host->regs + 0x20) 59#define NFC_V21_UNLOCKSTART_BLKADDR0 (host->regs + 0x20)
60#define NFC_V21_UNLOCKEND_BLKADDR (host->regs + 0x22) 60#define NFC_V21_UNLOCKSTART_BLKADDR1 (host->regs + 0x24)
61#define NFC_V21_UNLOCKSTART_BLKADDR2 (host->regs + 0x28)
62#define NFC_V21_UNLOCKSTART_BLKADDR3 (host->regs + 0x2c)
63#define NFC_V21_UNLOCKEND_BLKADDR0 (host->regs + 0x22)
64#define NFC_V21_UNLOCKEND_BLKADDR1 (host->regs + 0x26)
65#define NFC_V21_UNLOCKEND_BLKADDR2 (host->regs + 0x2a)
66#define NFC_V21_UNLOCKEND_BLKADDR3 (host->regs + 0x2e)
61#define NFC_V1_V2_NF_WRPRST (host->regs + 0x18) 67#define NFC_V1_V2_NF_WRPRST (host->regs + 0x18)
62#define NFC_V1_V2_CONFIG1 (host->regs + 0x1a) 68#define NFC_V1_V2_CONFIG1 (host->regs + 0x1a)
63#define NFC_V1_V2_CONFIG2 (host->regs + 0x1c) 69#define NFC_V1_V2_CONFIG2 (host->regs + 0x1c)
@@ -152,6 +158,7 @@ struct mxc_nand_host {
152 int clk_act; 158 int clk_act;
153 int irq; 159 int irq;
154 int eccsize; 160 int eccsize;
161 int active_cs;
155 162
156 struct completion op_completion; 163 struct completion op_completion;
157 164
@@ -445,7 +452,7 @@ static void send_page_v1_v2(struct mtd_info *mtd, unsigned int ops)
445 for (i = 0; i < bufs; i++) { 452 for (i = 0; i < bufs; i++) {
446 453
447 /* NANDFC buffer 0 is used for page read/write */ 454 /* NANDFC buffer 0 is used for page read/write */
448 writew(i, NFC_V1_V2_BUF_ADDR); 455 writew((host->active_cs << 4) | i, NFC_V1_V2_BUF_ADDR);
449 456
450 writew(ops, NFC_V1_V2_CONFIG2); 457 writew(ops, NFC_V1_V2_CONFIG2);
451 458
@@ -470,7 +477,7 @@ static void send_read_id_v1_v2(struct mxc_nand_host *host)
470 struct nand_chip *this = &host->nand; 477 struct nand_chip *this = &host->nand;
471 478
472 /* NANDFC buffer 0 is used for device ID output */ 479 /* NANDFC buffer 0 is used for device ID output */
473 writew(0x0, NFC_V1_V2_BUF_ADDR); 480 writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR);
474 481
475 writew(NFC_ID, NFC_V1_V2_CONFIG2); 482 writew(NFC_ID, NFC_V1_V2_CONFIG2);
476 483
@@ -505,7 +512,7 @@ static uint16_t get_dev_status_v1_v2(struct mxc_nand_host *host)
505 uint32_t store; 512 uint32_t store;
506 uint16_t ret; 513 uint16_t ret;
507 514
508 writew(0x0, NFC_V1_V2_BUF_ADDR); 515 writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR);
509 516
510 /* 517 /*
511 * The device status is stored in main_area0. To 518 * The device status is stored in main_area0. To
@@ -686,24 +693,24 @@ static void mxc_nand_select_chip(struct mtd_info *mtd, int chip)
686 struct nand_chip *nand_chip = mtd->priv; 693 struct nand_chip *nand_chip = mtd->priv;
687 struct mxc_nand_host *host = nand_chip->priv; 694 struct mxc_nand_host *host = nand_chip->priv;
688 695
689 switch (chip) { 696 if (chip == -1) {
690 case -1:
691 /* Disable the NFC clock */ 697 /* Disable the NFC clock */
692 if (host->clk_act) { 698 if (host->clk_act) {
693 clk_disable(host->clk); 699 clk_disable(host->clk);
694 host->clk_act = 0; 700 host->clk_act = 0;
695 } 701 }
696 break; 702 return;
697 case 0: 703 }
704
705 if (!host->clk_act) {
698 /* Enable the NFC clock */ 706 /* Enable the NFC clock */
699 if (!host->clk_act) { 707 clk_enable(host->clk);
700 clk_enable(host->clk); 708 host->clk_act = 1;
701 host->clk_act = 1; 709 }
702 }
703 break;
704 710
705 default: 711 if (nfc_is_v21()) {
706 break; 712 host->active_cs = chip;
713 writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR);
707 } 714 }
708} 715}
709 716
@@ -834,8 +841,14 @@ static void preset_v1_v2(struct mtd_info *mtd)
834 841
835 /* Blocks to be unlocked */ 842 /* Blocks to be unlocked */
836 if (nfc_is_v21()) { 843 if (nfc_is_v21()) {
837 writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR); 844 writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR0);
838 writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR); 845 writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR1);
846 writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR2);
847 writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR3);
848 writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR0);
849 writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR1);
850 writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR2);
851 writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR3);
839 } else if (nfc_is_v1()) { 852 } else if (nfc_is_v1()) {
840 writew(0x0, NFC_V1_UNLOCKSTART_BLKADDR); 853 writew(0x0, NFC_V1_UNLOCKSTART_BLKADDR);
841 writew(0x4000, NFC_V1_UNLOCKEND_BLKADDR); 854 writew(0x4000, NFC_V1_UNLOCKEND_BLKADDR);
@@ -1200,7 +1213,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
1200 irq_control_v1_v2(host, 1); 1213 irq_control_v1_v2(host, 1);
1201 1214
1202 /* first scan to find the device and get the page size */ 1215 /* first scan to find the device and get the page size */
1203 if (nand_scan_ident(mtd, 1, NULL)) { 1216 if (nand_scan_ident(mtd, nfc_is_v21() ? 4 : 1, NULL)) {
1204 err = -ENXIO; 1217 err = -ENXIO;
1205 goto escan; 1218 goto escan;
1206 } 1219 }