blob: 5c11ac94aada2e1c3c78224f76cb1ce1e1d86fdc [file] [log] [blame]
Stefan Agner72d7bea2014-09-12 13:06:35 +02001/*
2 * Copyright 2009-2014 Freescale Semiconductor, Inc. and others
3 *
4 * Description: MPC5125, VF610, MCF54418 and Kinetis K70 Nand driver.
5 * Ported to U-Boot by Stefan Agner
6 * Based on RFC driver posted on Kernel Mailing list by Bill Pringlemeir
7 * Jason ported to M54418TWR and MVFA5.
8 * Authors: Stefan Agner <stefan.agner@toradex.com>
9 * Bill Pringlemeir <bpringlemeir@nbsps.com>
10 * Shaohui Xie <b21989@freescale.com>
11 * Jason Jin <Jason.jin@freescale.com>
12 *
13 * Based on original driver mpc5121_nfc.c.
14 *
15 * This is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * Limitations:
21 * - Untested on MPC5125 and M54418.
22 * - DMA not used.
23 * - 2K pages or less.
24 * - Only 2K page w. 64+OOB and hardware ECC.
25 */
26
27#include <common.h>
28#include <malloc.h>
29
30#include <linux/mtd/mtd.h>
31#include <linux/mtd/nand.h>
32#include <linux/mtd/partitions.h>
33
34#include <nand.h>
35#include <errno.h>
36#include <asm/io.h>
37
38/* Register Offsets */
39#define NFC_FLASH_CMD1 0x3F00
40#define NFC_FLASH_CMD2 0x3F04
41#define NFC_COL_ADDR 0x3F08
42#define NFC_ROW_ADDR 0x3F0c
43#define NFC_ROW_ADDR_INC 0x3F14
44#define NFC_FLASH_STATUS1 0x3F18
45#define NFC_FLASH_STATUS2 0x3F1c
46#define NFC_CACHE_SWAP 0x3F28
47#define NFC_SECTOR_SIZE 0x3F2c
48#define NFC_FLASH_CONFIG 0x3F30
49#define NFC_IRQ_STATUS 0x3F38
50
51/* Addresses for NFC MAIN RAM BUFFER areas */
52#define NFC_MAIN_AREA(n) ((n) * 0x1000)
53
54#define PAGE_2K 0x0800
55#define OOB_64 0x0040
56
57/*
58 * NFC_CMD2[CODE] values. See section:
59 * - 31.4.7 Flash Command Code Description, Vybrid manual
60 * - 23.8.6 Flash Command Sequencer, MPC5125 manual
61 *
62 * Briefly these are bitmasks of controller cycles.
63 */
64#define READ_PAGE_CMD_CODE 0x7EE0
Stefan Agner8fca2d82015-05-08 19:07:13 +020065#define READ_ONFI_PARAM_CMD_CODE 0x4860
Stefan Agner72d7bea2014-09-12 13:06:35 +020066#define PROGRAM_PAGE_CMD_CODE 0x7FC0
67#define ERASE_CMD_CODE 0x4EC0
68#define READ_ID_CMD_CODE 0x4804
69#define RESET_CMD_CODE 0x4040
70#define STATUS_READ_CMD_CODE 0x4068
71
72/* NFC ECC mode define */
73#define ECC_BYPASS 0
74#define ECC_45_BYTE 6
Stefan Agner080a71e2015-05-08 19:07:12 +020075#define ECC_60_BYTE 7
Stefan Agner72d7bea2014-09-12 13:06:35 +020076
77/*** Register Mask and bit definitions */
78
79/* NFC_FLASH_CMD1 Field */
80#define CMD_BYTE2_MASK 0xFF000000
81#define CMD_BYTE2_SHIFT 24
82
83/* NFC_FLASH_CM2 Field */
84#define CMD_BYTE1_MASK 0xFF000000
85#define CMD_BYTE1_SHIFT 24
86#define CMD_CODE_MASK 0x00FFFF00
87#define CMD_CODE_SHIFT 8
88#define BUFNO_MASK 0x00000006
89#define BUFNO_SHIFT 1
90#define START_BIT (1<<0)
91
92/* NFC_COL_ADDR Field */
93#define COL_ADDR_MASK 0x0000FFFF
94#define COL_ADDR_SHIFT 0
95
96/* NFC_ROW_ADDR Field */
97#define ROW_ADDR_MASK 0x00FFFFFF
98#define ROW_ADDR_SHIFT 0
99#define ROW_ADDR_CHIP_SEL_RB_MASK 0xF0000000
100#define ROW_ADDR_CHIP_SEL_RB_SHIFT 28
101#define ROW_ADDR_CHIP_SEL_MASK 0x0F000000
102#define ROW_ADDR_CHIP_SEL_SHIFT 24
103
104/* NFC_FLASH_STATUS2 Field */
105#define STATUS_BYTE1_MASK 0x000000FF
106
107/* NFC_FLASH_CONFIG Field */
108#define CONFIG_ECC_SRAM_ADDR_MASK 0x7FC00000
109#define CONFIG_ECC_SRAM_ADDR_SHIFT 22
110#define CONFIG_ECC_SRAM_REQ_BIT (1<<21)
111#define CONFIG_DMA_REQ_BIT (1<<20)
112#define CONFIG_ECC_MODE_MASK 0x000E0000
113#define CONFIG_ECC_MODE_SHIFT 17
114#define CONFIG_FAST_FLASH_BIT (1<<16)
115#define CONFIG_16BIT (1<<7)
116#define CONFIG_BOOT_MODE_BIT (1<<6)
117#define CONFIG_ADDR_AUTO_INCR_BIT (1<<5)
118#define CONFIG_BUFNO_AUTO_INCR_BIT (1<<4)
119#define CONFIG_PAGE_CNT_MASK 0xF
120#define CONFIG_PAGE_CNT_SHIFT 0
121
122/* NFC_IRQ_STATUS Field */
123#define IDLE_IRQ_BIT (1<<29)
124#define IDLE_EN_BIT (1<<20)
125#define CMD_DONE_CLEAR_BIT (1<<18)
126#define IDLE_CLEAR_BIT (1<<17)
127
128#define NFC_TIMEOUT (1000)
129
130/* ECC status placed at end of buffers. */
131#define ECC_SRAM_ADDR ((PAGE_2K+256-8) >> 3)
132#define ECC_STATUS_MASK 0x80
133#define ECC_ERR_COUNT 0x3F
134
135/*
136 * ECC status is stored at NFC_CFG[ECCADD] +4 for little-endian
137 * and +7 for big-endian SOC.
138 */
139#ifdef CONFIG_VF610
140#define ECC_OFFSET 4
141#else
142#define ECC_OFFSET 7
143#endif
144
145struct vf610_nfc {
146 struct mtd_info *mtd;
147 struct nand_chip chip;
148 void __iomem *regs;
149 uint column;
Stefan Agner72d7bea2014-09-12 13:06:35 +0200150 /* Status and ID are in alternate locations. */
151 int alt_buf;
152#define ALT_BUF_ID 1
153#define ALT_BUF_STAT 2
Stefan Agner8fca2d82015-05-08 19:07:13 +0200154#define ALT_BUF_ONFI 3
Stefan Agner72d7bea2014-09-12 13:06:35 +0200155 struct clk *clk;
156};
157
158#define mtd_to_nfc(_mtd) \
159 (struct vf610_nfc *)((struct nand_chip *)_mtd->priv)->priv
160
Stefan Agner080a71e2015-05-08 19:07:12 +0200161#if defined(CONFIG_SYS_NAND_VF610_NFC_45_ECC_BYTES)
162#define ECC_HW_MODE ECC_45_BYTE
163
164static struct nand_ecclayout vf610_nfc_ecc = {
Stefan Agner72d7bea2014-09-12 13:06:35 +0200165 .eccbytes = 45,
166 .eccpos = {19, 20, 21, 22, 23,
167 24, 25, 26, 27, 28, 29, 30, 31,
168 32, 33, 34, 35, 36, 37, 38, 39,
169 40, 41, 42, 43, 44, 45, 46, 47,
170 48, 49, 50, 51, 52, 53, 54, 55,
171 56, 57, 58, 59, 60, 61, 62, 63},
172 .oobfree = {
173 {.offset = 8,
174 .length = 11} }
175};
Stefan Agner080a71e2015-05-08 19:07:12 +0200176#elif defined(CONFIG_SYS_NAND_VF610_NFC_60_ECC_BYTES)
177#define ECC_HW_MODE ECC_60_BYTE
178
179static struct nand_ecclayout vf610_nfc_ecc = {
180 .eccbytes = 60,
181 .eccpos = { 4, 5, 6, 7, 8, 9, 10, 11,
182 12, 13, 14, 15, 16, 17, 18, 19,
183 20, 21, 22, 23, 24, 25, 26, 27,
184 28, 29, 30, 31, 32, 33, 34, 35,
185 36, 37, 38, 39, 40, 41, 42, 43,
186 44, 45, 46, 47, 48, 49, 50, 51,
187 52, 53, 54, 55, 56, 57, 58, 59,
188 60, 61, 62, 63 },
189 .oobfree = {
190 {.offset = 2,
191 .length = 2} }
192};
193#endif
Stefan Agner72d7bea2014-09-12 13:06:35 +0200194
195static inline u32 vf610_nfc_read(struct mtd_info *mtd, uint reg)
196{
197 struct vf610_nfc *nfc = mtd_to_nfc(mtd);
198
199 return readl(nfc->regs + reg);
200}
201
202static inline void vf610_nfc_write(struct mtd_info *mtd, uint reg, u32 val)
203{
204 struct vf610_nfc *nfc = mtd_to_nfc(mtd);
205
206 writel(val, nfc->regs + reg);
207}
208
209static inline void vf610_nfc_set(struct mtd_info *mtd, uint reg, u32 bits)
210{
211 vf610_nfc_write(mtd, reg, vf610_nfc_read(mtd, reg) | bits);
212}
213
214static inline void vf610_nfc_clear(struct mtd_info *mtd, uint reg, u32 bits)
215{
216 vf610_nfc_write(mtd, reg, vf610_nfc_read(mtd, reg) & ~bits);
217}
218
219static inline void vf610_nfc_set_field(struct mtd_info *mtd, u32 reg,
220 u32 mask, u32 shift, u32 val)
221{
222 vf610_nfc_write(mtd, reg,
223 (vf610_nfc_read(mtd, reg) & (~mask)) | val << shift);
224}
225
226static inline void vf610_nfc_memcpy(void *dst, const void *src, size_t n)
227{
228 /*
229 * Use this accessor for the interal SRAM buffers. On ARM we can
230 * treat the SRAM buffer as if its memory, hence use memcpy
231 */
232 memcpy(dst, src, n);
233}
234
235/* Clear flags for upcoming command */
236static inline void vf610_nfc_clear_status(void __iomem *regbase)
237{
238 void __iomem *reg = regbase + NFC_IRQ_STATUS;
239 u32 tmp = __raw_readl(reg);
240 tmp |= CMD_DONE_CLEAR_BIT | IDLE_CLEAR_BIT;
241 __raw_writel(tmp, reg);
242}
243
244/* Wait for complete operation */
245static inline void vf610_nfc_done(struct mtd_info *mtd)
246{
247 struct vf610_nfc *nfc = mtd_to_nfc(mtd);
248 uint start;
249
250 /*
251 * Barrier is needed after this write. This write need
252 * to be done before reading the next register the first
253 * time.
254 * vf610_nfc_set implicates such a barrier by using writel
255 * to write to the register.
256 */
257 vf610_nfc_set(mtd, NFC_FLASH_CMD2, START_BIT);
258
259 start = get_timer(0);
260
261 while (!(vf610_nfc_read(mtd, NFC_IRQ_STATUS) & IDLE_IRQ_BIT)) {
262 if (get_timer(start) > NFC_TIMEOUT) {
263 printf("Timeout while waiting for !BUSY.\n");
264 return;
265 }
266 }
267 vf610_nfc_clear_status(nfc->regs);
268}
269
270static u8 vf610_nfc_get_id(struct mtd_info *mtd, int col)
271{
272 u32 flash_id;
273
274 if (col < 4) {
275 flash_id = vf610_nfc_read(mtd, NFC_FLASH_STATUS1);
276 return (flash_id >> (3-col)*8) & 0xff;
277 } else {
278 flash_id = vf610_nfc_read(mtd, NFC_FLASH_STATUS2);
279 return flash_id >> 24;
280 }
281}
282
283static u8 vf610_nfc_get_status(struct mtd_info *mtd)
284{
285 return vf610_nfc_read(mtd, NFC_FLASH_STATUS2) & STATUS_BYTE1_MASK;
286}
287
288/* Single command */
289static void vf610_nfc_send_command(void __iomem *regbase, u32 cmd_byte1,
290 u32 cmd_code)
291{
292 void __iomem *reg = regbase + NFC_FLASH_CMD2;
293 u32 tmp;
294 vf610_nfc_clear_status(regbase);
295
296 tmp = __raw_readl(reg);
297 tmp &= ~(CMD_BYTE1_MASK | CMD_CODE_MASK | BUFNO_MASK);
298 tmp |= cmd_byte1 << CMD_BYTE1_SHIFT;
299 tmp |= cmd_code << CMD_CODE_SHIFT;
300 __raw_writel(tmp, reg);
301}
302
303/* Two commands */
304static void vf610_nfc_send_commands(void __iomem *regbase, u32 cmd_byte1,
305 u32 cmd_byte2, u32 cmd_code)
306{
307 void __iomem *reg = regbase + NFC_FLASH_CMD1;
308 u32 tmp;
309 vf610_nfc_send_command(regbase, cmd_byte1, cmd_code);
310
311 tmp = __raw_readl(reg);
312 tmp &= ~CMD_BYTE2_MASK;
313 tmp |= cmd_byte2 << CMD_BYTE2_SHIFT;
314 __raw_writel(tmp, reg);
315}
316
317static void vf610_nfc_addr_cycle(struct mtd_info *mtd, int column, int page)
318{
319 if (column != -1) {
320 struct vf610_nfc *nfc = mtd_to_nfc(mtd);
Stefan Agner5dec2862015-05-08 19:07:09 +0200321 if (nfc->chip.options & NAND_BUSWIDTH_16)
322 column = column / 2;
Stefan Agner72d7bea2014-09-12 13:06:35 +0200323 vf610_nfc_set_field(mtd, NFC_COL_ADDR, COL_ADDR_MASK,
324 COL_ADDR_SHIFT, column);
325 }
326 if (page != -1)
327 vf610_nfc_set_field(mtd, NFC_ROW_ADDR, ROW_ADDR_MASK,
328 ROW_ADDR_SHIFT, page);
329}
330
Stefan Agner5dec2862015-05-08 19:07:09 +0200331static inline void vf610_nfc_ecc_mode(struct mtd_info *mtd, int ecc_mode)
332{
333 vf610_nfc_set_field(mtd, NFC_FLASH_CONFIG,
334 CONFIG_ECC_MODE_MASK,
335 CONFIG_ECC_MODE_SHIFT, ecc_mode);
336}
337
Stefan Agner55765b12015-03-24 17:54:20 +0100338static inline void vf610_nfc_transfer_size(void __iomem *regbase, int size)
339{
340 __raw_writel(size, regbase + NFC_SECTOR_SIZE);
341}
342
Stefan Agner72d7bea2014-09-12 13:06:35 +0200343/* Send command to NAND chip */
344static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
345 int column, int page)
346{
347 struct vf610_nfc *nfc = mtd_to_nfc(mtd);
Stefan Agner5dec2862015-05-08 19:07:09 +0200348 int page_sz = nfc->chip.options & NAND_BUSWIDTH_16 ? 1 : 0;
Stefan Agner72d7bea2014-09-12 13:06:35 +0200349
Stefan Agner5dec2862015-05-08 19:07:09 +0200350 nfc->column = max(column, 0);
351 nfc->alt_buf = 0;
Stefan Agner72d7bea2014-09-12 13:06:35 +0200352
353 switch (command) {
Stefan Agner6fcfd1e2015-05-08 19:07:07 +0200354 case NAND_CMD_SEQIN:
355 /* Use valid column/page from preread... */
356 vf610_nfc_addr_cycle(mtd, column, page);
357 /*
358 * SEQIN => data => PAGEPROG sequence is done by the controller
359 * hence we do not need to issue the command here...
360 */
361 return;
Stefan Agner72d7bea2014-09-12 13:06:35 +0200362 case NAND_CMD_PAGEPROG:
Stefan Agner5dec2862015-05-08 19:07:09 +0200363 page_sz += mtd->writesize + mtd->oobsize;
364 vf610_nfc_transfer_size(nfc->regs, page_sz);
Stefan Agner72d7bea2014-09-12 13:06:35 +0200365 vf610_nfc_send_commands(nfc->regs, NAND_CMD_SEQIN,
366 command, PROGRAM_PAGE_CMD_CODE);
Stefan Agner080a71e2015-05-08 19:07:12 +0200367 vf610_nfc_ecc_mode(mtd, ECC_HW_MODE);
Stefan Agner72d7bea2014-09-12 13:06:35 +0200368 break;
369
370 case NAND_CMD_RESET:
Stefan Agner55765b12015-03-24 17:54:20 +0100371 vf610_nfc_transfer_size(nfc->regs, 0);
Stefan Agner72d7bea2014-09-12 13:06:35 +0200372 vf610_nfc_send_command(nfc->regs, command, RESET_CMD_CODE);
373 break;
Stefan Agner5dec2862015-05-08 19:07:09 +0200374
Stefan Agner72d7bea2014-09-12 13:06:35 +0200375 case NAND_CMD_READOOB:
Stefan Agner5dec2862015-05-08 19:07:09 +0200376 page_sz += mtd->oobsize;
377 column = mtd->writesize;
378 vf610_nfc_transfer_size(nfc->regs, page_sz);
Stefan Agner72d7bea2014-09-12 13:06:35 +0200379 vf610_nfc_send_commands(nfc->regs, NAND_CMD_READ0,
380 NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
381 vf610_nfc_addr_cycle(mtd, column, page);
Stefan Agner5dec2862015-05-08 19:07:09 +0200382 vf610_nfc_ecc_mode(mtd, ECC_BYPASS);
383 break;
384
385 case NAND_CMD_READ0:
386 page_sz += mtd->writesize + mtd->oobsize;
387 column = 0;
388 vf610_nfc_transfer_size(nfc->regs, page_sz);
389 vf610_nfc_send_commands(nfc->regs, NAND_CMD_READ0,
390 NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
391 vf610_nfc_addr_cycle(mtd, column, page);
Stefan Agner080a71e2015-05-08 19:07:12 +0200392 vf610_nfc_ecc_mode(mtd, ECC_HW_MODE);
Stefan Agner72d7bea2014-09-12 13:06:35 +0200393 break;
394
Stefan Agner8fca2d82015-05-08 19:07:13 +0200395 case NAND_CMD_PARAM:
396 nfc->alt_buf = ALT_BUF_ONFI;
397 vf610_nfc_transfer_size(nfc->regs, 768);
398 vf610_nfc_send_command(nfc->regs, NAND_CMD_PARAM,
399 READ_ONFI_PARAM_CMD_CODE);
400 vf610_nfc_set_field(mtd, NFC_ROW_ADDR, ROW_ADDR_MASK,
401 ROW_ADDR_SHIFT, column);
402 vf610_nfc_ecc_mode(mtd, ECC_BYPASS);
403 break;
404
Stefan Agner72d7bea2014-09-12 13:06:35 +0200405 case NAND_CMD_ERASE1:
Stefan Agner55765b12015-03-24 17:54:20 +0100406 vf610_nfc_transfer_size(nfc->regs, 0);
Stefan Agner72d7bea2014-09-12 13:06:35 +0200407 vf610_nfc_send_commands(nfc->regs, command,
408 NAND_CMD_ERASE2, ERASE_CMD_CODE);
409 vf610_nfc_addr_cycle(mtd, column, page);
410 break;
411
412 case NAND_CMD_READID:
413 nfc->alt_buf = ALT_BUF_ID;
Stefan Agner8fca2d82015-05-08 19:07:13 +0200414 nfc->column = 0;
Stefan Agner55765b12015-03-24 17:54:20 +0100415 vf610_nfc_transfer_size(nfc->regs, 0);
Stefan Agner72d7bea2014-09-12 13:06:35 +0200416 vf610_nfc_send_command(nfc->regs, command, READ_ID_CMD_CODE);
Stefan Agner8fca2d82015-05-08 19:07:13 +0200417 vf610_nfc_set_field(mtd, NFC_ROW_ADDR, ROW_ADDR_MASK,
418 ROW_ADDR_SHIFT, column);
Stefan Agner72d7bea2014-09-12 13:06:35 +0200419 break;
420
421 case NAND_CMD_STATUS:
422 nfc->alt_buf = ALT_BUF_STAT;
Stefan Agner55765b12015-03-24 17:54:20 +0100423 vf610_nfc_transfer_size(nfc->regs, 0);
Stefan Agner72d7bea2014-09-12 13:06:35 +0200424 vf610_nfc_send_command(nfc->regs, command,
425 STATUS_READ_CMD_CODE);
426 break;
427 default:
428 return;
429 }
430
431 vf610_nfc_done(mtd);
432}
433
Stefan Agner72d7bea2014-09-12 13:06:35 +0200434/* Read data from NFC buffers */
435static void vf610_nfc_read_buf(struct mtd_info *mtd, u_char *buf, int len)
436{
437 struct vf610_nfc *nfc = mtd_to_nfc(mtd);
438 uint c = nfc->column;
Stefan Agner72d7bea2014-09-12 13:06:35 +0200439
Stefan Agner8fca2d82015-05-08 19:07:13 +0200440 /* Alternate buffers are only supported through read_byte */
441 if (nfc->alt_buf)
442 return;
443
444 vf610_nfc_memcpy(buf, nfc->regs + NFC_MAIN_AREA(0) + c, len);
Stefan Agner72d7bea2014-09-12 13:06:35 +0200445
Stefan Agner5dec2862015-05-08 19:07:09 +0200446 nfc->column += len;
Stefan Agner72d7bea2014-09-12 13:06:35 +0200447}
448
449/* Write data to NFC buffers */
450static void vf610_nfc_write_buf(struct mtd_info *mtd, const u_char *buf,
451 int len)
452{
453 struct vf610_nfc *nfc = mtd_to_nfc(mtd);
454 uint c = nfc->column;
455 uint l;
456
457 l = min((uint)len, mtd->writesize + mtd->oobsize - c);
458 nfc->column += l;
459 vf610_nfc_memcpy(nfc->regs + NFC_MAIN_AREA(0) + c, buf, l);
460}
461
462/* Read byte from NFC buffers */
463static u8 vf610_nfc_read_byte(struct mtd_info *mtd)
464{
Stefan Agner8fca2d82015-05-08 19:07:13 +0200465 struct vf610_nfc *nfc = mtd_to_nfc(mtd);
Stefan Agner72d7bea2014-09-12 13:06:35 +0200466 u8 tmp;
Stefan Agner8fca2d82015-05-08 19:07:13 +0200467 uint c = nfc->column;
468
469 switch (nfc->alt_buf) {
470 case ALT_BUF_ID:
471 tmp = vf610_nfc_get_id(mtd, c);
472 break;
473 case ALT_BUF_STAT:
474 tmp = vf610_nfc_get_status(mtd);
475 break;
476 case ALT_BUF_ONFI:
477#ifdef __LITTLE_ENDIAN
478 /* Reverse byte since the controller uses big endianness */
479 c = nfc->column ^ 0x3;
480 tmp = *((u8 *)(nfc->regs + NFC_MAIN_AREA(0) + c));
481 break;
482#endif
483 default:
484 tmp = *((u8 *)(nfc->regs + NFC_MAIN_AREA(0) + c));
485 break;
486 }
487 nfc->column++;
Stefan Agner72d7bea2014-09-12 13:06:35 +0200488 return tmp;
489}
490
491/* Read word from NFC buffers */
492static u16 vf610_nfc_read_word(struct mtd_info *mtd)
493{
494 u16 tmp;
495 vf610_nfc_read_buf(mtd, (u_char *)&tmp, sizeof(tmp));
496 return tmp;
497}
498
499/* If not provided, upper layers apply a fixed delay. */
500static int vf610_nfc_dev_ready(struct mtd_info *mtd)
501{
502 /* NFC handles R/B internally; always ready. */
503 return 1;
504}
505
506/*
507 * This function supports Vybrid only (MPC5125 would have full RB and four CS)
508 */
509static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip)
510{
511#ifdef CONFIG_VF610
512 u32 tmp = vf610_nfc_read(mtd, NFC_ROW_ADDR);
513 tmp &= ~(ROW_ADDR_CHIP_SEL_RB_MASK | ROW_ADDR_CHIP_SEL_MASK);
514 tmp |= 1 << ROW_ADDR_CHIP_SEL_RB_SHIFT;
515
516 if (chip == 0)
517 tmp |= 1 << ROW_ADDR_CHIP_SEL_SHIFT;
518 else if (chip == 1)
519 tmp |= 2 << ROW_ADDR_CHIP_SEL_SHIFT;
520
521 vf610_nfc_write(mtd, NFC_ROW_ADDR, tmp);
522#endif
523}
524
525/* Count the number of 0's in buff upto max_bits */
526static inline int count_written_bits(uint8_t *buff, int size, int max_bits)
527{
528 uint32_t *buff32 = (uint32_t *)buff;
529 int k, written_bits = 0;
530
531 for (k = 0; k < (size / 4); k++) {
532 written_bits += hweight32(~buff32[k]);
533 if (written_bits > max_bits)
534 break;
535 }
536
537 return written_bits;
538}
539
540static inline int vf610_nfc_correct_data(struct mtd_info *mtd, u_char *dat)
541{
542 struct vf610_nfc *nfc = mtd_to_nfc(mtd);
543 u8 ecc_status;
544 u8 ecc_count;
545 int flip;
546
547 ecc_status = __raw_readb(nfc->regs + ECC_SRAM_ADDR * 8 + ECC_OFFSET);
548 ecc_count = ecc_status & ECC_ERR_COUNT;
549 if (!(ecc_status & ECC_STATUS_MASK))
550 return ecc_count;
551
552 /* If 'ecc_count' zero or less then buffer is all 0xff or erased. */
553 flip = count_written_bits(dat, nfc->chip.ecc.size, ecc_count);
554
555 /* ECC failed. */
Stefan Agnerd111bf92015-05-08 19:07:08 +0200556 if (flip > ecc_count && flip > (nfc->chip.ecc.strength / 2))
Stefan Agner72d7bea2014-09-12 13:06:35 +0200557 return -1;
Stefan Agner72d7bea2014-09-12 13:06:35 +0200558
559 /* Erased page. */
560 memset(dat, 0xff, nfc->chip.ecc.size);
561 return 0;
562}
563
564
565static int vf610_nfc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
566 uint8_t *buf, int oob_required, int page)
567{
568 int eccsize = chip->ecc.size;
569 int stat;
570 uint8_t *p = buf;
571
572
573 vf610_nfc_read_buf(mtd, p, eccsize);
574
575 if (oob_required)
576 vf610_nfc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
577
578 stat = vf610_nfc_correct_data(mtd, p);
579
580 if (stat < 0)
581 mtd->ecc_stats.failed++;
582 else
583 mtd->ecc_stats.corrected += stat;
584
585 return 0;
586}
587
588/*
589 * ECC will be calculated automatically
590 */
591static int vf610_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
592 const uint8_t *buf, int oob_required)
593{
594 vf610_nfc_write_buf(mtd, buf, mtd->writesize);
595 if (oob_required)
596 vf610_nfc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
597
598 return 0;
599}
600
601struct vf610_nfc_config {
602 int hardware_ecc;
603 int width;
604 int flash_bbt;
605};
606
607static int vf610_nfc_nand_init(int devnum, void __iomem *addr)
608{
609 struct mtd_info *mtd = &nand_info[devnum];
610 struct nand_chip *chip;
611 struct vf610_nfc *nfc;
612 int err = 0;
Stefan Agner72d7bea2014-09-12 13:06:35 +0200613 struct vf610_nfc_config cfg = {
614 .hardware_ecc = 1,
615#ifdef CONFIG_SYS_NAND_BUSWIDTH_16BIT
616 .width = 16,
617#else
618 .width = 8,
619#endif
620 .flash_bbt = 1,
621 };
622
623 nfc = malloc(sizeof(*nfc));
624 if (!nfc) {
625 printf(KERN_ERR "%s: Memory exhausted!\n", __func__);
626 return -ENOMEM;
627 }
628
629 chip = &nfc->chip;
630 nfc->regs = addr;
631
632 mtd->priv = chip;
633 chip->priv = nfc;
634
Stefan Agner8fca2d82015-05-08 19:07:13 +0200635 if (cfg.width == 16)
Stefan Agner72d7bea2014-09-12 13:06:35 +0200636 chip->options |= NAND_BUSWIDTH_16;
Stefan Agner8fca2d82015-05-08 19:07:13 +0200637
638 /* Use 8-bit mode during initialization */
639 vf610_nfc_clear(mtd, NFC_FLASH_CONFIG, CONFIG_16BIT);
Stefan Agner72d7bea2014-09-12 13:06:35 +0200640
Sanchayan Maity22604572014-11-24 11:03:59 +0530641 /* Disable subpage writes as we do not provide ecc->hwctl */
642 chip->options |= NAND_NO_SUBPAGE_WRITE;
643
Stefan Agner72d7bea2014-09-12 13:06:35 +0200644 chip->dev_ready = vf610_nfc_dev_ready;
645 chip->cmdfunc = vf610_nfc_command;
646 chip->read_byte = vf610_nfc_read_byte;
647 chip->read_word = vf610_nfc_read_word;
648 chip->read_buf = vf610_nfc_read_buf;
649 chip->write_buf = vf610_nfc_write_buf;
650 chip->select_chip = vf610_nfc_select_chip;
651
652 /* Bad block options. */
653 if (cfg.flash_bbt)
Stefan Agner84d656a2015-05-08 19:07:10 +0200654 chip->bbt_options = NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB |
655 NAND_BBT_CREATE;
Stefan Agner72d7bea2014-09-12 13:06:35 +0200656
Stefan Agner72d7bea2014-09-12 13:06:35 +0200657 /* Set configuration register. */
658 vf610_nfc_clear(mtd, NFC_FLASH_CONFIG, CONFIG_ADDR_AUTO_INCR_BIT);
659 vf610_nfc_clear(mtd, NFC_FLASH_CONFIG, CONFIG_BUFNO_AUTO_INCR_BIT);
660 vf610_nfc_clear(mtd, NFC_FLASH_CONFIG, CONFIG_BOOT_MODE_BIT);
661 vf610_nfc_clear(mtd, NFC_FLASH_CONFIG, CONFIG_DMA_REQ_BIT);
662 vf610_nfc_set(mtd, NFC_FLASH_CONFIG, CONFIG_FAST_FLASH_BIT);
663
664 /* Enable Idle IRQ */
665 vf610_nfc_set(mtd, NFC_IRQ_STATUS, IDLE_EN_BIT);
666
667 /* PAGE_CNT = 1 */
668 vf610_nfc_set_field(mtd, NFC_FLASH_CONFIG, CONFIG_PAGE_CNT_MASK,
669 CONFIG_PAGE_CNT_SHIFT, 1);
670
671 /* Set ECC_STATUS offset */
672 vf610_nfc_set_field(mtd, NFC_FLASH_CONFIG,
673 CONFIG_ECC_SRAM_ADDR_MASK,
674 CONFIG_ECC_SRAM_ADDR_SHIFT, ECC_SRAM_ADDR);
675
676 /* first scan to find the device and get the page size */
677 if (nand_scan_ident(mtd, CONFIG_SYS_MAX_NAND_DEVICE, NULL)) {
678 err = -ENXIO;
679 goto error;
680 }
681
Stefan Agner8fca2d82015-05-08 19:07:13 +0200682 if (cfg.width == 16)
683 vf610_nfc_set(mtd, NFC_FLASH_CONFIG, CONFIG_16BIT);
684
Stefan Agner72d7bea2014-09-12 13:06:35 +0200685 chip->ecc.mode = NAND_ECC_SOFT; /* default */
686
Stefan Agner72d7bea2014-09-12 13:06:35 +0200687 /* Single buffer only, max 256 OOB minus ECC status */
Stefan Agner5dec2862015-05-08 19:07:09 +0200688 if (mtd->writesize + mtd->oobsize > PAGE_2K + 256 - 8) {
Stefan Agner72d7bea2014-09-12 13:06:35 +0200689 dev_err(nfc->dev, "Unsupported flash size\n");
690 err = -ENXIO;
691 goto error;
692 }
Stefan Agner72d7bea2014-09-12 13:06:35 +0200693
694 if (cfg.hardware_ecc) {
695 if (mtd->writesize != PAGE_2K && mtd->oobsize < 64) {
696 dev_err(nfc->dev, "Unsupported flash with hwecc\n");
697 err = -ENXIO;
698 goto error;
699 }
700
Stefan Agner080a71e2015-05-08 19:07:12 +0200701 /* Current HW ECC layouts only use 64 bytes of OOB */
702 if (mtd->oobsize > 64)
703 mtd->oobsize = 64;
Stefan Agner72d7bea2014-09-12 13:06:35 +0200704
705 /* propagate ecc.layout to mtd_info */
706 mtd->ecclayout = chip->ecc.layout;
707 chip->ecc.read_page = vf610_nfc_read_page;
708 chip->ecc.write_page = vf610_nfc_write_page;
709 chip->ecc.mode = NAND_ECC_HW;
710
Stefan Agner72d7bea2014-09-12 13:06:35 +0200711 chip->ecc.size = PAGE_2K;
Stefan Agner080a71e2015-05-08 19:07:12 +0200712 chip->ecc.layout = &vf610_nfc_ecc;
713#if defined(CONFIG_SYS_NAND_VF610_NFC_45_ECC_BYTES)
Stefan Agner72d7bea2014-09-12 13:06:35 +0200714 chip->ecc.strength = 24;
Stefan Agner080a71e2015-05-08 19:07:12 +0200715 chip->ecc.bytes = 45;
716#elif defined(CONFIG_SYS_NAND_VF610_NFC_60_ECC_BYTES)
717 chip->ecc.strength = 32;
718 chip->ecc.bytes = 60;
719#endif
Stefan Agner72d7bea2014-09-12 13:06:35 +0200720
Stefan Agner72d7bea2014-09-12 13:06:35 +0200721 /* Enable ECC_STATUS */
722 vf610_nfc_set(mtd, NFC_FLASH_CONFIG, CONFIG_ECC_SRAM_REQ_BIT);
723 }
724
725 /* second phase scan */
726 err = nand_scan_tail(mtd);
727 if (err)
728 return err;
729
730 err = nand_register(devnum);
731 if (err)
732 return err;
733
734 return 0;
735
736error:
737 return err;
738}
739
740void board_nand_init(void)
741{
742 int err = vf610_nfc_nand_init(0, (void __iomem *)CONFIG_SYS_NAND_BASE);
743 if (err)
744 printf("VF610 NAND init failed (err %d)\n", err);
745}