arm64: versal-net: Add support for Versal NET platform

Versal NET platform is based on Versal chip which is reusing a lot of IPs.
For more information about new IPs please take a look at DT which describe
currently supported devices.
The patch is adding architecture and board support with soc detection
algorithm. Generic setting should be very similar to Versal but it will
likely diverge in longer run.

Signed-off-by: Michal Simek <michal.simek@amd.com>
Link: https://lore.kernel.org/r/320206853dc370ce290a4e7b6d0bb26b05206021.1663589964.git.michal.simek@amd.com
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9a6c2e8..2e83394 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1251,6 +1251,18 @@
 	imply BOARD_LATE_INIT
 	imply ENV_VARS_UBOOT_RUNTIME_CONFIG
 
+config ARCH_VERSAL_NET
+	bool "Support Xilinx Keystone Platform"
+	select ARM64
+	select CLK
+	select DM
+	select DM_ETH if NET
+	select DM_MMC if MMC
+	select DM_SERIAL
+	select OF_CONTROL
+	imply BOARD_LATE_INIT
+	imply ENV_VARS_UBOOT_RUNTIME_CONFIG
+
 config ARCH_VF610
 	bool "Freescale Vybrid"
 	select CPU_V7A
@@ -2300,6 +2312,8 @@
 
 source "arch/arm/mach-versal/Kconfig"
 
+source "arch/arm/mach-versal-net/Kconfig"
+
 source "arch/arm/mach-zynqmp-r5/Kconfig"
 
 source "arch/arm/cpu/armv7/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 1f4a1d5..ac602ae 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -88,6 +88,7 @@
 machine-$(CONFIG_ARCH_OCTEONTX2)	+= octeontx2
 machine-$(CONFIG_ARCH_UNIPHIER)		+= uniphier
 machine-$(CONFIG_ARCH_VERSAL)		+= versal
+machine-$(CONFIG_ARCH_VERSAL_NET)	+= versal-net
 machine-$(CONFIG_ARCH_ZYNQ)		+= zynq
 machine-$(CONFIG_ARCH_ZYNQMP)		+= zynqmp
 machine-$(CONFIG_ARCH_ZYNQMP_R5)	+= zynqmp-r5
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 5a42d50..5d4b76c 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -383,6 +383,8 @@
 	versal-mini-emmc0.dtb \
 	versal-mini-emmc1.dtb \
 	xilinx-versal-virt.dtb
+dtb-$(CONFIG_ARCH_VERSAL_NET) += \
+	xilinx-versal-net-virt.dtb
 dtb-$(CONFIG_ARCH_ZYNQMP_R5) += \
 	zynqmp-r5.dtb
 dtb-$(CONFIG_AM33XX) += \
