From ce3bead6089b9f2356d3c89d289912c34714071d Mon Sep 17 00:00:00 2001
From: Kuldeep Singh <kuldeep.singh@nxp.com>
Date: Thu, 21 Nov 2019 17:15:17 +0530
Subject: [PATCH] fsl-lsch3: soc: Enable AHB read support for Flexspi
 controller

Enable AHB support for Flexspi controller interface meaning
memory can be accessed via md command using absolute addresses

Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur@nxp.com>
Signed-off-by: Ashish Kumar <Ashish.Kumar@nxp.com>
Signed-off-by: Rajat Srivastava <rajat.srivastava@nxp.com>
Signed-off-by: Kuldeep Singh <kuldeep.singh@nxp.com>
Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com>
---
 arch/arm/cpu/armv8/fsl-layerscape/Kconfig     |  9 ++++
 arch/arm/cpu/armv8/fsl-layerscape/soc.c       | 44 +++++++++++++++++++
 .../arm/include/asm/arch-fsl-layerscape/soc.h |  7 +++
 3 files changed, 60 insertions(+)

diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
index 0de840aaa2..ab1e3fbed6 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
+++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
@@ -397,6 +397,15 @@ config QSPI_AHB_INIT
 	  But some QSPI flash size up to 64MBytes, so initialize the QSPI AHB
 	  bus for those flashes to support the full QSPI flash size.
 
+config FSPI_AHB_EN_4BYTE
+	bool "Enable 4-byte Fast Read command for AHB mode"
+	default n
+	help
+	  The default setting for FlexSPI AHB bus just supports 3-byte addressing.
+	  But some FlexSPI flash sizes are up to 64MBytes.
+	  This flag enables fast read command for AHB mode and modifies required
+	  LUT to support full FlexSPI flash.
+
 config SYS_CCI400_OFFSET
 	hex "Offset for CCI400 base"
 	depends on SYS_FSL_HAS_CCI400
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
index 4b193c6091..578f8d12de 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
@@ -686,6 +686,47 @@ void fsl_lsch2_early_init_f(void)
 }
 #endif
 
+#ifdef CONFIG_FSPI_AHB_EN_4BYTE
+int fspi_ahb_init(void)
+{
+	/* Enable 4bytes address support and fast read */
+	u32 *fspi_lut, lut_key, *fspi_key;
+
+	fspi_key = (void *)SYS_NXP_FSPI_ADDR + SYS_NXP_FSPI_LUTKEY_BASE_ADDR;
+	fspi_lut = (void *)SYS_NXP_FSPI_ADDR + SYS_NXP_FSPI_LUT_BASE_ADDR;
+
+	lut_key = in_be32(fspi_key);
+
+	if (lut_key == SYS_NXP_FSPI_LUTKEY) {
+		/* That means the register is BE */
+		out_be32(fspi_key, SYS_NXP_FSPI_LUTKEY);
+		/* Unlock the lut table */
+		out_be32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_UNLOCK);
+		/* Create READ LUT */
+		out_be32(fspi_lut, 0x0820040c);
+		out_be32(fspi_lut + 1, 0x24003008);
+		out_be32(fspi_lut + 2, 0x00000000);
+		/* Lock the lut table */
+		out_be32(fspi_key, SYS_NXP_FSPI_LUTKEY);
+		out_be32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_LOCK);
+	} else {
+		/* That means the register is LE */
+		out_le32(fspi_key, SYS_NXP_FSPI_LUTKEY);
+		/* Unlock the lut table */
+		out_le32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_UNLOCK);
+		/* Create READ LUT */
+		out_le32(fspi_lut, 0x0820040c);
+		out_le32(fspi_lut + 1, 0x24003008);
+		out_le32(fspi_lut + 2, 0x00000000);
+		/* Lock the lut table */
+		out_le32(fspi_key, SYS_NXP_FSPI_LUTKEY);
+		out_le32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_LOCK);
+	}
+
+	return 0;
+}
+#endif
+
 #ifdef CONFIG_QSPI_AHB_INIT
 /* Enable 4bytes address support and fast read */
 int qspi_ahb_init(void)
@@ -878,6 +919,9 @@ int board_late_init(void)
 #ifdef CONFIG_QSPI_AHB_INIT
 	qspi_ahb_init();
 #endif
+#ifdef CONFIG_FSPI_AHB_EN_4BYTE
+	fspi_ahb_init();
+#endif
 
 	return fsl_board_late_init();
 }
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/soc.h b/arch/arm/include/asm/arch-fsl-layerscape/soc.h
index 35719d747b..c62d414aac 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/soc.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/soc.h
@@ -140,6 +140,13 @@ void init_pfe_scfg_dcfg_regs(void);
 int qspi_ahb_init(void);
 #endif
 
+#ifdef CONFIG_FSPI_AHB_EN_4BYTE
+#define SYS_NXP_FSPI_LUTCR_LOCK			0x00000001
+#define SYS_NXP_FSPI_LUTCR_UNLOCK		0x00000002
+#define SYS_NXP_FSPI_LUTKEY			0x5AF05AF0
+int fspi_ahb_init(void);
+#endif
+
 void cpu_name(char *name);
 #ifdef CONFIG_SYS_FSL_ERRATUM_A009635
 void erratum_a009635(void);
-- 
2.39.5