arm: zynq: Rework FPGA initialization

This commit moves the FPGA descriptor definition
to mach-zynq, where it makes more sense.

Based on patches from Ariel D'Alessandro <ariel@vanguardiasur.com.ar>
and Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>

Signed-off-by: Michal Simek <michal.simek@xilinx.com>
diff --git a/arch/arm/mach-zynq/cpu.c b/arch/arm/mach-zynq/cpu.c
index df4eec8..7853785 100644
--- a/arch/arm/mach-zynq/cpu.c
+++ b/arch/arm/mach-zynq/cpu.c
@@ -4,14 +4,45 @@
  * Copyright (C) 2012 Xilinx, Inc. All rights reserved.
  */
 #include <common.h>
+#include <zynqpl.h>
 #include <asm/io.h>
 #include <asm/arch/clk.h>
-#include <asm/arch/sys_proto.h>
 #include <asm/arch/hardware.h>
+#include <asm/arch/ps7_init_gpl.h>
+#include <asm/arch/sys_proto.h>
 
 #define ZYNQ_SILICON_VER_MASK	0xF0000000
 #define ZYNQ_SILICON_VER_SHIFT	28
 
+#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
+    (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
+xilinx_desc fpga = {
+	.family = xilinx_zynq,
+	.iface = devcfg,
+	.operations = &zynq_op,
+};
+#endif
+
+static const struct {
+	u8 idcode;
+#if defined(CONFIG_FPGA)
+	u32 fpga_size;
+#endif
+	char *devicename;
+} zynq_fpga_descs[] = {
+	ZYNQ_DESC(7Z007S),
+	ZYNQ_DESC(7Z010),
+	ZYNQ_DESC(7Z012S),
+	ZYNQ_DESC(7Z014S),
+	ZYNQ_DESC(7Z015),
+	ZYNQ_DESC(7Z020),
+	ZYNQ_DESC(7Z030),
+	ZYNQ_DESC(7Z035),
+	ZYNQ_DESC(7Z045),
+	ZYNQ_DESC(7Z100),
+	{ /* Sentinel */ },
+};
+
 int arch_cpu_init(void)
 {
 	zynq_slcr_unlock();
@@ -59,3 +90,36 @@
 	dcache_enable();
 }
 #endif
+
+static int __maybe_unused cpu_desc_id(void)
+{
+	u32 idcode;
+	u8 i;
+
+	idcode = zynq_slcr_get_idcode();
+	for (i = 0; zynq_fpga_descs[i].idcode; i++) {
+		if (zynq_fpga_descs[i].idcode == idcode)
+			return i;
+	}
+
+	return -ENODEV;
+}
+
+#if defined(CONFIG_ARCH_EARLY_INIT_R)
+int arch_early_init_r(void)
+{
+#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
+    (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
+	int cpu_id = cpu_desc_id();
+
+	if (cpu_id < 0)
+		return 0;
+
+	fpga.size = zynq_fpga_descs[cpu_id].fpga_size;
+	fpga.name = zynq_fpga_descs[cpu_id].devicename;
+	fpga_init();
+	fpga_add(fpga_xilinx, &fpga);
+#endif
+	return 0;
+}
+#endif