flash/stm32l4x: add support of STM32G0Bx/G0Cx devices
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
This commit is contained in:
parent
e7e46ba61e
commit
43d31a8fd5
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue