aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/mxc_nand.c
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/mtd/nand/mxc_nand.c
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/mtd/nand/mxc_nand.c')
-rw-r--r--drivers/mtd/nand/mxc_nand.c222
1 files changed, 221 insertions, 1 deletions
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