riscv: Add AST2700 SoC initial platform support
AST2700 SoCs integrates a Ibex 32-bits RISC-V core as the boot MCU
for the first stage bootloader execution, namely SPL.
This patch implements the preliminary base to successfully run SPL
on this RV32-based MCU to the console banner message.
Signed-off-by: Chia-Wei Wang <chiawei_wang@aspeedtech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
diff --git a/board/aspeed/ibex_ast2700/sli.c b/board/aspeed/ibex_ast2700/sli.c
new file mode 100644
index 0000000..7868111
--- /dev/null
+++ b/board/aspeed/ibex_ast2700/sli.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) Aspeed Technology Inc.
+ */
+#include <asm/io.h>
+#include <asm/arch/sli.h>
+#include <asm/arch/scu.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+
+#define SLI_POLL_TIMEOUT_US 100
+
+static void sli_clear_interrupt_status(uint32_t base)
+{
+ writel(-1, (void *)base + SLI_INTR_STATUS);
+}
+
+static int sli_wait(uint32_t base, uint32_t mask)
+{
+ uint32_t value;
+
+ sli_clear_interrupt_status(base);
+
+ do {
+ value = readl((void *)base + SLI_INTR_STATUS);
+ if (value & SLI_INTR_RX_ERRORS)
+ return -1;
+ } while ((value & mask) != mask);
+
+ return 0;
+}
+
+static int sli_wait_suspend(uint32_t base)
+{
+ return sli_wait(base, SLI_INTR_TX_SUSPEND | SLI_INTR_RX_SUSPEND);
+}
+
+/*
+ * CPU die --- downstream pads ---> I/O die
+ * CPU die <--- upstream pads ----- I/O die
+ *
+ * US/DS PAD[3:0] : SLIM[3:0]
+ * US/DS PAD[5:4] : SLIH[1:0]
+ * US/DS PAD[7:6] : SLIV[1:0]
+ */
+int sli_init(void)
+{
+ uint32_t value;
+
+ /* The following training sequence is designed for AST2700A0 */
+ value = FIELD_GET(SCU1_REVISION_HWID, readl(SCU1_REVISION));
+ if (value)
+ return 0;
+
+ /* Return if SLI had been calibrated */
+ value = readl((void *)SLIH_IOD_BASE + SLI_CTRL_III);
+ value = FIELD_GET(SLI_CLK_SEL, value);
+ if (value) {
+ debug("SLI has been initialized\n");
+ return 0;
+ }
+
+ /* 25MHz PAD delay for AST2700A0 */
+ value = SLI_RX_PHY_LAH_SEL_NEG | SLI_TRANS_EN | SLI_CLEAR_BUS;
+ writel(value, (void *)SLIH_IOD_BASE + SLI_CTRL_I);
+ writel(value, (void *)SLIM_IOD_BASE + SLI_CTRL_I);
+ writel(value | SLIV_RAW_MODE, (void *)SLIV_IOD_BASE + SLI_CTRL_I);
+ sli_wait_suspend(SLIH_IOD_BASE);
+ sli_wait_suspend(SLIH_CPU_BASE);
+
+ return 0;
+}