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:
Gwendal Grignou
2015-04-03 15:48:23 -07:00
committed by chrome-bot
parent 92ea78398b
commit 72afc55bd9
4 changed files with 122 additions and 80 deletions

View File

@@ -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)
;

View File

@@ -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)

View File

@@ -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

View File

@@ -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;