norflash: clean-up norflash.c
authorRoberto Vargas <roberto.vargas@arm.com>
Wed, 26 Jul 2017 13:15:07 +0000 (14:15 +0100)
committerRoberto Vargas <roberto.vargas@arm.com>
Tue, 22 Aug 2017 08:41:59 +0000 (09:41 +0100)
- Add comments to all the functions
- Simplify nor_poll_dws
- Simplify nor_word_program

Change-Id: I29c0199d2908a4fceb1ac3430fcfdd699be22bb3
Signed-off-by: Roberto Vargas <roberto.vargas@arm.com>
plat/arm/board/common/drivers/norflash/norflash.c

index cc63d758ea2f9bb9c7b39f9428afbc45e4281429..053696eedc70fbf2b6373cef00e204de0b5a3ff3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,14 @@
 #include <mmio.h>
 #include <norflash.h>
 
+/*
+ * This file supplies a low level interface to the vexpress NOR flash
+ * memory of juno and fvp. This memory is organized as an interleaved
+ * memory of two chips with a 16 bit word. It means that every 32 bit
+ * access is going to access to two different chips. This is very
+ * important when we send commands or read status of the chips
+ */
+
 /* Helper macros to access two flash banks in parallel */
 #define NOR_2X16(d)                    ((d << 16) | (d & 0xffff))
 
@@ -18,6 +26,9 @@
  */
 #define DWS_WORD_PROGRAM_RETRIES       1000
 
+/* Helper macro to detect end of command */
+#define NOR_CMD_END (NOR_DWS | NOR_DWS << 16l)
+
 /*
  * Poll Write State Machine. Return values:
  *    0      = WSM ready
  */
 static int nor_poll_dws(uintptr_t base_addr, unsigned int retries)
 {
-       uint32_t status;
-       int ret;
+       unsigned long status;
 
-       for (;;) {
+       do {
                nor_send_cmd(base_addr, NOR_CMD_READ_STATUS_REG);
                status = mmio_read_32(base_addr);
-               if ((status & NOR_DWS) &&
-                   (status & (NOR_DWS << 16))) {
-                       ret = 0;
-                       break;
-               }
-               if (retries-- == 0) {
-                       ret = -EBUSY;
-                       break;
-               }
-       }
+               if ((status & NOR_CMD_END) == NOR_CMD_END)
+                       return 0;
+       } while (retries-- > 0);
 
-       return ret;
+       return -EBUSY;
 }
 
 void nor_send_cmd(uintptr_t base_addr, unsigned long cmd)
@@ -51,6 +54,9 @@ void nor_send_cmd(uintptr_t base_addr, unsigned long cmd)
 }
 
 /*
+ * This function programs a word in the flash. Be aware that it only
+ * can reset bits that were previously set. It cannot set bits that
+ * were previously reset. The resulting bits = old_bits & new bits.
  * Return values:
  *    0      = success
  *    -EBUSY = WSM not ready
@@ -66,24 +72,24 @@ int nor_word_program(uintptr_t base_addr, unsigned long data)
        mmio_write_32(base_addr, data);
 
        ret = nor_poll_dws(base_addr, DWS_WORD_PROGRAM_RETRIES);
-       if (ret != 0) {
-               goto word_program_end;
-       }
-
-       /* Full status check */
-       nor_send_cmd(base_addr, NOR_CMD_READ_STATUS_REG);
-       status = mmio_read_32(base_addr);
+       if (ret == 0) {
+               /* Full status check */
+               nor_send_cmd(base_addr, NOR_CMD_READ_STATUS_REG);
+               status = mmio_read_32(base_addr);
 
-       if (status & (NOR_PS | NOR_BLS)) {
-               nor_send_cmd(base_addr, NOR_CMD_CLEAR_STATUS_REG);
-               ret = -EPERM;
+               if (status & (NOR_PS | NOR_BLS)) {
+                       nor_send_cmd(base_addr, NOR_CMD_CLEAR_STATUS_REG);
+                       ret = -EPERM;
+               }
        }
 
-word_program_end:
        nor_send_cmd(base_addr, NOR_CMD_READ_ARRAY);
        return ret;
 }
 
+/*
+ * Lock a full 256 block
+ */
 void nor_lock(uintptr_t base_addr)
 {
        nor_send_cmd(base_addr, NOR_CMD_LOCK_UNLOCK);
@@ -91,10 +97,12 @@ void nor_lock(uintptr_t base_addr)
        nor_send_cmd(base_addr, NOR_CMD_READ_ARRAY);
 }
 
+/*
+ * unlock a full 256 block
+ */
 void nor_unlock(uintptr_t base_addr)
 {
        nor_send_cmd(base_addr, NOR_CMD_LOCK_UNLOCK);
        mmio_write_32(base_addr, NOR_2X16(NOR_UNLOCK_BLOCK));
        nor_send_cmd(base_addr, NOR_CMD_READ_ARRAY);
 }
-