blob: 781c218ba1d1e31ea3af9d54970c5a66bb9eac7c [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/*
2 * Copyright (c) 2003-2013 Marvell Corporation
3 *
4 * Copyright (c) 2009-2010 Micron Technology, Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#include <common.h>
17#include <malloc.h>
18#include <spi_flash.h>
19#include <nand.h>
20#include <linux/bitops.h>
21#include <linux/mtd/mtd.h>
22#include <linux/mtd/nand.h>
23#include <asm/errno.h>
24#include <asm/io.h>
25#include <asm/bitops.h>
26#include "spinand.h"
27#include <mtd/pxa3xx_bbm.h>
28#include <watchdog.h>
29#ifndef CONFIG_SF_DEFAULT_SPEED
30# define CONFIG_SF_DEFAULT_SPEED 1000000
31#endif
32#ifndef CONFIG_SF_DEFAULT_MODE
33# define CONFIG_SF_DEFAULT_MODE SPI_MODE_3
34#endif
35
36#ifndef CONFIG_SPINAND_CS
37#define CONFIG_SPINAND_CS 25
38#endif
39#define FLASH_TIME_OUT (20*CONFIG_SYS_HZ)
40#define BUFSIZE (2 * 2048)
41
42
43/* #define CONFIG_MTD_SPINAND_ONDIEECC 1 */
44
45#ifdef CONFIG_MTD_SPINAND_ONDIEECC
46static int enable_hw_ecc;
47static int enable_read_hw_ecc;
48
49static struct nand_ecclayout spinand_oob_64 = {
50 .eccbytes = 24,
51 .eccpos = {
52 1, 2, 3, 4, 5, 6,
53 17, 18, 19, 20, 21, 22,
54 33, 34, 35, 36, 37, 38,
55 49, 50, 51, 52, 53, 54, },
56 .oobavail = 32,
57 .oobfree = {
58 {.offset = 8,
59 .length = 8},
60 {.offset = 24,
61 .length = 8},
62 {.offset = 40,
63 .length = 8},
64 {.offset = 56,
65 .length = 8}, }
66};
67#endif
68
69extern int spi_dma_xfer(struct spi_slave *slave, const u8 *cmd, size_t cmd_len,
70 const u32 *dout, u32 *din, size_t data_len);
71
72int spinand_cmd(struct spi_flash *spi_nand, struct spinand_cmd *cmd)
73{
74 char cmdbuf[16], cmd_len = 1;
75 int ret, datalen = 0;
76 unsigned long flags = SPI_XFER_BEGIN;
77
78 cmdbuf[0] = cmd->cmd;
79 if (cmd->n_dummy) {
80 cmdbuf[1] = 0x0;
81 cmd_len += cmd->n_dummy;
82 } else if (cmd->addr) {
83 memcpy(&cmdbuf[1], cmd->addr, cmd->n_addr);
84 cmd_len += cmd->n_addr;
85 }
86
87 if (cmd->n_rx)
88 datalen = cmd->n_rx;
89 else if (cmd->n_tx)
90 datalen = cmd->n_tx;
91 else
92 flags |= SPI_XFER_END;
93
94 ret = spi_xfer(spi_nand->spi, cmd_len*8, cmdbuf, NULL, flags);
95 if (ret) {
96 debug("SPINAND: Failed to send command (%zu bytes): %d\n",
97 cmd_len, ret);
98 } else if (datalen != 0) {
99 ret = spi_xfer(spi_nand->spi, datalen * 8, cmd->tx_buf,
100 cmd->rx_buf, SPI_XFER_END);
101 if (ret)
102 debug("SPINAND: Failed to transfer %zu bytes of data: %d\n",
103 datalen, ret);
104 }
105
106 return ret;
107}
108
109static int spinand_dma_transfer(struct spi_flash *spi_nand, struct spinand_cmd *cmd)
110{
111 int ret = 0;
112 char cmdbuf[4], cmd_len = 1;
113
114 cmdbuf[0] = cmd->cmd;
115 if(cmd->addr){
116 memcpy(&cmdbuf[1], cmd->addr, cmd->n_addr);
117 cmd_len += cmd->n_addr;
118 }
119 if (cmd->n_rx)
120 ret = spi_dma_xfer(spi_nand->spi, (u8 *)cmdbuf, cmd_len, NULL,
121 (u32 *)cmd->rx_buf, cmd->n_rx);
122 if (cmd->n_tx)
123 ret = spi_dma_xfer(spi_nand->spi, (u8 *)cmdbuf, cmd_len,
124 (u32 *)cmd->tx_buf, NULL, cmd->n_tx);
125 if (ret != 0) {
126 debug("SPINAND: error %d dma trasfer.\n", ret);
127 return ret;
128 }
129
130 return 0;
131}
132
133static int spinand_read_id(struct spi_flash *spi_nand, u8 *id)
134{
135 int retval;
136 u8 nand_id[2];
137 struct spinand_cmd cmd = {0};
138
139 cmd.cmd = CMD_READ_ID;
140 cmd.n_dummy = 1;
141 cmd.n_rx = 2;
142 cmd.rx_buf = &nand_id[0];
143
144 retval = spinand_cmd(spi_nand, &cmd);
145 if (retval != 0) {
146 debug("SPINAND: error %d reading id\n", retval);
147 return retval;
148 }
149 id[0] = nand_id[0];
150 id[1] = nand_id[1];
151
152 return 0;
153}
154
155static int spinand_read_status(struct spi_flash *spi_nand, uint8_t *status)
156{
157 struct spinand_cmd cmd = {0};
158 int ret;
159
160 cmd.cmd = CMD_READ_REG;
161 cmd.n_addr = 1;
162 cmd.addr[0] = REG_STATUS;
163 cmd.n_rx = 1;
164 cmd.rx_buf = status;
165
166 ret = spinand_cmd(spi_nand, &cmd);
167 if (ret != 0) {
168 debug("SPINAND: error %d read status register\n", ret);
169 return ret;
170 }
171
172 return 0;
173}
174
175static int spinand_get_otp(struct spi_flash *spi_nand, u8 *otp)
176{
177 struct spinand_cmd cmd = {0};
178 int retval;
179
180 cmd.cmd = CMD_READ_REG;
181 cmd.n_addr = 1;
182 cmd.addr[0] = REG_OTP;
183 cmd.n_rx = 1;
184 cmd.rx_buf = otp;
185
186 retval = spinand_cmd(spi_nand, &cmd);
187 if (retval != 0) {
188 debug("SPINAND: error %d get otp\n", retval);
189 return retval;
190 }
191 return 0;
192}
193
194static int spinand_get_protect(struct spi_flash *spi_nand, u8 *otp)
195{
196 struct spinand_cmd cmd = {0};
197 int retval;
198
199 cmd.cmd = CMD_READ_REG;
200 cmd.n_addr = 1;
201 cmd.addr[0] = REG_BLOCK_LOCK;
202 cmd.n_rx = 1;
203 cmd.rx_buf = otp;
204
205 retval = spinand_cmd(spi_nand, &cmd);
206 if (retval != 0) {
207 debug("SPINAND error %d get otp\n", retval);
208 return retval;
209 }
210
211 return 0;
212}
213
214static int spinand_set_otp(struct spi_flash *spi_nand, u8 *otp)
215{
216 int retval;
217 struct spinand_cmd cmd = {0};
218
219 cmd.cmd = CMD_WRITE_REG,
220 cmd.n_addr = 1,
221 cmd.addr[0] = REG_OTP,
222 cmd.n_tx = 1,
223 cmd.tx_buf = otp,
224
225 retval = spinand_cmd(spi_nand, &cmd);
226 if (retval != 0) {
227 debug("SPINAND error %d set otp\n", retval);
228 return retval;
229 }
230 return 0;
231}
232#if 0
233static int wait_till_ready(struct spi_flash *spi_nand)
234{
235 unsigned long timebase;
236 int retval;
237 u8 stat = 0;
238
239 timebase = get_timer(0);
240 do {
241 WATCHDOG_RESET();
242
243 retval = spinand_read_status(spi_nand, &stat);
244 if (retval < 0)
245 return -1;
246 else if (!(stat & 0x1))
247 break;
248
249 } while (get_timer(timebase) < FLASH_TIME_OUT);
250
251 if ((stat & 0x1) == 0)
252 return 0;
253
254 return -1;
255}
256#endif
257#ifdef CONFIG_MTD_SPINAND_ONDIEECC
258static int spinand_enable_ecc(struct spi_flash *spi_nand)
259{
260 int retval;
261 u8 otp = 0;
262
263 retval = spinand_get_otp(spi_nand, &otp);
264 if (retval != 0) {
265 debug("SPINAND get otp error.\n");
266 return retval;
267 }
268 if ((otp & OTP_ECC_MASK) == OTP_ECC_MASK) {
269 return 0;
270 } else {
271 otp |= OTP_ECC_MASK;
272 retval = spinand_set_otp(spi_nand, &otp);
273 retval = spinand_get_otp(spi_nand, &otp);
274 return retval;
275 }
276}
277#endif
278
279static int spinand_disable_ecc(struct spi_flash *spi_nand)
280{
281 int retval;
282 u8 otp = 0;
283
284 retval = spinand_get_otp(spi_nand, &otp);
285 if ((otp & OTP_ECC_MASK) == OTP_ECC_MASK) {
286 otp &= ~OTP_ECC_MASK;
287 retval = spinand_set_otp(spi_nand, &otp);
288 retval = spinand_get_otp(spi_nand, &otp);
289 return retval;
290 } else
291 return 0;
292}
293
294static int spinand_write_enable(struct spi_flash *spi_nand)
295{
296 struct spinand_cmd cmd = {0};
297
298 cmd.cmd = CMD_WR_ENABLE;
299 return spinand_cmd(spi_nand, &cmd);
300}
301
302static int spinand_read_page_to_cache(struct spi_flash *spi_nand, u16 page_id)
303{
304 struct spinand_cmd cmd = {0};
305 u16 row;
306
307 row = page_id;
308 cmd.cmd = CMD_READ;
309 cmd.n_addr = 3;
310 cmd.addr[1] = (u8)((row & 0xff00) >> 8);
311 cmd.addr[2] = (u8)(row & 0x00ff);
312
313 return spinand_cmd(spi_nand, &cmd);
314}
315
316static int spinand_read_from_cache(struct spi_flash *spi_nand, u16 byte_id,
317 u16 len, u8 *rbuf)
318{
319 struct spinand_cmd cmd = {0};
320 u16 column;
321 int ret;
322
323 column = byte_id;
324 cmd.cmd = CMD_READ_RDM;
325 cmd.n_addr = 3;
326 cmd.addr[0] = (u8)((column & 0xff00) >> 8);
327 cmd.addr[1] = (u8)(column & 0x00ff);
328 cmd.addr[2] = (u8)(0xff);
329 cmd.n_dummy = 0;
330 cmd.n_rx = len;
331 cmd.rx_buf = rbuf;
332 ret = spinand_dma_transfer(spi_nand, &cmd);
333 if (ret != 0) {
334 debug("SPINAND error %d read_from_cache\n", ret);
335 return ret;
336 }
337 return 0;
338}
339
340static int spinand_read_page(struct spi_flash *spi_nand, u16 page_id,
341 u16 offset, u16 len, u8 *rbuf)
342{
343 int ret;
344 u8 status = 0;
345
346#ifdef CONFIG_MTD_SPINAND_ONDIEECC
347 if (enable_read_hw_ecc) {
348 if (spinand_enable_ecc(spi_nand))
349 debug("SPINAND enable HW ECC failed!");
350 }
351#endif
352 ret = spinand_read_page_to_cache(spi_nand, page_id);
353
354 while (1) {
355 ret = spinand_read_status(spi_nand, &status);
356 if (ret < 0) {
357 debug("SPINAND err %d read status register\n", ret);
358 return ret;
359 }
360
361 if ((status & STATUS_OIP_MASK) == STATUS_READY) {
362 if ((status & STATUS_ECC_MASK) == STATUS_ECC_ERROR) {
363 debug("SPINAND ecc error, page=%d\n", page_id);
364 return 0;
365 }
366 break;
367 }
368 }
369
370 ret = spinand_read_from_cache(spi_nand, offset, len, rbuf);
371 if (ret != 0)
372 debug("SPINAND read from cache failed!!\n");
373
374#ifdef CONFIG_MTD_SPINAND_ONDIEECC
375 if (enable_read_hw_ecc) {
376 ret = spinand_disable_ecc(spi_nand);
377 enable_read_hw_ecc = 0;
378 }
379#endif
380 return 0;
381}
382
383static int spinand_program_data_to_cache(struct spi_flash *spi_nand,
384 u16 byte_id, u16 len, u8 *wbuf)
385{
386 struct spinand_cmd cmd = {0};
387 u16 column;
388 int ret;
389 column = byte_id;
390 cmd.cmd = CMD_PROG_PAGE_CLRCACHE;
391 cmd.n_addr = 2;
392 cmd.addr[0] = (u8)((column & 0xff00) >> 8);
393 cmd.addr[1] = (u8)(column & 0x00ff);
394
395 cmd.n_tx = len;
396 cmd.tx_buf = wbuf;
397 ret = spinand_dma_transfer(spi_nand, &cmd);
398 if (ret != 0) {
399 debug("SPINAND error %d read_from_cache\n", ret);
400 return ret;
401 }
402 return 0;
403}
404
405static int spinand_program_execute(struct spi_flash *spi_nand, u16 page_id)
406{
407 struct spinand_cmd cmd = {0};
408 u16 row;
409
410 row = page_id;
411 cmd.cmd = CMD_PROG_PAGE_EXC;
412 cmd.n_addr = 3;
413 cmd.addr[1] = (u8)((row & 0xff00) >> 8);
414 cmd.addr[2] = (u8)(row & 0x00ff);
415
416 return spinand_cmd(spi_nand, &cmd);
417}
418
419static int spinand_program_page(struct spi_flash *spi_nand,
420 u16 page_id, u16 offset, u16 len, u8 *buf)
421{
422 int retval;
423 u8 status = 0;
424 uint8_t *wbuf;
425#ifdef CONFIG_MTD_SPINAND_ONDIEECC
426 /* unsigned int i j; */
427 enable_read_hw_ecc = 0;
428 /* wbuf = malloc(2112);
429 spinand_read_page(spi_nand, page_id, 0, 0x840, wbuf);
430 for (i = offset, j = 0; i < len; i++, j++)
431 wbuf[i] &= buf[j]; */
432
433 if (enable_hw_ecc)
434 retval = spinand_enable_ecc(spi_nand);
435#endif
436 wbuf = buf;
437
438 retval = spinand_write_enable(spi_nand);
439
440 retval = spinand_program_data_to_cache(spi_nand, offset, len, wbuf);
441 retval = spinand_program_execute(spi_nand, page_id);
442 while (1) {
443 retval = spinand_read_status(spi_nand, &status);
444 if (retval < 0) {
445 debug("SPINAND error %d reading status register\n",
446 retval);
447 return retval;
448 }
449
450 if ((status & STATUS_OIP_MASK) == STATUS_READY) {
451 if ((status & STATUS_P_FAIL_MASK) == STATUS_P_FAIL) {
452 debug("SPINAND program error, page %d\n", page_id);
453 return -1;
454 } else
455 break;
456 }
457 }
458#ifdef CONFIG_MTD_SPINAND_ONDIEECC
459 if (enable_hw_ecc) {
460 retval = spinand_disable_ecc(spi_nand);
461 enable_hw_ecc = 0;
462 }
463#endif
464
465 return 0;
466}
467
468static int spinand_erase_block_erase(struct spi_flash *spi_nand, u16 block_id)
469{
470 struct spinand_cmd cmd = {0};
471 u16 row;
472
473 row = block_id;
474 cmd.cmd = CMD_ERASE_BLK;
475 cmd.n_addr = 3;
476 cmd.addr[1] = (u8)((row & 0xff00) >> 8);
477 cmd.addr[2] = (u8)(row & 0x00ff);
478
479 return spinand_cmd(spi_nand, &cmd);
480}
481
482static int spinand_erase_block(struct spi_flash *spi_nand, u16 block_id)
483{
484 int retval;
485 u8 status = 0;
486
487 retval = spinand_write_enable(spi_nand);
488
489 retval = spinand_erase_block_erase(spi_nand, block_id);
490 while (1) {
491 retval = spinand_read_status(spi_nand, &status);
492 if (retval < 0) {
493 debug("SPINAND error %d reading status register\n",
494 (int) retval);
495 return retval;
496 }
497
498 if ((status & STATUS_OIP_MASK) == STATUS_READY) {
499 if ((status & STATUS_E_FAIL_MASK) == STATUS_E_FAIL) {
500 debug("SPINAND erase error,block %d\n",
501 block_id);
502 return -1;
503 } else
504 break;
505 }
506 }
507 return 0;
508}
509
510#ifdef CONFIG_MTD_SPINAND_ONDIEECC
511static int spinand_write_page_hwecc(struct mtd_info *mtd,
512 struct nand_chip *chip, const uint8_t *buf, int oob_required)
513{
514 const uint8_t *p = buf;
515 int eccsize = chip->ecc.size;
516 int eccsteps = chip->ecc.steps;
517
518 enable_hw_ecc = 1;
519 chip->write_buf(mtd, p, eccsize * eccsteps);
520 return 0;
521}
522
523static int spinand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
524 uint8_t *buf, int oob_required, int page)
525{
526 u8 status;
527 uint8_t *p = buf;
528 int eccsize = chip->ecc.size;
529 int eccsteps = chip->ecc.steps;
530 struct spinand_info *info = (struct spinand_info *)chip->priv;
531
532 enable_read_hw_ecc = 1;
533
534 chip->read_buf(mtd, p, eccsize * eccsteps);
535 if (oob_required)
536 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
537
538 while (1) {
539 spinand_read_status(info->spi, &status);
540 if ((status & STATUS_OIP_MASK) == STATUS_READY) {
541 if ((status & STATUS_ECC_MASK) == STATUS_ECC_ERROR) {
542 debug("spinand: ECC error\n");
543 mtd->ecc_stats.failed++;
544 } else if ((status & STATUS_ECC_MASK) ==
545 STATUS_ECC_1BIT_CORRECTED)
546 mtd->ecc_stats.corrected++;
547 break;
548 }
549 }
550 return 0;
551
552}
553#endif
554
555static void spinand_select_chip(struct mtd_info *mtd, int dev)
556{
557}
558
559static uint8_t spinand_read_byte(struct mtd_info *mtd)
560{
561 struct nand_chip *chip = (struct nand_chip *)mtd->priv;
562 struct spinand_info *info = (struct spinand_info *)chip->priv;
563 struct nand_state *state = (struct nand_state *)info->priv;
564 u8 data;
565
566 data = state->buf[state->buf_ptr];
567 state->buf_ptr++;
568 return data;
569}
570
571static int spinand_wait(struct mtd_info *mtd, struct nand_chip *chip)
572{
573 struct spinand_info *info = (struct spinand_info *)chip->priv;
574 unsigned long timebase;
575 u8 status;
576
577 timebase = get_timer(0);
578 do {
579 WATCHDOG_RESET();
580
581 spinand_read_status(info->spi, &status);
582 if ((status & STATUS_E_FAIL_MASK) == STATUS_E_FAIL)
583 return NAND_STATUS_FAIL;
584
585 if ((status & STATUS_P_FAIL_MASK) == STATUS_P_FAIL)
586 return NAND_STATUS_FAIL;
587
588 if ((status & STATUS_OIP_MASK) == STATUS_READY)
589 return 0;
590
591 } while (get_timer(timebase) < FLASH_TIME_OUT);
592
593 return 0;
594}
595
596static void spinand_write_buf(struct mtd_info *mtd, const uint8_t *buf,
597 int len)
598{
599 struct nand_chip *chip = (struct nand_chip *)mtd->priv;
600 struct spinand_info *info = (struct spinand_info *)chip->priv;
601 struct nand_state *state = (struct nand_state *)info->priv;
602
603 memcpy(state->buf+state->buf_ptr, buf, len);
604 state->buf_ptr += len;
605}
606
607static void spinand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
608{
609 struct nand_chip *chip = (struct nand_chip *)mtd->priv;
610 struct spinand_info *info = (struct spinand_info *)chip->priv;
611 struct nand_state *state = (struct nand_state *)info->priv;
612
613 memcpy(buf, state->buf+state->buf_ptr, len);
614 state->buf_ptr += len;
615 flush_dcache_all();
616}
617
618static int spinand_lock_block(struct spi_flash *spi_nand, u8 lock)
619{
620 struct spinand_cmd cmd = {0};
621 int ret;
622 u8 otp = 0;
623
624 cmd.cmd = CMD_WRITE_REG;
625 cmd.n_addr = 1;
626 cmd.addr[0] = REG_BLOCK_LOCK;
627 cmd.n_tx = 1;
628 cmd.tx_buf = &lock;
629
630 ret = spinand_cmd(spi_nand, &cmd);
631 if (ret != 0) {
632 debug("SPINAND: error %d lock block\n", ret);
633 return ret;
634 }
635
636 ret = spinand_get_protect(spi_nand, &otp);
637 return otp;
638}
639
640static void spinand_cmdfunc(struct mtd_info *mtd, unsigned int command,
641 int column, int page)
642{
643 struct nand_chip *chip = (struct nand_chip *)mtd->priv;
644 struct spinand_info *info = (struct spinand_info *)chip->priv;
645 struct nand_state *state = (struct nand_state *)info->priv;
646 struct pxa3xx_bbm *pxa3xx_bbm = mtd->bbm;
647 loff_t addr;
648
649 if (pxa3xx_bbm && (command == NAND_CMD_READOOB ||
650 command == NAND_CMD_READ0 ||
651 command == NAND_CMD_SEQIN ||
652 command == NAND_CMD_ERASE1)) {
653 addr = (loff_t)page << mtd->writesize_shift;
654 addr = pxa3xx_bbm->search(mtd, addr);
655 page = addr >> mtd->writesize_shift;
656 }
657 switch (command) {
658 /*
659 * READ0 - read in first 0x800 bytes
660 */
661 case NAND_CMD_READ1:
662 case NAND_CMD_READ0:
663 state->buf_ptr = 0;
664 spinand_read_page(info->spi, page, 0x0, 0x800, state->buf);
665 break;
666 /* READOOB reads only the OOB because no ECC is performed. */
667 case NAND_CMD_READOOB:
668 state->buf_ptr = 0;
669 spinand_read_page(info->spi, page, 0x800, 0x40, state->buf);
670 break;
671 case NAND_CMD_RNDOUT:
672 state->buf_ptr = column;
673 break;
674 case NAND_CMD_READID:
675 state->buf_ptr = 0;
676 spinand_read_id(info->spi, (u8 *)state->buf);
677 break;
678 case NAND_CMD_PARAM:
679 state->buf_ptr = 0;
680 break;
681 /* ERASE1 stores the block and page address */
682 case NAND_CMD_ERASE1:
683 spinand_erase_block(info->spi, page);
684 break;
685 /* ERASE2 uses the block and page address from ERASE1 */
686 case NAND_CMD_ERASE2:
687 break;
688 /* SEQIN sets up the addr buffer and all registers except the length */
689 case NAND_CMD_SEQIN:
690 state->col = column;
691 state->row = page;
692 state->buf_ptr = 0;
693 break;
694 /* PAGEPROG reuses all of the setup from SEQIN and adds the length */
695 case NAND_CMD_PAGEPROG:
696 spinand_program_page(info->spi, state->row, state->col,
697 state->buf_ptr, state->buf);
698 break;
699 case NAND_CMD_STATUS:
700 spinand_get_otp(info->spi, state->buf);
701 if (!(state->buf[0] & 0x80))
702 state->buf[0] = 0x80;
703 state->buf_ptr = 0;
704 break;
705 case NAND_CMD_LOCK:
706 if (spinand_lock_block(info->spi, BL_ALL_UNLOCKED))
707 printf("Error: Fail to unlock SPI NAND.\n");
708 break;
709 /* RESET command */
710 case NAND_CMD_RESET:
711 break;
712 default:
713 debug("SPINAND: Unknown CMD: 0x%x\n", command);
714 }
715}
716
717int board_nand_init(struct nand_chip *nand)
718{
719 struct spinand_info *info;
720 struct spi_flash *spi_nand;
721 struct nand_state *state;
722 struct spi_slave *spi;
723 int ret;
724 int bus = 0;
725
726 unsigned int speed = CONFIG_SF_DEFAULT_SPEED;
727 unsigned int mode = CONFIG_SF_DEFAULT_MODE;
728
729 info = malloc(sizeof(struct spinand_info));
730 if (!info) {
731 fprintf(stderr, "Spinand out of memory. (%d bytes)\n",
732 sizeof(struct spinand_info));
733 ret = -ENOMEM;
734 goto err_alloc_info;
735 }
736 state = malloc(sizeof(struct nand_state));
737 if (!state) {
738 fprintf(stderr, "Spinand out of memory. (%d bytes)\n",
739 sizeof(struct nand_state));
740 ret = -ENOMEM;
741 goto err_alloc_state;
742 }
743 spi_nand = malloc(sizeof(struct spi_flash));
744 if (!spi_nand) {
745 fprintf(stderr, "Spinand out of memory (%d bytes)\n",
746 sizeof(struct spi_flash));
747 ret = -ENOMEM;
748 goto err_alloc_spinand;
749 }
750 spi = malloc(sizeof(struct spi_slave));
751 if (!spi) {
752 fprintf(stderr, "Spinand out of memory (%d bytes)\n",
753 sizeof(struct spi_slave));
754 ret = -ENOMEM;
755 goto err_alloc_spi;
756 }
757
758 info->priv = state;
759 state->buf_ptr = 0;
760 state->buf = malloc(BUFSIZE);
761 if (!state->buf) {
762 fprintf(stderr, "Spinand out of memory (%d bytes)\n",
763 BUFSIZE);
764 ret = -ENOMEM;
765 goto err_alloc_buf;
766 }
767
768 spi_init();
769 spi = spi_setup_slave(bus, CONFIG_SPINAND_CS, speed, mode);
770 if (!spi) {
771 printf("SF: Failed to set up slave\n");
772 ret = 1;
773 goto err_alloc;
774 }
775
776 ret = spi_claim_bus(spi);
777 if (ret) {
778 debug("SF: Failed to claim SPI bus: %d\n", ret);
779 ret = 1;
780 goto err_alloc;
781 }
782
783 spi_nand->spi = spi;
784 info->spi = spi_nand;
785 nand->priv = info;
786
787#ifdef CONFIG_MTD_SPINAND_ONDIEECC
788 nand->ecc.mode = NAND_ECC_HW;
789 nand->ecc.size = 0x200;
790 nand->ecc.bytes = 0x6;
791 nand->ecc.steps = 0x4;
792
793 nand->ecc.total = nand->ecc.steps * nand->ecc.bytes;
794 nand->ecc.layout = &spinand_oob_64;
795 nand->ecc.read_page = spinand_read_page_hwecc;
796 nand->ecc.write_page = spinand_write_page_hwecc;
797#else
798 nand->ecc.mode = NAND_ECC_NONE;
799 ret = spinand_disable_ecc(info->spi);
800#endif
801 nand->read_buf = spinand_read_buf;
802 nand->write_buf = spinand_write_buf;
803 nand->read_byte = spinand_read_byte;
804 nand->cmdfunc = spinand_cmdfunc;
805 nand->waitfunc = spinand_wait;
806 nand->options |= NAND_CACHEPRG;
807 nand->select_chip = spinand_select_chip;
808
809#ifdef CONFIG_BBM
810 nand->scan_bbt = pxa3xx_scan_bbt;
811 nand->block_markbad = pxa3xx_block_markbad;
812 nand->block_bad = pxa3xx_block_bad;
813#endif
814 return 0;
815err_alloc:
816 free(state->buf);
817err_alloc_buf:
818 free(spi);
819err_alloc_spi:
820 free(spi_nand);
821err_alloc_spinand:
822 free(state);
823err_alloc_state:
824 free(info);
825err_alloc_info:
826 return ret;
827}