aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTarek BOCHKATI <tarek.bouchkati@gmail.com>2020-02-07 12:52:14 +0100
committerTomas Vanek <vanekt@fbl.cz>2020-03-10 20:18:47 +0000
commit123e10288df62e6f66426cdab7adb93fd7348d5f (patch)
tree06766fe421b25a6c34c54300ca6d12b0438546e5
parentb304971f380d89d5e934859b2c36e81c26df6eee (diff)
flash/stm32h7x: fix bank sizes for devices with trimmed flash
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>
-rw-r--r--src/flash/nor/stm32h7x.c77
1 files changed, 49 insertions, 28 deletions
diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c
index 7882c11a..6edbc00f 100644
--- a/src/flash/nor/stm32h7x.c
+++ b/src/flash/nor/stm32h7x.c
@@ -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;