]> git.sur5r.net Git - openocd/blobdiff - src/flash/nor/at91sam4.c
flash/at91sam4: fix clang static analyzer warning
[openocd] / src / flash / nor / at91sam4.c
index 94d5bfda4e663e0b24259b92163fd224d2ae5733..2eec15e2a66ad4a20d30a580a74db12e4c5a3166 100644 (file)
@@ -464,7 +464,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
                        .bank_number = 0,
                        .base_address = FLASH_BANK_BASE_S,
                        .controller_address = 0x400e0a00,
-                       .flash_wait_states = 6, /* workaround silicon bug */
+                       .flash_wait_states = 5,
                        .present = 1,
                        .size_bytes =  1024 * 1024,
                        .nsectors   =  128,
@@ -499,7 +499,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
                        .bank_number = 0,
                        .base_address = FLASH_BANK_BASE_S,
                        .controller_address = 0x400e0a00,
-                       .flash_wait_states = 6, /* workaround silicon bug */
+                       .flash_wait_states = 5,
                        .present = 1,
                        .size_bytes =  512 * 1024,
                        .nsectors   =  64,
@@ -532,7 +532,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
                        .bank_number = 0,
                        .base_address = FLASH_BANK_BASE_S,
                        .controller_address = 0x400e0a00,
-                       .flash_wait_states = 6, /* workaround silicon bug */
+                       .flash_wait_states = 5,
                        .present = 1,
                        .size_bytes =  512 * 1024,
                        .nsectors   =  64,
@@ -565,7 +565,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
                        .bank_number = 0,
                        .base_address = FLASH_BANK_BASE_S,
                        .controller_address = 0x400e0a00,
-                       .flash_wait_states = 6, /* workaround silicon bug */
+                       .flash_wait_states = 5,
                        .present = 1,
                        .size_bytes =  512 * 1024,
                        .nsectors   =  64,
@@ -598,7 +598,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
                        .bank_number = 0,
                        .base_address = FLASH_BANK_BASE_S,
                        .controller_address = 0x400e0a00,
-                       .flash_wait_states = 6, /* workaround silicon bug */
+                       .flash_wait_states = 5,
                        .present = 1,
                        .size_bytes =  1024 * 1024,
                        .nsectors   =  128,
@@ -631,7 +631,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
                        .bank_number = 0,
                        .base_address = FLASH_BANK_BASE_S,
                        .controller_address = 0x400e0a00,
-                       .flash_wait_states = 6, /* workaround silicon bug */
+                       .flash_wait_states = 5,
                        .present = 1,
                        .size_bytes =  1024 * 1024,
                        .nsectors   =  128,
@@ -682,6 +682,40 @@ static const struct sam4_chip_details all_sam4_details[] = {
                  },
                },
        },
+       /*at91sam4sa16c - TFBGA100/VFBGA100/LQFP100*/
+       {
+               .chipid_cidr    = 0x28a70ce0,
+               .name           = "at91sam4sa16c",
+               .total_flash_size     = 1024 * 1024,
+               .total_sram_size      = 160 * 1024,
+               .n_gpnvms       = 2,
+               .n_banks        = 1,
+
+/*             .bank[0] = { */
+               {
+                 {
+                       .probed = 0,
+                       .pChip  = NULL,
+                       .pBank  = NULL,
+                       .bank_number = 0,
+                       .base_address = FLASH_BANK_BASE_S,
+                       .controller_address = 0x400e0a00,
+                       .flash_wait_states = 5,
+                       .present = 1,
+                       .size_bytes =  1024 * 1024,
+                       .nsectors   =  128,
+                       .sector_size = 8192,
+                       .page_size   = 512,
+                 },
+/*             .bank[1] = {*/
+                 {
+                       .present = 0,
+                       .probed = 0,
+                       .bank_number = 1,
+
+                 },
+               },
+       },
        /*atsam4s16b - LQFP64/QFN64/WLCSP64*/
        {
                .chipid_cidr    = 0x289C0CE0,
@@ -1261,61 +1295,86 @@ static const struct sam4_chip_details all_sam4_details[] = {
                },
        },
 
