1 /* SPDX-License-Identifier: GPL-2.0-or-later */
4 * Copyright (C) 2009 by Dean Glazeski
12 #include <target/arm.h>
13 #include <helper/log.h>
17 #define AT91C_PIOX_SODR (0x30) /**< Offset to PIO SODR. */
18 #define AT91C_PIOX_CODR (0x34) /**< Offset to PIO CODR. */
19 #define AT91C_PIOX_PDSR (0x3C) /**< Offset to PIO PDSR. */
20 #define AT91C_ECCX_CR (0x00) /**< Offset to ECC CR. */
21 #define AT91C_ECCX_SR (0x08) /**< Offset to ECC SR. */
22 #define AT91C_ECCX_PR (0x0C) /**< Offset to ECC PR. */
23 #define AT91C_ECCX_NPR (0x10) /**< Offset to ECC NPR. */
26 * Representation of a pin on an AT91SAM9 chip.
29 /** Address of the PIO controller. */
37 * Private data for the controller that is stored in the NAND device structure.
39 struct at91sam9_nand
{
40 /** Address of the ECC controller for NAND. */
43 /** Address data is written to. */
46 /** Address commands are written to. */
49 /** Address addresses are written to. */
52 /** I/O structure for hosted reads/writes. */
53 struct arm_nand_data io
;
55 /** Pin representing the ready/~busy line. */
56 struct at91sam9_pin busy
;
58 /** Pin representing the chip enable. */
59 struct at91sam9_pin ce
;
63 * Checks if the target is halted and prints an error message if it isn't.
65 * @param target Target to be checked.
66 * @param label String label for where function is called from.
67 * @return True if the target is halted.
69 static int at91sam9_halted(struct target
*target
, const char *label
)
71 if (target
->state
== TARGET_HALTED
)
74 LOG_ERROR("Target must be halted to use NAND controller (%s)", label
);
79 * Initialize the AT91SAM9 NAND controller.
81 * @param nand NAND device the controller is attached to.
82 * @return Success or failure of initialization.
84 static int at91sam9_init(struct nand_device
*nand
)
86 struct target
*target
= nand
->target
;
88 if (!at91sam9_halted(target
, "init"))
89 return ERROR_NAND_OPERATION_FAILED
;
95 * Enable NAND device attached to a controller.
97 * @param nand NAND controller information for controlling NAND device.
98 * @return Success or failure of the enabling.
100 static int at91sam9_enable(struct nand_device
*nand
)
102 struct at91sam9_nand
*info
= nand
->controller_priv
;
103 struct target
*target
= nand
->target
;
105 return target_write_u32(target
, info
->ce
.pioc
+ AT91C_PIOX_CODR
, 1 << info
->ce
.num
);
109 * Disable NAND device attached to a controller.
111 * @param nand NAND controller information for controlling NAND device.
112 * @return Success or failure of the disabling.
114 static int at91sam9_disable(struct nand_device
*nand
)
116 struct at91sam9_nand
*info
= nand
->controller_priv
;
117 struct target
*target
= nand
->target
;
119 return target_write_u32(target
, info
->ce
.pioc
+ AT91C_PIOX_SODR
, 1 << info
->ce
.num
);
123 * Send a command to the NAND device.
125 * @param nand NAND device to write the command to.
126 * @param command Command to be written.
127 * @return Success or failure of writing the command.
129 static int at91sam9_command(struct nand_device
*nand
, uint8_t command
)
131 struct at91sam9_nand
*info
= nand
->controller_priv
;
132 struct target
*target
= nand
->target
;
134 if (!at91sam9_halted(target
, "command"))
135 return ERROR_NAND_OPERATION_FAILED
;
137 at91sam9_enable(nand
);
139 return target_write_u8(target
, info
->cmd
, command
);
143 * Reset the AT91SAM9 NAND controller.
145 * @param nand NAND device to be reset.
146 * @return Success or failure of reset.
148 static int at91sam9_reset(struct nand_device
*nand
)
150 if (!at91sam9_halted(nand
->target
, "reset"))
151 return ERROR_NAND_OPERATION_FAILED
;
153 return at91sam9_disable(nand
);
157 * Send an address to the NAND device attached to an AT91SAM9 NAND controller.
159 * @param nand NAND device to send the address to.
160 * @param address Address to be sent.
161 * @return Success or failure of sending the address.
163 static int at91sam9_address(struct nand_device
*nand
, uint8_t address
)
165 struct at91sam9_nand
*info
= nand
->controller_priv
;
166 struct target
*target
= nand
->target
;
168 if (!at91sam9_halted(nand
->target
, "address"))
169 return ERROR_NAND_OPERATION_FAILED
;
171 return target_write_u8(target
, info
->addr
, address
);
175 * Read data directly from the NAND device attached to an AT91SAM9 NAND
178 * @param nand NAND device to read from.
179 * @param data Pointer to where the data should be put.
180 * @return Success or failure of reading the data.
182 static int at91sam9_read_data(struct nand_device
*nand
, void *data
)
184 struct at91sam9_nand
*info
= nand
->controller_priv
;
185 struct target
*target
= nand
->target
;
187 if (!at91sam9_halted(nand
->target
, "read data"))
188 return ERROR_NAND_OPERATION_FAILED
;
190 return target_read_u8(target
, info
->data
, data
);
194 * Write data directly to the NAND device attached to an AT91SAM9 NAND
197 * @param nand NAND device to be written to.
198 * @param data Data to be written.
199 * @return Success or failure of the data write.
201 static int at91sam9_write_data(struct nand_device
*nand
, uint16_t data
)
203 struct at91sam9_nand
*info
= nand
->controller_priv
;
204 struct target
*target
= nand
->target
;
206 if (!at91sam9_halted(target
, "write data"))
207 return ERROR_NAND_OPERATION_FAILED
;
209 return target_write_u8(target
, info
->data
, data
);
213 * Determine if the NAND device is ready by looking at the ready/~busy pin.
215 * @param nand NAND device to check.
216 * @param timeout Time in milliseconds to wait for NAND to be ready.
217 * @return True if the NAND is ready in the timeout period.
219 static int at91sam9_nand_ready(struct nand_device
*nand
, int timeout
)
221 struct at91sam9_nand
*info
= nand
->controller_priv
;
222 struct target
*target
= nand
->target
;
225 if (!at91sam9_halted(target
, "nand ready"))
229 target_read_u32(target
, info
->busy
.pioc
+ AT91C_PIOX_PDSR
, &status
);
231 if (status
& (1 << info
->busy
.num
))
235 } while (timeout
-- > 0);
241 * Read a block of data from the NAND device attached to an AT91SAM9. This
242 * utilizes the ARM hosted NAND read function.
244 * @param nand NAND device to read from.
245 * @param data Pointer to where the read data should be placed.
246 * @param size Size of the data being read.
247 * @return Success or failure of the hosted read.
249 static int at91sam9_read_block_data(struct nand_device
*nand
, uint8_t *data
, int size
)
251 struct at91sam9_nand
*info
= nand
->controller_priv
;
252 struct arm_nand_data
*io
= &info
->io
;
255 if (!at91sam9_halted(nand
->target
, "read block"))
256 return ERROR_NAND_OPERATION_FAILED
;
258 io
->chunk_size
= nand
->page_size
;
259 status
= arm_nandread(io
, data
, size
);
265 * Write a block of data to a NAND device attached to an AT91SAM9. This uses
266 * the ARM hosted write function to write the data.
268 * @param nand NAND device to write to.
269 * @param data Data to be written to device.
270 * @param size Size of the data being written.
271 * @return Success or failure of the hosted write.
273 static int at91sam9_write_block_data(struct nand_device
*nand
, uint8_t *data
, int size
)
275 struct at91sam9_nand
*info
= nand
->controller_priv
;
276 struct arm_nand_data
*io
= &info
->io
;
279 if (!at91sam9_halted(nand
->target
, "write block"))
280 return ERROR_NAND_OPERATION_FAILED
;
282 io
->chunk_size
= nand
->page_size
;
283 status
= arm_nandwrite(io
, data
, size
);
289 * Initialize the ECC controller on the AT91SAM9.
291 * @param target Target to configure ECC on.
292 * @param info NAND controller information for where the ECC is.
293 * @return Success or failure of initialization.
295 static int at91sam9_ecc_init(struct target
*target
, struct at91sam9_nand
*info
)
298 LOG_ERROR("ECC controller address must be set when not reading raw NAND data");
299 return ERROR_NAND_OPERATION_FAILED
;
302 /* reset ECC parity registers */
303 return target_write_u32(target
, info
->ecc
+ AT91C_ECCX_CR
, 1);
307 * Initialize an area for the OOB based on whether a user is requesting the OOB
308 * data. This determines the size of the OOB and allocates the space in case
309 * the user has not requested the OOB data.
311 * @param nand NAND device we are creating an OOB for.
312 * @param oob Pointer to the user supplied OOB area.
313 * @param size Size of the OOB.
314 * @return Pointer to an area to store OOB data.
316 static uint8_t *at91sam9_oob_init(struct nand_device
*nand
, uint8_t *oob
, uint32_t *size
)
319 /* user doesn't want OOB, allocate it */
320 if (nand
->page_size
== 512)
322 else if (nand
->page_size
== 2048)
327 LOG_ERROR("Unable to allocate space for OOB");
331 memset(oob
, 0xFF, *size
);
338 * Reads a page from an AT91SAM9 NAND controller and verifies using 1-bit ECC
339 * controller on chip. This makes an attempt to correct any errors that are
340 * encountered while reading the page of data.
342 * @param nand NAND device to read from
343 * @param page Page to be read.
344 * @param data Pointer to where data should be read to.
345 * @param data_size Size of the data to be read.
346 * @param oob Pointer to where OOB data should be read to.
347 * @param oob_size Size of the OOB data to be read.
348 * @return Success or failure of reading the NAND page.
350 static int at91sam9_read_page(struct nand_device
*nand
, uint32_t page
,
351 uint8_t *data
, uint32_t data_size
, uint8_t *oob
, uint32_t oob_size
)
354 struct at91sam9_nand
*info
= nand
->controller_priv
;
355 struct target
*target
= nand
->target
;
359 retval
= at91sam9_ecc_init(target
, info
);
360 if (retval
!= ERROR_OK
)
363 retval
= nand_page_command(nand
, page
, NAND_CMD_READ0
, !data
);
364 if (retval
!= ERROR_OK
)
368 retval
= nand_read_data_page(nand
, data
, data_size
);
369 if (retval
!= ERROR_OK
)
373 oob_data
= at91sam9_oob_init(nand
, oob
, &oob_size
);
374 retval
= nand_read_data_page(nand
, oob_data
, oob_size
);
375 if (retval
== ERROR_OK
&& data
) {
376 target_read_u32(target
, info
->ecc
+ AT91C_ECCX_SR
, &status
);
378 LOG_ERROR("Error detected!");
380 LOG_ERROR("Multiple errors encountered; unrecoverable!");
382 /* attempt recovery */
385 target_read_u32(target
,
386 info
->ecc
+ AT91C_ECCX_PR
,
388 uint32_t word
= (parity
& 0x0000FFF0) >> 4;
389 uint32_t bit
= parity
& 0x0F;
391 data
[word
] ^= (0x1) << bit
;
392 LOG_INFO("Data word %d, bit %d corrected.",
399 /* we could write back correct ECC data */
400 LOG_ERROR("Error in ECC bytes detected");
405 /* if it wasn't asked for, free it */
413 * Write a page of data including 1-bit ECC information to a NAND device
414 * attached to an AT91SAM9 controller. If there is OOB data to be written,
415 * this will ignore the computed ECC from the ECC controller.
417 * @param nand NAND device to write to.
418 * @param page Page to write.
419 * @param data Pointer to data being written.
420 * @param data_size Size of the data being written.
421 * @param oob Pointer to OOB data being written.
422 * @param oob_size Size of the OOB data.
423 * @return Success or failure of the page write.
425 static int at91sam9_write_page(struct nand_device
*nand
, uint32_t page
,
426 uint8_t *data
, uint32_t data_size
, uint8_t *oob
, uint32_t oob_size
)
428 struct at91sam9_nand
*info
= nand
->controller_priv
;
429 struct target
*target
= nand
->target
;
431 uint8_t *oob_data
= oob
;
432 uint32_t parity
, nparity
;
434 retval
= at91sam9_ecc_init(target
, info
);
435 if (retval
!= ERROR_OK
)
438 retval
= nand_page_command(nand
, page
, NAND_CMD_SEQIN
, !data
);
439 if (retval
!= ERROR_OK
)
443 retval
= nand_write_data_page(nand
, data
, data_size
);
444 if (retval
!= ERROR_OK
) {
445 LOG_ERROR("Unable to write data to NAND device");
450 oob_data
= at91sam9_oob_init(nand
, oob
, &oob_size
);
453 /* no OOB given, so read in the ECC parity from the ECC controller */
454 target_read_u32(target
, info
->ecc
+ AT91C_ECCX_PR
, &parity
);
455 target_read_u32(target
, info
->ecc
+ AT91C_ECCX_NPR
, &nparity
);
457 oob_data
[0] = (uint8_t) parity
;
458 oob_data
[1] = (uint8_t) (parity
>> 8);
459 oob_data
[2] = (uint8_t) nparity
;
460 oob_data
[3] = (uint8_t) (nparity
>> 8);
463 retval
= nand_write_data_page(nand
, oob_data
, oob_size
);
468 if (retval
!= ERROR_OK
) {
469 LOG_ERROR("Unable to write OOB data to NAND");
473 retval
= nand_write_finish(nand
);
479 * Handle the initial NAND device command for AT91SAM9 controllers. This
480 * initializes much of the controller information struct to be ready for future
483 NAND_DEVICE_COMMAND_HANDLER(at91sam9_nand_device_command
)
485 unsigned long chip
= 0, ecc
= 0;
486 struct at91sam9_nand
*info
= NULL
;
488 LOG_DEBUG("AT91SAM9 NAND Device Command");
490 if (CMD_ARGC
< 3 || CMD_ARGC
> 4) {
491 LOG_ERROR("parameters: %s target chip_addr", CMD_ARGV
[0]);
492 return ERROR_NAND_OPERATION_FAILED
;
495 COMMAND_PARSE_NUMBER(ulong
, CMD_ARGV
[2], chip
);
497 LOG_ERROR("invalid NAND chip address: %s", CMD_ARGV
[2]);
498 return ERROR_NAND_OPERATION_FAILED
;
502 COMMAND_PARSE_NUMBER(ulong
, CMD_ARGV
[3], ecc
);
504 LOG_ERROR("invalid ECC controller address: %s", CMD_ARGV
[3]);
505 return ERROR_NAND_OPERATION_FAILED
;
509 info
= calloc(1, sizeof(*info
));
511 LOG_ERROR("unable to allocate space for controller private data");
512 return ERROR_NAND_OPERATION_FAILED
;
516 info
->cmd
= chip
| (1 << 22);
517 info
->addr
= chip
| (1 << 21);
520 nand
->controller_priv
= info
;
521 info
->io
.target
= nand
->target
;
522 info
->io
.data
= info
->data
;
523 info
->io
.op
= ARM_NAND_NONE
;
529 * Handle the AT91SAM9 CLE command for specifying the address line to use for
530 * writing commands to a NAND device.
532 COMMAND_HANDLER(handle_at91sam9_cle_command
)
534 struct nand_device
*nand
= NULL
;
535 struct at91sam9_nand
*info
= NULL
;
536 unsigned num
, address_line
;
539 command_print(CMD
, "incorrect number of arguments for 'at91sam9 cle' command");
543 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], num
);
544 nand
= get_nand_device_by_num(num
);
546 command_print(CMD
, "invalid nand device number: %s", CMD_ARGV
[0]);
550 info
= nand
->controller_priv
;
552 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[1], address_line
);
553 info
->cmd
= info
->data
| (1 << address_line
);
559 * Handle the AT91SAM9 ALE command for specifying the address line to use for
560 * writing addresses to the NAND device.
562 COMMAND_HANDLER(handle_at91sam9_ale_command
)
564 struct nand_device
*nand
= NULL
;
565 struct at91sam9_nand
*info
= NULL
;
566 unsigned num
, address_line
;
569 return ERROR_COMMAND_SYNTAX_ERROR
;
571 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], num
);
572 nand
= get_nand_device_by_num(num
);
574 command_print(CMD
, "invalid nand device number: %s", CMD_ARGV
[0]);
575 return ERROR_COMMAND_ARGUMENT_INVALID
;
578 info
= nand
->controller_priv
;
580 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[1], address_line
);
581 info
->addr
= info
->data
| (1 << address_line
);
587 * Handle the AT91SAM9 RDY/~BUSY command for specifying the pin that watches the
588 * RDY/~BUSY line from the NAND device.
590 COMMAND_HANDLER(handle_at91sam9_rdy_busy_command
)
592 struct nand_device
*nand
= NULL
;
593 struct at91sam9_nand
*info
= NULL
;
594 unsigned num
, base_pioc
, pin_num
;
597 return ERROR_COMMAND_SYNTAX_ERROR
;
599 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], num
);
600 nand
= get_nand_device_by_num(num
);
602 command_print(CMD
, "invalid nand device number: %s", CMD_ARGV
[0]);
603 return ERROR_COMMAND_ARGUMENT_INVALID
;
606 info
= nand
->controller_priv
;
608 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[1], base_pioc
);
609 info
->busy
.pioc
= base_pioc
;
611 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[2], pin_num
);
612 info
->busy
.num
= pin_num
;
618 * Handle the AT91SAM9 CE command for specifying the pin that is used to enable
619 * or disable the NAND device.
621 COMMAND_HANDLER(handle_at91sam9_ce_command
)
623 struct nand_device
*nand
= NULL
;
624 struct at91sam9_nand
*info
= NULL
;
625 unsigned num
, base_pioc
, pin_num
;
628 return ERROR_COMMAND_SYNTAX_ERROR
;
630 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], num
);
631 nand
= get_nand_device_by_num(num
);
633 command_print(CMD
, "invalid nand device number: %s", CMD_ARGV
[0]);
634 return ERROR_COMMAND_ARGUMENT_INVALID
;
637 info
= nand
->controller_priv
;
639 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[1], base_pioc
);
640 info
->ce
.pioc
= base_pioc
;
642 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[2], pin_num
);
643 info
->ce
.num
= pin_num
;
648 static const struct command_registration at91sam9_sub_command_handlers
[] = {
651 .handler
= handle_at91sam9_cle_command
,
652 .mode
= COMMAND_CONFIG
,
653 .help
= "set command latch enable address line (default is 22)",
654 .usage
= "bank_id address_line",
658 .handler
= handle_at91sam9_ale_command
,
659 .mode
= COMMAND_CONFIG
,
660 .help
= "set address latch enable address line (default is 21)",
661 .usage
= "bank_id address_line",
665 .handler
= handle_at91sam9_rdy_busy_command
,
666 .mode
= COMMAND_CONFIG
,
667 .help
= "set the GPIO input pin connected to "
668 "the RDY/~BUSY signal (no default)",
669 .usage
= "bank_id pio_base_addr pin_num",
673 .handler
= handle_at91sam9_ce_command
,
674 .mode
= COMMAND_CONFIG
,
675 .help
= "set the GPIO output pin connected to "
676 "the chip enable signal (no default)",
677 .usage
= "bank_id pio_base_addr pin_num",
679 COMMAND_REGISTRATION_DONE
682 static const struct command_registration at91sam9_command_handler
[] = {
686 .help
= "AT91SAM9 NAND flash controller commands",
688 .chain
= at91sam9_sub_command_handlers
,
690 COMMAND_REGISTRATION_DONE
694 * Structure representing the AT91SAM9 NAND controller.
696 struct nand_flash_controller at91sam9_nand_controller
= {
698 .nand_device_command
= at91sam9_nand_device_command
,
699 .commands
= at91sam9_command_handler
,
700 .init
= at91sam9_init
,
701 .command
= at91sam9_command
,
702 .reset
= at91sam9_reset
,
703 .address
= at91sam9_address
,
704 .read_data
= at91sam9_read_data
,
705 .write_data
= at91sam9_write_data
,
706 .nand_ready
= at91sam9_nand_ready
,
707 .read_block_data
= at91sam9_read_block_data
,
708 .write_block_data
= at91sam9_write_block_data
,
709 .read_page
= at91sam9_read_page
,
710 .write_page
= at91sam9_write_page
,