mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-31 02:51:26 +00:00
stm32: cleanup flash-f by using constant from register.h
Use constants from registers.h, to easily support other ECs. Fix indentation in registers.h BRANCH=none TEST=compile + following patches tested on STM32F411 BUG=None Change-Id: Iecb3ce759a5c4ff13463e7df1cb7e03fc1ce6f69 Signed-off-by: Gwendal Grignou <gwendal@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/264030 Reviewed-by: Alexandru M Stan <amstan@chromium.org>
This commit is contained in:
committed by
chrome-bot
parent
92ea78398b
commit
72afc55bd9
@@ -465,7 +465,7 @@ void flash_physical_permanent_protect(void)
|
||||
write_optb(0, 0x11);
|
||||
/* Reset by using OBL_LAUNCH to take changes into account */
|
||||
asm volatile("cpsid i");
|
||||
STM32_FLASH_CR |= STM32_FLASH_CR_OBL_LAUNCH;
|
||||
STM32_FLASH_CR |= FLASH_CR_OBL_LAUNCH;
|
||||
/* Spin and wait for reboot; should never return */
|
||||
while (1)
|
||||
;
|
||||
|
||||
@@ -27,22 +27,6 @@
|
||||
/* Flash page programming timeout. This is 2x the datasheet max. */
|
||||
#define FLASH_TIMEOUT_US 16000
|
||||
|
||||
/* Flash unlocking keys */
|
||||
#define KEY1 0x45670123
|
||||
#define KEY2 0xCDEF89AB
|
||||
|
||||
/* Lock bits for FLASH_CR register */
|
||||
#define PG (1<<0)
|
||||
#define PER (1<<1)
|
||||
#define OPTPG (1<<4)
|
||||
#define OPTER (1<<5)
|
||||
#define STRT (1<<6)
|
||||
#define CR_LOCK (1<<7)
|
||||
#define PRG_LOCK 0
|
||||
#define OPT_LOCK (1<<9)
|
||||
|
||||
static int write_optb(int byte, uint8_t value);
|
||||
|
||||
static inline int calculate_flash_timeout(void)
|
||||
{
|
||||
return (FLASH_TIMEOUT_US *
|
||||
@@ -52,11 +36,21 @@ static inline int calculate_flash_timeout(void)
|
||||
static int wait_busy(void)
|
||||
{
|
||||
int timeout = calculate_flash_timeout();
|
||||
while (STM32_FLASH_SR & (1 << 0) && timeout-- > 0)
|
||||
while ((STM32_FLASH_SR & FLASH_SR_BUSY) && timeout-- > 0)
|
||||
udelay(CYCLE_PER_FLASH_LOOP);
|
||||
return (timeout > 0) ? EC_SUCCESS : EC_ERROR_TIMEOUT;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We at least unlock the control register lock.
|
||||
* We may also unlock other locks.
|
||||
*/
|
||||
enum extra_lock_type {
|
||||
NO_EXTRA_LOCK = 0,
|
||||
OPT_LOCK = 1,
|
||||
};
|
||||
|
||||
static int unlock(int locks)
|
||||
{
|
||||
/*
|
||||
@@ -65,27 +59,30 @@ static int unlock(int locks)
|
||||
*/
|
||||
ignore_bus_fault(1);
|
||||
|
||||
/* unlock CR if needed */
|
||||
if (STM32_FLASH_CR & CR_LOCK) {
|
||||
STM32_FLASH_KEYR = KEY1;
|
||||
STM32_FLASH_KEYR = KEY2;
|
||||
/* Always unlock CR if needed */
|
||||
if (STM32_FLASH_CR & FLASH_CR_LOCK) {
|
||||
STM32_FLASH_KEYR = FLASH_KEYR_KEY1;
|
||||
STM32_FLASH_KEYR = FLASH_KEYR_KEY2;
|
||||
}
|
||||
/* unlock option memory if required */
|
||||
if ((locks & OPT_LOCK) && !(STM32_FLASH_CR & OPT_LOCK)) {
|
||||
STM32_FLASH_OPTKEYR = KEY1;
|
||||
STM32_FLASH_OPTKEYR = KEY2;
|
||||
if ((locks & OPT_LOCK) && STM32_FLASH_OPT_LOCKED) {
|
||||
STM32_FLASH_OPTKEYR = FLASH_OPTKEYR_KEY1;
|
||||
STM32_FLASH_OPTKEYR = FLASH_OPTKEYR_KEY2;
|
||||
}
|
||||
|
||||
/* Re-enable bus fault handler */
|
||||
ignore_bus_fault(0);
|
||||
|
||||
return ((STM32_FLASH_CR ^ OPT_LOCK) & (locks | CR_LOCK)) ?
|
||||
EC_ERROR_UNKNOWN : EC_SUCCESS;
|
||||
if ((locks & OPT_LOCK) && STM32_FLASH_OPT_LOCKED)
|
||||
return EC_ERROR_UNKNOWN;
|
||||
if (STM32_FLASH_CR & FLASH_CR_LOCK)
|
||||
return EC_ERROR_UNKNOWN;
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
static void lock(void)
|
||||
{
|
||||
STM32_FLASH_CR = CR_LOCK;
|
||||
STM32_FLASH_CR |= FLASH_CR_LOCK;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -121,8 +118,8 @@ static int erase_optb(void)
|
||||
return rv;
|
||||
|
||||
/* Must be set in 2 separate lines. */
|
||||
STM32_FLASH_CR |= OPTER;
|
||||
STM32_FLASH_CR |= STRT;
|
||||
STM32_FLASH_CR |= FLASH_CR_OPTSTRT;
|
||||
STM32_FLASH_CR |= FLASH_CR_STRT;
|
||||
|
||||
rv = wait_busy();
|
||||
if (rv)
|
||||
@@ -132,6 +129,7 @@ static int erase_optb(void)
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
static int write_optb(int byte, uint8_t value);
|
||||
/*
|
||||
* Since the option byte erase is WHOLE erase, this function is to keep
|
||||
* rest of bytes, but make this byte 0xff.
|
||||
@@ -190,12 +188,12 @@ static int write_optb(int byte, uint8_t value)
|
||||
return rv;
|
||||
|
||||
/* set OPTPG bit */
|
||||
STM32_FLASH_CR |= OPTPG;
|
||||
STM32_FLASH_CR |= FLASH_CR_OPTPG;
|
||||
|
||||
*hword = ((~value) << STM32_OPTB_COMPL_SHIFT) | value;
|
||||
|
||||
/* reset OPTPG bit */
|
||||
STM32_FLASH_CR &= ~OPTPG;
|
||||
STM32_FLASH_CR &= ~FLASH_CR_OPTPG;
|
||||
|
||||
rv = wait_busy();
|
||||
if (rv)
|
||||
@@ -210,23 +208,38 @@ static int write_optb(int byte, uint8_t value)
|
||||
|
||||
int flash_physical_write(int offset, int size, const char *data)
|
||||
{
|
||||
#if CONFIG_FLASH_WRITE_SIZE == 1
|
||||
uint8_t *address = (uint8_t *)(CONFIG_PROGRAM_MEMORY_BASE + offset);
|
||||
uint8_t quantum = 0;
|
||||
#elif CONFIG_FLASH_WRITE_SIZE == 2
|
||||
uint16_t *address = (uint16_t *)(CONFIG_PROGRAM_MEMORY_BASE + offset);
|
||||
uint16_t quantum = 0;
|
||||
#elif CONFIG_FLASH_WRITE_SIZE == 4
|
||||
uint32_t *address = (uint32_t *)(CONFIG_PROGRAM_MEMORY_BASE + offset);
|
||||
uint32_t quantum = 0;
|
||||
#else
|
||||
#error "CONFIG_FLASH_WRITE_SIZE not supported."
|
||||
#endif
|
||||
int res = EC_SUCCESS;
|
||||
int timeout = calculate_flash_timeout();
|
||||
int i;
|
||||
|
||||
if (unlock(PRG_LOCK) != EC_SUCCESS) {
|
||||
if (unlock(NO_EXTRA_LOCK) != EC_SUCCESS) {
|
||||
res = EC_ERROR_UNKNOWN;
|
||||
goto exit_wr;
|
||||
}
|
||||
|
||||
/* Clear previous error status */
|
||||
STM32_FLASH_SR = 0x34;
|
||||
STM32_FLASH_SR = FLASH_SR_ALL_ERR | FLASH_SR_EOP;
|
||||
|
||||
/* set PG bit */
|
||||
STM32_FLASH_CR |= PG;
|
||||
STM32_FLASH_CR |= FLASH_CR_PG;
|
||||
|
||||
for (; size > 0; size -= sizeof(uint16_t)) {
|
||||
for (; size > 0; size -= CONFIG_FLASH_WRITE_SIZE) {
|
||||
int i;
|
||||
|
||||
for (i = CONFIG_FLASH_WRITE_SIZE - 1, quantum = 0; i >= 0; i--)
|
||||
quantum = (quantum << 8) + data[i];
|
||||
data += CONFIG_FLASH_WRITE_SIZE;
|
||||
/*
|
||||
* Reload the watchdog timer to avoid watchdog reset when doing
|
||||
* long writing with interrupt disabled.
|
||||
@@ -234,27 +247,30 @@ int flash_physical_write(int offset, int size, const char *data)
|
||||
watchdog_reload();
|
||||
|
||||
/* wait to be ready */
|
||||
for (i = 0; (STM32_FLASH_SR & 1) && (i < timeout);
|
||||
for (i = 0;
|
||||
(STM32_FLASH_SR & FLASH_SR_BUSY) &&
|
||||
(i < timeout);
|
||||
i++)
|
||||
;
|
||||
|
||||
/* write the half word */
|
||||
*address++ = data[0] + (data[1] << 8);
|
||||
data += 2;
|
||||
/* write the data */
|
||||
*address++ = quantum;
|
||||
|
||||
/* Wait for writes to complete */
|
||||
for (i = 0; (STM32_FLASH_SR & 1) && (i < timeout);
|
||||
for (i = 0;
|
||||
(STM32_FLASH_SR & FLASH_SR_BUSY) &&
|
||||
(i < timeout);
|
||||
i++)
|
||||
;
|
||||
|
||||
if (STM32_FLASH_SR & 1) {
|
||||
if (STM32_FLASH_SR & FLASH_SR_BUSY) {
|
||||
res = EC_ERROR_TIMEOUT;
|
||||
goto exit_wr;
|
||||
}
|
||||
|
||||
/* Check for error conditions - erase failed, voltage error,
|
||||
* protection error */
|
||||
if (STM32_FLASH_SR & 0x14) {
|
||||
if (STM32_FLASH_SR & FLASH_SR_ALL_ERR) {
|
||||
res = EC_ERROR_UNKNOWN;
|
||||
goto exit_wr;
|
||||
}
|
||||
@@ -262,7 +278,7 @@ int flash_physical_write(int offset, int size, const char *data)
|
||||
|
||||
exit_wr:
|
||||
/* Disable PG bit */
|
||||
STM32_FLASH_CR &= ~PG;
|
||||
STM32_FLASH_CR &= ~FLASH_CR_PG;
|
||||
|
||||
lock();
|
||||
|
||||
@@ -272,29 +288,30 @@ exit_wr:
|
||||
int flash_physical_erase(int offset, int size)
|
||||
{
|
||||
int res = EC_SUCCESS;
|
||||
int sector_size;
|
||||
int timeout_us;
|
||||
|
||||
if (unlock(PRG_LOCK) != EC_SUCCESS)
|
||||
if (unlock(NO_EXTRA_LOCK) != EC_SUCCESS)
|
||||
return EC_ERROR_UNKNOWN;
|
||||
|
||||
/* Clear previous error status */
|
||||
STM32_FLASH_SR = 0x34;
|
||||
STM32_FLASH_SR = FLASH_SR_ALL_ERR | FLASH_SR_EOP;
|
||||
|
||||
/* set PER bit */
|
||||
STM32_FLASH_CR |= PER;
|
||||
/* set SER/PER bit */
|
||||
STM32_FLASH_CR |= FLASH_CR_PER;
|
||||
|
||||
for (; size > 0; size -= CONFIG_FLASH_ERASE_SIZE,
|
||||
offset += CONFIG_FLASH_ERASE_SIZE) {
|
||||
while (size > 0) {
|
||||
timestamp_t deadline;
|
||||
|
||||
sector_size = CONFIG_FLASH_ERASE_SIZE;
|
||||
timeout_us = FLASH_TIMEOUT_US;
|
||||
/* Do nothing if already erased */
|
||||
if (flash_is_erased(offset, CONFIG_FLASH_ERASE_SIZE))
|
||||
continue;
|
||||
|
||||
if (flash_is_erased(offset, sector_size))
|
||||
goto next_sector;
|
||||
/* select page to erase */
|
||||
STM32_FLASH_AR = CONFIG_PROGRAM_MEMORY_BASE + offset;
|
||||
|
||||
/* set STRT bit : start erase */
|
||||
STM32_FLASH_CR |= STRT;
|
||||
STM32_FLASH_CR |= FLASH_CR_STRT;
|
||||
|
||||
/*
|
||||
* Reload the watchdog timer to avoid watchdog reset during a
|
||||
@@ -302,13 +319,14 @@ int flash_physical_erase(int offset, int size)
|
||||
*/
|
||||
watchdog_reload();
|
||||
|
||||
deadline.val = get_time().val + FLASH_TIMEOUT_US;
|
||||
deadline.val = get_time().val + timeout_us;
|
||||
/* Wait for erase to complete */
|
||||
while ((STM32_FLASH_SR & 1) &&
|
||||
watchdog_reload();
|
||||
while ((STM32_FLASH_SR & FLASH_SR_BUSY) &&
|
||||
(get_time().val < deadline.val)) {
|
||||
usleep(300);
|
||||
usleep(timeout_us/100);
|
||||
}
|
||||
if (STM32_FLASH_SR & 1) {
|
||||
if (STM32_FLASH_SR & FLASH_SR_BUSY) {
|
||||
res = EC_ERROR_TIMEOUT;
|
||||
goto exit_er;
|
||||
}
|
||||
@@ -317,15 +335,18 @@ int flash_physical_erase(int offset, int size)
|
||||
* Check for error conditions - erase failed, voltage error,
|
||||
* protection error
|
||||
*/
|
||||
if (STM32_FLASH_SR & 0x14) {
|
||||
if (STM32_FLASH_SR & FLASH_SR_ALL_ERR) {
|
||||
res = EC_ERROR_UNKNOWN;
|
||||
goto exit_er;
|
||||
}
|
||||
next_sector:
|
||||
size -= sector_size;
|
||||
offset += sector_size;
|
||||
}
|
||||
|
||||
exit_er:
|
||||
/* reset PER bit */
|
||||
STM32_FLASH_CR &= ~PER;
|
||||
/* reset SER/PER bit */
|
||||
STM32_FLASH_CR &= ~FLASH_CR_PER;
|
||||
|
||||
lock();
|
||||
|
||||
@@ -400,6 +421,9 @@ static int registers_need_reset(void)
|
||||
int ro_at_boot = (flags & EC_FLASH_PROTECT_RO_AT_BOOT) ? 1 : 0;
|
||||
int ro_wp_region_start = WP_BANK_OFFSET;
|
||||
int ro_wp_region_end = WP_BANK_OFFSET + WP_BANK_COUNT;
|
||||
#ifdef CONFIG_FLASH_PSTATE
|
||||
ro_wp_region_end += PSTATE_BANK_COUNT;
|
||||
#endif
|
||||
|
||||
for (i = ro_wp_region_start; i < ro_wp_region_end; i++)
|
||||
if (flash_physical_get_protect_at_boot(i) != ro_at_boot)
|
||||
|
||||
@@ -1298,14 +1298,14 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t;
|
||||
#define STM32_FLASH_WRPR REG32(STM32_FLASH_REGS_BASE + 0x20)
|
||||
|
||||
#define STM32_OPTB_BASE 0x1ff80000
|
||||
#define STM32_OPTB_RDP 0x00
|
||||
#define STM32_OPTB_USER 0x04
|
||||
#define STM32_OPTB_WRP1L 0x08
|
||||
#define STM32_OPTB_WRP1H 0x0c
|
||||
#define STM32_OPTB_WRP2L 0x10
|
||||
#define STM32_OPTB_WRP2H 0x14
|
||||
#define STM32_OPTB_WRP3L 0x18
|
||||
#define STM32_OPTB_WRP3H 0x1c
|
||||
#define STM32_OPTB_RDP 0x00
|
||||
#define STM32_OPTB_USER 0x04
|
||||
#define STM32_OPTB_WRP1L 0x08
|
||||
#define STM32_OPTB_WRP1H 0x0c
|
||||
#define STM32_OPTB_WRP2L 0x10
|
||||
#define STM32_OPTB_WRP2H 0x14
|
||||
#define STM32_OPTB_WRP3L 0x18
|
||||
#define STM32_OPTB_WRP3H 0x1c
|
||||
|
||||
#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3)
|
||||
#define STM32_FLASH_REGS_BASE 0x40022000
|
||||
@@ -1316,22 +1316,40 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t;
|
||||
#define STM32_FLASH_ACR_LATENCY (1 << 0)
|
||||
#define STM32_FLASH_ACR_PRFTEN (1 << 4)
|
||||
#define STM32_FLASH_KEYR REG32(STM32_FLASH_REGS_BASE + 0x04)
|
||||
#define FLASH_KEYR_KEY1 0x45670123
|
||||
#define FLASH_KEYR_KEY2 0xCDEF89AB
|
||||
|
||||
#define STM32_FLASH_OPTKEYR REG32(STM32_FLASH_REGS_BASE + 0x08)
|
||||
#define FLASH_OPTKEYR_KEY1 FLASH_KEYR_KEY1
|
||||
#define FLASH_OPTKEYR_KEY2 FLASH_KEYR_KEY2
|
||||
#define STM32_FLASH_SR REG32(STM32_FLASH_REGS_BASE + 0x0c)
|
||||
#define FLASH_SR_BUSY (1 << 0)
|
||||
#define FLASH_SR_PGERR (1 << 2)
|
||||
#define FLASH_SR_WRPRTERR (1 << 4)
|
||||
#define FLASH_SR_ALL_ERR \
|
||||
(FLASH_SR_PGERR | FLASH_SR_WRPRTERR)
|
||||
#define FLASH_SR_EOP (1 << 5)
|
||||
#define STM32_FLASH_CR REG32(STM32_FLASH_REGS_BASE + 0x10)
|
||||
#define STM32_FLASH_CR_OBL_LAUNCH (1 << 13)
|
||||
#define FLASH_CR_PG (1 << 0)
|
||||
#define FLASH_CR_PER (1 << 1)
|
||||
#define FLASH_CR_OPTPG (1 << 4)
|
||||
#define FLASH_CR_OPTSTRT (1 << 5)
|
||||
#define FLASH_CR_STRT (1 << 6)
|
||||
#define FLASH_CR_LOCK (1 << 7)
|
||||
#define FLASH_CR_OPTWRE (1 << 9)
|
||||
#define FLASH_CR_OBL_LAUNCH (1 << 13)
|
||||
#define STM32_FLASH_OPT_LOCKED (STM32_FLASH_CR & FLASH_CR_OPTWRE)
|
||||
#define STM32_FLASH_AR REG32(STM32_FLASH_REGS_BASE + 0x14)
|
||||
#define STM32_FLASH_OBR REG32(STM32_FLASH_REGS_BASE + 0x1c)
|
||||
#define STM32_FLASH_OBR_RDP_MASK (3 << 1)
|
||||
#define STM32_FLASH_OBR_RDP_MASK (3 << 1)
|
||||
#define STM32_FLASH_WRPR REG32(STM32_FLASH_REGS_BASE + 0x20)
|
||||
|
||||
#define STM32_OPTB_BASE 0x1FFFF800
|
||||
|
||||
#define STM32_OPTB_RDP_OFF 0x00
|
||||
#define STM32_OPTB_USER_OFF 0x02
|
||||
#define STM32_OPTB_WRP_OFF(n) (0x08 + (n&3) * 2)
|
||||
#define STM32_OPTB_WRP01 0x08
|
||||
#define STM32_OPTB_WRP23 0x0c
|
||||
#define STM32_OPTB_RDP_OFF 0x00
|
||||
#define STM32_OPTB_USER_OFF 0x02
|
||||
#define STM32_OPTB_WRP_OFF(n) (0x08 + (n&3) * 2)
|
||||
#define STM32_OPTB_WRP01 0x08
|
||||
#define STM32_OPTB_WRP23 0x0c
|
||||
|
||||
#define STM32_OPTB_COMPL_SHIFT 8
|
||||
|
||||
|
||||
@@ -291,7 +291,7 @@ void system_reset(int flags)
|
||||
* The reload request triggers a chip reset, so let's just
|
||||
* use this for hard reset.
|
||||
*/
|
||||
STM32_FLASH_CR |= STM32_FLASH_CR_OBL_LAUNCH;
|
||||
STM32_FLASH_CR |= FLASH_CR_OBL_LAUNCH;
|
||||
#elif defined(CHIP_FAMILY_STM32L4)
|
||||
STM32_FLASH_KEYR = FLASH_KEYR_KEY1;
|
||||
STM32_FLASH_KEYR = FLASH_KEYR_KEY2;
|
||||
|
||||
Reference in New Issue
Block a user