armv8: QSPI: Add AHB bus 16MB+ size support

The default configuration for QSPI AHB bus can't support 16MB+.
But some flash on NXP layerscape board are more than 16MB.

Signed-off-by: Yuan Yao <yao.yuan@nxp.com>
Reviewed-by: York Sun <york.sun@nxp.com>
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
index ed1c4ee..6772584 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
+++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
@@ -76,6 +76,13 @@
 	help
 		Enable Freescale Secure Boot feature
 
+config QSPI_AHB_INIT
+	bool "Init the QSPI AHB bus"
+	help
+	  The default setting for QSPI AHB bus just support 3bytes addressing.
+	  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 SYS_FSL_IFC_BANK_COUNT
 	int "Maximum banks of Integrated flash controller"
 	depends on ARCH_LS1043A || ARCH_LS1046A || ARCH_LS2080A
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
index 6c42387..2f54625 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
@@ -373,6 +373,45 @@
 }
 #endif
 
+#ifdef CONFIG_QSPI_AHB_INIT
+/* Enable 4bytes address support and fast read */
+int qspi_ahb_init(void)
+{
+	u32 *qspi_lut, lut_key, *qspi_key;
+
+	qspi_key = (void *)SYS_FSL_QSPI_ADDR + 0x300;
+	qspi_lut = (void *)SYS_FSL_QSPI_ADDR + 0x310;
+
+	lut_key = in_be32(qspi_key);
+
+	if (lut_key == 0x5af05af0) {
+		/* That means the register is BE */
+		out_be32(qspi_key, 0x5af05af0);
+		/* Unlock the lut table */
+		out_be32(qspi_key + 1, 0x00000002);
+		out_be32(qspi_lut, 0x0820040c);
+		out_be32(qspi_lut + 1, 0x1c080c08);
+		out_be32(qspi_lut + 2, 0x00002400);
+		/* Lock the lut table */
+		out_be32(qspi_key, 0x5af05af0);
+		out_be32(qspi_key + 1, 0x00000001);
+	} else {
+		/* That means the register is LE */
+		out_le32(qspi_key, 0x5af05af0);
+		/* Unlock the lut table */
+		out_le32(qspi_key + 1, 0x00000002);
+		out_le32(qspi_lut, 0x0820040c);
+		out_le32(qspi_lut + 1, 0x1c080c08);
+		out_le32(qspi_lut + 2, 0x00002400);
+		/* Lock the lut table */
+		out_le32(qspi_key, 0x5af05af0);
+		out_le32(qspi_key + 1, 0x00000001);
+	}
+
+	return 0;
+}
+#endif
+
 #ifdef CONFIG_BOARD_LATE_INIT
 int board_late_init(void)
 {
@@ -382,6 +421,9 @@
 #ifdef CONFIG_CHAIN_OF_TRUST
 	fsl_setenv_chain_of_trust();
 #endif
+#ifdef CONFIG_QSPI_AHB_INIT
+	qspi_ahb_init();
+#endif
 
 	return 0;
 }