layerscape: Initial TF-A support for LS1043ardb

This patch introduce TF-A support for NXP's ls1043a platform.
more details information of ls1043a chip and ls1043ardb board
can be found at docs/plat/ls1043a.rst.

Boot sequence on ls1043a is: bootrom loads bl1 firstly, then bl1
loads bl2, bl2 will load bl31, bl32 and bl33, bl31 will boot
bl32(tee os) and bl33(u-boot or uefi), bl33 boot Linux kernel.

Now TF-A on ls1043ardb platform has the following features in this patch:
	* Support boot from Nor flash.
	* TF-A can boot bl33 which runs in el2 of non-secure world.
	* TF-A boot OPTee OS.
	* Support PSCI

Signed-off-by: Jiafei Pan <Jiafei.Pan@nxp.com>
Signed-off-by: Chenyin.Ha <Chenyin.Ha@nxp.com>
Signed-off-by: Chenhui Zhao <chenhui.zhao@nxp.com>
Signed-off-by: jiaheng.fan <jiaheng.fan@nxp.com>
Signed-off-by: Wen He <wen.he_1@nxp.com>
diff --git a/plat/layerscape/board/ls1043/ls1043_psci.c b/plat/layerscape/board/ls1043/ls1043_psci.c
new file mode 100644
index 0000000..a41e79e
--- /dev/null
+++ b/plat/layerscape/board/ls1043/ls1043_psci.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <debug.h>
+#include <errno.h>
+#include <assert.h>
+#include <platform.h>
+#include <psci.h>
+#include <mmio.h>
+#include <sys/endian.h>
+#include <gicv2.h>
+#include <delay_timer.h>
+#include "platform_def.h"
+
+#define LS_SCFG_BASE			0x01570000
+/* register to store warm boot entry, big endian, higher 32bit */
+#define LS_SCFG_SCRATCHRW0_OFFSET	     0x600
+/* register to store warm boot entry, big endian, lower 32bit */
+#define LS_SCFG_SCRATCHRW1_OFFSET	     0x604
+#define LS_SCFG_COREBCR_OFFSET		     0x680
+
+#define LS_DCFG_BASE			0x01EE0000
+#define LS_DCFG_RSTCR_OFFSET		     0x0B0
+#define LS_DCFG_RSTRQMR1_OFFSET		     0x0C0
+#define LS_DCFG_BRR_OFFSET		     0x0E4
+
+#define LS_SCFG_CORE0_SFT_RST_OFFSET		0x130
+#define LS_SCFG_CORE1_SFT_RST_OFFSET		0x134
+#define LS_SCFG_CORE2_SFT_RST_OFFSET		0x138
+#define LS_SCFG_CORE3_SFT_RST_OFFSET		0x13C
+
+#define LS_SCFG_CORESRENCR_OFFSET		0x204
+
+#define LS_SCFG_RVBAR0_0_OFFSET			0x220
+#define LS_SCFG_RVBAR0_1_OFFSET			0x224
+
+#define LS_SCFG_RVBAR1_0_OFFSET			0x228
+#define LS_SCFG_RVBAR1_1_OFFSET			0x22C
+
+#define LS_SCFG_RVBAR2_0_OFFSET			0x230
+#define LS_SCFG_RVBAR2_1_OFFSET			0x234
+
+#define LS_SCFG_RVBAR3_0_OFFSET			0x238
+#define LS_SCFG_RVBAR3_1_OFFSET			0x23C
+
+/* the entry for core warm boot */
+static uintptr_t warmboot_entry;
+
+/* warm reset single core */
+static void ls1043_reset_core(int core_pos)
+{
+	assert(core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT);
+
+	/* set 0 in RVBAR, boot from bootrom at 0x0 */
+	mmio_write_32(LS_SCFG_BASE + LS_SCFG_RVBAR0_0_OFFSET + core_pos * 8,
+		      0);
+	mmio_write_32(LS_SCFG_BASE + LS_SCFG_RVBAR0_1_OFFSET + core_pos * 8,
+		      0);
+
+	dsb();
+	/* enable core soft reset */
+	mmio_write_32(LS_SCFG_BASE + LS_SCFG_CORESRENCR_OFFSET,
+		      htobe32(1 << 31));
+	dsb();
+	isb();
+	/* reset core */
+	mmio_write_32(LS_SCFG_BASE + LS_SCFG_CORE0_SFT_RST_OFFSET +
+			core_pos * 4, htobe32(1 << 31));
+	mdelay(10);
+}
+
+static void __dead2 ls1043_system_reset(void)
+{
+	/* clear reset request mask bits */
+	mmio_write_32(LS_DCFG_BASE + LS_DCFG_RSTRQMR1_OFFSET, 0);
+
+	/* set reset request bit */
+	mmio_write_32(LS_DCFG_BASE + LS_DCFG_RSTCR_OFFSET,
+		      htobe32((uint32_t)0x2));
+
+	/* system will reset; if fail, enter wfi */
+	dsb();
+	isb();
+	wfi();
+
+	panic();
+}
+
+
+static int ls1043_pwr_domain_on(u_register_t mpidr)
+{
+	int core_pos = plat_core_pos_by_mpidr(mpidr);
+	uint32_t core_mask = 1 << core_pos;
+	uint32_t brr;
+
+	assert(core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT);
+
+	/* set warm boot entry */
+	mmio_write_32(LS_SCFG_BASE + LS_SCFG_SCRATCHRW0_OFFSET,
+		htobe32((uint32_t)(warmboot_entry >> 32)));
+
+	mmio_write_32(LS_SCFG_BASE + LS_SCFG_SCRATCHRW1_OFFSET,
+		htobe32((uint32_t)warmboot_entry));
+
+	dsb();
+
+	brr = be32toh(mmio_read_32(LS_DCFG_BASE + LS_DCFG_BRR_OFFSET));
+	if (brr & core_mask) {
+		/* core has been released, must reset it to restart */
+		ls1043_reset_core(core_pos);
+
+		/* set bit in core boot control register to enable boot */
+		mmio_write_32(LS_SCFG_BASE + LS_SCFG_COREBCR_OFFSET,
+			htobe32(core_mask));
+
+	} else {
+		/* set bit in core boot control register to enable boot */
+		mmio_write_32(LS_SCFG_BASE + LS_SCFG_COREBCR_OFFSET,
+			htobe32(core_mask));
+
+		/* release core */
+		mmio_write_32(LS_DCFG_BASE + LS_DCFG_BRR_OFFSET,
+			      htobe32(brr | core_mask));
+	}
+
+	mdelay(20);
+
+	/* wake core in case it is in wfe */
+	dsb();
+	isb();
+	sev();
+
+	return PSCI_E_SUCCESS;
+}
+
+static void ls1043_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	/* Per cpu gic distributor setup */
+	gicv2_pcpu_distif_init();
+
+	/* Enable the gic CPU interface */
+	gicv2_cpuif_enable();
+}
+
+static void ls1043_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	/* Disable the gic CPU interface */
+	gicv2_cpuif_disable();
+}
+
+static plat_psci_ops_t ls1043_psci_pm_ops = {
+	.system_reset = ls1043_system_reset,
+	.pwr_domain_on = ls1043_pwr_domain_on,
+	.pwr_domain_on_finish = ls1043_pwr_domain_on_finish,
+	.pwr_domain_off = ls1043_pwr_domain_off,
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	warmboot_entry = sec_entrypoint;
+	*psci_ops = &ls1043_psci_pm_ops;
+	return 0;
+}