configure: use consistent help text
[openocd.git] / src / flash / nand / at91sam9.c
blob4f0f6470ea38f2a8a54a425eb317e249dbf420c5
1 /*
2 * Copyright (C) 2009 by Dean Glazeski
3 * dnglaze@gmail.com
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 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
25 #include <target/arm.h>
26 #include <helper/log.h>
27 #include "imp.h"
28 #include "arm_io.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. */
38 /**
39 * Representation of a pin on an AT91SAM9 chip.
41 struct at91sam9_pin {
42 /** Address of the PIO controller. */
43 uint32_t pioc;
45 /** Pin number. */
46 uint32_t num;
49 /**
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. */
54 uint32_t ecc;
56 /** Address data is written to. */
57 uint32_t data;
59 /** Address commands are written to. */
60 uint32_t cmd;
62 /** Address addresses are written to. */
63 uint32_t addr;
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;
75 /**
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)
85 return true;
87 LOG_ERROR("Target must be halted to use NAND controller (%s)", label);
88 return false;
91 /**
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;
104 return ERROR_OK;
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
189 * controller.
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
208 * controller.
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;
236 uint32_t status;
238 if (!at91sam9_halted(target, "nand ready"))
239 return 0;
241 do {
242 target_read_u32(target, info->busy.pioc + AT91C_PIOx_PDSR, &status);
244 if (status & (1 << info->busy.num))
245 return 1;
247 alive_sleep(1);
248 } while (timeout-- > 0);
250 return 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;
266 int status;
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);
274 return status;
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;
290 int status;
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);
298 return status;
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)
310 if (!info->ecc) {
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)
331 if (!oob) {
332 /* user doesn't want OOB, allocate it */
333 if (nand->page_size == 512)
334 *size = 16;
335 else if (nand->page_size == 2048)
336 *size = 64;
338 oob = malloc(*size);
339 if (!oob) {
340 LOG_ERROR("Unable to allocate space for OOB");
341 return NULL;
344 memset(oob, 0xFF, *size);
347 return oob;
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)
366 int retval;
367 struct at91sam9_nand *info = nand->controller_priv;
368 struct target *target = nand->target;
369 uint8_t *oob_data;
370 uint32_t status;
372 retval = at91sam9_ecc_init(target, info);
373 if (ERROR_OK != retval)
374 return retval;
376 retval = nand_page_command(nand, page, NAND_CMD_READ0, !data);
377 if (ERROR_OK != retval)
378 return retval;
380 if (data) {
381 retval = nand_read_data_page(nand, data, data_size);
382 if (ERROR_OK != retval)
383 return 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);
390 if (status & 1) {
391 LOG_ERROR("Error detected!");
392 if (status & 4)
393 LOG_ERROR("Multiple errors encountered; unrecoverable!");
394 else {
395 /* attempt recovery */
396 uint32_t parity;
398 target_read_u32(target,
399 info->ecc + AT91C_ECCx_PR,
400 &parity);
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.",
406 (unsigned) word,
407 (unsigned) bit);
411 if (status & 2) {
412 /* we could write back correct ECC data */
413 LOG_ERROR("Error in ECC bytes detected");
417 if (!oob) {
418 /* if it wasn't asked for, free it */
419 free(oob_data);
422 return retval;
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;
443 int retval;
444 uint8_t *oob_data = oob;
445 uint32_t parity, nparity;
447 retval = at91sam9_ecc_init(target, info);
448 if (ERROR_OK != retval)
449 return retval;
451 retval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data);
452 if (ERROR_OK != retval)
453 return retval;
455 if (data) {
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");
459 return retval;
463 oob_data = at91sam9_oob_init(nand, oob, &oob_size);
465 if (!oob) {
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);
478 if (!oob)
479 free(oob_data);
481 if (ERROR_OK != retval) {
482 LOG_ERROR("Unable to write OOB data to NAND");
483 return retval;
486 retval = nand_write_finish(nand);
488 return retval;
492 * Handle the initial NAND device command for AT91SAM9 controllers. This
493 * initializes much of the controller information struct to be ready for future
494 * reads and writes.
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);
509 if (chip == 0) {
510 LOG_ERROR("invalid NAND chip address: %s", CMD_ARGV[2]);
511 return ERROR_NAND_OPERATION_FAILED;
514 if (CMD_ARGC == 4) {
515 COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[3], ecc);
516 if (ecc == 0) {
517 LOG_ERROR("invalid ECC controller address: %s", CMD_ARGV[3]);
518 return ERROR_NAND_OPERATION_FAILED;
522 info = calloc(1, sizeof(*info));
523 if (!info) {
524 LOG_ERROR("unable to allocate space for controller private data");
525 return ERROR_NAND_OPERATION_FAILED;
528 info->data = chip;
529 info->cmd = chip | (1 << 22);
530 info->addr = chip | (1 << 21);
531 info->ecc = ecc;
533 nand->controller_priv = info;
534 info->io.target = nand->target;
535 info->io.data = info->data;
536 info->io.op = ARM_NAND_NONE;
538 return ERROR_OK;
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;
551 if (CMD_ARGC != 2) {
552 command_print(CMD_CTX, "incorrect number of arguments for 'at91sam9 cle' command");
553 return ERROR_OK;
556 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
557 nand = get_nand_device_by_num(num);
558 if (!nand) {
559 command_print(CMD_CTX, "invalid nand device number: %s", CMD_ARGV[0]);
560 return ERROR_OK;
563 info = nand->controller_priv;
565 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], address_line);
566 info->cmd = info->data | (1 << address_line);
568 return ERROR_OK;
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;
581 if (CMD_ARGC != 2)
582 return ERROR_COMMAND_SYNTAX_ERROR;
584 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
585 nand = get_nand_device_by_num(num);
586 if (!nand) {
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);
596 return ERROR_OK;
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;
609 if (CMD_ARGC != 3)
610 return ERROR_COMMAND_SYNTAX_ERROR;
612 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
613 nand = get_nand_device_by_num(num);
614 if (!nand) {
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;
627 return ERROR_OK;
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;
640 if (CMD_ARGC != 3)
641 return ERROR_COMMAND_SYNTAX_ERROR;
643 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
644 nand = get_nand_device_by_num(num);
645 if (!nand) {
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;
658 return ERROR_OK;
661 static const struct command_registration at91sam9_sub_command_handlers[] = {
663 .name = "cle",
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",
670 .name = "ale",
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",
677 .name = "rdy_busy",
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",
685 .name = "ce",
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[] = {
697 .name = "at91sam9",
698 .mode = COMMAND_ANY,
699 .help = "AT91SAM9 NAND flash controller commands",
700 .usage = "",
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 = {
710 .name = "at91sam9",
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,