diff --git a/arch/arm/dts/xilinx-versal-net-virt.dts b/arch/arm/dts/xilinx-versal-net-virt.dts
new file mode 100644
index 0000000..c99257c
--- /dev/null
+++ b/arch/arm/dts/xilinx-versal-net-virt.dts
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Empty device tree for versal-net-virt board
+ *
+ * Copyright (C) 2022, Advanced Micro Devices, Inc.
+ */
+
+/dts-v1/;
+
+/ {
+};
diff --git a/arch/arm/mach-versal-net/Kconfig b/arch/arm/mach-versal-net/Kconfig
new file mode 100644
index 0000000..62825e1
--- /dev/null
+++ b/arch/arm/mach-versal-net/Kconfig
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier: GPL-2.0
+
+if ARCH_VERSAL_NET
+
+config SYS_BOARD
+	string "Board name"
+	default "versal-net"
+
+config SYS_VENDOR
+	string "Vendor name"
+	default "xilinx"
+
+config SYS_SOC
+	default "versal-net"
+
+config SYS_CONFIG_NAME
+	string "Board configuration name"
+	default "xilinx_versal_net"
+	help
+	  This option contains information about board configuration name.
+	  Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
+	  will be used for board configuration.
+
+config SYS_MEM_RSVD_FOR_MMU
+	bool "Reserve memory for MMU Table"
+	help
+	  If defined this option is used to setup different space for
+	  MMU table than the one which will be allocated during
+	  relocation.
+
+config GICV3
+	def_bool y
+
+config SYS_MALLOC_LEN
+	default 0x2000000
+
+config ZYNQ_SDHCI_MAX_FREQ
+	default 200000000
+
+source "board/xilinx/Kconfig"
+source "board/xilinx/versal-net/Kconfig"
+
+endif
diff --git a/arch/arm/mach-versal-net/Makefile b/arch/arm/mach-versal-net/Makefile
new file mode 100644
index 0000000..e12c4c0
--- /dev/null
+++ b/arch/arm/mach-versal-net/Makefile
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2021 - 2022, Xilinx, Inc.
+# Copyright (C) 2022, Advanced Micro Devices, Inc.
+#
+# Michal Simek <michal.simek@amd.com>
+#
+
+obj-y	+= clk.o
+obj-y	+= cpu.o
diff --git a/arch/arm/mach-versal-net/clk.c b/arch/arm/mach-versal-net/clk.c
new file mode 100644
index 0000000..d097de7
--- /dev/null
+++ b/arch/arm/mach-versal-net/clk.c
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016 - 2022,  Xilinx, Inc.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc.
+ *
+ * Michal Simek <michal.simek@amd.com>
+ */
+
+#include <common.h>
+#include <init.h>
+#include <time.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_CLOCKS
+/**
+ * set_cpu_clk_info - Initialize clock framework
+ *
+ * Return: 0 always.
+ *
+ * This function is called from common code after relocation and sets up the
+ * clock framework. The framework must not be used before this function had been
+ * called.
+ */
+int set_cpu_clk_info(void)
+{
+	gd->cpu_clk = get_tbclk();
+
+	gd->bd->bi_arm_freq = gd->cpu_clk / 1000000;
+	gd->bd->bi_dsp_freq = 0;
+
+	return 0;
+}
+#endif
diff --git a/arch/arm/mach-versal-net/cpu.c b/arch/arm/mach-versal-net/cpu.c
new file mode 100644
index 0000000..4c9b154
--- /dev/null
+++ b/arch/arm/mach-versal-net/cpu.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 - 2022, Xilinx, Inc.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc.
+ *
+ * Michal Simek <michal.simek@amd.com>
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/armv8/mmu.h>
+#include <asm/cache.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/cache.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define VERSAL_NET_MEM_MAP_USED	5
+
+#define DRAM_BANKS CONFIG_NR_DRAM_BANKS
+
+/* +1 is end of list which needs to be empty */
+#define VERSAL_NET_MEM_MAP_MAX (VERSAL_NET_MEM_MAP_USED + DRAM_BANKS + 1)
+
+static struct mm_region versal_mem_map[VERSAL_NET_MEM_MAP_MAX] = {
+	{
+		.virt = 0x80000000UL,
+		.phys = 0x80000000UL,
+		.size = 0x70000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		.virt = 0xf0000000UL,
+		.phys = 0xf0000000UL,
+		.size = 0x0fe00000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		.virt = 0x400000000UL,
+		.phys = 0x400000000UL,
+		.size = 0x200000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		.virt = 0x600000000UL,
+		.phys = 0x600000000UL,
+		.size = 0x800000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+			 PTE_BLOCK_INNER_SHARE
+	}, {
+		.virt = 0xe00000000UL,
+		.phys = 0xe00000000UL,
+		.size = 0xf200000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}
+};
+
+void mem_map_fill(void)
+{
+	int banks = VERSAL_NET_MEM_MAP_USED;
+
+	for (int i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		/* Zero size means no more DDR that's this is end */
+		if (!gd->bd->bi_dram[i].size)
+			break;
+
+		versal_mem_map[banks].virt = gd->bd->bi_dram[i].start;
+		versal_mem_map[banks].phys = gd->bd->bi_dram[i].start;
+		versal_mem_map[banks].size = gd->bd->bi_dram[i].size;
+		versal_mem_map[banks].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+					      PTE_BLOCK_INNER_SHARE;
+		banks = banks + 1;
+	}
+}
+
+struct mm_region *mem_map = versal_mem_map;
+
+u64 get_page_table_size(void)
+{
+	return 0x14000;
+}
diff --git a/arch/arm/mach-versal-net/include/mach/hardware.h b/arch/arm/mach-versal-net/include/mach/hardware.h
new file mode 100644
index 0000000..2eb5498
--- /dev/null
+++ b/arch/arm/mach-versal-net/include/mach/hardware.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2016 - 2022, Xilinx, Inc.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc.
+ */
+
+#ifndef __ASSEMBLY__
+#include <linux/bitops.h>
+#endif
+
+#define PMC_TAP	0xF11A0000
+
+#define PMC_TAP_IDCODE		(PMC_TAP + 0)
+#define PMC_TAP_VERSION		(PMC_TAP + 0x4)
+# define PMC_VERSION_MASK	GENMASK(7, 0)
+# define PS_VERSION_MASK	GENMASK(15, 8)
+# define RTL_VERSION_MASK	GENMASK(23, 16)
+# define PLATFORM_MASK		GENMASK(27, 24)
+# define PLATFORM_VERSION_MASK	GENMASK(31, 28)
+#define PMC_TAP_USERCODE	(PMC_TAP + 0x8)
+
+enum versal_net_platform {
+	VERSAL_NET_SILICON = 0,
+	VERSAL_NET_SPP = 1,
+	VERSAL_NET_EMU = 2,
+	VERSAL_NET_QEMU = 3,
+};
diff --git a/arch/arm/mach-versal-net/include/mach/sys_proto.h b/arch/arm/mach-versal-net/include/mach/sys_proto.h
new file mode 100644
index 0000000..5bba903
--- /dev/null
+++ b/arch/arm/mach-versal-net/include/mach/sys_proto.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2021 - 2022, Xilinx, Inc.
+ * Copyright (C) 2022, Advanced Micro Devices, Inc.
+ */
+
+#include <linux/build_bug.h>
+
+void mem_map_fill(void);
+
+static inline int zynqmp_mmio_write(const u32 address, const u32 mask,
+				    const u32 value)
+{
+	BUILD_BUG();
+	return -EINVAL;
+}