]> git.gag.com Git - fw/openocd/commitdiff
flash/stm32h7x: fix bank sizes for devices with trimmed flash
authorTarek BOCHKATI <tarek.bouchkati@gmail.com>
Fri, 7 Feb 2020 11:52:14 +0000 (12:52 +0100)
committerTomas Vanek <vanekt@fbl.cz>
Tue, 10 Mar 2020 20:18:47 +0000 (20:18 +0000)
STM32H7yxxI: dual independent 1 MByte banks
STM32H7yxxG: dual independent 512 Kbyte banks
STM32H7yxxB: single 128 Kbyte bank

where y = [4/5] or [A/B]

references: (documents are available in www.st.com)
 - STM32H7[4/5]x[G/I] : DS12110 Rev 7
    >> 3.3.1 Embedded Flash memory
 - STM32H750xB : RM0433 Rev 6
    >> Table 11. Flash memory organization on STM32H750xB devices
 - STM32H7[A/B]x[B/G/I] : RM0455 Rev 3
    >> 4.3.4 Flash memory architecture and usage

Change-Id: Ic9346964ef2554abf47f5832e25adfdc77bd323e
Signed-off-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com>
Reviewed-on: http://openocd.zylin.com/5442
Tested-by: jenkins
Reviewed-by: Christopher Head <chead@zaber.com>
src/flash/nor/stm32h7x.c