-       /*at91sam4sa16c*/
+       /* atsamg53n19 */
        {
-               .chipid_cidr    = 0x28a70ce0,
-               .name           = "at91sam4sa16c",
-               .total_flash_size     = 1024 * 1024,
-               .total_sram_size      = 160 * 1024,
-               .n_gpnvms       = 3,
-               .n_banks        = 2,
+               .chipid_cidr    = 0x247e0ae0,
+               .name           = "atsamg53n19",
+               .total_flash_size     = 512 * 1024,
+               .total_sram_size      = 96 * 1024,
+               .n_gpnvms       = 2,
+               .n_banks        = 1,
 
-/*             .bank[0] = { */
+/*             .bank[0] = {*/
                {
                        {
                                .probed = 0,
                                .pChip  = NULL,
                                .pBank  = NULL,
                                .bank_number = 0,
-                               .base_address = FLASH_BANK0_BASE_SD,
+                               .base_address = FLASH_BANK_BASE_S,
                                .controller_address = 0x400e0a00,
-                               .flash_wait_states = 6, /* workaround silicon bug */
+                               .flash_wait_states = 5,
                                .present = 1,
                                .size_bytes =  512 * 1024,
                                .nsectors   =  64,
                                .sector_size = 8192,
                                .page_size   = 512,
                        },
+/*             .bank[1] = {*/
+                 {
+                       .present = 0,
+                       .probed = 0,
+                       .bank_number = 1,
 
-/*             .bank[1] = { */
+                 },
+               }
+       },
+
+       /* atsamg55g19 */
+       {
+               .chipid_cidr    = 0x24470ae0,
+               .name           = "atsamg55g19",
+               .total_flash_size     = 512 * 1024,
+               .total_sram_size      = 160 * 1024,
+               .n_gpnvms       = 2,
+               .n_banks        = 1,
+
+               {
+/*                     .bank[0] = */
                        {
                                .probed = 0,
                                .pChip  = NULL,
                                .pBank  = NULL,
-                               .bank_number = 1,
-                               .base_address = FLASH_BANK1_BASE_1024K_SD,
-                               .controller_address = 0x400e0c00,
-                               .flash_wait_states = 6, /* workaround silicon bug */
+                               .bank_number = 0,
+                               .base_address = FLASH_BANK_BASE_S,
+                               .controller_address = 0x400e0a00,
+                               .flash_wait_states = 5,
                                .present = 1,
                                .size_bytes =  512 * 1024,
                                .nsectors   =  64,
                                .sector_size = 8192,
                                .page_size   = 512,
                        },
-               },
+/*                     .bank[1] = */
+                       {
+                               .present = 0,
+                               .probed = 0,
+                               .bank_number = 1,
+                       },
+               }
        },
 
