update files to correct FSF address
[openocd.git] / src / flash / nand / at91sam9.c
index 7cfd763a8b157d350fbe047b8d55c56e2a1f48a6..3f4e5e277b0f981e7f435e0e085c14a3fb1b9d84 100644 (file)
@@ -15,8 +15,9 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the
  * Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 #include "imp.h"
 #include "arm_io.h"
 
-#define AT91C_PIOx_SODR (0x30) /**< Offset to PIO SODR. */
-#define AT91C_PIOx_CODR (0x34) /**< Offset to PIO CODR. */
-#define AT91C_PIOx_PDSR (0x3C) /**< Offset to PIO PDSR. */
-#define AT91C_ECCx_CR (0x00) /**< Offset to ECC CR. */
-#define AT91C_ECCx_SR (0x08) /**< Offset to ECC SR. */
-#define AT91C_ECCx_PR (0x0C) /**< Offset to ECC PR. */
-#define AT91C_ECCx_NPR (0x10) /**< Offset to ECC NPR. */
+#define AT91C_PIOx_SODR (0x30) /**< Offset to PIO SODR. */
+#define AT91C_PIOx_CODR (0x34) /**< Offset to PIO CODR. */
+#define AT91C_PIOx_PDSR (0x3C) /**< Offset to PIO PDSR. */
+#define AT91C_ECCx_CR (0x00)   /**< Offset to ECC CR. */
+#define AT91C_ECCx_SR (0x08)   /**< Offset to ECC SR. */
+#define AT91C_ECCx_PR (0x0C)   /**< Offset to ECC PR. */
+#define AT91C_ECCx_NPR (0x10)  /**< Offset to ECC NPR. */
 
 /**
  * Representation of a pin on an AT91SAM9 chip.
  */
 struct at91sam9_pin {
-       /** Target this pin is on. */
-       struct target *target;
-
        /** Address of the PIO controller. */
        uint32_t pioc;
 
@@ -52,9 +50,6 @@ struct at91sam9_pin {
  * Private data for the controller that is stored in the NAND device structure.
  */
 struct at91sam9_nand {
-       /** Target the NAND is attached to. */
-       struct target *target;
-
        /** Address of the ECC controller for NAND. */
        uint32_t ecc;
 
@@ -101,12 +96,10 @@ static int at91sam9_halted(struct target *target, const char *label)
  */
 static int at91sam9_init(struct nand_device *nand)
 {
-       struct at91sam9_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
 
-       if (!at91sam9_halted(target, "init")) {
+       if (!at91sam9_halted(target, "init"))
                return ERROR_NAND_OPERATION_FAILED;
-       }
 
        return ERROR_OK;
 }
@@ -117,9 +110,10 @@ static int at91sam9_init(struct nand_device *nand)
  * @param info NAND controller information for controlling NAND device.
  * @return Success or failure of the enabling.
  */
-static int at91sam9_enable(struct at91sam9_nand *info)
+static int at91sam9_enable(struct nand_device *nand)
 {
-       struct target *target = info->target;
+       struct at91sam9_nand *info = nand->controller_priv;
+       struct target *target = nand->target;
 
        return target_write_u32(target, info->ce.pioc + AT91C_PIOx_CODR, 1 << info->ce.num);
 }
@@ -130,9 +124,10 @@ static int at91sam9_enable(struct at91sam9_nand *info)
  * @param info NAND controller information for controlling NAND device.
  * @return Success or failure of the disabling.
  */
-static int at91sam9_disable(struct at91sam9_nand *info)
+static int at91sam9_disable(struct nand_device *nand)
 {
-       struct target *target = info->target;
+       struct at91sam9_nand *info = nand->controller_priv;
+       struct target *target = nand->target;
 
        return target_write_u32(target, info->ce.pioc + AT91C_PIOx_SODR, 1 << info->ce.num);
 }
@@ -147,13 +142,12 @@ static int at91sam9_disable(struct at91sam9_nand *info)
 static int at91sam9_command(struct nand_device *nand, uint8_t command)
 {
        struct at91sam9_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
 
-       if (!at91sam9_halted(target, "command")) {
+       if (!at91sam9_halted(target, "command"))
                return ERROR_NAND_OPERATION_FAILED;
-       }
 
-       at91sam9_enable(info);
+       at91sam9_enable(nand);
 
        return target_write_u8(target, info->cmd, command);
 }
@@ -166,13 +160,10 @@ static int at91sam9_command(struct nand_device *nand, uint8_t command)
  */
 static int at91sam9_reset(struct nand_device *nand)
 {
-       struct at91sam9_nand *info = nand->controller_priv;
-
-       if (!at91sam9_halted(info->target, "reset")) {
+       if (!at91sam9_halted(nand->target, "reset"))
                return ERROR_NAND_OPERATION_FAILED;
-       }
 
-       return at91sam9_disable(info);
+       return at91sam9_disable(nand);
 }
 
 /**
@@ -185,11 +176,10 @@ static int at91sam9_reset(struct nand_device *nand)
 static int at91sam9_address(struct nand_device *nand, uint8_t address)
 {
        struct at91sam9_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
 
-       if (!at91sam9_halted(info->target, "address")) {
+       if (!at91sam9_halted(nand->target, "address"))
                return ERROR_NAND_OPERATION_FAILED;
-       }
 
        return target_write_u8(target, info->addr, address);
 }
@@ -205,11 +195,10 @@ static int at91sam9_address(struct nand_device *nand, uint8_t address)
 static int at91sam9_read_data(struct nand_device *nand, void *data)
 {
        struct at91sam9_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
 
-       if (!at91sam9_halted(info->target, "read data")) {
+       if (!at91sam9_halted(nand->target, "read data"))
                return ERROR_NAND_OPERATION_FAILED;
-       }
 
        return target_read_u8(target, info->data, data);
 }
@@ -225,11 +214,10 @@ static int at91sam9_read_data(struct nand_device *nand, void *data)
 static int at91sam9_write_data(struct nand_device *nand, uint16_t data)
 {
        struct at91sam9_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
 
-       if (!at91sam9_halted(target, "write data")) {
+       if (!at91sam9_halted(target, "write data"))
                return ERROR_NAND_OPERATION_FAILED;
-       }
 
        return target_write_u8(target, info->data, data);
 }
@@ -244,19 +232,17 @@ static int at91sam9_write_data(struct nand_device *nand, uint16_t data)
 static int at91sam9_nand_ready(struct nand_device *nand, int timeout)
 {
        struct at91sam9_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
        uint32_t status;
 
-       if (!at91sam9_halted(target, "nand ready")) {
+       if (!at91sam9_halted(target, "nand ready"))
                return 0;
-       }
 
        do {
                target_read_u32(target, info->busy.pioc + AT91C_PIOx_PDSR, &status);
 
-               if (status & (1 << info->busy.num)) {
+               if (status & (1 << info->busy.num))
                        return 1;
-               }
 
                alive_sleep(1);
        } while (timeout-- > 0);
@@ -279,9 +265,8 @@ static int at91sam9_read_block_data(struct nand_device *nand, uint8_t *data, int
        struct arm_nand_data *io = &info->io;
        int status;
 
-       if (!at91sam9_halted(info->target, "read block")) {
+       if (!at91sam9_halted(nand->target, "read block"))
                return ERROR_NAND_OPERATION_FAILED;
-       }
 
        io->chunk_size = nand->page_size;
        status = arm_nandread(io, data, size);
@@ -304,9 +289,8 @@ static int at91sam9_write_block_data(struct nand_device *nand, uint8_t *data, in
        struct arm_nand_data *io = &info->io;
        int status;
 
-       if (!at91sam9_halted(info->target, "write block")) {
+       if (!at91sam9_halted(nand->target, "write block"))
                return ERROR_NAND_OPERATION_FAILED;
-       }
 
        io->chunk_size = nand->page_size;
        status = arm_nandwrite(io, data, size);
@@ -328,7 +312,7 @@ static int at91sam9_ecc_init(struct target *target, struct at91sam9_nand *info)
                return ERROR_NAND_OPERATION_FAILED;
        }
 
-       // reset ECC parity registers
+       /* reset ECC parity registers */
        return target_write_u32(target, info->ecc + AT91C_ECCx_CR, 1);
 }
 
@@ -342,19 +326,19 @@ static int at91sam9_ecc_init(struct target *target, struct at91sam9_nand *info)
  * @param size Size of the OOB.
  * @return Pointer to an area to store OOB data.
  */
-static uint8_t * at91sam9_oob_init(struct nand_device *nand, uint8_t *oob, uint32_t *size)
+static uint8_t *at91sam9_oob_init(struct nand_device *nand, uint8_t *oob, uint32_t *size)
 {
        if (!oob) {
-               // user doesn't want OOB, allocate it
-               if (nand->page_size == 512) {
+               /* user doesn't want OOB, allocate it */
+               if (nand->page_size == 512)
                        *size = 16;
-               } else if (nand->page_size == 2048) {
+               else if (nand->page_size == 2048)
                        *size = 64;
-               }
 
                oob = malloc(*size);
                if (!oob) {
                        LOG_ERROR("Unable to allocate space for OOB");
+                       return NULL;
                }
 
                memset(oob, 0xFF, *size);
@@ -377,29 +361,26 @@ static uint8_t * at91sam9_oob_init(struct nand_device *nand, uint8_t *oob, uint3
  * @return Success or failure of reading the NAND page.
  */
 static int at91sam9_read_page(struct nand_device *nand, uint32_t page,
-               uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
+       uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
 {
        int retval;
        struct at91sam9_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
        uint8_t *oob_data;
        uint32_t status;
 
        retval = at91sam9_ecc_init(target, info);
-       if (ERROR_OK != retval) {
+       if (ERROR_OK != retval)
                return retval;
-       }
 
        retval = nand_page_command(nand, page, NAND_CMD_READ0, !data);
-       if (ERROR_OK != retval) {
+       if (ERROR_OK != retval)
                return retval;
-       }
 
        if (data) {
                retval = nand_read_data_page(nand, data, data_size);
-               if (ERROR_OK != retval) {
+               if (ERROR_OK != retval)
                        return retval;
-               }
        }
 
        oob_data = at91sam9_oob_init(nand, oob, &oob_size);
@@ -408,29 +389,33 @@ static int at91sam9_read_page(struct nand_device *nand, uint32_t page,
                target_read_u32(target, info->ecc + AT91C_ECCx_SR, &status);
                if (status & 1) {
                        LOG_ERROR("Error detected!");
-                       if (status & 4) {
+                       if (status & 4)
                                LOG_ERROR("Multiple errors encountered; unrecoverable!");
-                       else {
-                               // attempt recovery
+                       else {
+                               /* attempt recovery */
                                uint32_t parity;
 
-                               target_read_u32(target, info->ecc + AT91C_ECCx_PR, &parity);
+                               target_read_u32(target,
+                                       info->ecc + AT91C_ECCx_PR,
+                                       &parity);
                                uint32_t word = (parity & 0x0000FFF0) >> 4;
                                uint32_t bit = parity & 0x0F;
 
                                data[word] ^= (0x1) << bit;
-                               LOG_INFO("Data word %d, bit %d corrected.", word, bit);
+                               LOG_INFO("Data word %d, bit %d corrected.",
+                                       (unsigned) word,
+                                       (unsigned) bit);
                        }
                }
 
                if (status & 2) {
-                       // we could write back correct ECC data
+                       /* we could write back correct ECC data */
                        LOG_ERROR("Error in ECC bytes detected");
                }
        }
 
        if (!oob) {
-               // if it wasn't asked for, free it
+               /* if it wasn't asked for, free it */
                free(oob_data);
        }
 
@@ -451,23 +436,21 @@ static int at91sam9_read_page(struct nand_device *nand, uint32_t page,
  * @return Success or failure of the page write.
  */
 static int at91sam9_write_page(struct nand_device *nand, uint32_t page,
-               uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
+       uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
 {
        struct at91sam9_nand *info = nand->controller_priv;
-       struct target *target = info->target;
+       struct target *target = nand->target;
        int retval;
        uint8_t *oob_data = oob;
        uint32_t parity, nparity;
 
        retval = at91sam9_ecc_init(target, info);
-       if (ERROR_OK != retval) {
+       if (ERROR_OK != retval)
                return retval;
-       }
 
        retval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data);
-       if (ERROR_OK != retval) {
+       if (ERROR_OK != retval)
                return retval;
-       }
 
        if (data) {
                retval = nand_write_data_page(nand, data, data_size);
@@ -480,7 +463,7 @@ static int at91sam9_write_page(struct nand_device *nand, uint32_t page,
        oob_data = at91sam9_oob_init(nand, oob, &oob_size);
 
        if (!oob) {
-               // no OOB given, so read in the ECC parity from the ECC controller
+               /* no OOB given, so read in the ECC parity from the ECC controller */
                target_read_u32(target, info->ecc + AT91C_ECCx_PR, &parity);
                target_read_u32(target, info->ecc + AT91C_ECCx_NPR, &nparity);
 
@@ -492,9 +475,8 @@ static int at91sam9_write_page(struct nand_device *nand, uint32_t page,
 
        retval = nand_write_data_page(nand, oob_data, oob_size);
 
-       if (!oob) {
+       if (!oob)
                free(oob_data);
-       }
 
        if (ERROR_OK != retval) {
                LOG_ERROR("Unable to write OOB data to NAND");
@@ -513,23 +495,16 @@ static int at91sam9_write_page(struct nand_device *nand, uint32_t page,
  */
 NAND_DEVICE_COMMAND_HANDLER(at91sam9_nand_device_command)
 {
-       struct target *target = NULL;
        unsigned long chip = 0, ecc = 0;
        struct at91sam9_nand *info = NULL;
 
-       LOG_DEBUG("AT91SAM9 NAND Device Command\n");
+       LOG_DEBUG("AT91SAM9 NAND Device Command");
 
        if (CMD_ARGC < 3 || CMD_ARGC > 4) {
                LOG_ERROR("parameters: %s target chip_addr", CMD_ARGV[0]);
                return ERROR_NAND_OPERATION_FAILED;
        }
 
-       target = get_target(CMD_ARGV[1]);
-       if (!target) {
-               LOG_ERROR("invalid target: %s", CMD_ARGV[1]);
-               return ERROR_NAND_OPERATION_FAILED;
-       }
-
        COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], chip);
        if (chip == 0) {
                LOG_ERROR("invalid NAND chip address: %s", CMD_ARGV[2]);
@@ -550,14 +525,13 @@ NAND_DEVICE_COMMAND_HANDLER(at91sam9_nand_device_command)
                return ERROR_NAND_OPERATION_FAILED;
        }
 
-       info->target = target;
        info->data = chip;
        info->cmd = chip | (1 << 22);
        info->addr = chip | (1 << 21);
        info->ecc = ecc;
 
        nand->controller_priv = info;
-       info->io.target = target;
+       info->io.target = nand->target;
        info->io.data = info->data;
        info->io.op = ARM_NAND_NONE;
 
@@ -604,9 +578,8 @@ COMMAND_HANDLER(handle_at91sam9_ale_command)
        struct at91sam9_nand *info = NULL;
        unsigned num, address_line;
 
-       if (CMD_ARGC != 2) {
+       if (CMD_ARGC != 2)
                return ERROR_COMMAND_SYNTAX_ERROR;
-       }
 
        COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
        nand = get_nand_device_by_num(num);
@@ -633,9 +606,8 @@ COMMAND_HANDLER(handle_at91sam9_rdy_busy_command)
        struct at91sam9_nand *info = NULL;
        unsigned num, base_pioc, pin_num;
 
-       if (CMD_ARGC != 3) {
+       if (CMD_ARGC != 3)
                return ERROR_COMMAND_SYNTAX_ERROR;
-       }
 
        COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
        nand = get_nand_device_by_num(num);
@@ -665,9 +637,8 @@ COMMAND_HANDLER(handle_at91sam9_ce_command)
        struct at91sam9_nand *info = NULL;
        unsigned num, base_pioc, pin_num;
 
-       if (CMD_ARGC != 3) {
+       if (CMD_ARGC != 3)
                return ERROR_COMMAND_SYNTAX_ERROR;
-       }
 
        COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
        nand = get_nand_device_by_num(num);
@@ -693,28 +664,30 @@ static const struct command_registration at91sam9_sub_command_handlers[] = {
                .handler = handle_at91sam9_cle_command,
                .mode = COMMAND_CONFIG,
                .help = "set command latch enable address line (default is 22)",
-               .usage = "<device_id> <address_line>",
+               .usage = "bank_id address_line",
        },
        {
                .name = "ale",
                .handler = handle_at91sam9_ale_command,
                .mode = COMMAND_CONFIG,
                .help = "set address latch enable address line (default is 21)",
-               .usage = "<device_id> <address_line>",
+               .usage = "bank_id address_line",
        },
        {
                .name = "rdy_busy",
                .handler = handle_at91sam9_rdy_busy_command,
                .mode = COMMAND_CONFIG,
-               .help = "set the input pin connected to RDY/~BUSY signal (no default)",
-               .usage = "<device_id> <base_pioc> <pin_num>",
+               .help = "set the GPIO input pin connected to "
+                       "the RDY/~BUSY signal (no default)",
+               .usage = "bank_id pio_base_addr pin_num",
        },
        {
                .name = "ce",
                .handler = handle_at91sam9_ce_command,
                .mode = COMMAND_CONFIG,
-               .help = "set the output pin connected to chip enable signal (no default)",
-               .usage = "<device_id> <base_pioc> <pin_num>",
+               .help = "set the GPIO output pin connected to "
+                       "the chip enable signal (no default)",
+               .usage = "bank_id pio_base_addr pin_num",
        },
        COMMAND_REGISTRATION_DONE
 };
@@ -724,6 +697,7 @@ static const struct command_registration at91sam9_command_handler[] = {
                .name = "at91sam9",
                .mode = COMMAND_ANY,
                .help = "AT91SAM9 NAND flash controller commands",
+               .usage = "",
                .chain = at91sam9_sub_command_handlers,
        },
        COMMAND_REGISTRATION_DONE

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)