board: presidio-asic: Add basic G3 engr. development board support

Add basic Presidio G3 engineering board support

Signed-off-by: Alex Nemirovsky <alex.nemirovsky@cortina-access.com>
diff --git a/board/cortina/presidio-asic/Kconfig b/board/cortina/presidio-asic/Kconfig
new file mode 100644
index 0000000..8e6f6cf
--- /dev/null
+++ b/board/cortina/presidio-asic/Kconfig
@@ -0,0 +1,18 @@
+if TARGET_PRESIDIO_ASIC
+config BIT64
+       bool
+       default y
+
+select SOC_CA7774
+
+config SYS_BOARD
+	default "presidio-asic"
+
+config SYS_VENDOR
+	default "cortina"
+
+config SYS_CONFIG_NAME
+	default "presidio_asic"
+
+source "board/cortina/common/Kconfig"
+endif
diff --git a/board/cortina/presidio-asic/MAINTAINERS b/board/cortina/presidio-asic/MAINTAINERS
new file mode 100644
index 0000000..9db17bd
--- /dev/null
+++ b/board/cortina/presidio-asic/MAINTAINERS
@@ -0,0 +1,6 @@
+Cortina Presidio ASIC G3 Engineering BOARD
+M:	Alex Nemirovsky <alex.nemirovsky@cortina-access.com>
+S:	Supported
+F:	board/cortina/presidio-asic/
+F:	include/configs/presidio_asic.h
+F:	configs/cortina_presidio-asic*defconfig
diff --git a/board/cortina/presidio-asic/Makefile b/board/cortina/presidio-asic/Makefile
new file mode 100644
index 0000000..d167a15
--- /dev/null
+++ b/board/cortina/presidio-asic/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier:	GPL-2.0+
+#
+# (C) Copyright 2020 Cortina-Access.Inc.
+#
+#
+
+obj-y	:= presidio.o
+obj-y	+= lowlevel_init.o
diff --git a/board/cortina/presidio-asic/lowlevel_init.S b/board/cortina/presidio-asic/lowlevel_init.S
new file mode 100644
index 0000000..4450a5d
--- /dev/null
+++ b/board/cortina/presidio-asic/lowlevel_init.S
@@ -0,0 +1,87 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Cortina-Access
+ *
+ */
+
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+#include <asm/macro.h>
+#include <asm/armv8/mmu.h>
+
+	.globl lowlevel_init
+lowlevel_init:
+	mov	x29, lr			/* Save LR */
+
+#if defined(CONFIG_SOC_CA7774)
+	/* Enable SMPEN in CPUECTLR */
+	mrs     x0, s3_1_c15_c2_1
+	tst     x0, #0x40
+        b.ne    skip_smp_setup
+	orr     x0, x0, #0x40
+	msr     s3_1_c15_c2_1, x0
+skip_smp_setup:
+#endif
+
+#if defined(CONFIG_SOC_CA8277B)
+	/* Enable CPU Timer */
+	ldr x0, =CONFIG_SYS_TIMER_BASE
+	mov x1, #1
+	str w1, [x0]
+#endif
+
+#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
+	branch_if_slave x0, 1f
+#ifndef CONFIG_TARGET_VENUS
+	ldr	x0, =GICD_BASE
+	bl	gic_init_secure
+#endif
+1:
+#if defined(CONFIG_GICV3)
+	ldr	x0, =GICR_BASE
+	bl	gic_init_secure_percpu
+#elif defined(CONFIG_GICV2)
+	ldr	x0, =GICD_BASE
+	ldr	x1, =GICC_BASE
+	bl	gic_init_secure_percpu
+#endif
+#endif
+
+#ifdef CONFIG_ARMV8_MULTIENTRY
+	branch_if_master x0, x1, 2f
+
+	/*
+	 * Slave should wait for master clearing spin table.
+	 * This sync prevent salves observing incorrect
+	 * value of spin table and jumping to wrong place.
+	 */
+#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
+#ifdef CONFIG_GICV2
+	ldr	x0, =GICC_BASE
+#endif
+	bl	gic_wait_for_interrupt
+#endif
+
+	/*
+	 * All slaves will enter EL2 and optionally EL1.
+	 */
+	adr	x4, lowlevel_in_el2
+	ldr	x5, =ES_TO_AARCH64
+	bl	armv8_switch_to_el2
+
+lowlevel_in_el2:
+#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
+	adr	x4, lowlevel_in_el1
+	ldr	x5, =ES_TO_AARCH64
+	bl	armv8_switch_to_el1
+
+lowlevel_in_el1:
+#endif
+
+#endif /* CONFIG_ARMV8_MULTIENTRY */
+
+2:
+	mov	lr, x29			/* Restore LR */
+	ret
diff --git a/board/cortina/presidio-asic/presidio.c b/board/cortina/presidio-asic/presidio.c
new file mode 100644
index 0000000..b4fa01f
--- /dev/null
+++ b/board/cortina/presidio-asic/presidio.c
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2020 - Cortina Access Inc.
+ *
+ */
+#include <common.h>
+#include <malloc.h>
+#include <errno.h>
+#include <netdev.h>
+#include <asm/io.h>
+#include <linux/compiler.h>
+#include <configs/presidio_asic.h>
+#include <linux/psci.h>
+#include <asm/psci.h>
+#include <cpu_func.h>
+#include <asm/armv8/mmu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define CA_PERIPH_BASE                  0xE0000000UL
+#define CA_PERIPH_SIZE                  0x20000000UL
+#define CA_GLOBAL_BASE                  0xf4320000
+#define CA_GLOBAL_JTAG_ID               0xf4320000
+#define CA_GLOBAL_BLOCK_RESET           0xf4320004
+#define CA_GLOBAL_BLOCK_RESET_RESET_DMA BIT(16)
+#define CA_DMA_SEC_SSP_BAUDRATE_CTRL    0xf7001b94
+#define CA_DMA_SEC_SSP_ID               0xf7001b80
+
+int print_cpuinfo(void)
+{
+	printf("CPU:   Cortina Presidio G3\n");
+	return 0;
+}
+
+static struct mm_region presidio_mem_map[] = {
+	{
+	.virt = DDR_BASE,
+	.phys = DDR_BASE,
+	.size = PHYS_SDRAM_1_SIZE,
+	.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+		 PTE_BLOCK_OUTER_SHARE
+	},
+	{
+	.virt = CA_PERIPH_BASE,
+	.phys = CA_PERIPH_BASE,
+	.size = CA_PERIPH_SIZE,
+	.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+		 PTE_BLOCK_NON_SHARE
+	},
+	{
+	/* List terminator */
+	0,
+	}
+};
+
+struct mm_region *mem_map = presidio_mem_map;
+
+static noinline int invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1,
+				       u64 arg2)
+{
+	asm volatile("mov x0, %0\n"
+		    "mov x1, %1\n"
+		    "mov x2, %2\n"
+		    "mov x3, %3\n"
+		    "smc	#0\n"
+		    : "+r" (function_id)
+		    : "r" (arg0), "r" (arg1), "r" (arg2)
+		    );
+
+	return function_id;
+}
+
+int board_early_init_r(void)
+{
+	dcache_disable();
+	return 0;
+}
+
+int board_init(void)
+{
+	unsigned int reg_data, jtag_id;
+
+	/* Enable timer */
+	writel(1, CONFIG_SYS_TIMER_BASE);
+
+	/* Enable snoop in CCI400 slave port#4 */
+	writel(3, 0xF5595000);
+
+	jtag_id = readl(CA_GLOBAL_JTAG_ID);
+
+	/* If this is HGU variant then do not use
+	 * the Saturn daughter card ref. clk
+	 */
+	if (jtag_id == 0x1010D8F3) {
+		reg_data = readl(0xF3100064);
+		/* change multifunc. REF CLK pin to
+		 * a simple GPIO pin
+		 */
+		reg_data |= (1 << 1);
+		writel(reg_data, 0xf3100064);
+	}
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	unsigned int ddr_size;
+
+	ddr_size = readl(0x111100c);
+	gd->ram_size = ddr_size * 0x100000;
+	return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+	invoke_psci_fn_smc(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
+}
+
+#ifdef CONFIG_LAST_STAGE_INIT
+int last_stage_init(void)
+{
+	u32 val;
+
+	val = readl(CA_GLOBAL_BLOCK_RESET);
+	val &= ~CA_GLOBAL_BLOCK_RESET_RESET_DMA;
+	writel(val, CA_GLOBAL_BLOCK_RESET);
+
+	/* reduce output pclk ~3.7Hz to save power consumption */
+	writel(0x000000FF, CA_DMA_SEC_SSP_BAUDRATE_CTRL);
+
+	return 0;
+}
+#endif