-       /* at91samg53n19 */
+       /* atsamg55j19 */
        {
-               .chipid_cidr    = 0x247e0ae0,
-               .name           = "at91samg53n19",
+               .chipid_cidr    = 0x24570ae0,
+               .name           = "atsamg55j19",
                .total_flash_size     = 512 * 1024,
-               .total_sram_size      = 96 * 1024,
+               .total_sram_size      = 160 * 1024,
                .n_gpnvms       = 2,
                .n_banks        = 1,
 
-/*             .bank[0] = {*/
                {
+/*                     .bank[0] = */
                        {
                                .probed = 0,
                                .pChip  = NULL,
@@ -1323,20 +1382,19 @@ static const struct sam4_chip_details all_sam4_details[] = {
                                .bank_number = 0,
                                .base_address = FLASH_BANK_BASE_S,
                                .controller_address = 0x400e0a00,
-                               .flash_wait_states = 6, /* workaround silicon bug */
+                               .flash_wait_states = 5,
                                .present = 1,
                                .size_bytes =  512 * 1024,
                                .nsectors   =  64,
                                .sector_size = 8192,
                                .page_size   = 512,
                        },
-/*             .bank[1] = {*/
-                 {
-                       .present = 0,
-                       .probed = 0,
-                       .bank_number = 1,
-
-                 },
+/*                     .bank[1] = */
+                       {
+                               .present = 0,
+                               .probed = 0,
+                               .bank_number = 1,
+                       },
                }
        },
 
@@ -1917,6 +1975,8 @@ static const struct archnames { unsigned value; const char *name; } archnames[]
        { 0x42,  "AT91x42 Series"                                                       },
        { 0x43,  "SAMG51 Series"
        },
+       { 0x44,  "SAMG55 Series (49-pin WLCSP)"                                         },
+       { 0x45,  "SAMG55 Series (64-pin)"                                                        },
        { 0x47,  "SAMG53 Series"
        },
        { 0x55,  "AT91x55 Series"                                                       },
@@ -2316,6 +2376,11 @@ static int sam4_GetInfo(struct sam4_chip *pChip)
 {
        const struct sam4_reg_list *pReg;
        uint32_t regval;
+       int r;
+
+       r = sam4_ReadAllRegs(pChip);
+       if (r != ERROR_OK)
+               return r;
 
        pReg = &(sam4_all_regs[0]);
        while (pReg->name) {
@@ -2444,6 +2509,22 @@ FLASH_BANK_COMMAND_HANDLER(sam4_flash_bank_command)
        return ERROR_OK;
 }
 
+/**
+ * Remove all chips from the internal list without distingushing which one
+ * is owned by this bank. This simplification works only for one shot
+ * deallocation like current flash_free_all_banks()
+ */
+static void sam4_free_driver_priv(struct flash_bank *bank)
+{
+       struct sam4_chip *chip = all_sam4_chips;
+       while (chip) {
+               struct sam4_chip *next = chip->next;
+               free(chip);
+               chip = next;
+       }
+       all_sam4_chips = NULL;
+}
+
 static int sam4_GetDetails(struct sam4_bank_private *pPrivate)
 {
        const struct sam4_chip_details *pDetails;
@@ -2468,6 +2549,8 @@ static int sam4_GetDetails(struct sam4_bank_private *pPrivate)
                        pPrivate->pChip->cfg.CHIPID_CIDR);
                sam4_explain_chipid_cidr(pPrivate->pChip);
                return ERROR_FAIL;
+       } else {
+               LOG_DEBUG("SAM4 Found chip %s, CIDR 0x%08x", pDetails->name, pDetails->chipid_cidr);
        }
 
        /* DANGER: THERE ARE DRAGONS HERE */
@@ -2503,14 +2586,35 @@ static int sam4_GetDetails(struct sam4_bank_private *pPrivate)
        return ERROR_OK;
 }
 
