aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Chien Peter Lin <peterlin@andestech.com>2023-07-04 19:13:20 +0800
committerLeo Yu-Chi Liang <ycliang@andestech.com>2023-07-06 17:28:08 +0800
commitbc35b49a5c12891d969e28dbf29024ca664dea8b (patch)
tree9b3ef41d80f6bdc93586996f987597035fe2d0ea
parent9eb0fc24c9804118e44b70851b1ad03aa1fc8cd4 (diff)
downloadu-boot-bc35b49a5c12891d969e28dbf29024ca664dea8b.zip
u-boot-bc35b49a5c12891d969e28dbf29024ca664dea8b.tar.gz
u-boot-bc35b49a5c12891d969e28dbf29024ca664dea8b.tar.bz2
riscv: andes_plicsw: Fix IPI during OpenSBI invocation
On some AE350 boards, we need to explicitly initialize the priority registers to a non-zero value so the boot hart can instruct secondary harts to jump to OpenSBI. This patch also updates the information about PLICSW. Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com> Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
-rw-r--r--arch/riscv/lib/andes_plicsw.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/arch/riscv/lib/andes_plicsw.c b/arch/riscv/lib/andes_plicsw.c
index 324eb44..7518408 100644
--- a/arch/riscv/lib/andes_plicsw.c
+++ b/arch/riscv/lib/andes_plicsw.c
@@ -2,9 +2,10 @@
/*
* Copyright (C) 2019, Rick Chen <rick@andestech.com>
*
- * U-Boot syscon driver for Andes's Platform Level Interrupt Controller (PLIC).
- * The PLIC block holds memory-mapped claim and pending registers
- * associated with software interrupt.
+ * U-Boot syscon driver for Andes' PLICSW
+ * The PLICSW block is an Andes-specific design for software interrupts,
+ * contains memory-mapped priority, enable, claim and pending registers
+ * similar to RISC-V PLIC.
*/
#include <common.h>
@@ -26,9 +27,13 @@
#define ENABLE_REG(base, hart) ((ulong)(base) + 0x2000 + (hart) * 0x80)
/* claim register */
#define CLAIM_REG(base, hart) ((ulong)(base) + 0x200004 + (hart) * 0x1000)
+/* priority register */
+#define PRIORITY_REG(base) ((ulong)(base) + PLICSW_PRIORITY_BASE)
#define ENABLE_HART_IPI (0x01010101)
#define SEND_IPI_TO_HART(hart) (0x1 << (hart))
+#define PLICSW_PRIORITY_BASE 0x4
+#define PLICSW_INTERRUPT_PER_HART 0x8
DECLARE_GLOBAL_DATA_PTR;
@@ -43,9 +48,21 @@ static int enable_ipi(int hart)
return 0;
}
+static void init_priority_ipi(int hart_num)
+{
+ uint32_t *priority = (void *)PRIORITY_REG(gd->arch.plicsw);
+
+ for (int i = 0; i < hart_num * PLICSW_INTERRUPT_PER_HART; i++) {
+ writel(1, &priority[i]);
+ }
+
+ return;
+}
+
int riscv_init_ipi(void)
{
int ret;
+ int hart_num = 0;
long *base = syscon_get_first_range(RISCV_SYSCON_PLICSW);
ofnode node;
struct udevice *dev;
@@ -79,8 +96,10 @@ int riscv_init_ipi(void)
ret = ofnode_read_u32(node, "reg", &reg);
if (ret == 0)
enable_ipi(reg);
+ hart_num++;
}
+ init_priority_ipi(hart_num);
return 0;
}