Commit f4953e76 authored by Roberto Vargas's avatar Roberto Vargas
Browse files

norflash: clean-up norflash.c



- Add comments to all the functions
- Simplify nor_poll_dws
- Simplify nor_word_program

Change-Id: I29c0199d2908a4fceb1ac3430fcfdd699be22bb3
Signed-off-by: default avatarRoberto Vargas <roberto.vargas@arm.com>
parent 5ae4dab2
/* /*
* 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 * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -8,6 +8,14 @@ ...@@ -8,6 +8,14 @@
#include <mmio.h> #include <mmio.h>
#include <norflash.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 */ /* Helper macros to access two flash banks in parallel */
#define NOR_2X16(d) ((d << 16) | (d & 0xffff)) #define NOR_2X16(d) ((d << 16) | (d & 0xffff))
...@@ -18,6 +26,9 @@ ...@@ -18,6 +26,9 @@
*/ */
#define DWS_WORD_PROGRAM_RETRIES 1000 #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: * Poll Write State Machine. Return values:
* 0 = WSM ready * 0 = WSM ready
...@@ -25,24 +36,16 @@ ...@@ -25,24 +36,16 @@
*/ */
static int nor_poll_dws(uintptr_t base_addr, unsigned int retries) static int nor_poll_dws(uintptr_t base_addr, unsigned int retries)
{ {
uint32_t status; unsigned long status;
int ret;
for (;;) { do {
nor_send_cmd(base_addr, NOR_CMD_READ_STATUS_REG); nor_send_cmd(base_addr, NOR_CMD_READ_STATUS_REG);
status = mmio_read_32(base_addr); status = mmio_read_32(base_addr);
if ((status & NOR_DWS) && if ((status & NOR_CMD_END) == NOR_CMD_END)
(status & (NOR_DWS << 16))) { return 0;
ret = 0; } while (retries-- > 0);
break;
}
if (retries-- == 0) {
ret = -EBUSY;
break;
}
}
return ret; return -EBUSY;
} }
void nor_send_cmd(uintptr_t base_addr, unsigned long cmd) 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) ...@@ -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: * Return values:
* 0 = success * 0 = success
* -EBUSY = WSM not ready * -EBUSY = WSM not ready
...@@ -66,10 +72,7 @@ int nor_word_program(uintptr_t base_addr, unsigned long data) ...@@ -66,10 +72,7 @@ int nor_word_program(uintptr_t base_addr, unsigned long data)
mmio_write_32(base_addr, data); mmio_write_32(base_addr, data);
ret = nor_poll_dws(base_addr, DWS_WORD_PROGRAM_RETRIES); ret = nor_poll_dws(base_addr, DWS_WORD_PROGRAM_RETRIES);
if (ret != 0) { if (ret == 0) {
goto word_program_end;
}
/* Full status check */ /* Full status check */
nor_send_cmd(base_addr, NOR_CMD_READ_STATUS_REG); nor_send_cmd(base_addr, NOR_CMD_READ_STATUS_REG);
status = mmio_read_32(base_addr); status = mmio_read_32(base_addr);
...@@ -78,12 +81,15 @@ int nor_word_program(uintptr_t base_addr, unsigned long data) ...@@ -78,12 +81,15 @@ int nor_word_program(uintptr_t base_addr, unsigned long data)
nor_send_cmd(base_addr, NOR_CMD_CLEAR_STATUS_REG); nor_send_cmd(base_addr, NOR_CMD_CLEAR_STATUS_REG);
ret = -EPERM; ret = -EPERM;
} }
}
word_program_end:
nor_send_cmd(base_addr, NOR_CMD_READ_ARRAY); nor_send_cmd(base_addr, NOR_CMD_READ_ARRAY);
return ret; return ret;
} }
/*
* Lock a full 256 block
*/
void nor_lock(uintptr_t base_addr) void nor_lock(uintptr_t base_addr)
{ {
nor_send_cmd(base_addr, NOR_CMD_LOCK_UNLOCK); nor_send_cmd(base_addr, NOR_CMD_LOCK_UNLOCK);
...@@ -91,10 +97,12 @@ void nor_lock(uintptr_t base_addr) ...@@ -91,10 +97,12 @@ void nor_lock(uintptr_t base_addr)
nor_send_cmd(base_addr, NOR_CMD_READ_ARRAY); nor_send_cmd(base_addr, NOR_CMD_READ_ARRAY);
} }
/*
* unlock a full 256 block
*/
void nor_unlock(uintptr_t base_addr) void nor_unlock(uintptr_t base_addr)
{ {
nor_send_cmd(base_addr, NOR_CMD_LOCK_UNLOCK); nor_send_cmd(base_addr, NOR_CMD_LOCK_UNLOCK);
mmio_write_32(base_addr, NOR_2X16(NOR_UNLOCK_BLOCK)); mmio_write_32(base_addr, NOR_2X16(NOR_UNLOCK_BLOCK));
nor_send_cmd(base_addr, NOR_CMD_READ_ARRAY); nor_send_cmd(base_addr, NOR_CMD_READ_ARRAY);
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment