arm: nuvoton: Add support for Nuvoton NPCM750 BMC

Add basic support for the Nuvoton NPCM750 EVB (Poleg).

Signed-off-by: Jim Liu <JJLIU0@nuvoton.com>
diff --git a/arch/arm/mach-npcm/Kconfig b/arch/arm/mach-npcm/Kconfig
new file mode 100644
index 0000000..cf5043d
--- /dev/null
+++ b/arch/arm/mach-npcm/Kconfig
@@ -0,0 +1,26 @@
+if ARCH_NPCM
+
+config SYS_ARCH
+	default "arm"
+
+config SYS_TEXT_BASE
+	default 0x8000
+
+choice
+	prompt "Nuvoton SoC select"
+	default ARCH_NPCM7xx
+
+config ARCH_NPCM7xx
+	bool "Support Nuvoton NPCM7xx SoC"
+	select CPU_V7A
+	select OF_CONTROL
+	select DM
+	help
+	  General support for NPCM7xx BMC (Poleg).
+	  Nuvoton NPCM7xx BMC is based on the Cortex A9.
+
+endchoice
+
+source "arch/arm/mach-npcm/npcm7xx/Kconfig"
+
+endif
diff --git a/arch/arm/mach-npcm/Makefile b/arch/arm/mach-npcm/Makefile
new file mode 100644
index 0000000..8a1572b
--- /dev/null
+++ b/arch/arm/mach-npcm/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_NPCM7xx) += npcm7xx/
diff --git a/arch/arm/mach-npcm/npcm7xx/Kconfig b/arch/arm/mach-npcm/npcm7xx/Kconfig
new file mode 100644
index 0000000..237e7ba
--- /dev/null
+++ b/arch/arm/mach-npcm/npcm7xx/Kconfig
@@ -0,0 +1,22 @@
+if ARCH_NPCM7xx
+
+config SYS_CPU
+        default "armv7"
+
+config SYS_SOC
+	default "npcm7xx"
+
+config TARGET_POLEG
+	bool "NPCM POLEG board"
+	help
+	  poleg EVB is Nuvoton evaluation board for NPCM750 SoC,
+	  supports general functions of Basebase Management
+	  Controller(BMC).
+
+config SYS_MEM_TOP_HIDE
+	hex "Reserved TOP memory"
+	default 0x03000000
+
+source "board/nuvoton/poleg_evb/Kconfig"
+
+endif
diff --git a/arch/arm/mach-npcm/npcm7xx/Makefile b/arch/arm/mach-npcm/npcm7xx/Makefile
new file mode 100644
index 0000000..49f9877
--- /dev/null
+++ b/arch/arm/mach-npcm/npcm7xx/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_TARGET_POLEG) += cpu.o l2_cache_pl310_init.o l2_cache_pl310.o
diff --git a/arch/arm/mach-npcm/npcm7xx/cpu.c b/arch/arm/mach-npcm/npcm7xx/cpu.c
new file mode 100644
index 0000000..dd74bb9
--- /dev/null
+++ b/arch/arm/mach-npcm/npcm7xx/cpu.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021 Nuvoton Technology Corp.
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <asm/armv7.h>
+#include <asm/io.h>
+#include <asm/arch/gcr.h>
+
+int print_cpuinfo(void)
+{
+	struct npcm_gcr *gcr = (struct npcm_gcr *)NPCM_GCR_BA;
+	unsigned int id, mdlr;
+
+	mdlr = readl(&gcr->mdlr);
+
+	printf("CPU: ");
+
+	switch (mdlr) {
+	case POLEG_NPCM750:
+		printf("NPCM750 ");
+		break;
+	case POLEG_NPCM730:
+		printf("NPCM730 ");
+		break;
+	case POLEG_NPCM710:
+		printf("NPCM710 ");
+		break;
+	default:
+		printf("NPCM7XX ");
+		break;
+	}
+
+	id = readl(&gcr->pdid);
+	switch (id) {
+	case POLEG_Z1:
+		printf("Z1 is no supported! @ ");
+		break;
+	case POLEG_A1:
+		printf("A1 @ ");
+		break;
+	default:
+		printf("Unknown\n");
+		break;
+	}
+
+	return 0;
+}
+
+void s_init(void)
+{
+	/* Invalidate L2 cache in lowlevel_init */
+	v7_outer_cache_inval_all();
+}
+
+void enable_caches(void)
+{
+	dcache_enable();
+}
+
+void disable_caches(void)
+{
+	dcache_disable();
+}
diff --git a/arch/arm/mach-npcm/npcm7xx/l2_cache_pl310.c b/arch/arm/mach-npcm/npcm7xx/l2_cache_pl310.c
new file mode 100644
index 0000000..cba2e34
--- /dev/null
+++ b/arch/arm/mach-npcm/npcm7xx/l2_cache_pl310.c
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021 Nuvoton Technology Corp.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/pl310.h>
+
+void l2_pl310_init(void);
+
+void set_pl310_ctrl(u32 enable)
+{
+	struct pl310_regs *const pl310 = (struct pl310_regs *)CONFIG_SYS_PL310_BASE;
+
+	writel(enable, &pl310->pl310_ctrl);
+}
+
+void v7_outer_cache_enable(void)
+{
+	l2_pl310_init();
+
+	set_pl310_ctrl(1);
+}
+
+void v7_outer_cache_disable(void)
+{
+	set_pl310_ctrl(0);
+}
diff --git a/arch/arm/mach-npcm/npcm7xx/l2_cache_pl310_init.S b/arch/arm/mach-npcm/npcm7xx/l2_cache_pl310_init.S
new file mode 100644
index 0000000..8ec4e37
--- /dev/null
+++ b/arch/arm/mach-npcm/npcm7xx/l2_cache_pl310_init.S
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2021 Nuvoton Technology Corp.
+ */
+
+.align 5
+
+#include <linux/linkage.h>
+
+#ifndef CONFIG_SYS_L2CACHE_OFF
+
+ENTRY(l2_pl310_init)
+
+@------------------------------------------------------------------
+@ L2CC (PL310) Initialization
+@------------------------------------------------------------------
+	@ In this example PL310 PA = VA. The memory was marked as Device memory
+	@ in previous stages when defining CORE0 private address space
+	LDR     r0, =0xF03FC000        @ A9_BASE_ADDR
+
+	@ Disable L2 Cache controller just in case it is already on
+	LDR     r1, =0x0
+	STR     r1, [r0,#0x100]
+
+	@ Set aux cntrl
+	@ Way size = 32KB
+	@ Way = 16
+	LDR     r1, =0x02050000
+	ORR	r1, r1, #(1 << 29)	@ Instruction prefetch enable
+	ORR	r1, r1, #(1 << 28)	@ Data prefetch enable
+	ORR	r1, r1, #(1 << 22)	@ cache replacement policy
+	STR     r1, [r0,#0x104]		@ auxilary control reg at offset 0x104
+
+	@ Set tag RAM latency
+	@ 1 cycle RAM write access latency
+	@ 1 cycle RAM read access latency
+	@ 1 cycle RAM setup latency
+	LDR     r1, =0x00000000
+	STR     r1, [r0,#0x108]		@ tag ram control reg at offset 0x108
+
+	@ Set Data RAM latency
+	@ 1 cycle RAM write access latency
+	@ 2 cycles RAM read access latency
+	@ 1 cycle RAM setup latency
+	LDR     r1, =0x00000000
+	STR     r1, [r0,#0x10C]		@ data ram control reg at offset 0x108
+
+	@Cache maintenance - invalidate 16 ways (0xffff) - base offset 0x77C
+	LDR     r1, =0xFFFF
+	STR     r1, [r0,#0x77C]		@ invalidate by way register at offset 0x77C
+poll_invalidate:
+	LDR     r1, [r0,#0x77C]		@ invalidate by way register at offset 0x77C
+	TST     r1, #1
+	BNE     poll_invalidate
+
+	@ Ensure L2 remains disabled for the time being
+	LDR     r1, =0x0
+	STR     r1, [r0,#0x100]
+
+	MRC     p15, 4, r0, c15, c0, 0     @ Read periph base address
+	@ SCU offset from base of private peripheral space = 0x000
+
+	LDR     r1, [r0, #0x0]             @ Read the SCU Control Register
+	ORR     r1, r1, #0x1               @ Set bit 0 (The Enable bit)
+	STR     r1, [r0, #0x0]             @ Write back modifed value
+
+	BX	lr
+
+ENDPROC(l2_pl310_init)
+
+#endif