From 784502aeaed11aad205eb80ed05b1f78fc643d93 Mon Sep 17 00:00:00 2001 From: Roberto Vargas Date: Fri, 28 Jul 2017 10:38:24 +0100 Subject: [PATCH] norflash: Add nor_erase() to NOR driver NOR memory only supports setting bits to 1. To clear a bit, set to zero, the NOR memory needs to be erased. Change-Id: Ia82eb15a5af9a6d4fc7e5ea2b58e6db87226b351 Signed-off-by: Roberto Vargas --- .../plat/arm/board/common/drivers/norflash.h | 2 ++ .../board/common/drivers/norflash/norflash.c | 24 ++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/include/plat/arm/board/common/drivers/norflash.h b/include/plat/arm/board/common/drivers/norflash.h index 4b66e4251..5763b36df 100644 --- a/include/plat/arm/board/common/drivers/norflash.h +++ b/include/plat/arm/board/common/drivers/norflash.h @@ -19,6 +19,7 @@ #define NOR_CMD_WORD_PROGRAM 0x40 #define NOR_CMD_BLOCK_ERASE 0x20 #define NOR_CMD_LOCK_UNLOCK 0x60 +#define NOR_CMD_BLOCK_ERASE_ACK 0xD0 /* Second bus cycle */ #define NOR_LOCK_BLOCK 0x01 @@ -39,6 +40,7 @@ void nor_send_cmd(uintptr_t base_addr, unsigned long cmd); int nor_word_program(uintptr_t base_addr, unsigned long data); int nor_lock(uintptr_t base_addr); int nor_unlock(uintptr_t base_addr); +int nor_erase(uintptr_t base_addr); #endif /* __NORFLASH_H_ */ diff --git a/plat/arm/board/common/drivers/norflash/norflash.c b/plat/arm/board/common/drivers/norflash/norflash.c index ee9eca7e1..e0047c006 100644 --- a/plat/arm/board/common/drivers/norflash/norflash.c +++ b/plat/arm/board/common/drivers/norflash/norflash.c @@ -25,6 +25,7 @@ * model */ #define DWS_WORD_PROGRAM_RETRIES 1000 +#define DWS_WORD_ERASE_RETRIES 3000000 #define DWS_WORD_LOCK_RETRIES 1000 /* Helper macro to detect end of command */ @@ -35,7 +36,7 @@ * 0 = WSM ready * -EBUSY = WSM busy after the number of retries */ -static int nor_poll_dws(uintptr_t base_addr, unsigned int retries) +static int nor_poll_dws(uintptr_t base_addr, unsigned long int retries) { unsigned long status; @@ -90,6 +91,27 @@ int nor_word_program(uintptr_t base_addr, unsigned long data) return ret; } +/* + * Erase a full 256K block + * Return values: + * 0 = success + * -EBUSY = WSM not ready + */ +int nor_erase(uintptr_t base_addr) +{ + int ret; + + nor_send_cmd(base_addr, NOR_CMD_CLEAR_STATUS_REG); + + nor_send_cmd(base_addr, NOR_CMD_BLOCK_ERASE); + nor_send_cmd(base_addr, NOR_CMD_BLOCK_ERASE_ACK); + + ret = nor_poll_dws(base_addr, DWS_WORD_ERASE_RETRIES); + nor_send_cmd(base_addr, NOR_CMD_READ_ARRAY); + + return ret; +} + /* * Lock a full 256 block * Return values: