flash/stm32l4x: add support of STM32G0Bx/G0Cx devices 36/6036/13
authorTarek BOCHKATI <tarek.bouchkati@gmail.com>
Tue, 19 Jan 2021 12:26:48 +0000 (13:26 +0100)
committerOleksij Rempel <linux@rempel-privat.de>
Thu, 26 Aug 2021 06:38:17 +0000 (06:38 +0000)
this device has a dual bank flash architecture up to 512 KB (page 2KB)
reference: RM0444 Rev 5

notes:
 - 128k variant is always single bank
 - 256k variant flash is contiguous (no gap) in dual bank mode
 - BKER is bit 13 vs bit 11 for other devices
   > added cr_bker_mask in stm32l4_flash_bank struct
 - BSY2 for bank 2 operations
   > added sr_bsy_mask in stm32l4_flash_bank struct
   > proposed optimization: always wait for (BSY1 | BSY2) with
     STM32G0Bx/G0Cx devices only (for L4+ devices BSY2=PEMPTY)

TODO: update flashloader to use the proper BSY bits
      temporarily don't use the loader in dual bank mode

Change-Id: I54b0c93b494e7209da818791d15edd8cd42c2732
Signed-off-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/6036
Reviewed-by: Oleksij Rempel <linux@rempel-privat.de>
Tested-by: jenkins
src/flash/nor/stm32l4x.c
src/flash/nor/stm32l4x.h

index 32dff35e021c9190ecf2ae4196016a811f875305..ff804bbaf90b22d092af384c644041f36f74676d 100644 (file)
@@ -218,6 +218,8 @@ struct stm32l4_flash_bank {
        bool dual_bank_mode;
        int hole_sectors;
        uint32_t user_bank_size;
+       uint32_t cr_bker_mask;
+       uint32_t sr_bsy_mask;
        uint32_t wrpxxr_mask;
        const struct stm32l4_part_info *part_info;
        uint32_t flash_regs_base;
@@ -275,6 +277,10 @@ static const struct stm32l4_rev stm32_466_revs[] = {
        { 0x1000, "A" }, { 0x1001, "Z" }, { 0x2000, "B" },
 };
 
+static const struct stm32l4_rev stm32_467_revs[] = {
+       { 0x1000, "A" },
+};
+
 static const struct stm32l4_rev stm32_468_revs[] = {
        { 0x1000, "A" }, { 0x2000, "B" }, { 0x2001, "Z" },
 };
@@ -396,6 +402,18 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
          .otp_base              = 0x1FFF7000,
          .otp_size              = 1024,
        },
