2 * Copyright (C) 2009 by Dean Glazeski
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the
17 * Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include <target/arm.h>
26 #include <helper/log.h>
30 #define AT91C_PIOx_SODR (0x30) /**< Offset to PIO SODR. */
31 #define AT91C_PIOx_CODR (0x34) /**< Offset to PIO CODR. */
32 #define AT91C_PIOx_PDSR (0x3C) /**< Offset to PIO PDSR. */
33 #define AT91C_ECCx_CR (0x00) /**< Offset to ECC CR. */
34 #define AT91C_ECCx_SR (0x08) /**< Offset to ECC SR. */
35 #define AT91C_ECCx_PR (0x0C) /**< Offset to ECC PR. */
36 #define AT91C_ECCx_NPR (0x10) /**< Offset to ECC NPR. */
39 * Representation of a pin on an AT91SAM9 chip.
42 /** Address of the PIO controller. */
50 * Private data for the controller that is stored in the NAND device structure.
52 struct at91sam9_nand
{
53 /** Address of the ECC controller for NAND. */
56 /** Address data is written to. */
59 /** Address commands are written to. */
62 /** Address addresses are written to. */
65 /** I/O structure for hosted reads/writes. */
66 struct arm_nand_data io
;
68 /** Pin representing the ready/~busy line. */
69 struct at91sam9_pin busy
;
71 /** Pin representing the chip enable. */
72 struct at91sam9_pin ce
;
76 * Checks if the target is halted and prints an error message if it isn't.
78 * @param target Target to be checked.
79 * @param label String label for where function is called from.
80 * @return True if the target is halted.
82 static int at91sam9_halted(struct target
*target
, const char *label
)
84 if (target
->state
== TARGET_HALTED
)
87 LOG_ERROR("Target must be halted to use NAND controller (%s)", label
);
92 * Initialize the AT91SAM9 NAND controller.
94 * @param nand NAND device the controller is attached to.
95 * @return Success or failure of initialization.
97 static int at91sam9_init(struct nand_device
*nand
)
99 struct target
*target
= nand
->target
;
101 if (!at91sam9_halted(target
, "init"))
102 return ERROR_NAND_OPERATION_FAILED
;
108 * Enable NAND device attached to a controller.
110 * @param info NAND controller information for controlling NAND device.
111 * @return Success or failure of the enabling.
113 static int at91sam9_enable(struct nand_device
*nand
)
115 struct at91sam9_nand
*info
= nand
->controller_priv
;
116 struct target
*target
= nand
->target
;
118 return target_write_u32(target
, info
->ce
.pioc
+ AT91C_PIOx_CODR
, 1 << info
->ce
.num
);
122 * Disable NAND device attached to a controller.
124 * @param info NAND controller information for controlling NAND device.
125 * @return Success or failure of the disabling.
127 static int at91sam9_disable(struct nand_device
*nand
)
129 struct at91sam9_nand
*info
= nand
->controller_priv
;
130 struct target
*target
= nand
->target
;
132 return target_write_u32(target
, info
->ce
.pioc
+ AT91C_PIOx_SODR
, 1 << info
->ce
.num
);
136 * Send a command to the NAND device.
138 * @param nand NAND device to write the command to.
139 * @param command Command to be written.
140 * @return Success or failure of writing the command.
142 static int at91sam9_command(struct nand_device
*nand
, uint8_t command
)
144 struct at91sam9_nand
*info
= nand
->controller_priv
;
145 struct target
*target
= nand
->target
;
147 if (!at91sam9_halted(target
, "command"))
148 return ERROR_NAND_OPERATION_FAILED
;
150 at91sam9_enable(nand
);
152 return target_write_u8(target
, info
->cmd
, command
);
156 * Reset the AT91SAM9 NAND controller.
158 * @param nand NAND device to be reset.
159 * @return Success or failure of reset.
161 static int at91sam9_reset(struct nand_device
*nand
)
163 if (!at91sam9_halted(nand
->target
, "reset"))
164 return ERROR_NAND_OPERATION_FAILED
;
166 return at91sam9_disable(nand
);
170 * Send an address to the NAND device attached to an AT91SAM9 NAND controller.
172 * @param nand NAND device to send the address to.
173 * @param address Address to be sent.
174 * @return Success or failure of sending the address.
176 static int at91sam9_address(struct nand_device
*nand
, uint8_t address
)
178 struct at91sam9_nand
*info
= nand
->controller_priv
;
179 struct target
*target
= nand
->target
;
181 if (!at91sam9_halted(nand
->target
, "address"))
182 return ERROR_NAND_OPERATION_FAILED
;
184 return target_write_u8(target
, info
->addr
, address
);
188 * Read data directly from the NAND device attached to an AT91SAM9 NAND
191 * @param nand NAND device to read from.
192 * @param data Pointer to where the data should be put.
193 * @return Success or failure of reading the data.
195 static int at91sam9_read_data(struct nand_device
*nand
, void *data
)
197 struct at91sam9_nand
*info
= nand
->controller_priv
;
198 struct target
*target
= nand
->target
;
200 if (!at91sam9_halted(nand
->target
, "read data"))
201 return ERROR_NAND_OPERATION_FAILED
;
203 return target_read_u8(target
, info
->data
, data
);
207 * Write data directly to the NAND device attached to an AT91SAM9 NAND
210 * @param nand NAND device to be written to.
211 * @param data Data to be written.
212 * @return Success or failure of the data write.
214 static int at91sam9_write_data(struct nand_device
*nand
, uint16_t data
)
216 struct at91sam9_nand
*info
= nand
->controller_priv
;
217 struct target
*target
= nand
->target
;
219 if (!at91sam9_halted(target
, "write data"))
220 return ERROR_NAND_OPERATION_FAILED
;
222 return target_write_u8(target
, info
->data
, data
);
226 * Determine if the NAND device is ready by looking at the ready/~busy pin.
228 * @param nand NAND device to check.
229 * @param timeout Time in milliseconds to wait for NAND to be ready.
230 * @return True if the NAND is ready in the timeout period.
232 static int at91sam9_nand_ready(struct nand_device
*nand
, int timeout
)
234 struct at91sam9_nand
*info
= nand
->controller_priv
;
235 struct target
*target
= nand
->target
;
238 if (!at91sam9_halted(target
, "nand ready"))
242 target_read_u32(target
, info
->busy
.pioc
+ AT91C_PIOx_PDSR
, &status
);
244 if (status
& (1 << info
->busy
.num
))
248 } while (timeout
-- > 0);
254 * Read a block of data from the NAND device attached to an AT91SAM9. This
255 * utilizes the ARM hosted NAND read function.
257 * @param nand NAND device to read from.
258 * @param data Pointer to where the read data should be placed.
259 * @param size Size of the data being read.
260 * @return Success or failure of the hosted read.
262 static int at91sam9_read_block_data(struct nand_device
*nand
, uint8_t *data
, int size
)
264 struct at91sam9_nand
*info
= nand
->controller_priv
;
265 struct arm_nand_data
*io
= &info
->io
;
268 if (!at91sam9_halted(nand
->target
, "read block"))
269 return ERROR_NAND_OPERATION_FAILED
;
271 io
->chunk_size
= nand
->page_size
;
272 status
= arm_nandread(io
, data
, size
);
278 * Write a block of data to a NAND device attached to an AT91SAM9. This uses
279 * the ARM hosted write function to write the data.
281 * @param nand NAND device to write to.
282 * @param data Data to be written to device.
283 * @param size Size of the data being written.
284 * @return Success or failure of the hosted write.
286 static int at91sam9_write_block_data(struct nand_device
*nand
, uint8_t *data
, int size
)
288 struct at91sam9_nand
*info
= nand
->controller_priv
;
289 struct arm_nand_data
*io
= &info
->io
;
292 if (!at91sam9_halted(nand
->target
, "write block"))
293 return ERROR_NAND_OPERATION_FAILED
;
295 io
->chunk_size
= nand
->page_size
;
296 status
= arm_nandwrite(io
, data
, size
);
302 * Initialize the ECC controller on the AT91SAM9.
304 * @param target Target to configure ECC on.
305 * @param info NAND controller information for where the ECC is.
306 * @return Success or failure of initialization.
308 static int at91sam9_ecc_init(struct target
*target
, struct at91sam9_nand
*info
)
311 LOG_ERROR("ECC controller address must be set when not reading raw NAND data");
312 return ERROR_NAND_OPERATION_FAILED
;
315 /* reset ECC parity registers */
316 return target_write_u32(target
, info
->ecc
+ AT91C_ECCx_CR
, 1);
320 * Initialize an area for the OOB based on whether a user is requesting the OOB
321 * data. This determines the size of the OOB and allocates the space in case
322 * the user has not requested the OOB data.
324 * @param nand NAND device we are creating an OOB for.
325 * @param oob Pointer to the user supplied OOB area.
326 * @param size Size of the OOB.
327 * @return Pointer to an area to store OOB data.
329 static uint8_t *at91sam9_oob_init(struct nand_device
*nand
, uint8_t *oob
, uint32_t *size
)
332 /* user doesn't want OOB, allocate it */
333 if (nand
->page_size
== 512)
335 else if (nand
->page_size
== 2048)
340 LOG_ERROR("Unable to allocate space for OOB");
344 memset(oob
, 0xFF, *size
);
351 * Reads a page from an AT91SAM9 NAND controller and verifies using 1-bit ECC
352 * controller on chip. This makes an attempt to correct any errors that are
353 * encountered while reading the page of data.
355 * @param nand NAND device to read from
356 * @param page Page to be read.
357 * @param data Pointer to where data should be read to.
358 * @param data_size Size of the data to be read.
359 * @param oob Pointer to where OOB data should be read to.
360 * @param oob_size Size of the OOB data to be read.
361 * @return Success or failure of reading the NAND page.
363 static int at91sam9_read_page(struct nand_device
*nand
, uint32_t page
,
364 uint8_t *data
, uint32_t data_size
, uint8_t *oob
, uint32_t oob_size
)
367 struct at91sam9_nand
*info
= nand
->controller_priv
;
368 struct target
*target
= nand
->target
;
372 retval
= at91sam9_ecc_init(target
, info
);
373 if (ERROR_OK
!= retval
)
376 retval
= nand_page_command(nand
, page
, NAND_CMD_READ0
, !data
);
377 if (ERROR_OK
!= retval
)
381 retval
= nand_read_data_page(nand
, data
, data_size
);
382 if (ERROR_OK
!= retval
)
386 oob_data
= at91sam9_oob_init(nand
, oob
, &oob_size
);
387 retval
= nand_read_data_page(nand
, oob_data
, oob_size
);
388 if (ERROR_OK
== retval
&& data
) {
389 target_read_u32(target
, info
->ecc
+ AT91C_ECCx_SR
, &status
);
391 LOG_ERROR("Error detected!");
393 LOG_ERROR("Multiple errors encountered; unrecoverable!");
395 /* attempt recovery */
398 target_read_u32(target
,
399 info
->ecc
+ AT91C_ECCx_PR
,
401 uint32_t word
= (parity
& 0x0000FFF0) >> 4;
402 uint32_t bit
= parity
& 0x0F;
404 data
[word
] ^= (0x1) << bit
;
405 LOG_INFO("Data word %d, bit %d corrected.",
412 /* we could write back correct ECC data */
413 LOG_ERROR("Error in ECC bytes detected");
418 /* if it wasn't asked for, free it */
426 * Write a page of data including 1-bit ECC information to a NAND device
427 * attached to an AT91SAM9 controller. If there is OOB data to be written,
428 * this will ignore the computed ECC from the ECC controller.
430 * @param nand NAND device to write to.
431 * @param page Page to write.
432 * @param data Pointer to data being written.
433 * @param data_size Size of the data being written.
434 * @param oob Pointer to OOB data being written.
435 * @param oob_size Size of the OOB data.
436 * @return Success or failure of the page write.
438 static int at91sam9_write_page(struct nand_device
*nand
, uint32_t page
,
439 uint8_t *data
, uint32_t data_size
, uint8_t *oob
, uint32_t oob_size
)
441 struct at91sam9_nand
*info
= nand
->controller_priv
;
442 struct target
*target
= nand
->target
;
444 uint8_t *oob_data
= oob
;
445 uint32_t parity
, nparity
;
447 retval
= at91sam9_ecc_init(target
, info
);
448 if (ERROR_OK
!= retval
)
451 retval
= nand_page_command(nand
, page
, NAND_CMD_SEQIN
, !data
);
452 if (ERROR_OK
!= retval
)
456 retval
= nand_write_data_page(nand
, data
, data_size
);
457 if (ERROR_OK
!= retval
) {
458 LOG_ERROR("Unable to write data to NAND device");
463 oob_data
= at91sam9_oob_init(nand
, oob
, &oob_size
);
466 /* no OOB given, so read in the ECC parity from the ECC controller */
467 target_read_u32(target
, info
->ecc
+ AT91C_ECCx_PR
, &parity
);
468 target_read_u32(target
, info
->ecc
+ AT91C_ECCx_NPR
, &nparity
);
470 oob_data
[0] = (uint8_t) parity
;
471 oob_data
[1] = (uint8_t) (parity
>> 8);
472 oob_data
[2] = (uint8_t) nparity
;
473 oob_data
[3] = (uint8_t) (nparity
>> 8);
476 retval
= nand_write_data_page(nand
, oob_data
, oob_size
);
481 if (ERROR_OK
!= retval
) {
482 LOG_ERROR("Unable to write OOB data to NAND");
486 retval
= nand_write_finish(nand
);
492 * Handle the initial NAND device command for AT91SAM9 controllers. This
493 * initializes much of the controller information struct to be ready for future
496 NAND_DEVICE_COMMAND_HANDLER(at91sam9_nand_device_command
)
498 unsigned long chip
= 0, ecc
= 0;
499 struct at91sam9_nand
*info
= NULL
;
501 LOG_DEBUG("AT91SAM9 NAND Device Command");
503 if (CMD_ARGC
< 3 || CMD_ARGC
> 4) {
504 LOG_ERROR("parameters: %s target chip_addr", CMD_ARGV
[0]);
505 return ERROR_NAND_OPERATION_FAILED
;
508 COMMAND_PARSE_NUMBER(ulong
, CMD_ARGV
[2], chip
);
510 LOG_ERROR("invalid NAND chip address: %s", CMD_ARGV
[2]);
511 return ERROR_NAND_OPERATION_FAILED
;
515 COMMAND_PARSE_NUMBER(ulong
, CMD_ARGV
[3], ecc
);
517 LOG_ERROR("invalid ECC controller address: %s", CMD_ARGV
[3]);
518 return ERROR_NAND_OPERATION_FAILED
;
522 info
= calloc(1, sizeof(*info
));
524 LOG_ERROR("unable to allocate space for controller private data");
525 return ERROR_NAND_OPERATION_FAILED
;
529 info
->cmd
= chip
| (1 << 22);
530 info
->addr
= chip
| (1 << 21);
533 nand
->controller_priv
= info
;
534 info
->io
.target
= nand
->target
;
535 info
->io
.data
= info
->data
;
536 info
->io
.op
= ARM_NAND_NONE
;
542 * Handle the AT91SAM9 CLE command for specifying the address line to use for
543 * writing commands to a NAND device.
545 COMMAND_HANDLER(handle_at91sam9_cle_command
)
547 struct nand_device
*nand
= NULL
;
548 struct at91sam9_nand
*info
= NULL
;
549 unsigned num
, address_line
;
552 command_print(CMD_CTX
, "incorrect number of arguments for 'at91sam9 cle' command");
556 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], num
);
557 nand
= get_nand_device_by_num(num
);
559 command_print(CMD_CTX
, "invalid nand device number: %s", CMD_ARGV
[0]);
563 info
= nand
->controller_priv
;
565 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[1], address_line
);
566 info
->cmd
= info
->data
| (1 << address_line
);
572 * Handle the AT91SAM9 ALE command for specifying the address line to use for
573 * writing addresses to the NAND device.
575 COMMAND_HANDLER(handle_at91sam9_ale_command
)
577 struct nand_device
*nand
= NULL
;
578 struct at91sam9_nand
*info
= NULL
;
579 unsigned num
, address_line
;
582 return ERROR_COMMAND_SYNTAX_ERROR
;
584 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], num
);
585 nand
= get_nand_device_by_num(num
);
587 command_print(CMD_CTX
, "invalid nand device number: %s", CMD_ARGV
[0]);
588 return ERROR_COMMAND_ARGUMENT_INVALID
;
591 info
= nand
->controller_priv
;
593 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[1], address_line
);
594 info
->addr
= info
->data
| (1 << address_line
);
600 * Handle the AT91SAM9 RDY/~BUSY command for specifying the pin that watches the
601 * RDY/~BUSY line from the NAND device.
603 COMMAND_HANDLER(handle_at91sam9_rdy_busy_command
)
605 struct nand_device
*nand
= NULL
;
606 struct at91sam9_nand
*info
= NULL
;
607 unsigned num
, base_pioc
, pin_num
;
610 return ERROR_COMMAND_SYNTAX_ERROR
;
612 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], num
);
613 nand
= get_nand_device_by_num(num
);
615 command_print(CMD_CTX
, "invalid nand device number: %s", CMD_ARGV
[0]);
616 return ERROR_COMMAND_ARGUMENT_INVALID
;
619 info
= nand
->controller_priv
;
621 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[1], base_pioc
);
622 info
->busy
.pioc
= base_pioc
;
624 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[2], pin_num
);
625 info
->busy
.num
= pin_num
;
631 * Handle the AT91SAM9 CE command for specifying the pin that is used to enable
632 * or disable the NAND device.
634 COMMAND_HANDLER(handle_at91sam9_ce_command
)
636 struct nand_device
*nand
= NULL
;
637 struct at91sam9_nand
*info
= NULL
;
638 unsigned num
, base_pioc
, pin_num
;
641 return ERROR_COMMAND_SYNTAX_ERROR
;
643 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], num
);
644 nand
= get_nand_device_by_num(num
);
646 command_print(CMD_CTX
, "invalid nand device number: %s", CMD_ARGV
[0]);
647 return ERROR_COMMAND_ARGUMENT_INVALID
;
650 info
= nand
->controller_priv
;
652 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[1], base_pioc
);
653 info
->ce
.pioc
= base_pioc
;
655 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[2], pin_num
);
656 info
->ce
.num
= pin_num
;
661 static const struct command_registration at91sam9_sub_command_handlers
[] = {
664 .handler
= handle_at91sam9_cle_command
,
665 .mode
= COMMAND_CONFIG
,
666 .help
= "set command latch enable address line (default is 22)",
667 .usage
= "bank_id address_line",
671 .handler
= handle_at91sam9_ale_command
,
672 .mode
= COMMAND_CONFIG
,
673 .help
= "set address latch enable address line (default is 21)",
674 .usage
= "bank_id address_line",
678 .handler
= handle_at91sam9_rdy_busy_command
,
679 .mode
= COMMAND_CONFIG
,
680 .help
= "set the GPIO input pin connected to "
681 "the RDY/~BUSY signal (no default)",
682 .usage
= "bank_id pio_base_addr pin_num",
686 .handler
= handle_at91sam9_ce_command
,
687 .mode
= COMMAND_CONFIG
,
688 .help
= "set the GPIO output pin connected to "
689 "the chip enable signal (no default)",
690 .usage
= "bank_id pio_base_addr pin_num",
692 COMMAND_REGISTRATION_DONE
695 static const struct command_registration at91sam9_command_handler
[] = {
699 .help
= "AT91SAM9 NAND flash controller commands",
701 .chain
= at91sam9_sub_command_handlers
,
703 COMMAND_REGISTRATION_DONE
707 * Structure representing the AT91SAM9 NAND controller.
709 struct nand_flash_controller at91sam9_nand_controller
= {
711 .nand_device_command
= at91sam9_nand_device_command
,
712 .commands
= at91sam9_command_handler
,
713 .init
= at91sam9_init
,
714 .command
= at91sam9_command
,
715 .reset
= at91sam9_reset
,
716 .address
= at91sam9_address
,
717 .read_data
= at91sam9_read_data
,
718 .write_data
= at91sam9_write_data
,
719 .nand_ready
= at91sam9_nand_ready
,
720 .read_block_data
= at91sam9_read_block_data
,
721 .write_block_data
= at91sam9_write_block_data
,
722 .read_page
= at91sam9_read_page
,
723 .write_page
= at91sam9_write_page
,