-static int _sam4_probe(struct flash_bank *bank, int noise)
+static int sam4_info(struct flash_bank *bank, char *buf, int buf_size)
+{
+       struct sam4_bank_private *pPrivate;
+       int k = bank->size / 1024;
+
+       pPrivate = get_sam4_bank_private(bank);
+       if (pPrivate == NULL) {
+               buf[0] = '\0';
+               return ERROR_FAIL;
+       }
+
+       snprintf(buf, buf_size,
+               "%s bank %d: %d kB at 0x%08" PRIx32,
+               pPrivate->pChip->details.name,
+               pPrivate->bank_number,
+               k,
+               bank->base);
+
+       return ERROR_OK;
+}
+
+static int sam4_probe(struct flash_bank *bank)
 {
        unsigned x;
        int r;
        struct sam4_bank_private *pPrivate;
 
 
-       LOG_DEBUG("Begin: Bank: %d, Noise: %d", bank->bank_number, noise);
+       LOG_DEBUG("Begin: Bank: %d", bank->bank_number);
        if (bank->target->state != TARGET_HALTED) {
                LOG_ERROR("Target not halted");
                return ERROR_TARGET_NOT_HALTED;
@@ -2538,6 +2642,7 @@ static int _sam4_probe(struct flash_bank *bank, int noise)
        for (x = 0; x < SAM4_MAX_FLASH_BANKS; x++) {
                if (bank->base == pPrivate->pChip->details.bank[x].base_address) {
                        bank->size = pPrivate->pChip->details.bank[x].size_bytes;
+                       LOG_DEBUG("SAM4 Set flash bank to %08X - %08X, idx %d", bank->base, bank->base + bank->size, x);
                        break;
                }
        }
@@ -2576,14 +2681,15 @@ static int _sam4_probe(struct flash_bank *bank, int noise)
        return r;
 }
 
-static int sam4_probe(struct flash_bank *bank)
-{
-       return _sam4_probe(bank, 1);
-}
-
 static int sam4_auto_probe(struct flash_bank *bank)
 {
-       return _sam4_probe(bank, 0);
+       struct sam4_bank_private *pPrivate;
+
+       pPrivate = get_sam4_bank_private(bank);
+       if (pPrivate && pPrivate->probed)
+               return ERROR_OK;
+
+       return sam4_probe(bank);
 }
 
 static int sam4_erase(struct flash_bank *bank, int first, int last)
@@ -2683,20 +2789,17 @@ static int sam4_page_read(struct sam4_bank_private *pPrivate, unsigned pagenum,
        return r;
 }
 
-static int sam4_page_write(struct sam4_bank_private *pPrivate, unsigned pagenum, const uint8_t *buf)
+static int sam4_set_wait(struct sam4_bank_private *pPrivate)
 {
-       uint32_t adr;
-       uint32_t status;
        uint32_t fmr;   /* EEFC Flash Mode Register */
        int r;
 
-       adr = pagenum * pPrivate->page_size;
-       adr = (adr + pPrivate->base_address);
-
        /* Get flash mode register value */
        r = target_read_u32(pPrivate->pChip->target, pPrivate->controller_address, &fmr);
-       if (r != ERROR_OK)
-               LOG_DEBUG("Error Read failed: read flash mode register");
+       if (r != ERROR_OK) {
+               LOG_ERROR("Error Read failed: read flash mode register");
+               return r;
+       }
 
        /* Clear flash wait state field */
        fmr &= 0xfffff0ff;
@@ -2707,7 +2810,19 @@ static int sam4_page_write(struct sam4_bank_private *pPrivate, unsigned pagenum,
        LOG_DEBUG("Flash Mode: 0x%08x", ((unsigned int)(fmr)));
        r = target_write_u32(pPrivate->pBank->target, pPrivate->controller_address, fmr);
        if (r != ERROR_OK)
-               LOG_DEBUG("Error Write failed: set flash mode register");
+               LOG_ERROR("Error Write failed: set flash mode register");
+
+       return r;
+}
+
+static int sam4_page_write(struct sam4_bank_private *pPrivate, unsigned pagenum, const uint8_t *buf)
+{
+       uint32_t adr;
+       uint32_t status;
+       int r;
+
+       adr = pagenum * pPrivate->page_size;
+       adr = (adr + pPrivate->base_address);
 
        /* 1st sector 8kBytes - page 0 - 15*/
        /* 2nd sector 8kBytes - page 16 - 30*/
@@ -2795,6 +2910,10 @@ static int sam4_write(struct flash_bank *bank,
                goto done;
        }
 
+       r = sam4_set_wait(pPrivate);
+       if (r != ERROR_OK)
+               goto done;
+
        /* what page do we start & end in? */
        page_cur = offset / pPrivate->page_size;
        page_end = (offset + count - 1) / pPrivate->page_size;
@@ -3012,7 +3131,8 @@ showall:
                }
                if ((who >= 0) && (((unsigned)(who)) < pChip->details.n_gpnvms)) {
                        r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), who, &v);
-                       command_print(CMD_CTX, "sam4-gpnvm%u: %u", who, v);
+                       if (r == ERROR_OK)
+                               command_print(CMD_CTX, "sam4-gpnvm%u: %u", who, v);
                        return r;
                } else {
                        command_print(CMD_CTX, "sam4-gpnvm invalid GPNVM: %u", who);
@@ -3124,4 +3244,6 @@ struct flash_driver at91sam4_flash = {
        .auto_probe = sam4_auto_probe,
        .erase_check = default_flash_blank_check,
        .protect_check = sam4_protect_check,
+       .info = sam4_info,
+       .free_driver_priv = sam4_free_driver_priv,
 };