aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2010-08-06 09:53:11 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2010-08-06 11:38:09 -0400
commit71ec51554a2c22ff03c7aac6866cdf395099994d (patch)
tree02b4e6a734114d4327f0bf739e4eabb09106912b /drivers
parent6e85dfdc19ef526edec285aed47c83934882e9bd (diff)
mxc_nand: Add v3 (i.MX51) Support
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/nand/Kconfig2
-rw-r--r--drivers/mtd/nand/mxc_nand.c222
2 files changed, 222 insertions, 2 deletions
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 1d69920a2c93..79afdc1b3377 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -481,7 +481,7 @@ config MTD_NAND_MPC5121_NFC
481 481
482config MTD_NAND_MXC 482config MTD_NAND_MXC
483 tristate "MXC NAND support" 483 tristate "MXC NAND support"
484 depends on ARCH_MX2 || ARCH_MX25 || ARCH_MX3 484 depends on ARCH_MX2 || ARCH_MX25 || ARCH_MX3 || ARCH_MX51
485 help 485 help
486 This enables the driver for the NAND flash controller on the 486 This enables the driver for the NAND flash controller on the
487 MXC processors. 487 MXC processors.
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 1433a8389109..3657a6eb026f 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -39,6 +39,8 @@
39 39
40#define nfc_is_v21() (cpu_is_mx25() || cpu_is_mx35()) 40#define nfc_is_v21() (cpu_is_mx25() || cpu_is_mx35())
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#define nfc_is_v3_2() cpu_is_mx51()
43#define nfc_is_v3() nfc_is_v3_2()
42 44
43/* Addresses for NFC registers */ 45/* Addresses for NFC registers */
44#define NFC_V1_V2_BUF_SIZE (host->regs + 0x00) 46#define NFC_V1_V2_BUF_SIZE (host->regs + 0x00)
@@ -80,6 +82,54 @@
80#define NFC_ID (1 << 4) 82#define NFC_ID (1 << 4)
81#define NFC_STATUS (1 << 5) 83#define NFC_STATUS (1 << 5)
82 84
85#define NFC_V3_FLASH_CMD (host->regs_axi + 0x00)
86#define NFC_V3_FLASH_ADDR0 (host->regs_axi + 0x04)
87
88#define NFC_V3_CONFIG1 (host->regs_axi + 0x34)
89#define NFC_V3_CONFIG1_SP_EN (1 << 0)
90#define NFC_V3_CONFIG1_RBA(x) (((x) & 0x7 ) << 4)
91
92#define NFC_V3_ECC_STATUS_RESULT (host->regs_axi + 0x38)
93
94#define NFC_V3_LAUNCH (host->regs_axi + 0x40)
95
96#define NFC_V3_WRPROT (host->regs_ip + 0x0)
97#define NFC_V3_WRPROT_LOCK_TIGHT (1 << 0)
98#define NFC_V3_WRPROT_LOCK (1 << 1)
99#define NFC_V3_WRPROT_UNLOCK (1 << 2)
100#define NFC_V3_WRPROT_BLS_UNLOCK (2 << 6)
101
102#define NFC_V3_WRPROT_UNLOCK_BLK_ADD0 (host->regs_ip + 0x04)
103
104#define NFC_V3_CONFIG2 (host->regs_ip + 0x24)
105#define NFC_V3_CONFIG2_PS_512 (0 << 0)
106#define NFC_V3_CONFIG2_PS_2048 (1 << 0)
107#define NFC_V3_CONFIG2_PS_4096 (2 << 0)
108#define NFC_V3_CONFIG2_ONE_CYCLE (1 << 2)
109#define NFC_V3_CONFIG2_ECC_EN (1 << 3)
110#define NFC_V3_CONFIG2_2CMD_PHASES (1 << 4)
111#define NFC_V3_CONFIG2_NUM_ADDR_PHASE0 (1 << 5)
112#define NFC_V3_CONFIG2_ECC_MODE_8 (1 << 6)
113#define NFC_V3_CONFIG2_PPB(x) (((x) & 0x3) << 7)
114#define NFC_V3_CONFIG2_NUM_ADDR_PHASE1(x) (((x) & 0x3) << 12)
115#define NFC_V3_CONFIG2_INT_MSK (1 << 15)
116#define NFC_V3_CONFIG2_ST_CMD(x) (((x) & 0xff) << 24)
117#define NFC_V3_CONFIG2_SPAS(x) (((x) & 0xff) << 16)
118
119#define NFC_V3_CONFIG3 (host->regs_ip + 0x28)
120#define NFC_V3_CONFIG3_ADD_OP(x) (((x) & 0x3) << 0)
121#define NFC_V3_CONFIG3_FW8 (1 << 3)
122#define NFC_V3_CONFIG3_SBB(x) (((x) & 0x7) << 8)
123#define NFC_V3_CONFIG3_NUM_OF_DEVICES(x) (((x) & 0x7) << 12)
124#define NFC_V3_CONFIG3_RBB_MODE (1 << 15)
125#define NFC_V3_CONFIG3_NO_SDMA (1 << 20)
126
127#define NFC_V3_IPC (host->regs_ip + 0x2C)
128#define NFC_V3_IPC_CREQ (1 << 0)
129#define NFC_V3_IPC_INT (1 << 31)
130
131#define NFC_V3_DELAY_LINE (host->regs_ip + 0x34)
132
83struct mxc_nand_host { 133struct mxc_nand_host {
84 struct mtd_info mtd; 134 struct mtd_info mtd;
85 struct nand_chip nand; 135 struct nand_chip nand;
@@ -91,6 +141,8 @@ struct mxc_nand_host {
91 141
92 void __iomem *base; 142 void __iomem *base;
93 void __iomem *regs; 143 void __iomem *regs;
144 void __iomem *regs_axi;
145 void __iomem *regs_ip;
94 int status_request; 146 int status_request;
95 struct clk *clk; 147 struct clk *clk;
96 int clk_act; 148 int clk_act;
@@ -169,6 +221,20 @@ static irqreturn_t mxc_nfc_irq(int irq, void *dev_id)
169 return IRQ_HANDLED; 221 return IRQ_HANDLED;
170} 222}
171 223
224static int check_int_v3(struct mxc_nand_host *host)
225{
226 uint32_t tmp;
227
228 tmp = readl(NFC_V3_IPC);
229 if (!(tmp & NFC_V3_IPC_INT))
230 return 0;
231
232 tmp &= ~NFC_V3_IPC_INT;
233 writel(tmp, NFC_V3_IPC);
234
235 return 1;
236}
237
172static int check_int_v1_v2(struct mxc_nand_host *host) 238static int check_int_v1_v2(struct mxc_nand_host *host)
173{ 239{
174 uint32_t tmp; 240 uint32_t tmp;
@@ -209,6 +275,18 @@ static void wait_op_done(struct mxc_nand_host *host, int useirq)
209 } 275 }
210} 276}
211 277
278static void send_cmd_v3(struct mxc_nand_host *host, uint16_t cmd, int useirq)
279{
280 /* fill command */
281 writel(cmd, NFC_V3_FLASH_CMD);
282
283 /* send out command */
284 writel(NFC_CMD, NFC_V3_LAUNCH);
285
286 /* Wait for operation to complete */
287 wait_op_done(host, useirq);
288}
289
212/* This function issues the specified command to the NAND device and 290/* This function issues the specified command to the NAND device and
213 * waits for completion. */ 291 * waits for completion. */
214static void send_cmd_v1_v2(struct mxc_nand_host *host, uint16_t cmd, int useirq) 292static void send_cmd_v1_v2(struct mxc_nand_host *host, uint16_t cmd, int useirq)
@@ -237,6 +315,17 @@ static void send_cmd_v1_v2(struct mxc_nand_host *host, uint16_t cmd, int useirq)
237 } 315 }
238} 316}
239 317
318static void send_addr_v3(struct mxc_nand_host *host, uint16_t addr, int islast)
319{
320 /* fill address */
321 writel(addr, NFC_V3_FLASH_ADDR0);
322
323 /* send out address */
324 writel(NFC_ADDR, NFC_V3_LAUNCH);
325
326 wait_op_done(host, 0);
327}
328
240/* This function sends an address (or partial address) to the 329/* This function sends an address (or partial address) to the
241 * NAND device. The address is used to select the source/destination for 330 * NAND device. The address is used to select the source/destination for
242 * a NAND command. */ 331 * a NAND command. */
@@ -251,6 +340,22 @@ static void send_addr_v1_v2(struct mxc_nand_host *host, uint16_t addr, int islas
251 wait_op_done(host, islast); 340 wait_op_done(host, islast);
252} 341}
253 342
343static void send_page_v3(struct mtd_info *mtd, unsigned int ops)
344{
345 struct nand_chip *nand_chip = mtd->priv;
346 struct mxc_nand_host *host = nand_chip->priv;
347 uint32_t tmp;
348
349 tmp = readl(NFC_V3_CONFIG1);
350 tmp &= ~(7 << 4);
351 writel(tmp, NFC_V3_CONFIG1);
352
353 /* transfer data from NFC ram to nand */
354 writel(ops, NFC_V3_LAUNCH);
355
356 wait_op_done(host, false);
357}
358
254static void send_page_v1_v2(struct mtd_info *mtd, unsigned int ops) 359static void send_page_v1_v2(struct mtd_info *mtd, unsigned int ops)
255{ 360{
256 struct nand_chip *nand_chip = mtd->priv; 361 struct nand_chip *nand_chip = mtd->priv;
@@ -274,6 +379,16 @@ static void send_page_v1_v2(struct mtd_info *mtd, unsigned int ops)
274 } 379 }
275} 380}
276 381
382static void send_read_id_v3(struct mxc_nand_host *host)
383{
384 /* Read ID into main buffer */
385 writel(NFC_ID, NFC_V3_LAUNCH);
386
387 wait_op_done(host, true);
388
389 memcpy(host->data_buf, host->main_area0, 16);
390}
391
277/* Request the NANDFC to perform a read of the NAND device ID. */ 392/* Request the NANDFC to perform a read of the NAND device ID. */
278static void send_read_id_v1_v2(struct mxc_nand_host *host) 393static void send_read_id_v1_v2(struct mxc_nand_host *host)
279{ 394{
@@ -299,6 +414,14 @@ static void send_read_id_v1_v2(struct mxc_nand_host *host)
299 memcpy(host->data_buf, host->main_area0, 16); 414 memcpy(host->data_buf, host->main_area0, 16);
300} 415}
301 416
417static uint16_t get_dev_status_v3(struct mxc_nand_host *host)
418{
419 writew(NFC_STATUS, NFC_V3_LAUNCH);
420 wait_op_done(host, true);
421
422 return readl(NFC_V3_CONFIG1) >> 16;
423}
424
302/* This function requests the NANDFC to perform a read of the 425/* This function requests the NANDFC to perform a read of the
303 * NAND device status and returns the current status. */ 426 * NAND device status and returns the current status. */
304static uint16_t get_dev_status_v1_v2(struct mxc_nand_host *host) 427static uint16_t get_dev_status_v1_v2(struct mxc_nand_host *host)
@@ -381,7 +504,10 @@ static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
381 504
382 no_subpages = mtd->writesize >> 9; 505 no_subpages = mtd->writesize >> 9;
383 506
384 ecc_stat = readl(NFC_V1_V2_ECC_STATUS_RESULT); 507 if (nfc_is_v21())
508 ecc_stat = readl(NFC_V1_V2_ECC_STATUS_RESULT);
509 else
510 ecc_stat = readl(NFC_V3_ECC_STATUS_RESULT);
385 511
386 do { 512 do {
387 err = ecc_stat & ecc_bit_mask; 513 err = ecc_stat & ecc_bit_mask;
@@ -643,6 +769,72 @@ static void preset_v1_v2(struct mtd_info *mtd)
643 writew(0x4, NFC_V1_V2_WRPROT); 769 writew(0x4, NFC_V1_V2_WRPROT);
644} 770}
645 771
772static void preset_v3(struct mtd_info *mtd)
773{
774 struct nand_chip *chip = mtd->priv;
775 struct mxc_nand_host *host = chip->priv;
776 uint32_t config2, config3;
777 int i, addr_phases;
778
779 writel(NFC_V3_CONFIG1_RBA(0), NFC_V3_CONFIG1);
780 writel(NFC_V3_IPC_CREQ, NFC_V3_IPC);
781
782 /* Unlock the internal RAM Buffer */
783 writel(NFC_V3_WRPROT_BLS_UNLOCK | NFC_V3_WRPROT_UNLOCK,
784 NFC_V3_WRPROT);
785
786 /* Blocks to be unlocked */
787 for (i = 0; i < NAND_MAX_CHIPS; i++)
788 writel(0x0 | (0xffff << 16),
789 NFC_V3_WRPROT_UNLOCK_BLK_ADD0 + (i << 2));
790
791 writel(0, NFC_V3_IPC);
792
793 config2 = NFC_V3_CONFIG2_ONE_CYCLE |
794 NFC_V3_CONFIG2_2CMD_PHASES |
795 NFC_V3_CONFIG2_SPAS(mtd->oobsize >> 1) |
796 NFC_V3_CONFIG2_ST_CMD(0x70) |
797 NFC_V3_CONFIG2_NUM_ADDR_PHASE0;
798
799 if (chip->ecc.mode == NAND_ECC_HW)
800 config2 |= NFC_V3_CONFIG2_ECC_EN;
801
802 addr_phases = fls(chip->pagemask) >> 3;
803
804 if (mtd->writesize == 2048) {
805 config2 |= NFC_V3_CONFIG2_PS_2048;
806 config2 |= NFC_V3_CONFIG2_NUM_ADDR_PHASE1(addr_phases);
807 } else if (mtd->writesize == 4096) {
808 config2 |= NFC_V3_CONFIG2_PS_4096;
809 config2 |= NFC_V3_CONFIG2_NUM_ADDR_PHASE1(addr_phases);
810 } else {
811 config2 |= NFC_V3_CONFIG2_PS_512;
812 config2 |= NFC_V3_CONFIG2_NUM_ADDR_PHASE1(addr_phases - 1);
813 }
814
815 if (mtd->writesize) {
816 config2 |= NFC_V3_CONFIG2_PPB(ffs(mtd->erasesize / mtd->writesize) - 6);
817 host->eccsize = get_eccsize(mtd);
818 if (host->eccsize == 8)
819 config2 |= NFC_V3_CONFIG2_ECC_MODE_8;
820 }
821
822 writel(config2, NFC_V3_CONFIG2);
823
824 config3 = NFC_V3_CONFIG3_NUM_OF_DEVICES(0) |
825 NFC_V3_CONFIG3_NO_SDMA |
826 NFC_V3_CONFIG3_RBB_MODE |
827 NFC_V3_CONFIG3_SBB(6) | /* Reset default */
828 NFC_V3_CONFIG3_ADD_OP(0);
829
830 if (!(chip->options & NAND_BUSWIDTH_16))
831 config3 |= NFC_V3_CONFIG3_FW8;
832
833 writel(config3, NFC_V3_CONFIG3);
834
835 writel(0, NFC_V3_DELAY_LINE);
836}
837
646/* Used by the upper layer to write command to NAND Flash for 838/* Used by the upper layer to write command to NAND Flash for
647 * different operations to be carried out on NAND Flash */ 839 * different operations to be carried out on NAND Flash */
648static void mxc_nand_command(struct mtd_info *mtd, unsigned command, 840static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
@@ -843,6 +1035,30 @@ static int __init mxcnd_probe(struct platform_device *pdev)
843 oob_smallpage = &nandv1_hw_eccoob_smallpage; 1035 oob_smallpage = &nandv1_hw_eccoob_smallpage;
844 oob_largepage = &nandv1_hw_eccoob_largepage; 1036 oob_largepage = &nandv1_hw_eccoob_largepage;
845 this->ecc.bytes = 3; 1037 this->ecc.bytes = 3;
1038 host->eccsize = 1;
1039 } else if (nfc_is_v3_2()) {
1040 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1041 if (!res) {
1042 err = -ENODEV;
1043 goto eirq;
1044 }
1045 host->regs_ip = ioremap(res->start, resource_size(res));
1046 if (!host->regs_ip) {
1047 err = -ENOMEM;
1048 goto eirq;
1049 }
1050 host->regs_axi = host->base + 0x1e00;
1051 host->spare0 = host->base + 0x1000;
1052 host->spare_len = 64;
1053 host->preset = preset_v3;
1054 host->send_cmd = send_cmd_v3;
1055 host->send_addr = send_addr_v3;
1056 host->send_page = send_page_v3;
1057 host->send_read_id = send_read_id_v3;
1058 host->check_int = check_int_v3;
1059 host->get_dev_status = get_dev_status_v3;
1060 oob_smallpage = &nandv2_hw_eccoob_smallpage;
1061 oob_largepage = &nandv2_hw_eccoob_largepage;
846 } else 1062 } else
847 BUG(); 1063 BUG();
848 1064
@@ -918,6 +1134,8 @@ static int __init mxcnd_probe(struct platform_device *pdev)
918escan: 1134escan:
919 free_irq(host->irq, host); 1135 free_irq(host->irq, host);
920eirq: 1136eirq:
1137 if (host->regs_ip)
1138 iounmap(host->regs_ip);
921 iounmap(host->base); 1139 iounmap(host->base);
922eres: 1140eres:
923 clk_put(host->clk); 1141 clk_put(host->clk);
@@ -937,6 +1155,8 @@ static int __devexit mxcnd_remove(struct platform_device *pdev)
937 1155
938 nand_release(&host->mtd); 1156 nand_release(&host->mtd);
939 free_irq(host->irq, host); 1157 free_irq(host->irq, host);
1158 if (host->regs_ip)
1159 iounmap(host->regs_ip);
940 iounmap(host->base); 1160 iounmap(host->base);
941 kfree(host); 1161 kfree(host);
942 1162