+       {
+         .id                    = 0x467,
+         .revs                  = stm32_467_revs,
+         .num_revs              = ARRAY_SIZE(stm32_467_revs),
+         .device_str            = "STM32G0Bx/G0Cx",
+         .max_flash_size_kb     = 512,
+         .flags                 = F_HAS_DUAL_BANK,
+         .flash_regs_base       = 0x40022000,
+         .fsize_addr            = 0x1FFF75E0,
+         .otp_base              = 0x1FFF7000,
+         .otp_size              = 1024,
+       },
        {
          .id                    = 0x468,
          .revs                  = stm32_468_revs,
@@ -691,6 +709,7 @@ static inline int stm32l4_write_flash_reg_by_index(struct flash_bank *bank,
 
 static int stm32l4_wait_status_busy(struct flash_bank *bank, int timeout)
 {
+       struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;
        uint32_t status;
        int retval = ERROR_OK;
 
@@ -700,7 +719,7 @@ static int stm32l4_wait_status_busy(struct flash_bank *bank, int timeout)
                if (retval != ERROR_OK)
                        return retval;
                LOG_DEBUG("status: 0x%" PRIx32 "", status);
-               if ((status & FLASH_BSY) == 0)
+               if ((status & stm32l4_info->sr_bsy_mask) == 0)
                        break;
                if (timeout-- <= 0) {
                        LOG_ERROR("timed out waiting for flash");
@@ -1092,7 +1111,7 @@ static int stm32l4_erase(struct flash_bank *bank, unsigned int first,
                if (i >= stm32l4_info->bank1_sectors) {
                        uint8_t snb;
                        snb = i - stm32l4_info->bank1_sectors;
-                       erase_flags |= snb << FLASH_PAGE_SHIFT | FLASH_CR_BKER;
+                       erase_flags |= snb << FLASH_PAGE_SHIFT | stm32l4_info->cr_bker_mask;
                } else
                        erase_flags |= i << FLASH_PAGE_SHIFT;
                retval = stm32l4_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, erase_flags);
@@ -1463,7 +1482,18 @@ static int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer,
        if (retval != ERROR_OK)
                goto err_lock;
 
-       if (stm32l4_info->use_flashloader) {
+       /**
+        * FIXME update the flash loader to use a custom FLASH_SR_BSY mask
+        * Workaround for STM32G0Bx/G0Cx devices in dual bank mode,
+        * as the flash loader does not use the SR_BSY2
+        */
+       bool use_flashloader = stm32l4_info->use_flashloader;
+       if ((stm32l4_info->part_info->id == 0x467) && stm32l4_info->dual_bank_mode) {
+               LOG_INFO("Couldn't use the flash loader in dual-bank mode");
+               use_flashloader = false;
+       }
+
+       if (use_flashloader) {
                /* For TrustZone enabled devices, when TZEN is set and RDP level is 0.5,
                 * the debug is possible only in non-secure state.
                 * Thus means the flashloader will run in non-secure mode,
@@ -1474,7 +1504,7 @@ static int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer,
                retval = stm32l4_write_block(bank, buffer, offset, count / 8);
        }
 
-       if (!stm32l4_info->use_flashloader || retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
+       if (!use_flashloader || retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
                LOG_INFO("falling back to single memory accesses");
                retval = stm32l4_write_block_without_loader(bank, buffer, offset, count / 8);
        }
@@ -1573,6 +1603,8 @@ static int stm32l4_probe(struct flash_bank *bank)
                        stm32l4_info->idcode, part_info->device_str, rev_str, rev_id);
 
        stm32l4_info->flash_regs_base = stm32l4_info->part_info->flash_regs_base;
+       stm32l4_info->cr_bker_mask = FLASH_BKER;
+       stm32l4_info->sr_bsy_mask = FLASH_BSY;
 
        /* initialise the flash registers layout */
        if (part_info->flags & F_HAS_L5_FLASH_REGS)
@@ -1696,6 +1728,20 @@ static int stm32l4_probe(struct flash_bank *bank)
                num_pages = flash_size_kb / page_size_kb;
                stm32l4_info->bank1_sectors = num_pages;
                break;
+       case 0x467: /* STM32G0B/G0Cxx */
+               /* single/dual bank depending on bit(21) */
+               page_size_kb = 2;
+               num_pages = flash_size_kb / page_size_kb;
+               stm32l4_info->bank1_sectors = num_pages;
+               stm32l4_info->cr_bker_mask = FLASH_BKER_G0;
+
+               /* check DUAL_BANK bit */
+               if (stm32l4_info->optr & BIT(21)) {
+                       stm32l4_info->sr_bsy_mask = FLASH_BSY | FLASH_BSY2;
+                       stm32l4_info->dual_bank_mode = true;
+                       stm32l4_info->bank1_sectors = num_pages / 2;
+               }
+               break;
        case 0x469: /* STM32G47/G48xx */
                /* STM32G47/8 can be single/dual bank:
                 *   if DUAL_BANK = 0 -> single bank
index b8f3d8c5be724277f9b9b16e1720b1d35212e0e6..ba809ff407eaa943370eea718c4fff0e5d2be0ec 100644 (file)
@@ -24,7 +24,8 @@
 #define FLASH_PER                              (1 << 1)
 #define FLASH_MER1                             (1 << 2)
 #define FLASH_PAGE_SHIFT               3
-#define FLASH_CR_BKER                  (1 << 11)
+#define FLASH_BKER                             (1 << 11)
+#define FLASH_BKER_G0                  (1 << 13)
 #define FLASH_MER2                             (1 << 15)
 #define FLASH_STRT                             (1 << 16)
 #define FLASH_OPTSTRT                  (1 << 17)
@@ -36,6 +37,7 @@
 
 /* FLASH_SR register bits */
 #define FLASH_BSY                              (1 << 16)
+#define FLASH_BSY2                             (1 << 17)
 
 /* Fast programming not used => related errors not used*/
 #define FLASH_PGSERR                   (1 << 7) /* Programming sequence error */

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)