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
*/
......@@ -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
......@@ -25,24 +36,16 @@
*/
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);
}
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