norflash: Add nor_erase() to NOR driver
authorRoberto Vargas <roberto.vargas@arm.com>
Fri, 28 Jul 2017 09:38:24 +0000 (10:38 +0100)
committerRoberto Vargas <roberto.vargas@arm.com>
Tue, 22 Aug 2017 08:41:59 +0000 (09:41 +0100)
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 <roberto.vargas@arm.com>
include/plat/arm/board/common/drivers/norflash.h
plat/arm/board/common/drivers/norflash/norflash.c

index 4b66e42519767a24d6ac7bf61d564832d5c7e544..5763b36df1e13404bddef72a7e6670cd3dc139d9 100644 (file)
@@ -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_ */
 
index ee9eca7e1763d6c63fc4a1a998efddcb86a8a327..e0047c006c180c1f13120a3b6a9f234f66463193 100644 (file)
@@ -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: