plat/arm: Move norflash driver to drivers/ folder

This way it can be reused by other platforms if needed.

Note that this driver is designed to work with the Versatile Express NOR
flash of Juno and FVP. In said platforms, the memory is organized as an
interleaved memory of two chips with a 16 bit word.

Any platform that wishes to reuse it with a different configuration will
need to modify the driver so that it is more generic.

Change-Id: Ic721758425864e0cf42b7b9b04bf0d9513b6022e
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index 8b46c4b..2556fc0 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.mk
@@ -4,15 +4,15 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-PLAT_INCLUDES		+=	-Iinclude/plat/arm/board/common/			\
-				-Iinclude/plat/arm/board/common/drivers
+PLAT_INCLUDES		+=	-Iinclude/drivers/cfi/				\
+				-Iinclude/plat/arm/board/common/
 
-PLAT_BL_COMMON_SOURCES	+=	drivers/arm/pl011/${ARCH}/pl011_console.S		\
+PLAT_BL_COMMON_SOURCES	+=	drivers/arm/pl011/${ARCH}/pl011_console.S	\
 				plat/arm/board/common/${ARCH}/board_arm_helpers.S
 
-BL1_SOURCES		+=	plat/arm/board/common/drivers/norflash/norflash.c
+BL1_SOURCES		+=	drivers/cfi/v2m/v2m_flash.c
 
-BL2_SOURCES		+=	plat/arm/board/common/drivers/norflash/norflash.c
+BL2_SOURCES		+=	drivers/cfi/v2m/v2m_flash.c
 
 ifneq (${TRUSTED_BOARD_BOOT},0)
   ifneq (${ARM_CRYPTOCELL_INTEG}, 1)
diff --git a/plat/arm/board/common/drivers/norflash/norflash.c b/plat/arm/board/common/drivers/norflash/norflash.c
deleted file mode 100644
index 722cf33..0000000
--- a/plat/arm/board/common/drivers/norflash/norflash.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <errno.h>
-#include <mmio.h>
-#include <norflash.h>
-
-
-/*
- * DWS ready poll retries. The number of retries in this driver have been
- * obtained empirically from Juno. FVP implements a zero wait state NOR flash
- * 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 */
-#define NOR_CMD_END (NOR_DWS | NOR_DWS << 16l)
-
-/*
- * 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))
-
-static unsigned int nor_status(uintptr_t base_addr)
-{
-	unsigned long status;
-
-	nor_send_cmd(base_addr, NOR_CMD_READ_STATUS_REG);
-	status = mmio_read_32(base_addr);
-	status |= status >> 16; /* merge status from both flash banks */
-
-	return status & 0xFFFF;
-}
-
-/*
- * Poll Write State Machine.
- * Return values:
- *    0      = WSM ready
- *    -EBUSY = WSM busy after the number of retries
- */
-static int nor_poll_dws(uintptr_t base_addr, unsigned long int retries)
-{
-	unsigned long status;
-
-	do {
-		nor_send_cmd(base_addr, NOR_CMD_READ_STATUS_REG);
-		status = mmio_read_32(base_addr);
-		if ((status & NOR_CMD_END) == NOR_CMD_END)
-			return 0;
-	} while (retries-- > 0);
-
-	return -EBUSY;
-}
-
-/*
- * Return values:
- *    0      = success
- *    -EPERM = Device protected or Block locked
- *    -EIO   = General I/O error
- */
-static int nor_full_status_check(uintptr_t base_addr)
-{
-	unsigned long status;
-
-	/* Full status check */
-	status = nor_status(base_addr);
-
-	if (status & (NOR_PS | NOR_BLS | NOR_ESS | NOR_PSS))
-		return -EPERM;
-	if (status & (NOR_VPPS | NOR_ES))
-		return -EIO;
-	return 0;
-}
-
-void nor_send_cmd(uintptr_t base_addr, unsigned long cmd)
-{
-	mmio_write_32(base_addr, NOR_2X16(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
- *  otherwise it returns a negative value
- */
-int nor_word_program(uintptr_t base_addr, unsigned long data)
-{
-	uint32_t status;
-	int ret;
-
-	nor_send_cmd(base_addr, NOR_CMD_CLEAR_STATUS_REG);
-
-	/* Set the device in write word mode */
-	nor_send_cmd(base_addr, NOR_CMD_WORD_PROGRAM);
-	mmio_write_32(base_addr, data);
-
-	ret = nor_poll_dws(base_addr, DWS_WORD_PROGRAM_RETRIES);
-	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 (ret == 0)
-		ret = nor_full_status_check(base_addr);
-	nor_send_cmd(base_addr, NOR_CMD_READ_ARRAY);
-
-	return ret;
-}
-
-/*
- * Erase a full 256K block
- * Return values:
- *  0 = success
- *  otherwise it returns a negative value
- */
-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);
-	if (ret == 0)
-		ret = nor_full_status_check(base_addr);
-	nor_send_cmd(base_addr, NOR_CMD_READ_ARRAY);
-
-	return ret;
-}
-
-/*
- * Lock a full 256 block
- * Return values:
- *  0 = success
- *  otherwise it returns a negative value
- */
-int nor_lock(uintptr_t base_addr)
-{
-	int ret;
-
-	nor_send_cmd(base_addr, NOR_CMD_CLEAR_STATUS_REG);
-
-	nor_send_cmd(base_addr, NOR_CMD_LOCK_UNLOCK);
-	nor_send_cmd(base_addr, NOR_LOCK_BLOCK);
-
-	ret = nor_poll_dws(base_addr, DWS_WORD_LOCK_RETRIES);
-	if (ret == 0)
-		ret = nor_full_status_check(base_addr);
-	nor_send_cmd(base_addr, NOR_CMD_READ_ARRAY);
-
-	return ret;
-}
-
-/*
- * unlock a full 256 block
- * Return values:
- *  0 = success
- *  otherwise it returns a negative value
- */
-int nor_unlock(uintptr_t base_addr)
-{
-	int ret;
-
-	nor_send_cmd(base_addr, NOR_CMD_CLEAR_STATUS_REG);
-
-	nor_send_cmd(base_addr, NOR_CMD_LOCK_UNLOCK);
-	nor_send_cmd(base_addr, NOR_UNLOCK_BLOCK);
-
-	ret = nor_poll_dws(base_addr, DWS_WORD_LOCK_RETRIES);
-	if (ret == 0)
-		ret = nor_full_status_check(base_addr);
-	nor_send_cmd(base_addr, NOR_CMD_READ_ARRAY);
-
-	return ret;
-}
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 9bd3bde..332df4d 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -147,13 +147,13 @@
 				${FVP_SECURITY_SOURCES}
 
 BL31_SOURCES		+=	drivers/arm/smmu/smmu_v3.c			\
+				drivers/cfi/v2m/v2m_flash.c			\
 				lib/utils/mem_region.c				\
 				plat/arm/board/fvp/fvp_bl31_setup.c		\
 				plat/arm/board/fvp/fvp_pm.c			\
 				plat/arm/board/fvp/fvp_topology.c		\
 				plat/arm/board/fvp/aarch64/fvp_helpers.S	\
 				plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c	\
-				plat/arm/board/common/drivers/norflash/norflash.c \
 				plat/arm/common/arm_nor_psci_mem_protect.c	\
 				${FVP_CPU_LIBS}					\
 				${FVP_GIC_SOURCES}				\
diff --git a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
index b370fd5..8b17c9b 100644
--- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
+++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
@@ -1,17 +1,17 @@
 #
-# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 # SP_MIN source files specific to FVP platform
-BL32_SOURCES		+=	lib/utils/mem_region.c				\
+BL32_SOURCES		+=	drivers/cfi/v2m/v2m_flash.c			\
+				lib/utils/mem_region.c				\
 				plat/arm/board/fvp/aarch32/fvp_helpers.S	\
 				plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c	\
 				plat/arm/board/fvp/fvp_pm.c			\
 				plat/arm/board/fvp/fvp_topology.c		\
 				plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c	\
-				plat/arm/board/common/drivers/norflash/norflash.c	\
 				plat/arm/common/arm_nor_psci_mem_protect.c	\
 				${FVP_CPU_LIBS}					\
 				${FVP_GIC_SOURCES}				\
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 90fa938..6e137a7 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -73,12 +73,12 @@
 
 BL2U_SOURCES		+=	${JUNO_SECURITY_SOURCES}
 
-BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a53.S		\
+BL31_SOURCES		+=	drivers/cfi/v2m/v2m_flash.c		\
+				lib/cpus/aarch64/cortex_a53.S		\
 				lib/cpus/aarch64/cortex_a57.S		\
 				lib/cpus/aarch64/cortex_a72.S		\
 				lib/utils/mem_region.c			\
 				plat/arm/board/juno/juno_topology.c	\
-				plat/arm/board/common/drivers/norflash/norflash.c \
 				plat/arm/common/arm_nor_psci_mem_protect.c \
 				${JUNO_GIC_SOURCES}			\
 				${JUNO_INTERCONNECT_SOURCES}		\
diff --git a/plat/arm/board/juno/sp_min/sp_min-juno.mk b/plat/arm/board/juno/sp_min/sp_min-juno.mk
index cd1f497..5278109 100644
--- a/plat/arm/board/juno/sp_min/sp_min-juno.mk
+++ b/plat/arm/board/juno/sp_min/sp_min-juno.mk
@@ -1,15 +1,15 @@
 #
-# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 # SP_MIN source files specific to JUNO platform
-BL32_SOURCES	+=	lib/cpus/aarch32/cortex_a53.S		\
+BL32_SOURCES	+=	drivers/cfi/v2m/v2m_flash.c		\
+			lib/cpus/aarch32/cortex_a53.S		\
 			lib/cpus/aarch32/cortex_a57.S		\
 			lib/cpus/aarch32/cortex_a72.S		\
 			lib/utils/mem_region.c			\
-			plat/arm/board/common/drivers/norflash/norflash.c	\
 			plat/arm/board/juno/juno_topology.c	\
 			plat/arm/common/arm_nor_psci_mem_protect.c	\
 			plat/arm/soc/common/soc_css_security.c	\
diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk
index 284bae8..078f393 100644
--- a/plat/arm/board/sgi575/platform.mk
+++ b/plat/arm/board/sgi575/platform.mk
@@ -9,6 +9,6 @@
 BL2_SOURCES		+=	lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
-BL31_SOURCES		+=	lib/utils/mem_region.c			\
-				plat/arm/board/common/drivers/norflash/norflash.c \
+BL31_SOURCES		+=	drivers/cfi/v2m/v2m_flash.c		\
+				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c
diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk
index 633cee6..c833755 100644
--- a/plat/arm/board/sgm775/platform.mk
+++ b/plat/arm/board/sgm775/platform.mk
@@ -15,6 +15,6 @@
 BL2_SOURCES		+=	lib/utils/mem_region.c                  \
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
-BL31_SOURCES		+=	lib/utils/mem_region.c                  \
-				plat/arm/board/common/drivers/norflash/norflash.c \
+BL31_SOURCES		+=	drivers/cfi/v2m/v2m_flash.c		\
+				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c
diff --git a/plat/arm/common/arm_err.c b/plat/arm/common/arm_err.c
index e13e51f..519d44d 100644
--- a/plat/arm/common/arm_err.c
+++ b/plat/arm/common/arm_err.c
@@ -8,10 +8,10 @@
 #include <console.h>
 #include <debug.h>
 #include <errno.h>
-#include <norflash.h>
 #include <platform.h>
 #include <platform_def.h>
 #include <stdint.h>
+#include <v2m_flash.h>
 
 #pragma weak plat_arm_error_handler
 
diff --git a/plat/arm/common/arm_nor_psci_mem_protect.c b/plat/arm/common/arm_nor_psci_mem_protect.c
index 1b0b1da..07766a0 100644
--- a/plat/arm/common/arm_nor_psci_mem_protect.c
+++ b/plat/arm/common/arm_nor_psci_mem_protect.c
@@ -6,12 +6,11 @@
 
 #include <debug.h>
 #include <mmio.h>
-#include <norflash.h>
 #include <plat_arm.h>
 #include <platform_def.h>
 #include <psci.h>
 #include <utils.h>
-
+#include <v2m_flash.h>
 
 /*
  * DRAM1 is used also to load the NS boot loader. For this reason we