index 7882c11a74cc227fe9d4f80f7ffaa30f2fd8ffd8..6edbc00fa80de6714a6c8279cfd03ee78f2e735d 100644 (file)
@@ -117,7 +117,7 @@ struct stm32h7x_part_info {
        unsigned int block_size;     /* flash write word size in bytes */
        uint16_t max_flash_size_kb;
        uint8_t has_dual_bank;
-       uint16_t first_bank_size_kb; /* Used when has_dual_bank is true */
+       uint16_t max_bank_size_kb; /* Used when has_dual_bank is true */
        uint32_t flash_regs_base;    /* Flash controller registers location */
        uint32_t fsize_addr;         /* Location of FSIZE register */
        uint32_t wps_group_size; /* write protection group sectors' count */
@@ -173,7 +173,7 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = {
        .page_size_kb           = 128,
        .block_size                     = 32,
        .max_flash_size_kb      = 2048,
-       .first_bank_size_kb     = 1024,
+       .max_bank_size_kb       = 1024,
        .has_dual_bank          = 1,
        .flash_regs_base        = FLASH_REG_BASE_B0,
        .fsize_addr                     = 0x1FF1E880,
@@ -189,7 +189,7 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = {
        .page_size_kb           = 8,
        .block_size                     = 16,
        .max_flash_size_kb      = 2048,
-       .first_bank_size_kb     = 1024,
+       .max_bank_size_kb       = 1024,
        .has_dual_bank          = 1,
        .flash_regs_base        = FLASH_REG_BASE_B0,
        .fsize_addr                     = 0x08FFF80C,
@@ -740,8 +740,6 @@ static int stm32x_probe(struct flash_bank *bank)
        struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
        uint16_t flash_size_in_kb;
        uint32_t device_id;
-       uint32_t base_address = FLASH_BANK0_ADDRESS;
-       uint32_t second_bank_base;
 
        stm32x_info->probed = false;
        stm32x_info->part_info = NULL;
@@ -776,33 +774,58 @@ static int stm32x_probe(struct flash_bank *bank)
        } else
                LOG_INFO("flash size probed value %d", flash_size_in_kb);
 
-       /* Lower flash size devices are single bank */
-       if (stm32x_info->part_info->has_dual_bank && (flash_size_in_kb > stm32x_info->part_info->first_bank_size_kb)) {
-               /* Use the configured base address to determine if this is the first or second flash bank.
-                * Verify that the base address is reasonably correct and determine the flash bank size
+
+
+
+       /* setup bank size */
+       const uint32_t bank1_base = FLASH_BANK0_ADDRESS;
+       const uint32_t bank2_base = bank1_base + stm32x_info->part_info->max_bank_size_kb * 1024;
+       bool has_dual_bank = stm32x_info->part_info->has_dual_bank;
+
+       switch (device_id) {
+       case 0x450:
+       case 0x480:
+               /* For STM32H74x/75x and STM32H7Ax/Bx
+                *  - STM32H7xxxI devices contains dual bank, 1 Mbyte each
+                *  - STM32H7xxxG devices contains dual bank, 512 Kbyte each
+                *  - STM32H7xxxB devices contains single bank, 128 Kbyte
+                *  - the second bank starts always from 0x08100000
                 */
-               second_bank_base = base_address + stm32x_info->part_info->first_bank_size_kb * 1024;
-               if (bank->base == second_bank_base) {
-                       /* This is the second bank  */
-                       base_address = second_bank_base;
-                       flash_size_in_kb = flash_size_in_kb - stm32x_info->part_info->first_bank_size_kb;
-                       /* bank1 also uses a register offset */
-                       stm32x_info->flash_regs_base = FLASH_REG_BASE_B1;
-               } else if (bank->base == base_address) {
-                       /* This is the first bank */
-                       flash_size_in_kb = stm32x_info->part_info->first_bank_size_kb;
-               } else {
-                       LOG_WARNING("STM32H flash bank base address config is incorrect. "
-                                   TARGET_ADDR_FMT " but should rather be 0x%" PRIx32 " or 0x%" PRIx32,
-                                       bank->base, base_address, second_bank_base);
+               if (flash_size_in_kb == 128)
+                       has_dual_bank = false;
+               else
+                       /* flash size is 2M or 1M */
+                       flash_size_in_kb /= 2;
+               break;
+       default:
+               LOG_ERROR("unsupported device");
+               return ERROR_FAIL;
+       }
+
+       if (has_dual_bank) {
+               LOG_INFO("STM32H7 flash has dual banks");
+               if (bank->base != bank1_base && bank->base != bank2_base) {
+                       LOG_ERROR("STM32H7 flash bank base address config is incorrect. "
+                                       TARGET_ADDR_FMT " but should rather be 0x%" PRIx32 " or 0x%" PRIx32,
+                                       bank->base, bank1_base, bank2_base);
                        return ERROR_FAIL;
                }
-               LOG_INFO("STM32H flash has dual banks. Bank (%d) size is %dkb, base address is 0x%" PRIx32,
-                               bank->bank_number, flash_size_in_kb, base_address);
        } else {
-               LOG_INFO("STM32H flash size is %dkb, base address is 0x%" PRIx32, flash_size_in_kb, base_address);
+               LOG_INFO("STM32H7 flash has a single bank");
+               if (bank->base == bank2_base) {
+                       LOG_ERROR("this device has a single bank only");
+                       return ERROR_FAIL;
+               } else if (bank->base != bank1_base) {
+                       LOG_ERROR("STM32H7 flash bank base address config is incorrect. "
+                                       TARGET_ADDR_FMT " but should be 0x%" PRIx32,
+                                       bank->base, bank1_base);
+                       return ERROR_FAIL;
+               }
        }
 
+       LOG_INFO("Bank (%d) size is %d kb, base address is 0x%" PRIx32,
+               bank->bank_number, flash_size_in_kb, (uint32_t) bank->base);
+
        /* if the user sets the size manually then ignore the probed value
         * this allows us to work around devices that have an invalid flash size register value */
        if (stm32x_info->user_bank_size) {
@@ -815,8 +838,6 @@ static int stm32x_probe(struct flash_bank *bank)
 
        /* did we assign flash size? */
        assert(flash_size_in_kb != 0xffff);
-
-       bank->base = base_address;
        bank->size = flash_size_in_kb * 1024;
        bank->write_start_alignment = stm32x_info->part_info->block_size;
        bank->write_end_alignment = stm32x_info->part_info->block_size;