* [PATCH v5 1/8] riscv: Add initial support for P8700 SoC
2025-12-24 15:44 [PATCH v5 0/8] riscv: Add support for P8700 platform on Boston board Uros Stajic
@ 2025-12-24 15:45 ` Uros Stajic
2026-02-09 11:24 ` Leo Liang
2026-03-17 8:36 ` Leo Liang
2025-12-24 15:45 ` [PATCH v5 2/8] board: boston-riscv: Add initial support for P8700 Boston board Uros Stajic
` (6 subsequent siblings)
7 siblings, 2 replies; 21+ messages in thread
From: Uros Stajic @ 2025-12-24 15:45 UTC (permalink / raw)
To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu, Uros Stajic
From: Chao-ying Fu <cfu@mips.com>
Add initial platform support for the P8700-F, a high-performance
multi-core RV64GC SoC with optional multi-cluster configuration and
hardware multithreading.
This patch introduces the initial platform code necessary to support
the P8700 CPU in U-Boot.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
arch/riscv/Kconfig | 1 +
arch/riscv/cpu/p8700/Kconfig | 14 +++
arch/riscv/cpu/p8700/Makefile | 7 ++
arch/riscv/cpu/p8700/cache.c | 93 ++++++++++++++++++
arch/riscv/cpu/p8700/cpu.c | 111 ++++++++++++++++++++++
arch/riscv/cpu/p8700/dram.c | 37 ++++++++
arch/riscv/include/asm/arch-p8700/p8700.h | 110 +++++++++++++++++++++
7 files changed, 373 insertions(+)
create mode 100644 arch/riscv/cpu/p8700/Kconfig
create mode 100644 arch/riscv/cpu/p8700/Makefile
create mode 100644 arch/riscv/cpu/p8700/cache.c
create mode 100644 arch/riscv/cpu/p8700/cpu.c
create mode 100644 arch/riscv/cpu/p8700/dram.c
create mode 100644 arch/riscv/include/asm/arch-p8700/p8700.h
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 265b5320777..b4896544868 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -131,6 +131,7 @@ source "arch/riscv/cpu/jh7110/Kconfig"
source "arch/riscv/cpu/k1/Kconfig"
source "arch/riscv/cpu/k230/Kconfig"
source "arch/riscv/cpu/th1520/Kconfig"
+source "arch/riscv/cpu/p8700/Kconfig"
# architecture-specific options below
diff --git a/arch/riscv/cpu/p8700/Kconfig b/arch/riscv/cpu/p8700/Kconfig
new file mode 100644
index 00000000000..0913a6ce8f2
--- /dev/null
+++ b/arch/riscv/cpu/p8700/Kconfig
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+
+config P8700_RISCV
+ bool
+ select ARCH_EARLY_INIT_R
+ imply CPU
+ imply CPU_RISCV
+ imply RISCV_ACLINT if (RISCV_MMODE || SPL_RISCV_MMODE)
+ imply CMD_CPU
+ imply SPL_CPU_SUPPORT
+ imply SPL_OPENSBI
+ imply SPL_LOAD_FIT
diff --git a/arch/riscv/cpu/p8700/Makefile b/arch/riscv/cpu/p8700/Makefile
new file mode 100644
index 00000000000..32c5e2dce21
--- /dev/null
+++ b/arch/riscv/cpu/p8700/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+
+obj-y += cache.o
+obj-y += cpu.o
+obj-y += dram.o
diff --git a/arch/riscv/cpu/p8700/cache.c b/arch/riscv/cpu/p8700/cache.c
new file mode 100644
index 00000000000..7559c688321
--- /dev/null
+++ b/arch/riscv/cpu/p8700/cache.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+ */
+
+#include <cpu_func.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch-p8700/p8700.h>
+
+#define MCACHE_BASE_INST 0xec0500f3
+
+/* NOTE: We force to use a0 in mcache to encode via .word.
+ * 0xec0500f3 is a manually encoded custom RISC-V MCACHE instruction.
+ * The bits [19:15] are set to 01010, selecting register x10 (a0)
+ * as the source operand.
+ * The bits [24:20] represent the 'op' field, which is currently set to 0.
+ * Different cache operations are applied by OR-ing (op << 20) dynamically
+ * to this base value.
+ * Because of this encoding, the variable 'addr' is forced into register a0,
+ * so that the MCACHE instruction uses the address in a0 as its operand.
+ */
+#define cache_loop(start, end, lsize, op) do { \
+ const __typeof__(lsize) __lsize = (lsize); \
+ const register void *addr asm("a0") = (const void *)((start) & ~(__lsize - 1)); \
+ const void *aend = (const void *)(((end) - 1) & ~(__lsize - 1)); \
+ for (; addr <= aend; addr += __lsize) \
+ asm volatile (".word %0 | %1 # force to use %2" \
+ ::"i"(MCACHE_BASE_INST), "i"((op) << 20), "r"(addr)); \
+} while (0)
+
+static unsigned long lsize;
+static unsigned long l1d_total_size;
+static unsigned long slsize;
+
+static void probe_cache_config(void)
+{
+ lsize = 64;
+ l1d_total_size = 64 * 1024;
+
+ int l2_config = 0;
+
+ l2_config = readl((void __iomem *)GCR_L2_CONFIG);
+ int l2_line_size_info = (l2_config >> L2_LINE_SIZE_SHIFT)
+ & L2_LINE_SIZE_MASK;
+ slsize = (l2_line_size_info == 0) ? 0 : 1 << (l2_line_size_info + 1);
+}
+
+void flush_dcache_range(unsigned long start, unsigned long end)
+{
+ if (lsize == 0)
+ probe_cache_config();
+
+ /* aend will be miscalculated when size is zero, so we return here */
+ if (start >= end)
+ return;
+
+ cache_loop(start, end, lsize, HIT_WRITEBACK_INV_D);
+
+ /* flush L2 cache */
+ if (slsize)
+ cache_loop(start, end, slsize, HIT_WRITEBACK_INV_SD);
+
+ /* Instruction Hazard Barrier (IHB) — a hint-encoded SLLI (rd=0, rs1=0, imm=1).
+ * Ensures that all subsequent instruction fetches, including speculative ones,
+ * observe state changes from prior instructions.
+ * Required after MCACHE instructions when instruction fetch depends on cache ops.
+ */
+ asm volatile ("slli x0,x0,1 # ihb");
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long end)
+{
+ if (lsize == 0)
+ probe_cache_config();
+
+ /* aend will be miscalculated when size is zero, so we return here */
+ if (start >= end)
+ return;
+
+ /* invalidate L2 cache */
+ if (slsize)
+ cache_loop(start, end, slsize, HIT_INVALIDATE_SD);
+
+ cache_loop(start, end, lsize, HIT_INVALIDATE_D);
+
+ /* Instruction Hazard Barrier (IHB) — a hint-encoded SLLI (rd=0, rs1=0, imm=1).
+ * Ensures that all subsequent instruction fetches, including speculative ones,
+ * observe state changes from prior instructions.
+ * Required after MCACHE instructions when instruction fetch depends on cache ops.
+ */
+ asm volatile ("slli x0,x0,1 # ihb");
+}
diff --git a/arch/riscv/cpu/p8700/cpu.c b/arch/riscv/cpu/p8700/cpu.c
new file mode 100644
index 00000000000..d63f7073d75
--- /dev/null
+++ b/arch/riscv/cpu/p8700/cpu.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+ */
+
+#include <asm/encoding.h>
+#include <asm/io.h>
+#include <linux/types.h>
+#include <asm/arch-p8700/p8700.h>
+
+static __noreturn void jump_to_addr(ulong addr)
+{
+ asm volatile ("jr %0" :: "r"(addr) : "memory");
+ __builtin_unreachable();
+}
+
+void harts_early_init(void)
+{
+ if (!IS_ENABLED(CONFIG_RISCV_MMODE))
+ return;
+
+ ulong hartid = csr_read(CSR_MHARTID);
+
+ /* Wait for DDR3 calibration */
+ while (!(readl((void __iomem *)BOSTON_PLAT_DDR3STAT) &
+ BOSTON_PLAT_DDR3STAT_CALIB)) {
+ /* busy-wait */
+ }
+
+ /*
+ * Only mhartid[3:0] == 0 performs CM/GCR programming.
+ * Other harts skip CM/GCR setup and go straight to PMP/PMA setup.
+ */
+ if ((hartid & 0xFULL) == 0) {
+ ulong cm_base = CM_BASE;
+ void __iomem *gcr_win = (void __iomem *)0x1fb80000;
+ ulong cluster = (hartid >> MHARTID_CLUSTER_SHIFT) &
+ MHARTID_CLUSTER_MASK;
+
+ cm_base += cluster << CM_BASE_CLUSTER_SHIFT;
+
+ if ((hartid & 0xFFFFUL) == 0)
+ writeq(cm_base, gcr_win + GCR_BASE_OFFSET);
+
+ ulong core = (hartid >> MHARTID_CORE_SHIFT) & MHARTID_CORE_MASK;
+
+ /* Enable coherency for the current core */
+ cm_base += core << CM_BASE_CORE_SHIFT;
+ writeq((u64)GCR_CL_COH_EN_EN,
+ (void __iomem *)(cm_base + P8700_GCR_C0_COH_EN));
+
+ /*
+ * On hart 0, default PCIe DMA mapping should be the non-IOCU
+ * target.
+ */
+ if (hartid == 0) {
+ writel(0x00, (void __iomem *)BOSTON_PLAT_NOCPCIE0ADDR);
+ writel(0x00, (void __iomem *)BOSTON_PLAT_NOCPCIE1ADDR);
+ writel(0x00, (void __iomem *)BOSTON_PLAT_NOCPCIE2ADDR);
+ }
+ }
+
+ /* PMP setup */
+ csr_write(pmpaddr1, 0x2fffffffUL);
+ csr_write(pmpaddr2, 0x07ff7fffUL);
+ csr_write(pmpaddr3, 0x07f3ffffUL);
+ csr_write(pmpaddr4, 0x1fffffffffffffffUL);
+
+ unsigned long pmpcfg = ((unsigned long)(PMP_NAPOT | PMP_R | PMP_W |
+ PMP_X) << 32) |
+ ((unsigned long)(PMP_NAPOT | PMP_R |
+ PMP_X) << 24) |
+ ((unsigned long)(PMP_NAPOT | PMP_R | PMP_W |
+ PMP_X) << 16) |
+ ((unsigned long)(PMP_NAPOT | PMP_R | PMP_W |
+ PMP_X) << 8);
+
+ csr_write(pmpcfg0, pmpcfg);
+
+ /* PMA/cache attributes */
+ ulong pmacfg0;
+
+ if (hartid == 0) {
+ /*
+ * Hart 0: cacheable for pmp0, pmp1, pmp3; uncacheable for
+ * pmp2, pmp4.
+ */
+ pmacfg0 = ((unsigned long)CCA_CACHE_DISABLE << 32) |
+ ((unsigned long)CCA_CACHE_ENABLE << 24) |
+ ((unsigned long)CCA_CACHE_DISABLE << 16) |
+ ((unsigned long)CCA_CACHE_ENABLE << 8) |
+ ((unsigned long)CCA_CACHE_ENABLE);
+ } else {
+ /*
+ * Hart 1 or above: cacheable for pmp0, pmp1; uncacheable for
+ * pmp2, pmp3, pmp4.
+ */
+ pmacfg0 = ((unsigned long)CCA_CACHE_DISABLE << 32) |
+ ((unsigned long)CCA_CACHE_DISABLE << 24) |
+ ((unsigned long)CCA_CACHE_DISABLE << 16) |
+ ((unsigned long)CCA_CACHE_ENABLE << 8) |
+ ((unsigned long)CCA_CACHE_ENABLE);
+ }
+
+ asm volatile ("csrw %0, %1" :: "i"(CSR_PMACFG0), "r"(pmacfg0));
+ asm volatile ("fence" ::: "memory");
+
+ /* Secondary harts: after early setup, jump to the common entry point */
+ if (hartid != 0)
+ jump_to_addr(CONFIG_SYS_LOAD_ADDR);
+}
diff --git a/arch/riscv/cpu/p8700/dram.c b/arch/riscv/cpu/p8700/dram.c
new file mode 100644
index 00000000000..2b54326be39
--- /dev/null
+++ b/arch/riscv/cpu/p8700/dram.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <fdtdec.h>
+#include <init.h>
+#include <linux/sizes.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+ return fdtdec_setup_mem_size_base();
+}
+
+int dram_init_banksize(void)
+{
+ return fdtdec_setup_memory_banksize();
+}
+
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
+{
+ if (IS_ENABLED(CONFIG_64BIT)) {
+ /*
+ * Ensure that we run from first 4GB so that all
+ * addresses used by U-Boot are 32bit addresses.
+ *
+ * This in-turn ensures that 32bit DMA capable
+ * devices work fine because DMA mapping APIs will
+ * provide 32bit DMA addresses only.
+ */
+ if (gd->ram_top > SZ_4G)
+ return SZ_4G;
+ }
+ return gd->ram_top;
+}
diff --git a/arch/riscv/include/asm/arch-p8700/p8700.h b/arch/riscv/include/asm/arch-p8700/p8700.h
new file mode 100644
index 00000000000..5ca9b4b9497
--- /dev/null
+++ b/arch/riscv/include/asm/arch-p8700/p8700.h
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+ */
+
+#ifndef __P8700_H__
+#define __P8700_H__
+
+#define CSR_MIPSCONFIG7 0x7d7
+#define CSR_PMACFG0 0x7e0
+
+#define MHARTID_HART_SHIFT 0
+#define MHARTID_HART_MASK 0xf
+#define MHARTID_CORE_SHIFT 4
+#define MHARTID_CORE_MASK 0xff
+#define MHARTID_CLUSTER_SHIFT 16
+#define MHARTID_CLUSTER_MASK 0xf
+
+#define MARCHID_UARCH_SHIFT 0
+#define MARCHID_UARCH_MASK 0xff
+#define MARCHID_CLASS_SHIFT 8
+#define MARCHID_CLASS_MASK 0xff
+#define MARCHID_CLASS_M 0
+#define MARCHID_CLASS_I 1
+#define MARCHID_CLASS_P 2
+
+#define CM_BASE_CORE_SHIFT 8
+#define CM_BASE_CLUSTER_SHIFT 19
+
+#define P8700_TIMER_ADDR 0x16108050
+
+#define CCA_CACHE_ENABLE 0
+#define CCA_BUFFER_CACHE 1
+#define CCA_CACHE_DISABLE 2
+#define CCA_UNCACHE_ACC 3
+#define PMA_SPECULATION (0x1 << 3)
+
+#define L1_I_CACHE 0
+#define L1_D_CACHE 1
+#define L3_CACHE 2
+#define L2_CACHE 3
+
+#define HIT_INVALIDATE 4
+#define HIT_WRITEBACK_INV 5
+
+#define HIT_INVALIDATE_D ((HIT_INVALIDATE << 2) | L1_D_CACHE)
+#define HIT_INVALIDATE_SD ((HIT_INVALIDATE << 2) | L2_CACHE)
+#define HIT_WRITEBACK_INV_D ((HIT_WRITEBACK_INV << 2) | L1_D_CACHE)
+#define HIT_WRITEBACK_INV_SD ((HIT_WRITEBACK_INV << 2) | L2_CACHE)
+
+#define L1D_LINE_SIZE_SHIFT 10
+#define L1D_LINE_SIZE_MASK 0x7
+
+#define GCR_L2_CONFIG 0x16100130
+#define L2_LINE_SIZE_SHIFT 8
+#define L2_LINE_SIZE_MASK 0xf
+
+#define PMP_R 0x01
+#define PMP_W 0x02
+#define PMP_X 0x04
+#define PMP_TOR 0x8
+#define PMP_NA4 0x10
+#define PMP_NAPOT 0x18
+
+#define CM_BASE 0x16100000
+#define CPC_BASE (CM_BASE + 0x8000)
+
+/* CPC Block offsets */
+#define CPC_OFF_LOCAL 0x2000
+
+#define CPC_PWRUP_CTL 0x0030
+
+#define CPC_SYS_CONFIG 0x0140
+
+#define CPC_Cx_CMD 0x0000
+#define CPC_Cx_CMD_RESET 0x4
+
+#define P8700_GCR_C0_COH_EN 0x20f8
+#define P8700_GCR_C1_COH_EN 0x21f8
+#define P8700_GCR_C2_COH_EN 0x22f8
+#define P8700_GCR_C3_COH_EN 0x23f8
+#define P8700_GCR_C4_COH_EN 0x24f8
+#define P8700_GCR_C5_COH_EN 0x25f8
+
+#define GCR_CL_COH_EN 0x2008
+#define GCR_CL_COH_EN_EN (0x1 << 0)
+#define GCR_BASE_OFFSET 0x0008
+#define GIC_BASE_OFFSET 0x0080
+#define CPC_BASE_OFFSET 0x0088
+#define ENABLE 0x1
+#define COUNT_STOP (0x1 << 28)
+#define GIC_LOCAL_SECTION_OFS 0x8000
+#define GIC_VL_MASK 0x08
+#define GIC_VL_RMASK 0x0c
+#define GIC_VL_SMASK 0x10
+#define GIC_VL_COMPARE_MAP 0x44
+
+#define INDEXED(op, reg, idx, offset, base) \
+ li idx, offset ;\
+ add idx, idx, base ;\
+ op reg, (idx)
+
+#define BOSTON_PLAT_BASE 0x17ffd000
+#define BOSTON_PLAT_DDR3STAT (BOSTON_PLAT_BASE + 0x14)
+#define BOSTON_PLAT_DDR3STAT_CALIB (0x1 << 2)
+#define BOSTON_PLAT_NOCPCIE0ADDR (BOSTON_PLAT_BASE + 0x3c)
+#define BOSTON_PLAT_NOCPCIE1ADDR (BOSTON_PLAT_BASE + 0x40)
+#define BOSTON_PLAT_NOCPCIE2ADDR (BOSTON_PLAT_BASE + 0x44)
+
+#endif /* __P8700_H__ */
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH v5 1/8] riscv: Add initial support for P8700 SoC
2025-12-24 15:45 ` [PATCH v5 1/8] riscv: Add initial support for P8700 SoC Uros Stajic
@ 2026-02-09 11:24 ` Leo Liang
2026-03-17 8:36 ` Leo Liang
1 sibling, 0 replies; 21+ messages in thread
From: Leo Liang @ 2026-02-09 11:24 UTC (permalink / raw)
To: Uros Stajic; +Cc: u-boot@lists.denx.de, Djordje Todorovic, Chao-ying Fu
On Wed, Dec 24, 2025 at 03:45:22PM +0000, Uros Stajic wrote:
> From: Chao-ying Fu <cfu@mips.com>
>
> Add initial platform support for the P8700-F, a high-performance
> multi-core RV64GC SoC with optional multi-cluster configuration and
> hardware multithreading.
>
> This patch introduces the initial platform code necessary to support
> the P8700 CPU in U-Boot.
>
> Signed-off-by: Chao-ying Fu <cfu@mips.com>
> Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
> ---
> arch/riscv/Kconfig | 1 +
> arch/riscv/cpu/p8700/Kconfig | 14 +++
> arch/riscv/cpu/p8700/Makefile | 7 ++
> arch/riscv/cpu/p8700/cache.c | 93 ++++++++++++++++++
> arch/riscv/cpu/p8700/cpu.c | 111 ++++++++++++++++++++++
> arch/riscv/cpu/p8700/dram.c | 37 ++++++++
> arch/riscv/include/asm/arch-p8700/p8700.h | 110 +++++++++++++++++++++
> 7 files changed, 373 insertions(+)
> create mode 100644 arch/riscv/cpu/p8700/Kconfig
> create mode 100644 arch/riscv/cpu/p8700/Makefile
> create mode 100644 arch/riscv/cpu/p8700/cache.c
> create mode 100644 arch/riscv/cpu/p8700/cpu.c
> create mode 100644 arch/riscv/cpu/p8700/dram.c
> create mode 100644 arch/riscv/include/asm/arch-p8700/p8700.h
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v5 1/8] riscv: Add initial support for P8700 SoC
2025-12-24 15:45 ` [PATCH v5 1/8] riscv: Add initial support for P8700 SoC Uros Stajic
2026-02-09 11:24 ` Leo Liang
@ 2026-03-17 8:36 ` Leo Liang
2026-03-27 13:46 ` Uros Stajic
1 sibling, 1 reply; 21+ messages in thread
From: Leo Liang @ 2026-03-17 8:36 UTC (permalink / raw)
To: Uros Stajic; +Cc: u-boot@lists.denx.de, Djordje Todorovic, Chao-ying Fu
Hi Uros,
On Wed, Dec 24, 2025 at 03:45:22PM +0000, Uros Stajic wrote:
> From: Chao-ying Fu <cfu@mips.com>
>
> Add initial platform support for the P8700-F, a high-performance
> multi-core RV64GC SoC with optional multi-cluster configuration and
> hardware multithreading.
>
> This patch introduces the initial platform code necessary to support
> the P8700 CPU in U-Boot.
>
> Signed-off-by: Chao-ying Fu <cfu@mips.com>
> Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
> Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
> ---
> arch/riscv/Kconfig | 1 +
> arch/riscv/cpu/p8700/Kconfig | 14 +++
> arch/riscv/cpu/p8700/Makefile | 7 ++
> arch/riscv/cpu/p8700/cache.c | 93 ++++++++++++++++++
> arch/riscv/cpu/p8700/cpu.c | 111 ++++++++++++++++++++++
> arch/riscv/cpu/p8700/dram.c | 37 ++++++++
> arch/riscv/include/asm/arch-p8700/p8700.h | 110 +++++++++++++++++++++
> 7 files changed, 373 insertions(+)
> create mode 100644 arch/riscv/cpu/p8700/Kconfig
> create mode 100644 arch/riscv/cpu/p8700/Makefile
> create mode 100644 arch/riscv/cpu/p8700/cache.c
> create mode 100644 arch/riscv/cpu/p8700/cpu.c
> create mode 100644 arch/riscv/cpu/p8700/dram.c
> create mode 100644 arch/riscv/include/asm/arch-p8700/p8700.h
...
> diff --git a/arch/riscv/cpu/p8700/cpu.c b/arch/riscv/cpu/p8700/cpu.c
> new file mode 100644
> index 00000000000..d63f7073d75
> --- /dev/null
> +++ b/arch/riscv/cpu/p8700/cpu.c
> @@ -0,0 +1,111 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
> + */
> +
> +#include <asm/encoding.h>
> +#include <asm/io.h>
> +#include <linux/types.h>
> +#include <asm/arch-p8700/p8700.h>
> +
> +static __noreturn void jump_to_addr(ulong addr)
> +{
> + asm volatile ("jr %0" :: "r"(addr) : "memory");
> + __builtin_unreachable();
> +}
> +
> +void harts_early_init(void)
> +{
> + if (!IS_ENABLED(CONFIG_RISCV_MMODE))
> + return;
> +
> + ulong hartid = csr_read(CSR_MHARTID);
> +
> + /* Wait for DDR3 calibration */
> + while (!(readl((void __iomem *)BOSTON_PLAT_DDR3STAT) &
> + BOSTON_PLAT_DDR3STAT_CALIB)) {
> + /* busy-wait */
> + }
> +
> + /*
> + * Only mhartid[3:0] == 0 performs CM/GCR programming.
> + * Other harts skip CM/GCR setup and go straight to PMP/PMA setup.
> + */
> + if ((hartid & 0xFULL) == 0) {
> + ulong cm_base = CM_BASE;
> + void __iomem *gcr_win = (void __iomem *)0x1fb80000;
> + ulong cluster = (hartid >> MHARTID_CLUSTER_SHIFT) &
> + MHARTID_CLUSTER_MASK;
> +
> + cm_base += cluster << CM_BASE_CLUSTER_SHIFT;
> +
> + if ((hartid & 0xFFFFUL) == 0)
> + writeq(cm_base, gcr_win + GCR_BASE_OFFSET);
> +
> + ulong core = (hartid >> MHARTID_CORE_SHIFT) & MHARTID_CORE_MASK;
> +
> + /* Enable coherency for the current core */
> + cm_base += core << CM_BASE_CORE_SHIFT;
> + writeq((u64)GCR_CL_COH_EN_EN,
> + (void __iomem *)(cm_base + P8700_GCR_C0_COH_EN));
> +
> + /*
> + * On hart 0, default PCIe DMA mapping should be the non-IOCU
> + * target.
> + */
> + if (hartid == 0) {
> + writel(0x00, (void __iomem *)BOSTON_PLAT_NOCPCIE0ADDR);
> + writel(0x00, (void __iomem *)BOSTON_PLAT_NOCPCIE1ADDR);
> + writel(0x00, (void __iomem *)BOSTON_PLAT_NOCPCIE2ADDR);
> + }
> + }
> +
> + /* PMP setup */
> + csr_write(pmpaddr1, 0x2fffffffUL);
> + csr_write(pmpaddr2, 0x07ff7fffUL);
> + csr_write(pmpaddr3, 0x07f3ffffUL);
> + csr_write(pmpaddr4, 0x1fffffffffffffffUL);
> +
> + unsigned long pmpcfg = ((unsigned long)(PMP_NAPOT | PMP_R | PMP_W |
> + PMP_X) << 32) |
> + ((unsigned long)(PMP_NAPOT | PMP_R |
> + PMP_X) << 24) |
> + ((unsigned long)(PMP_NAPOT | PMP_R | PMP_W |
> + PMP_X) << 16) |
> + ((unsigned long)(PMP_NAPOT | PMP_R | PMP_W |
> + PMP_X) << 8);
> +
> + csr_write(pmpcfg0, pmpcfg);
> +
> + /* PMA/cache attributes */
> + ulong pmacfg0;
> +
> + if (hartid == 0) {
> + /*
> + * Hart 0: cacheable for pmp0, pmp1, pmp3; uncacheable for
> + * pmp2, pmp4.
> + */
Are these typos? Are they meant to be pma0, pma1, pma3, ...etc?
If yes, I can modify them on my side.
> + pmacfg0 = ((unsigned long)CCA_CACHE_DISABLE << 32) |
> + ((unsigned long)CCA_CACHE_ENABLE << 24) |
> + ((unsigned long)CCA_CACHE_DISABLE << 16) |
> + ((unsigned long)CCA_CACHE_ENABLE << 8) |
> + ((unsigned long)CCA_CACHE_ENABLE);
> + } else {
> + /*
> + * Hart 1 or above: cacheable for pmp0, pmp1; uncacheable for
> + * pmp2, pmp3, pmp4.
> + */
Ditto.
> + pmacfg0 = ((unsigned long)CCA_CACHE_DISABLE << 32) |
> + ((unsigned long)CCA_CACHE_DISABLE << 24) |
> + ((unsigned long)CCA_CACHE_DISABLE << 16) |
> + ((unsigned long)CCA_CACHE_ENABLE << 8) |
> + ((unsigned long)CCA_CACHE_ENABLE);
> + }
> +
> + asm volatile ("csrw %0, %1" :: "i"(CSR_PMACFG0), "r"(pmacfg0));
> + asm volatile ("fence" ::: "memory");
> +
> + /* Secondary harts: after early setup, jump to the common entry point */
> + if (hartid != 0)
> + jump_to_addr(CONFIG_SYS_LOAD_ADDR);
> +}
...
> diff --git a/arch/riscv/include/asm/arch-p8700/p8700.h b/arch/riscv/include/asm/arch-p8700/p8700.h
> new file mode 100644
> index 00000000000..5ca9b4b9497
> --- /dev/null
> +++ b/arch/riscv/include/asm/arch-p8700/p8700.h
> @@ -0,0 +1,110 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
> + */
> +
> +#ifndef __P8700_H__
> +#define __P8700_H__
> +
> +#define CSR_MIPSCONFIG7 0x7d7
> +#define CSR_PMACFG0 0x7e0
> +
> +#define MHARTID_HART_SHIFT 0
> +#define MHARTID_HART_MASK 0xf
> +#define MHARTID_CORE_SHIFT 4
> +#define MHARTID_CORE_MASK 0xff
> +#define MHARTID_CLUSTER_SHIFT 16
> +#define MHARTID_CLUSTER_MASK 0xf
> +
> +#define MARCHID_UARCH_SHIFT 0
> +#define MARCHID_UARCH_MASK 0xff
> +#define MARCHID_CLASS_SHIFT 8
> +#define MARCHID_CLASS_MASK 0xff
> +#define MARCHID_CLASS_M 0
> +#define MARCHID_CLASS_I 1
> +#define MARCHID_CLASS_P 2
> +
> +#define CM_BASE_CORE_SHIFT 8
> +#define CM_BASE_CLUSTER_SHIFT 19
> +
> +#define P8700_TIMER_ADDR 0x16108050
> +
> +#define CCA_CACHE_ENABLE 0
> +#define CCA_BUFFER_CACHE 1
> +#define CCA_CACHE_DISABLE 2
> +#define CCA_UNCACHE_ACC 3
> +#define PMA_SPECULATION (0x1 << 3)
> +
> +#define L1_I_CACHE 0
> +#define L1_D_CACHE 1
> +#define L3_CACHE 2
> +#define L2_CACHE 3
Just checking. Are these indices correct?
> +
> +#define HIT_INVALIDATE 4
> +#define HIT_WRITEBACK_INV 5
> +
> +#define HIT_INVALIDATE_D ((HIT_INVALIDATE << 2) | L1_D_CACHE)
> +#define HIT_INVALIDATE_SD ((HIT_INVALIDATE << 2) | L2_CACHE)
> +#define HIT_WRITEBACK_INV_D ((HIT_WRITEBACK_INV << 2) | L1_D_CACHE)
> +#define HIT_WRITEBACK_INV_SD ((HIT_WRITEBACK_INV << 2) | L2_CACHE)
> +
> +#define L1D_LINE_SIZE_SHIFT 10
> +#define L1D_LINE_SIZE_MASK 0x7
> +
> +#define GCR_L2_CONFIG 0x16100130
> +#define L2_LINE_SIZE_SHIFT 8
> +#define L2_LINE_SIZE_MASK 0xf
> +
> +#define PMP_R 0x01
> +#define PMP_W 0x02
> +#define PMP_X 0x04
> +#define PMP_TOR 0x8
> +#define PMP_NA4 0x10
> +#define PMP_NAPOT 0x18
> +
> +#define CM_BASE 0x16100000
> +#define CPC_BASE (CM_BASE + 0x8000)
> +
> +/* CPC Block offsets */
> +#define CPC_OFF_LOCAL 0x2000
> +
> +#define CPC_PWRUP_CTL 0x0030
> +
> +#define CPC_SYS_CONFIG 0x0140
> +
> +#define CPC_Cx_CMD 0x0000
> +#define CPC_Cx_CMD_RESET 0x4
> +
> +#define P8700_GCR_C0_COH_EN 0x20f8
> +#define P8700_GCR_C1_COH_EN 0x21f8
> +#define P8700_GCR_C2_COH_EN 0x22f8
> +#define P8700_GCR_C3_COH_EN 0x23f8
> +#define P8700_GCR_C4_COH_EN 0x24f8
> +#define P8700_GCR_C5_COH_EN 0x25f8
> +
> +#define GCR_CL_COH_EN 0x2008
> +#define GCR_CL_COH_EN_EN (0x1 << 0)
> +#define GCR_BASE_OFFSET 0x0008
> +#define GIC_BASE_OFFSET 0x0080
> +#define CPC_BASE_OFFSET 0x0088
> +#define ENABLE 0x1
> +#define COUNT_STOP (0x1 << 28)
> +#define GIC_LOCAL_SECTION_OFS 0x8000
> +#define GIC_VL_MASK 0x08
> +#define GIC_VL_RMASK 0x0c
> +#define GIC_VL_SMASK 0x10
> +#define GIC_VL_COMPARE_MAP 0x44
> +
> +#define INDEXED(op, reg, idx, offset, base) \
> + li idx, offset ;\
> + add idx, idx, base ;\
> + op reg, (idx)
> +
> +#define BOSTON_PLAT_BASE 0x17ffd000
"BOSTON_PLAT_BASE" seems to cause redefinition error when build with -Werror.
The redefinition is introduced in the second patch.
> +#define BOSTON_PLAT_DDR3STAT (BOSTON_PLAT_BASE + 0x14)
> +#define BOSTON_PLAT_DDR3STAT_CALIB (0x1 << 2)
> +#define BOSTON_PLAT_NOCPCIE0ADDR (BOSTON_PLAT_BASE + 0x3c)
> +#define BOSTON_PLAT_NOCPCIE1ADDR (BOSTON_PLAT_BASE + 0x40)
> +#define BOSTON_PLAT_NOCPCIE2ADDR (BOSTON_PLAT_BASE + 0x44)
> +
> +#endif /* __P8700_H__ */
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH v5 1/8] riscv: Add initial support for P8700 SoC
2026-03-17 8:36 ` Leo Liang
@ 2026-03-27 13:46 ` Uros Stajic
0 siblings, 0 replies; 21+ messages in thread
From: Uros Stajic @ 2026-03-27 13:46 UTC (permalink / raw)
To: Leo Liang; +Cc: u-boot@lists.denx.de, Djordje Todorovic
Hi Leo,
On 3/17/26 09:36, Leo Liang wrote:
> Hi Uros,
>
> On Wed, Dec 24, 2025 at 03:45:22PM +0000, Uros Stajic wrote:
>> From: Chao-ying Fu <cfu@mips.com>
>>
>> Add initial platform support for the P8700-F, a high-performance
>> multi-core RV64GC SoC with optional multi-cluster configuration and
>> hardware multithreading.
>>
>> This patch introduces the initial platform code necessary to support
>> the P8700 CPU in U-Boot.
>>
>> Signed-off-by: Chao-ying Fu <cfu@mips.com>
>> Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
>> Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
>> ---
>> arch/riscv/Kconfig | 1 +
>> arch/riscv/cpu/p8700/Kconfig | 14 +++
>> arch/riscv/cpu/p8700/Makefile | 7 ++
>> arch/riscv/cpu/p8700/cache.c | 93 ++++++++++++++++++
>> arch/riscv/cpu/p8700/cpu.c | 111 ++++++++++++++++++++++
>> arch/riscv/cpu/p8700/dram.c | 37 ++++++++
>> arch/riscv/include/asm/arch-p8700/p8700.h | 110 +++++++++++++++++++++
>> 7 files changed, 373 insertions(+)
>> create mode 100644 arch/riscv/cpu/p8700/Kconfig
>> create mode 100644 arch/riscv/cpu/p8700/Makefile
>> create mode 100644 arch/riscv/cpu/p8700/cache.c
>> create mode 100644 arch/riscv/cpu/p8700/cpu.c
>> create mode 100644 arch/riscv/cpu/p8700/dram.c
>> create mode 100644 arch/riscv/include/asm/arch-p8700/p8700.h
> ...
>> diff --git a/arch/riscv/cpu/p8700/cpu.c b/arch/riscv/cpu/p8700/cpu.c
>> new file mode 100644
>> index 00000000000..d63f7073d75
>> --- /dev/null
>> +++ b/arch/riscv/cpu/p8700/cpu.c
>> @@ -0,0 +1,111 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
>> + */
>> +
>> +#include <asm/encoding.h>
>> +#include <asm/io.h>
>> +#include <linux/types.h>
>> +#include <asm/arch-p8700/p8700.h>
>> +
>> +static __noreturn void jump_to_addr(ulong addr)
>> +{
>> + asm volatile ("jr %0" :: "r"(addr) : "memory");
>> + __builtin_unreachable();
>> +}
>> +
>> +void harts_early_init(void)
>> +{
>> + if (!IS_ENABLED(CONFIG_RISCV_MMODE))
>> + return;
>> +
>> + ulong hartid = csr_read(CSR_MHARTID);
>> +
>> + /* Wait for DDR3 calibration */
>> + while (!(readl((void __iomem *)BOSTON_PLAT_DDR3STAT) &
>> + BOSTON_PLAT_DDR3STAT_CALIB)) {
>> + /* busy-wait */
>> + }
>> +
>> + /*
>> + * Only mhartid[3:0] == 0 performs CM/GCR programming.
>> + * Other harts skip CM/GCR setup and go straight to PMP/PMA setup.
>> + */
>> + if ((hartid & 0xFULL) == 0) {
>> + ulong cm_base = CM_BASE;
>> + void __iomem *gcr_win = (void __iomem *)0x1fb80000;
>> + ulong cluster = (hartid >> MHARTID_CLUSTER_SHIFT) &
>> + MHARTID_CLUSTER_MASK;
>> +
>> + cm_base += cluster << CM_BASE_CLUSTER_SHIFT;
>> +
>> + if ((hartid & 0xFFFFUL) == 0)
>> + writeq(cm_base, gcr_win + GCR_BASE_OFFSET);
>> +
>> + ulong core = (hartid >> MHARTID_CORE_SHIFT) & MHARTID_CORE_MASK;
>> +
>> + /* Enable coherency for the current core */
>> + cm_base += core << CM_BASE_CORE_SHIFT;
>> + writeq((u64)GCR_CL_COH_EN_EN,
>> + (void __iomem *)(cm_base + P8700_GCR_C0_COH_EN));
>> +
>> + /*
>> + * On hart 0, default PCIe DMA mapping should be the non-IOCU
>> + * target.
>> + */
>> + if (hartid == 0) {
>> + writel(0x00, (void __iomem *)BOSTON_PLAT_NOCPCIE0ADDR);
>> + writel(0x00, (void __iomem *)BOSTON_PLAT_NOCPCIE1ADDR);
>> + writel(0x00, (void __iomem *)BOSTON_PLAT_NOCPCIE2ADDR);
>> + }
>> + }
>> +
>> + /* PMP setup */
>> + csr_write(pmpaddr1, 0x2fffffffUL);
>> + csr_write(pmpaddr2, 0x07ff7fffUL);
>> + csr_write(pmpaddr3, 0x07f3ffffUL);
>> + csr_write(pmpaddr4, 0x1fffffffffffffffUL);
>> +
>> + unsigned long pmpcfg = ((unsigned long)(PMP_NAPOT | PMP_R | PMP_W |
>> + PMP_X) << 32) |
>> + ((unsigned long)(PMP_NAPOT | PMP_R |
>> + PMP_X) << 24) |
>> + ((unsigned long)(PMP_NAPOT | PMP_R | PMP_W |
>> + PMP_X) << 16) |
>> + ((unsigned long)(PMP_NAPOT | PMP_R | PMP_W |
>> + PMP_X) << 8);
>> +
>> + csr_write(pmpcfg0, pmpcfg);
>> +
>> + /* PMA/cache attributes */
>> + ulong pmacfg0;
>> +
>> + if (hartid == 0) {
>> + /*
>> + * Hart 0: cacheable for pmp0, pmp1, pmp3; uncacheable for
>> + * pmp2, pmp4.
>> + */
>
> Are these typos? Are they meant to be pma0, pma1, pma3, ...etc?
> If yes, I can modify them on my side.
>
Yes, they are typos. They should be pma0, pma1, pma2, etc. I’ll fix that
in v6. Thanks for catching this.
>> + pmacfg0 = ((unsigned long)CCA_CACHE_DISABLE << 32) |
>> + ((unsigned long)CCA_CACHE_ENABLE << 24) |
>> + ((unsigned long)CCA_CACHE_DISABLE << 16) |
>> + ((unsigned long)CCA_CACHE_ENABLE << 8) |
>> + ((unsigned long)CCA_CACHE_ENABLE);
>> + } else {
>> + /*
>> + * Hart 1 or above: cacheable for pmp0, pmp1; uncacheable for
>> + * pmp2, pmp3, pmp4.
>> + */
>
> Ditto.
>
>> + pmacfg0 = ((unsigned long)CCA_CACHE_DISABLE << 32) |
>> + ((unsigned long)CCA_CACHE_DISABLE << 24) |
>> + ((unsigned long)CCA_CACHE_DISABLE << 16) |
>> + ((unsigned long)CCA_CACHE_ENABLE << 8) |
>> + ((unsigned long)CCA_CACHE_ENABLE);
>> + }
>> +
>> + asm volatile ("csrw %0, %1" :: "i"(CSR_PMACFG0), "r"(pmacfg0));
>> + asm volatile ("fence" ::: "memory");
>> +
>> + /* Secondary harts: after early setup, jump to the common entry point */
>> + if (hartid != 0)
>> + jump_to_addr(CONFIG_SYS_LOAD_ADDR);
>> +}
> ...
>> diff --git a/arch/riscv/include/asm/arch-p8700/p8700.h b/arch/riscv/include/asm/arch-p8700/p8700.h
>> new file mode 100644
>> index 00000000000..5ca9b4b9497
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/arch-p8700/p8700.h
>> @@ -0,0 +1,110 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
>> + */
>> +
>> +#ifndef __P8700_H__
>> +#define __P8700_H__
>> +
>> +#define CSR_MIPSCONFIG7 0x7d7
>> +#define CSR_PMACFG0 0x7e0
>> +
>> +#define MHARTID_HART_SHIFT 0
>> +#define MHARTID_HART_MASK 0xf
>> +#define MHARTID_CORE_SHIFT 4
>> +#define MHARTID_CORE_MASK 0xff
>> +#define MHARTID_CLUSTER_SHIFT 16
>> +#define MHARTID_CLUSTER_MASK 0xf
>> +
>> +#define MARCHID_UARCH_SHIFT 0
>> +#define MARCHID_UARCH_MASK 0xff
>> +#define MARCHID_CLASS_SHIFT 8
>> +#define MARCHID_CLASS_MASK 0xff
>> +#define MARCHID_CLASS_M 0
>> +#define MARCHID_CLASS_I 1
>> +#define MARCHID_CLASS_P 2
>> +
>> +#define CM_BASE_CORE_SHIFT 8
>> +#define CM_BASE_CLUSTER_SHIFT 19
>> +
>> +#define P8700_TIMER_ADDR 0x16108050
>> +
>> +#define CCA_CACHE_ENABLE 0
>> +#define CCA_BUFFER_CACHE 1
>> +#define CCA_CACHE_DISABLE 2
>> +#define CCA_UNCACHE_ACC 3
>> +#define PMA_SPECULATION (0x1 << 3)
>> +
>> +#define L1_I_CACHE 0
>> +#define L1_D_CACHE 1
>> +#define L3_CACHE 2
>> +#define L2_CACHE 3
>
> Just checking. Are these indices correct?
>
Yes, these indices are correct. According to the documentation for the
P8700 MCACHE instruction, the target cache values are defined as
L1 I-cache = 0, L1 D-cache = 1, L3 cache = 2, and L2 cache = 3.
>> +
>> +#define HIT_INVALIDATE 4
>> +#define HIT_WRITEBACK_INV 5
>> +
>> +#define HIT_INVALIDATE_D ((HIT_INVALIDATE << 2) | L1_D_CACHE)
>> +#define HIT_INVALIDATE_SD ((HIT_INVALIDATE << 2) | L2_CACHE)
>> +#define HIT_WRITEBACK_INV_D ((HIT_WRITEBACK_INV << 2) | L1_D_CACHE)
>> +#define HIT_WRITEBACK_INV_SD ((HIT_WRITEBACK_INV << 2) | L2_CACHE)
>> +
>> +#define L1D_LINE_SIZE_SHIFT 10
>> +#define L1D_LINE_SIZE_MASK 0x7
>> +
>> +#define GCR_L2_CONFIG 0x16100130
>> +#define L2_LINE_SIZE_SHIFT 8
>> +#define L2_LINE_SIZE_MASK 0xf
>> +
>> +#define PMP_R 0x01
>> +#define PMP_W 0x02
>> +#define PMP_X 0x04
>> +#define PMP_TOR 0x8
>> +#define PMP_NA4 0x10
>> +#define PMP_NAPOT 0x18
>> +
>> +#define CM_BASE 0x16100000
>> +#define CPC_BASE (CM_BASE + 0x8000)
>> +
>> +/* CPC Block offsets */
>> +#define CPC_OFF_LOCAL 0x2000
>> +
>> +#define CPC_PWRUP_CTL 0x0030
>> +
>> +#define CPC_SYS_CONFIG 0x0140
>> +
>> +#define CPC_Cx_CMD 0x0000
>> +#define CPC_Cx_CMD_RESET 0x4
>> +
>> +#define P8700_GCR_C0_COH_EN 0x20f8
>> +#define P8700_GCR_C1_COH_EN 0x21f8
>> +#define P8700_GCR_C2_COH_EN 0x22f8
>> +#define P8700_GCR_C3_COH_EN 0x23f8
>> +#define P8700_GCR_C4_COH_EN 0x24f8
>> +#define P8700_GCR_C5_COH_EN 0x25f8
>> +
>> +#define GCR_CL_COH_EN 0x2008
>> +#define GCR_CL_COH_EN_EN (0x1 << 0)
>> +#define GCR_BASE_OFFSET 0x0008
>> +#define GIC_BASE_OFFSET 0x0080
>> +#define CPC_BASE_OFFSET 0x0088
>> +#define ENABLE 0x1
>> +#define COUNT_STOP (0x1 << 28)
>> +#define GIC_LOCAL_SECTION_OFS 0x8000
>> +#define GIC_VL_MASK 0x08
>> +#define GIC_VL_RMASK 0x0c
>> +#define GIC_VL_SMASK 0x10
>> +#define GIC_VL_COMPARE_MAP 0x44
>> +
>> +#define INDEXED(op, reg, idx, offset, base) \
>> + li idx, offset ;\
>> + add idx, idx, base ;\
>> + op reg, (idx)
>> +
>> +#define BOSTON_PLAT_BASE 0x17ffd000
>
> "BOSTON_PLAT_BASE" seems to cause redefinition error when build with -Werror.
> The redefinition is introduced in the second patch.
>
You're right. The BOSTON_PLAT_BASE redefinition comes from the second
patch. I will fix it in v6.
>> +#define BOSTON_PLAT_DDR3STAT (BOSTON_PLAT_BASE + 0x14)
>> +#define BOSTON_PLAT_DDR3STAT_CALIB (0x1 << 2)
>> +#define BOSTON_PLAT_NOCPCIE0ADDR (BOSTON_PLAT_BASE + 0x3c)
>> +#define BOSTON_PLAT_NOCPCIE1ADDR (BOSTON_PLAT_BASE + 0x40)
>> +#define BOSTON_PLAT_NOCPCIE2ADDR (BOSTON_PLAT_BASE + 0x44)
>> +
>> +#endif /* __P8700_H__ */
Best regards,
Uros
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v5 2/8] board: boston-riscv: Add initial support for P8700 Boston board
2025-12-24 15:44 [PATCH v5 0/8] riscv: Add support for P8700 platform on Boston board Uros Stajic
2025-12-24 15:45 ` [PATCH v5 1/8] riscv: Add initial support for P8700 SoC Uros Stajic
@ 2025-12-24 15:45 ` Uros Stajic
2026-02-09 11:25 ` Leo Liang
` (2 more replies)
2025-12-24 15:46 ` [PATCH v5 3/8] gpio: Add GPIO driver for Intel EG20T Uros Stajic
` (5 subsequent siblings)
7 siblings, 3 replies; 21+ messages in thread
From: Uros Stajic @ 2025-12-24 15:45 UTC (permalink / raw)
To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu, Uros Stajic
From: Chao-ying Fu <cfu@mips.com>
Implement initial board-level support for the P8700 Boston SoC.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
arch/riscv/Kconfig | 11 +
arch/riscv/dts/Makefile | 1 +
arch/riscv/dts/boston-p8700.dts | 264 ++++++++++++++++++++++++
board/mips/boston-riscv/Kconfig | 43 ++++
board/mips/boston-riscv/MAINTAINERS | 9 +
board/mips/boston-riscv/Makefile | 8 +
board/mips/boston-riscv/boston-lcd.h | 20 ++
board/mips/boston-riscv/boston-regs.h | 38 ++++
board/mips/boston-riscv/boston-riscv.c | 30 +++
board/mips/boston-riscv/checkboard.c | 43 ++++
board/mips/boston-riscv/config.mk | 15 ++
board/mips/boston-riscv/lowlevel_init.S | 18 ++
board/mips/boston-riscv/reset.c | 15 ++
configs/boston-p8700_defconfig | 98 +++++++++
drivers/clk/Kconfig | 2 +-
include/configs/boston-riscv.h | 9 +
16 files changed, 623 insertions(+), 1 deletion(-)
create mode 100644 arch/riscv/dts/boston-p8700.dts
create mode 100644 board/mips/boston-riscv/Kconfig
create mode 100644 board/mips/boston-riscv/MAINTAINERS
create mode 100644 board/mips/boston-riscv/Makefile
create mode 100644 board/mips/boston-riscv/boston-lcd.h
create mode 100644 board/mips/boston-riscv/boston-regs.h
create mode 100644 board/mips/boston-riscv/boston-riscv.c
create mode 100644 board/mips/boston-riscv/checkboard.c
create mode 100644 board/mips/boston-riscv/config.mk
create mode 100644 board/mips/boston-riscv/lowlevel_init.S
create mode 100644 board/mips/boston-riscv/reset.c
create mode 100644 configs/boston-p8700_defconfig
create mode 100644 include/configs/boston-riscv.h
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index b4896544868..8eb12d4eb4e 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -61,6 +61,16 @@ config TARGET_XILINX_MBV
config TARGET_ASPEED_AST2700_IBEX
bool "Support Ibex RISC-V cores on Aspeed AST2700 SoC"
+config TARGET_MIPS_BOSTON
+ bool "Support Mips Boston Board"
+ select DM
+ select DM_EVENT
+ select DM_GPIO
+ select DM_SERIAL
+ select OF_CONTROL
+ select DISTRO_DEFAULTS
+ imply CMD_DM
+
endchoice
config SYS_ICACHE_OFF
@@ -119,6 +129,7 @@ source "board/spacemit/bananapi-f3/Kconfig"
source "board/starfive/visionfive2/Kconfig"
source "board/thead/th1520_lpi4a/Kconfig"
source "board/xilinx/mbv/Kconfig"
+source "board/mips/boston-riscv/Kconfig"
# platform-specific options below
source "arch/riscv/cpu/andes/Kconfig"
diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile
index 9b347fc3b50..63e3bd4c95f 100644
--- a/arch/riscv/dts/Makefile
+++ b/arch/riscv/dts/Makefile
@@ -16,6 +16,7 @@ dtb-$(CONFIG_TARGET_XILINX_MBV) += xilinx-mbv32.dtb
dtb-$(CONFIG_TARGET_XILINX_MBV) += xilinx-mbv64.dtb
dtb-$(CONFIG_TARGET_XILINX_MBV) += xilinx-binman.dtb
dtb-$(CONFIG_TARGET_ASPEED_AST2700_IBEX) += ast2700-ibex.dtb
+dtb-$(CONFIG_TARGET_MIPS_BOSTON) += boston-p8700.dtb
include $(srctree)/scripts/Makefile.dts
diff --git a/arch/riscv/dts/boston-p8700.dts b/arch/riscv/dts/boston-p8700.dts
new file mode 100644
index 00000000000..f27ebeda4a2
--- /dev/null
+++ b/arch/riscv/dts/boston-p8700.dts
@@ -0,0 +1,264 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/clock/boston-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/mips-gic.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "p8700";
+ compatible = "img,boston";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ timebase-frequency = <25000000>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "riscv";
+ reg = <0>;
+ mmu-type = "riscv,sv39";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zba", "zbb";
+ clocks = <&clk_boston BOSTON_CLK_CPU>;
+ clock-frequency = <25000000>;
+ bootph-all;
+ status = "okay";
+
+ cpu0_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x80000000 0x80000000>;
+ };
+
+ timer@16154000 {
+ compatible = "riscv,aclint-mtimer";
+ reg = <0x16108050 0x8>,
+ <0x16154000 0x7ff8>;
+ interrupts-extended = <&cpu0_intc 7>;
+ };
+
+ gic: interrupt-controller {
+ compatible = "mti,gic";
+
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ };
+
+ pci0: pci@10000000 {
+ device_type = "pci";
+ compatible = "xlnx,axi-pcie-host-1.00.a";
+ reg = <0x10000000 0x2000000>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SHARED 2 IRQ_TYPE_LEVEL_HIGH>;
+
+ ranges = <0x02000000 0 0x40000000
+ 0x40000000 0 0x40000000>;
+
+ bus-range = <0x00 0xff>;
+
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pci0_intc 1>,
+ <0 0 0 2 &pci0_intc 2>,
+ <0 0 0 3 &pci0_intc 3>,
+ <0 0 0 4 &pci0_intc 4>;
+
+ status = "disabled";
+
+ pci0_intc: interrupt-controller {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ pci1: pci@12000000 {
+ device_type = "pci";
+ compatible = "xlnx,axi-pcie-host-1.00.a";
+ reg = <0x12000000 0x2000000>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SHARED 1 IRQ_TYPE_LEVEL_HIGH>;
+
+ ranges = <0x02000000 0 0x20000000
+ 0x20000000 0 0x20000000>;
+
+ bus-range = <0x00 0xff>;
+
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pci1_intc 1>,
+ <0 0 0 2 &pci1_intc 2>,
+ <0 0 0 3 &pci1_intc 3>,
+ <0 0 0 4 &pci1_intc 4>;
+
+ status = "disabled";
+
+ pci1_intc: interrupt-controller {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ };
+ };
+
+ pci2: pci@14000000 {
+ device_type = "pci";
+ compatible = "xlnx,axi-pcie-host-1.00.a";
+ reg = <0x14000000 0x2000000>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SHARED 0 IRQ_TYPE_LEVEL_HIGH>;
+
+ ranges = <0x02000000 0 0x16000000
+ 0x16000000 0 0x100000>;
+
+ bus-range = <0x00 0xff>;
+
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pci2_intc 1>,
+ <0 0 0 2 &pci2_intc 2>,
+ <0 0 0 3 &pci2_intc 3>,
+ <0 0 0 4 &pci2_intc 4>;
+
+ pci2_intc: interrupt-controller {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ };
+
+ pci2_root@0,0,0 {
+ compatible = "pci10ee,7021", "pci-bridge";
+ reg = <0x00000000 0 0 0 0>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+
+ eg20t_bridge@1,0,0 {
+ compatible = "pci8086,8800", "pci-bridge";
+ reg = <0x00010000 0 0 0 0>;
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+
+ eg20t_mac@2,0,1 {
+ compatible = "pci8086,8802", "intel,pch-gbe";
+ reg = <0x00020100 0 0 0 0>;
+ phy-reset-gpios = <&eg20t_gpio 6 GPIO_ACTIVE_LOW>;
+ };
+
+ eg20t_gpio: eg20t_gpio@2,0,2 {
+ compatible = "pci8086,8803", "intel,eg20t-gpio";
+ reg = <0x00020200 0 0 0 0>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ mmc0: mmc@2,4,0 {
+ compatible = "intel,apl-sd";
+ reg = <0x00022000 0 0 0 0>;
+ };
+
+ mmc1: mmc@2,4,1 {
+ compatible = "intel,apl-sd";
+ reg = <0x00022100 0 0 0 0>;
+ };
+
+ eg20t_i2c@2,12,2 {
+ compatible = "pci8086,8817";
+ reg = <0x00026200 0 0 0 0>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rtc@0x68 {
+ compatible = "st,m41t81s";
+ reg = <0x68>;
+ };
+ };
+ };
+ };
+ };
+
+ plat_regs: system-controller@17ffd000 {
+ compatible = "img,boston-platform-regs", "syscon";
+ reg = <0x17ffd000 0x1000>;
+ bootph-all;
+ };
+
+ clk_boston: clock {
+ compatible = "img,boston-clock";
+ #clock-cells = <1>;
+ regmap = <&plat_regs>;
+ bootph-all;
+ };
+
+ reboot: syscon-reboot {
+ compatible = "syscon-reboot";
+ regmap = <&plat_regs>;
+ offset = <0x10>;
+ mask = <0x10>;
+ };
+
+ uart0: uart@17ffe000 {
+ compatible = "ns16550a";
+ reg = <0x17ffe000 0x1000>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SHARED 3 IRQ_TYPE_LEVEL_HIGH>;
+
+ clocks = <&clk_boston BOSTON_CLK_SYS>;
+ clock-frequency = <25000000>;
+
+ bootph-all;
+ };
+
+ lcd: lcd@17fff000 {
+ compatible = "img,boston-lcd";
+ reg = <0x17fff000 0x8>;
+ };
+
+ flash@18000000 {
+ compatible = "cfi-flash";
+ reg = <0x18000000 0x8000000>;
+ bank-width = <2>;
+ };
+};
diff --git a/board/mips/boston-riscv/Kconfig b/board/mips/boston-riscv/Kconfig
new file mode 100644
index 00000000000..68c5fc50489
--- /dev/null
+++ b/board/mips/boston-riscv/Kconfig
@@ -0,0 +1,43 @@
+if TARGET_MIPS_BOSTON
+
+config SYS_BOARD
+ default "boston-riscv"
+
+config SYS_VENDOR
+ default "mips"
+
+config SYS_CONFIG_NAME
+ default "boston-riscv"
+
+config SYS_CPU
+ default "p8700"
+
+config BOARD_SPECIFIC_OPTIONS
+ def_bool y
+ select P8700_RISCV
+ imply SYS_NS16550
+
+config SYS_CACHELINE_SIZE
+ default 64
+
+config SYS_SDRAM_BASE
+ hex
+ default 0x80000000
+
+config SYS_INIT_SP_ADDR
+ hex
+ default 0x80200000
+
+config STANDALONE_LOAD_ADDR
+ hex
+ default 0x80200000
+
+config SYS_MAX_FLASH_BANKS_DETECT
+ bool
+ default y
+
+config PHY_REALTEK
+ bool
+ default y
+
+endif
diff --git a/board/mips/boston-riscv/MAINTAINERS b/board/mips/boston-riscv/MAINTAINERS
new file mode 100644
index 00000000000..e350121395e
--- /dev/null
+++ b/board/mips/boston-riscv/MAINTAINERS
@@ -0,0 +1,9 @@
+BOSTON-RISCV BOARD
+M: Chao-ying Fu <cfu@mips.com>
+S: Maintained
+F: board/mips/boston-riscv/
+F: include/configs/boston-riscv.h
+F: arch/riscv/cpu/p8700/
+F: arch/riscv/include/asm/arch-p8700/
+F: configs/boston-p8700_defconfig
+F: arch/riscv/dts/boston-p8700.dts
diff --git a/board/mips/boston-riscv/Makefile b/board/mips/boston-riscv/Makefile
new file mode 100644
index 00000000000..0615c677d23
--- /dev/null
+++ b/board/mips/boston-riscv/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2016 Imagination Technologies
+
+obj-y += boston-riscv.o
+obj-y += checkboard.o
+obj-y += lowlevel_init.o
+obj-y += reset.o
diff --git a/board/mips/boston-riscv/boston-lcd.h b/board/mips/boston-riscv/boston-lcd.h
new file mode 100644
index 00000000000..5f5cd0fe126
--- /dev/null
+++ b/board/mips/boston-riscv/boston-lcd.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ */
+
+#ifndef __BOARD_BOSTON_LCD_H__
+#define __BOARD_BOSTON_LCD_H__
+
+/**
+ * lowlevel_display() - Display a message on Boston's LCD
+ * @msg: The string to display
+ *
+ * Display the string @msg on the 7 character LCD display of the Boston board.
+ * This is typically used for debug or to present some form of status
+ * indication to the user, allowing faults to be identified when things go
+ * wrong early enough that the UART isn't up.
+ */
+void lowlevel_display(const char msg[static 8]);
+
+#endif /* __BOARD_BOSTON_LCD_H__ */
diff --git a/board/mips/boston-riscv/boston-regs.h b/board/mips/boston-riscv/boston-regs.h
new file mode 100644
index 00000000000..4d5ea8833ab
--- /dev/null
+++ b/board/mips/boston-riscv/boston-regs.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ */
+
+#ifndef __BOARD_BOSTON_REGS_H__
+#define __BOARD_BOSTON_REGS_H__
+
+#ifndef BOSTON_PLAT_BASE
+#define BOSTON_PLAT_BASE (0x17ffd000)
+#endif
+#define BOSTON_LCD_BASE (0x17fff000)
+
+/*
+ * Platform Register Definitions
+ */
+#define BOSTON_PLAT_CORE_CL (BOSTON_PLAT_BASE + 0x04)
+
+#define BOSTON_PLAT_SOFT_RST (BOSTON_PLAT_BASE + 0x10)
+#define BOSTON_PLAT_SOFT_RST_SYSTEM (0x1 << 4)
+
+#define BOSTON_PLAT_DDR3STAT (BOSTON_PLAT_BASE + 0x14)
+#define BOSTON_PLAT_DDR3STAT_CALIB (0x1 << 2)
+
+#define BOSTON_PLAT_BUILDCFG0 (BOSTON_PLAT_BASE + 0x34)
+#define BOSTON_PLAT_BUILDCFG0_IOCU (0x1 << 0)
+#define BOSTON_PLAT_BUILDCFG0_PCIE0 (0x1 << 1)
+#define BOSTON_PLAT_BUILDCFG0_PCIE1 (0x1 << 2)
+#define BOSTON_PLAT_BUILDCFG0_PCIE2 (0x1 << 3)
+#define BOSTON_PLAT_BUILDCFG0_CFG_LTR (0xf << 4)
+#define BOSTON_PLAT_BUILDCFG0_CFG_NUM (0xff << 8)
+#define BOSTON_PLAT_BUILDCFG0_DP (0x1 << 24)
+#define BOSTON_PLAT_BUILDCFG0_DP_MULT (0xf << 28)
+
+#define BOSTON_PLAT_DDRCONF0 (BOSTON_PLAT_BASE + 0x38)
+#define BOSTON_PLAT_DDRCONF0_SIZE (0xf << 0)
+
+#endif /* __BOARD_BOSTON_REGS_H__ */
diff --git a/board/mips/boston-riscv/boston-riscv.c b/board/mips/boston-riscv/boston-riscv.c
new file mode 100644
index 00000000000..64abe61c6e4
--- /dev/null
+++ b/board/mips/boston-riscv/boston-riscv.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ */
+
+#include <asm/encoding.h>
+#include <linux/types.h>
+#include <asm/arch-p8700/p8700.h>
+
+#define PMACFG0_PMP3_SHIFT 24
+#define PMACFG0_PMP3_MASK (0xffUL << PMACFG0_PMP3_SHIFT)
+
+int board_early_init_r(void)
+{
+ if (!IS_ENABLED(CONFIG_RISCV_MMODE))
+ return 0;
+ ulong pmacfg0 = csr_read(CSR_PMACFG0);
+
+ /*
+ * Make the flash region (PMA entry corresponding to pmp3) uncached by
+ * setting the CCA field in CSR_PMACFG0[31:24].
+ */
+ pmacfg0 &= ~PMACFG0_PMP3_MASK;
+ pmacfg0 |= (ulong)CCA_CACHE_DISABLE << PMACFG0_PMP3_SHIFT;
+
+ csr_write(CSR_PMACFG0, pmacfg0);
+ asm volatile ("fence" ::: "memory");
+
+ return 0;
+}
diff --git a/board/mips/boston-riscv/checkboard.c b/board/mips/boston-riscv/checkboard.c
new file mode 100644
index 00000000000..c7bf6734433
--- /dev/null
+++ b/board/mips/boston-riscv/checkboard.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ */
+
+#include "boston-lcd.h"
+#include "boston-regs.h"
+#include <init.h>
+#include <asm/io.h>
+#include <asm/arch-p8700/p8700.h>
+
+int checkboard(void)
+{
+ u32 changelist, cfg, core, uarch;
+ u64 marchid;
+
+ lowlevel_display("U-boot ");
+
+ printf("Board: Mips Boston RISC-V\n");
+
+ changelist = __raw_readl((uint32_t *)BOSTON_PLAT_CORE_CL);
+ if (changelist > 1) {
+ asm volatile ("csrr %0, marchid" : "=r"(marchid)::);
+ core = (marchid >> MARCHID_CLASS_SHIFT) & MARCHID_CLASS_MASK;
+ uarch = (marchid >> MARCHID_UARCH_SHIFT) & MARCHID_UARCH_MASK;
+
+ printf("Core: class%x uarch%x cl%x", core, uarch, changelist);
+
+ cfg = __raw_readl((uint32_t *)BOSTON_PLAT_BUILDCFG0);
+ if (cfg & BOSTON_PLAT_BUILDCFG0_CFG_NUM)
+ printf(" config %u",
+ (cfg & BOSTON_PLAT_BUILDCFG0_CFG_NUM) >> 8);
+ if (cfg & BOSTON_PLAT_BUILDCFG0_CFG_LTR)
+ printf("%c",
+ 'a' + ((cfg & BOSTON_PLAT_BUILDCFG0_CFG_LTR) >> 4) - 1);
+ if (cfg & BOSTON_PLAT_BUILDCFG0_DP)
+ printf(", x%u debug port",
+ (cfg & BOSTON_PLAT_BUILDCFG0_DP_MULT) >> 28);
+ printf("\n");
+ }
+
+ return 0;
+}
diff --git a/board/mips/boston-riscv/config.mk b/board/mips/boston-riscv/config.mk
new file mode 100644
index 00000000000..c1e242f1088
--- /dev/null
+++ b/board/mips/boston-riscv/config.mk
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+quiet_cmd_srec_cat = SRECCAT $@
+ cmd_srec_cat = srec_cat -output $@ -$2 \
+ $< -binary \
+ -fill 0x00 -within $< -binary -range-pad 16 \
+ -offset $3
+
+u-boot.mcs: u-boot.bin
+ $(call cmd,srec_cat,intel,0x7c00000)
+
+# if srec_cat is present build u-boot.mcs by default
+has_srec_cat = $(call try-run,srec_cat -VERSion,y,n)
+INPUTS-$(has_srec_cat) += u-boot.mcs
+CLEAN_FILES += u-boot.mcs
diff --git a/board/mips/boston-riscv/lowlevel_init.S b/board/mips/boston-riscv/lowlevel_init.S
new file mode 100644
index 00000000000..8fa85749e40
--- /dev/null
+++ b/board/mips/boston-riscv/lowlevel_init.S
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ */
+
+#include "boston-regs.h"
+
+.data
+
+msg_ddr_cal: .ascii "DDR Cal "
+msg_ddr_ok: .ascii "DDR OK "
+
+.text
+
+ .globl lowlevel_display
+lowlevel_display:
+ li t0, BOSTON_LCD_BASE
+ jr ra
diff --git a/board/mips/boston-riscv/reset.c b/board/mips/boston-riscv/reset.c
new file mode 100644
index 00000000000..8e7e0572aad
--- /dev/null
+++ b/board/mips/boston-riscv/reset.c
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017 Imagination Technologies
+ */
+
+#include "boston-regs.h"
+#include <asm/io.h>
+#include <linux/delay.h>
+
+void _machine_restart(void)
+{
+ writel(BOSTON_PLAT_SOFT_RST_SYSTEM, (void __iomem *)BOSTON_PLAT_SOFT_RST);
+
+ udelay(1000);
+}
diff --git a/configs/boston-p8700_defconfig b/configs/boston-p8700_defconfig
new file mode 100644
index 00000000000..498ccb15b4c
--- /dev/null
+++ b/configs/boston-p8700_defconfig
@@ -0,0 +1,98 @@
+CONFIG_RISCV=y
+CONFIG_SYS_TEXT_BASE=0x1fc00000
+CONFIG_ENV_SIZE=0x40000
+CONFIG_ENV_SECT_SIZE=0x40000
+CONFIG_TARGET_MIPS_BOSTON=y
+CONFIG_DEFAULT_DEVICE_TREE="boston-p8700"
+
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_BEST_MATCH=y
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_SYS_PROMPT="boston # "
+CONFIG_CMD_GREPENV=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_SYS_MEMTEST_START=0x80000000
+CONFIG_SYS_MEMTEST_END=0x90000000
+CONFIG_BOOTDELAY=-1
+
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ARCH_RV64I=y
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_DISPLAY_BOARDINFO=y
+CONFIG_BOARD_INIT=n
+#CONFIG_CMD_BOOTEFI_SELFTEST=y
+#CONFIG_CMD_NVEDIT_EFI=y
+CONFIG_CMD_MII=y
+# CONFIG_OF_PRIOR_STAGE=y
+CONFIG_DM_MTD=y
+CONFIG_SMP=n
+CONFIG_XIP=y
+CONFIG_CLK_BOSTON=y
+CONFIG_RISCV_ISA_C=n
+CONFIG_SHOW_REGS=y
+CONFIG_SYS_NS16550=y
+
+CONFIG_CMD_PCI=y
+CONFIG_CMD_SNTP=y
+CONFIG_CMD_DNS=y
+CONFIG_CMD_LINK_LOCAL=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_ENV_ADDR=0x1ffc0000
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_MTD=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_FLASH_CFI_DRIVER=y
+CONFIG_CFI_FLASH=y
+CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
+CONFIG_SYS_FLASH_USE_PROTECTION=y
+CONFIG_SYS_FLASH_CFI=y
+CONFIG_SYS_FLASH_PROTECTION=y
+CONFIG_DM_ETH=y
+CONFIG_PCH_GBE=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_PCI_XILINX=y
+CONFIG_LZ4=y
+CONFIG_CLK=y
+CONFIG_EG20T_GPIO=y
+
+CONFIG_MMC=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CPU=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_EMBED=y
+CONFIG_CPU=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_PCI=y
+
+CONFIG_UNIT_TEST=y
+CONFIG_UT_LIB=n
+CONFIG_UT_LIB_ASN1=n
+CONFIG_UT_LOG=n
+CONFIG_UT_TIME=y
+CONFIG_UT_UNICODE=n
+CONFIG_UT_ENV=n
+CONFIG_UT_OVERLAY=n
+
+CONFIG_SYS_LOAD_ADDR=0x80000000
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80200000
+CONFIG_TEXT_BASE=0x1fc00000
+CONFIG_SYS_MALLOC_LEN=0x00800000
+CONFIG_SYS_BOOTM_LEN=0x04000000
+CONFIG_SYS_MAX_FLASH_SECT=1024
+CONFIG_PHY_ANEG_TIMEOUT=40000
+CONFIG_NET_RETRY_COUNT=10
+CONFIG_ENV_CALLBACK_LIST_STATIC="io.coherent:io_coherent,"
+CONFIG_BOOTARGS="root=/dev/sda rw earlycon console=ttyS0,115200n8r"
+CONFIG_BOARD_EARLY_INIT_R=y
+CONFIG_PCI_BRIDGE_MEM_ALIGNMENT=0x1
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index b884a02bdeb..bee76671b20 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -59,7 +59,7 @@ config CLK_BCM6345
clocks on BCM6345 SoCs. HW has no rate changing capabilities.
config CLK_BOSTON
- def_bool y if TARGET_BOSTON
+ def_bool y if TARGET_BOSTON || TARGET_MIPS_BOSTON
depends on CLK
select REGMAP
select SYSCON
diff --git a/include/configs/boston-riscv.h b/include/configs/boston-riscv.h
new file mode 100644
index 00000000000..f1ee6f6032a
--- /dev/null
+++ b/include/configs/boston-riscv.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+ */
+
+#ifndef __CONFIG_BOSTON_RISCV_H
+#define __CONFIG_BOSTON_RISCV_H
+
+#endif /* __CONFIG_BOSTON_RISCV_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH v5 2/8] board: boston-riscv: Add initial support for P8700 Boston board
2025-12-24 15:45 ` [PATCH v5 2/8] board: boston-riscv: Add initial support for P8700 Boston board Uros Stajic
@ 2026-02-09 11:25 ` Leo Liang
2026-03-17 8:48 ` Leo Liang
2026-03-18 11:16 ` Conor Dooley
2 siblings, 0 replies; 21+ messages in thread
From: Leo Liang @ 2026-02-09 11:25 UTC (permalink / raw)
To: Uros Stajic; +Cc: u-boot@lists.denx.de, Djordje Todorovic, Chao-ying Fu
On Wed, Dec 24, 2025 at 03:45:47PM +0000, Uros Stajic wrote:
> From: Chao-ying Fu <cfu@mips.com>
>
> Implement initial board-level support for the P8700 Boston SoC.
>
> Signed-off-by: Chao-ying Fu <cfu@mips.com>
> Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
> ---
> arch/riscv/Kconfig | 11 +
> arch/riscv/dts/Makefile | 1 +
> arch/riscv/dts/boston-p8700.dts | 264 ++++++++++++++++++++++++
> board/mips/boston-riscv/Kconfig | 43 ++++
> board/mips/boston-riscv/MAINTAINERS | 9 +
> board/mips/boston-riscv/Makefile | 8 +
> board/mips/boston-riscv/boston-lcd.h | 20 ++
> board/mips/boston-riscv/boston-regs.h | 38 ++++
> board/mips/boston-riscv/boston-riscv.c | 30 +++
> board/mips/boston-riscv/checkboard.c | 43 ++++
> board/mips/boston-riscv/config.mk | 15 ++
> board/mips/boston-riscv/lowlevel_init.S | 18 ++
> board/mips/boston-riscv/reset.c | 15 ++
> configs/boston-p8700_defconfig | 98 +++++++++
> drivers/clk/Kconfig | 2 +-
> include/configs/boston-riscv.h | 9 +
> 16 files changed, 623 insertions(+), 1 deletion(-)
> create mode 100644 arch/riscv/dts/boston-p8700.dts
> create mode 100644 board/mips/boston-riscv/Kconfig
> create mode 100644 board/mips/boston-riscv/MAINTAINERS
> create mode 100644 board/mips/boston-riscv/Makefile
> create mode 100644 board/mips/boston-riscv/boston-lcd.h
> create mode 100644 board/mips/boston-riscv/boston-regs.h
> create mode 100644 board/mips/boston-riscv/boston-riscv.c
> create mode 100644 board/mips/boston-riscv/checkboard.c
> create mode 100644 board/mips/boston-riscv/config.mk
> create mode 100644 board/mips/boston-riscv/lowlevel_init.S
> create mode 100644 board/mips/boston-riscv/reset.c
> create mode 100644 configs/boston-p8700_defconfig
> create mode 100644 include/configs/boston-riscv.h
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v5 2/8] board: boston-riscv: Add initial support for P8700 Boston board
2025-12-24 15:45 ` [PATCH v5 2/8] board: boston-riscv: Add initial support for P8700 Boston board Uros Stajic
2026-02-09 11:25 ` Leo Liang
@ 2026-03-17 8:48 ` Leo Liang
2026-03-18 11:16 ` Conor Dooley
2 siblings, 0 replies; 21+ messages in thread
From: Leo Liang @ 2026-03-17 8:48 UTC (permalink / raw)
To: Uros Stajic; +Cc: u-boot@lists.denx.de, Djordje Todorovic, Chao-ying Fu
On Wed, Dec 24, 2025 at 03:45:47PM +0000, Uros Stajic wrote:
> From: Chao-ying Fu <cfu@mips.com>
>
> Implement initial board-level support for the P8700 Boston SoC.
>
> Signed-off-by: Chao-ying Fu <cfu@mips.com>
> Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
> Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
> ---
> arch/riscv/Kconfig | 11 +
> arch/riscv/dts/Makefile | 1 +
> arch/riscv/dts/boston-p8700.dts | 264 ++++++++++++++++++++++++
> board/mips/boston-riscv/Kconfig | 43 ++++
> board/mips/boston-riscv/MAINTAINERS | 9 +
> board/mips/boston-riscv/Makefile | 8 +
> board/mips/boston-riscv/boston-lcd.h | 20 ++
> board/mips/boston-riscv/boston-regs.h | 38 ++++
> board/mips/boston-riscv/boston-riscv.c | 30 +++
> board/mips/boston-riscv/checkboard.c | 43 ++++
> board/mips/boston-riscv/config.mk | 15 ++
> board/mips/boston-riscv/lowlevel_init.S | 18 ++
> board/mips/boston-riscv/reset.c | 15 ++
> configs/boston-p8700_defconfig | 98 +++++++++
> drivers/clk/Kconfig | 2 +-
> include/configs/boston-riscv.h | 9 +
> 16 files changed, 623 insertions(+), 1 deletion(-)
> create mode 100644 arch/riscv/dts/boston-p8700.dts
> create mode 100644 board/mips/boston-riscv/Kconfig
> create mode 100644 board/mips/boston-riscv/MAINTAINERS
> create mode 100644 board/mips/boston-riscv/Makefile
> create mode 100644 board/mips/boston-riscv/boston-lcd.h
> create mode 100644 board/mips/boston-riscv/boston-regs.h
> create mode 100644 board/mips/boston-riscv/boston-riscv.c
> create mode 100644 board/mips/boston-riscv/checkboard.c
> create mode 100644 board/mips/boston-riscv/config.mk
> create mode 100644 board/mips/boston-riscv/lowlevel_init.S
> create mode 100644 board/mips/boston-riscv/reset.c
> create mode 100644 configs/boston-p8700_defconfig
> create mode 100644 include/configs/boston-riscv.h
>
> ...
> diff --git a/board/mips/boston-riscv/Kconfig b/board/mips/boston-riscv/Kconfig
> new file mode 100644
> index 00000000000..68c5fc50489
> --- /dev/null
> +++ b/board/mips/boston-riscv/Kconfig
> @@ -0,0 +1,43 @@
> +if TARGET_MIPS_BOSTON
> +
> +config SYS_BOARD
> + default "boston-riscv"
> +
> +config SYS_VENDOR
> + default "mips"
> +
> +config SYS_CONFIG_NAME
> + default "boston-riscv"
> +
> +config SYS_CPU
> + default "p8700"
> +
> +config BOARD_SPECIFIC_OPTIONS
> + def_bool y
> + select P8700_RISCV
> + imply SYS_NS16550
> +
> +config SYS_CACHELINE_SIZE
> + default 64
> +
> +config SYS_SDRAM_BASE
> + hex
> + default 0x80000000
> +
> +config SYS_INIT_SP_ADDR
> + hex
> + default 0x80200000
> +
> +config STANDALONE_LOAD_ADDR
> + hex
> + default 0x80200000
> +
> +config SYS_MAX_FLASH_BANKS_DETECT
> + bool
> + default y
> +
> +config PHY_REALTEK
> + bool
> + default y
> +
Use tab instead of space.
> +endif
> diff --git a/board/mips/boston-riscv/MAINTAINERS b/board/mips/boston-riscv/MAINTAINERS
> new file mode 100644
> index 00000000000..e350121395e
> --- /dev/null
> +++ b/board/mips/boston-riscv/MAINTAINERS
> @@ -0,0 +1,9 @@
> +BOSTON-RISCV BOARD
> +M: Chao-ying Fu <cfu@mips.com>
> +S: Maintained
> +F: board/mips/boston-riscv/
> +F: include/configs/boston-riscv.h
> +F: arch/riscv/cpu/p8700/
> +F: arch/riscv/include/asm/arch-p8700/
> +F: configs/boston-p8700_defconfig
> +F: arch/riscv/dts/boston-p8700.dts
Ditto.
> diff --git a/board/mips/boston-riscv/Makefile b/board/mips/boston-riscv/Makefile
> new file mode 100644
> index 00000000000..0615c677d23
> --- /dev/null
> +++ b/board/mips/boston-riscv/Makefile
> @@ -0,0 +1,8 @@
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# Copyright (C) 2016 Imagination Technologies
> +
> +obj-y += boston-riscv.o
> +obj-y += checkboard.o
> +obj-y += lowlevel_init.o
> +obj-y += reset.o
> diff --git a/board/mips/boston-riscv/boston-lcd.h b/board/mips/boston-riscv/boston-lcd.h
> new file mode 100644
> index 00000000000..5f5cd0fe126
> --- /dev/null
> +++ b/board/mips/boston-riscv/boston-lcd.h
> @@ -0,0 +1,20 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2016 Imagination Technologies
> + */
> +
> +#ifndef __BOARD_BOSTON_LCD_H__
> +#define __BOARD_BOSTON_LCD_H__
> +
> +/**
> + * lowlevel_display() - Display a message on Boston's LCD
> + * @msg: The string to display
> + *
> + * Display the string @msg on the 7 character LCD display of the Boston board.
> + * This is typically used for debug or to present some form of status
> + * indication to the user, allowing faults to be identified when things go
> + * wrong early enough that the UART isn't up.
> + */
> +void lowlevel_display(const char msg[static 8]);
> +
> +#endif /* __BOARD_BOSTON_LCD_H__ */
> diff --git a/board/mips/boston-riscv/boston-regs.h b/board/mips/boston-riscv/boston-regs.h
> new file mode 100644
> index 00000000000..4d5ea8833ab
> --- /dev/null
> +++ b/board/mips/boston-riscv/boston-regs.h
> @@ -0,0 +1,38 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2016 Imagination Technologies
> + */
> +
> +#ifndef __BOARD_BOSTON_REGS_H__
> +#define __BOARD_BOSTON_REGS_H__
> +
> +#ifndef BOSTON_PLAT_BASE
> +#define BOSTON_PLAT_BASE (0x17ffd000)
> +#endif
This causes redefinition error.
> +#define BOSTON_LCD_BASE (0x17fff000)
> +
> +/*
> + * Platform Register Definitions
> + */
> +#define BOSTON_PLAT_CORE_CL (BOSTON_PLAT_BASE + 0x04)
> +
> +#define BOSTON_PLAT_SOFT_RST (BOSTON_PLAT_BASE + 0x10)
> +#define BOSTON_PLAT_SOFT_RST_SYSTEM (0x1 << 4)
> +
> +#define BOSTON_PLAT_DDR3STAT (BOSTON_PLAT_BASE + 0x14)
> +#define BOSTON_PLAT_DDR3STAT_CALIB (0x1 << 2)
> +
> +#define BOSTON_PLAT_BUILDCFG0 (BOSTON_PLAT_BASE + 0x34)
> +#define BOSTON_PLAT_BUILDCFG0_IOCU (0x1 << 0)
> +#define BOSTON_PLAT_BUILDCFG0_PCIE0 (0x1 << 1)
> +#define BOSTON_PLAT_BUILDCFG0_PCIE1 (0x1 << 2)
> +#define BOSTON_PLAT_BUILDCFG0_PCIE2 (0x1 << 3)
> +#define BOSTON_PLAT_BUILDCFG0_CFG_LTR (0xf << 4)
> +#define BOSTON_PLAT_BUILDCFG0_CFG_NUM (0xff << 8)
> +#define BOSTON_PLAT_BUILDCFG0_DP (0x1 << 24)
> +#define BOSTON_PLAT_BUILDCFG0_DP_MULT (0xf << 28)
> +
> +#define BOSTON_PLAT_DDRCONF0 (BOSTON_PLAT_BASE + 0x38)
> +#define BOSTON_PLAT_DDRCONF0_SIZE (0xf << 0)
> +
> ...
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v5 2/8] board: boston-riscv: Add initial support for P8700 Boston board
2025-12-24 15:45 ` [PATCH v5 2/8] board: boston-riscv: Add initial support for P8700 Boston board Uros Stajic
2026-02-09 11:25 ` Leo Liang
2026-03-17 8:48 ` Leo Liang
@ 2026-03-18 11:16 ` Conor Dooley
2026-03-27 13:48 ` Uros Stajic
2 siblings, 1 reply; 21+ messages in thread
From: Conor Dooley @ 2026-03-18 11:16 UTC (permalink / raw)
To: Uros Stajic; +Cc: u-boot@lists.denx.de, Djordje Todorovic, Chao-ying Fu
[-- Attachment #1: Type: text/plain, Size: 1656 bytes --]
On Wed, Dec 24, 2025 at 03:45:47PM +0000, Uros Stajic wrote:
> From: Chao-ying Fu <cfu@mips.com>
>
> Implement initial board-level support for the P8700 Boston SoC.
>
> Signed-off-by: Chao-ying Fu <cfu@mips.com>
> Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
> diff --git a/arch/riscv/dts/boston-p8700.dts b/arch/riscv/dts/boston-p8700.dts
> new file mode 100644
> index 00000000000..f27ebeda4a2
> --- /dev/null
> +++ b/arch/riscv/dts/boston-p8700.dts
> @@ -0,0 +1,264 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
> + */
> +
> +/dts-v1/;
> +
> +#include <dt-bindings/clock/boston-clock.h>
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +#include <dt-bindings/interrupt-controller/mips-gic.h>
> +
> +/ {
> + #address-cells = <1>;
> + #size-cells = <1>;
> + model = "p8700";
> + compatible = "img,boston";
This is not a unique id, this is used by a mips mips board already.
I think the one that is being used in opensbi is mips,p8700-boston.
> +
> + aliases {
> + serial0 = &uart0;
> + };
> +
> + chosen {
> + stdout-path = "serial0:115200n8";
> + };
> +
> + cpus {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + timebase-frequency = <25000000>;
> +
> + cpu@0 {
> + device_type = "cpu";
> + compatible = "riscv";
There's a specific cpu compatible for this now. "riscv" in isolation is
only for qemu etc. OpenSBI actually wants the specific compatible.
Can this be sent to Linux, so it can get more eyeballs on the dts, and use
OF_UPSTREAM to import it to U-Boot?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH v5 2/8] board: boston-riscv: Add initial support for P8700 Boston board
2026-03-18 11:16 ` Conor Dooley
@ 2026-03-27 13:48 ` Uros Stajic
0 siblings, 0 replies; 21+ messages in thread
From: Uros Stajic @ 2026-03-27 13:48 UTC (permalink / raw)
To: Conor Dooley; +Cc: u-boot@lists.denx.de, Djordje Todorovic
Hi Conor,
On 3/18/26 12:16, Conor Dooley wrote:
> On Wed, Dec 24, 2025 at 03:45:47PM +0000, Uros Stajic wrote:
>> From: Chao-ying Fu<cfu@mips.com>
>>
>> Implement initial board-level support for the P8700 Boston SoC.
>>
>> Signed-off-by: Chao-ying Fu<cfu@mips.com>
>> Signed-off-by: Uros Stajic<uros.stajic@htecgroup.com>
>> diff --git a/arch/riscv/dts/boston-p8700.dts b/arch/riscv/dts/boston-p8700.dts
>> new file mode 100644
>> index 00000000000..f27ebeda4a2
>> --- /dev/null
>> +++ b/arch/riscv/dts/boston-p8700.dts
>> @@ -0,0 +1,264 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (C) 2021, Chao-ying Fu<cfu@mips.com>
>> + */
>> +
>> +/dts-v1/;
>> +
>> +#include <dt-bindings/clock/boston-clock.h>
>> +#include <dt-bindings/gpio/gpio.h>
>> +#include <dt-bindings/interrupt-controller/irq.h>
>> +#include <dt-bindings/interrupt-controller/mips-gic.h>
>> +
>> +/ {
>> + #address-cells = <1>;
>> + #size-cells = <1>;
>> + model = "p8700";
>> + compatible = "img,boston";
> This is not a unique id, this is used by a mips mips board already.
> I think the one that is being used in opensbi is mips,p8700-boston.
>
>> +
>> + aliases {
>> + serial0 = &uart0;
>> + };
>> +
>> + chosen {
>> + stdout-path = "serial0:115200n8";
>> + };
>> +
>> + cpus {
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> + timebase-frequency = <25000000>;
>> +
>> + cpu@0 {
>> + device_type = "cpu";
>> + compatible = "riscv";
> There's a specific cpu compatible for this now. "riscv" in isolation is
> only for qemu etc. OpenSBI actually wants the specific compatible.
>
Thanks for the review. I will update both compatibles in the next revision.
> Can this be sent to Linux, so it can get more eyeballs on the dts, and use
> OF_UPSTREAM to import it to U-Boot?
Yes, we are planning to start the upstream process of the DTS file, and
once it is merged, we can import it into U-boot.
Best regards,
Uros
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v5 3/8] gpio: Add GPIO driver for Intel EG20T
2025-12-24 15:44 [PATCH v5 0/8] riscv: Add support for P8700 platform on Boston board Uros Stajic
2025-12-24 15:45 ` [PATCH v5 1/8] riscv: Add initial support for P8700 SoC Uros Stajic
2025-12-24 15:45 ` [PATCH v5 2/8] board: boston-riscv: Add initial support for P8700 Boston board Uros Stajic
@ 2025-12-24 15:46 ` Uros Stajic
2025-12-24 15:46 ` [PATCH v5 4/8] pci: xilinx: Avoid writing memory base/limit for root bridge Uros Stajic
` (4 subsequent siblings)
7 siblings, 0 replies; 21+ messages in thread
From: Uros Stajic @ 2025-12-24 15:46 UTC (permalink / raw)
To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu, Uros Stajic
From: Chao-ying Fu <cfu@mips.com>
Add a GPIO driver for the Intel EG20T Platform Controller Hub, which
exposes a set of 12 GPIOs via PCI MMIO.
The driver implements basic GPIO operations (input/output direction,
value read/write, and function query) using the U-Boot driver model
infrastructure. It maps the required BAR1 region via `dm_pci_map_bar`
and uses internal registers to control pin state and direction.
This driver is required for platforms using EG20T, such as P8700-based
systems, to access GPIOs through the standard U-Boot DM GPIO framework.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
board/mips/boston-riscv/MAINTAINERS | 1 +
drivers/gpio/Kconfig | 7 ++
drivers/gpio/Makefile | 1 +
drivers/gpio/eg20t-gpio.c | 141 ++++++++++++++++++++++++++++
4 files changed, 150 insertions(+)
create mode 100644 drivers/gpio/eg20t-gpio.c
diff --git a/board/mips/boston-riscv/MAINTAINERS b/board/mips/boston-riscv/MAINTAINERS
index e350121395e..bc59a628c79 100644
--- a/board/mips/boston-riscv/MAINTAINERS
+++ b/board/mips/boston-riscv/MAINTAINERS
@@ -7,3 +7,4 @@ F: arch/riscv/cpu/p8700/
F: arch/riscv/include/asm/arch-p8700/
F: configs/boston-p8700_defconfig
F: arch/riscv/dts/boston-p8700.dts
+F: drivers/gpio/eg20t-gpio.c
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 2ed2bc82946..bd350d7ec96 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -728,4 +728,11 @@ config MPFS_GPIO
help
Enable to support the GPIO driver on Polarfire SoC
+config EG20T_GPIO
+ bool "Intel EG20T GPIO driver"
+ depends on DM_GPIO && PCI
+ help
+ Enable this to support the GPIO controller found in the Intel EG20T
+ Platform Controller Hub.
+
endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 910478c0c7a..3a823614253 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -80,3 +80,4 @@ obj-$(CONFIG_SLG7XL45106_I2C_GPO) += gpio_slg7xl45106.o
obj-$(CONFIG_$(PHASE_)ADP5585_GPIO) += adp5585_gpio.o
obj-$(CONFIG_RZG2L_GPIO) += rzg2l-gpio.o
obj-$(CONFIG_MPFS_GPIO) += mpfs_gpio.o
+obj-$(CONFIG_EG20T_GPIO) += eg20t-gpio.o
diff --git a/drivers/gpio/eg20t-gpio.c b/drivers/gpio/eg20t-gpio.c
new file mode 100644
index 00000000000..18dc5214c43
--- /dev/null
+++ b/drivers/gpio/eg20t-gpio.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ */
+
+#include <dm.h>
+#include <errno.h>
+#include <log.h>
+#include <pci.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+
+enum {
+ REG_IEN = 0x00,
+ REG_ISTATUS = 0x04,
+ REG_IDISP = 0x08,
+ REG_ICLR = 0x0c,
+ REG_IMASK = 0x10,
+ REG_IMASKCLR = 0x14,
+ REG_PO = 0x18,
+ REG_PI = 0x1c,
+ REG_PM = 0x20,
+};
+
+struct eg20t_gpio_priv {
+ void *base;
+};
+
+static int eg20t_gpio_get_value(struct udevice *dev, unsigned int offset)
+{
+ struct eg20t_gpio_priv *priv = dev_get_priv(dev);
+ u32 pm, pval;
+
+ pm = readl(priv->base + REG_PM);
+ if ((pm >> offset) & 0x1)
+ pval = readl(priv->base + REG_PO);
+ else
+ pval = readl(priv->base + REG_PI);
+
+ return (pval >> offset) & 0x1;
+}
+
+static int eg20t_gpio_set_value(struct udevice *dev, unsigned int offset,
+ int value)
+{
+ struct eg20t_gpio_priv *priv = dev_get_priv(dev);
+ u32 po;
+
+ po = readl(priv->base + REG_PO);
+ if (value)
+ po |= 1 << offset;
+ else
+ po &= ~(1 << offset);
+ writel(po, priv->base + REG_PO);
+
+ return 0;
+}
+
+static int eg20t_gpio_direction_input(struct udevice *dev, unsigned int offset)
+{
+ struct eg20t_gpio_priv *priv = dev_get_priv(dev);
+ u32 pm;
+
+ pm = readl(priv->base + REG_PM);
+ pm &= ~(1 << offset);
+ writel(pm, priv->base + REG_PM);
+
+ return 0;
+}
+
+static int eg20t_gpio_direction_output(struct udevice *dev, unsigned int offset,
+ int value)
+{
+ struct eg20t_gpio_priv *priv = dev_get_priv(dev);
+ u32 pm;
+
+ pm = readl(priv->base + REG_PM);
+ pm |= 1 << offset;
+ writel(pm, priv->base + REG_PM);
+
+ return eg20t_gpio_set_value(dev, offset, value);
+}
+
+static int eg20t_gpio_get_function(struct udevice *dev, unsigned int offset)
+{
+ struct eg20t_gpio_priv *priv = dev_get_priv(dev);
+ u32 pm;
+
+ pm = readl(priv->base + REG_PM);
+ if ((pm >> offset) & 0x1)
+ return GPIOF_OUTPUT;
+
+ return GPIOF_INPUT;
+}
+
+static const struct dm_gpio_ops eg20t_gpio_ops = {
+ .direction_input = eg20t_gpio_direction_input,
+ .direction_output = eg20t_gpio_direction_output,
+ .get_value = eg20t_gpio_get_value,
+ .set_value = eg20t_gpio_set_value,
+ .get_function = eg20t_gpio_get_function,
+};
+
+static int eg20t_gpio_probe(struct udevice *dev)
+{
+ struct eg20t_gpio_priv *priv = dev_get_priv(dev);
+ struct gpio_dev_priv *uc_priv = dev->uclass_priv_;
+
+ priv->base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_1, 0, 0,
+ PCI_REGION_TYPE, PCI_REGION_MEM);
+ if (!priv->base) {
+ debug("failed to map GPIO registers\n");
+ return -EINVAL;
+ }
+
+ uc_priv->gpio_count = 12;
+ uc_priv->bank_name = "eg20t";
+
+ return 0;
+}
+
+static const struct udevice_id eg20t_gpio_ids[] = {
+ { .compatible = "intel,eg20t-gpio" },
+ { }
+};
+
+U_BOOT_DRIVER(eg20t_gpio) = {
+ .name = "eg20t-gpio",
+ .id = UCLASS_GPIO,
+ .of_match = eg20t_gpio_ids,
+ .probe = eg20t_gpio_probe,
+ .priv_auto = sizeof(struct eg20t_gpio_priv),
+ .ops = &eg20t_gpio_ops,
+};
+
+static struct pci_device_id eg20t_gpio_supported[] = {
+ { PCI_VENDOR_ID_INTEL, 0x8803 },
+ { },
+};
+
+U_BOOT_PCI_DEVICE(eg20t_gpio, eg20t_gpio_supported);
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v5 4/8] pci: xilinx: Avoid writing memory base/limit for root bridge
2025-12-24 15:44 [PATCH v5 0/8] riscv: Add support for P8700 platform on Boston board Uros Stajic
` (2 preceding siblings ...)
2025-12-24 15:46 ` [PATCH v5 3/8] gpio: Add GPIO driver for Intel EG20T Uros Stajic
@ 2025-12-24 15:46 ` Uros Stajic
2025-12-24 15:46 ` [PATCH v5 5/8] riscv: Add syscon driver for MIPS GIC block Uros Stajic
` (3 subsequent siblings)
7 siblings, 0 replies; 21+ messages in thread
From: Uros Stajic @ 2025-12-24 15:46 UTC (permalink / raw)
To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu, Uros Stajic
From: Chao-ying Fu <cfu@mips.com>
Avoid writing to PCI_MEMORY_BASE and PCI_MEMORY_LIMIT registers for
bus 0, device 0 (the root bridge) in the Xilinx PCIe driver.
On platforms such as the MIPS Boston board, writing to these fields
results in incorrect values (e.g. base = 0x0, limit = 0x1600), which
causes Linux to fail PCIe memory space assignment.
As a result, Linux can boot successfully and probe the PCIe bus and
all connected devices on platforms like the MIPS Boston board.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
drivers/pci/pcie_xilinx.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/pci/pcie_xilinx.c b/drivers/pci/pcie_xilinx.c
index 63058e8e7c5..4ef20474a0b 100644
--- a/drivers/pci/pcie_xilinx.c
+++ b/drivers/pci/pcie_xilinx.c
@@ -132,6 +132,15 @@ static int pcie_xilinx_write_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong value,
enum pci_size_t size)
{
+ if (bdf == PCI_BDF(bus->seq_, 0, 0)) {
+ switch (offset) {
+ case PCI_MEMORY_BASE:
+ case PCI_MEMORY_LIMIT:
+ /* Writing the memory base or limit causes problems */
+ return 0;
+ }
+ }
+
return pci_generic_mmap_write_config(bus, pcie_xilinx_config_address,
bdf, offset, value, size);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v5 5/8] riscv: Add syscon driver for MIPS GIC block
2025-12-24 15:44 [PATCH v5 0/8] riscv: Add support for P8700 platform on Boston board Uros Stajic
` (3 preceding siblings ...)
2025-12-24 15:46 ` [PATCH v5 4/8] pci: xilinx: Avoid writing memory base/limit for root bridge Uros Stajic
@ 2025-12-24 15:46 ` Uros Stajic
2025-12-24 15:47 ` [PATCH v5 6/8] net: pch_gbe: Add PHY reset and MAC address fallback for RISC-V Uros Stajic
` (2 subsequent siblings)
7 siblings, 0 replies; 21+ messages in thread
From: Uros Stajic @ 2025-12-24 15:46 UTC (permalink / raw)
To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu, Uros Stajic
From: Chao-ying Fu <cfu@mips.com>
Add a UCLASS_SYSCON driver with DT match for the MIPS GIC block, so it
can be accessed via syscon/regmap.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
arch/riscv/Kconfig | 11 +++++++
arch/riscv/lib/Makefile | 1 +
arch/riscv/lib/mips_gic.c | 47 +++++++++++++++++++++++++++++
board/mips/boston-riscv/MAINTAINERS | 1 +
4 files changed, 60 insertions(+)
create mode 100644 arch/riscv/lib/mips_gic.c
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 8eb12d4eb4e..8436c4aaaba 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -407,6 +407,17 @@ config SIFIVE_CACHE
help
This enables the operations to configure SiFive cache
+config MIPS_GIC
+ bool
+ depends on RISCV_MMODE || SPL_RISCV_MMODE
+ select REGMAP
+ select SYSCON
+ select SPL_REGMAP if SPL
+ select SPL_SYSCON if SPL
+ help
+ The MIPS GIC block holds memory-mapped control and status registers
+ associated with software and timer interrupts.
+
config ANDES_PLICSW
bool
depends on RISCV_MMODE || SPL_RISCV_MMODE
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index f1f50918eff..d4f845d9892 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_SYS_CACHE_THEAD_CMO) += thead_cmo.o
ifeq ($(CONFIG_$(PHASE_)RISCV_MMODE),y)
obj-$(CONFIG_$(PHASE_)RISCV_ACLINT) += aclint_ipi.o
obj-$(CONFIG_ANDES_PLICSW) += andes_plicsw.o
+obj-$(CONFIG_MIPS_GIC) += mips_gic.o
else
obj-$(CONFIG_SBI) += sbi.o
obj-$(CONFIG_SBI_IPI) += sbi_ipi.o
diff --git a/arch/riscv/lib/mips_gic.c b/arch/riscv/lib/mips_gic.c
new file mode 100644
index 00000000000..7d761c58e74
--- /dev/null
+++ b/arch/riscv/lib/mips_gic.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+ *
+ * U-Boot syscon driver for MIPS GIC.
+ */
+
+#include <dm.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/syscon.h>
+#include <linux/err.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int riscv_init_ipi(void)
+{
+ return 0;
+}
+
+int riscv_send_ipi(int hart)
+{
+ return 0;
+}
+
+int riscv_clear_ipi(int hart)
+{
+ return 0;
+}
+
+int riscv_get_ipi(int hart, int *pending)
+{
+ return 0;
+}
+
+static const struct udevice_id mips_gic_ids[] = {
+ { .compatible = "mips,gic0", .data = RISCV_SYSCON_PLICSW },
+ { }
+};
+
+U_BOOT_DRIVER(mips_gic) = {
+ .name = "mips_gic",
+ .id = UCLASS_SYSCON,
+ .of_match = mips_gic_ids,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/board/mips/boston-riscv/MAINTAINERS b/board/mips/boston-riscv/MAINTAINERS
index bc59a628c79..0d9a951441f 100644
--- a/board/mips/boston-riscv/MAINTAINERS
+++ b/board/mips/boston-riscv/MAINTAINERS
@@ -8,3 +8,4 @@ F: arch/riscv/include/asm/arch-p8700/
F: configs/boston-p8700_defconfig
F: arch/riscv/dts/boston-p8700.dts
F: drivers/gpio/eg20t-gpio.c
+F: arch/riscv/lib/mips_gic.c
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH v5 6/8] net: pch_gbe: Add PHY reset and MAC address fallback for RISC-V
2025-12-24 15:44 [PATCH v5 0/8] riscv: Add support for P8700 platform on Boston board Uros Stajic
` (4 preceding siblings ...)
2025-12-24 15:46 ` [PATCH v5 5/8] riscv: Add syscon driver for MIPS GIC block Uros Stajic
@ 2025-12-24 15:47 ` Uros Stajic
2026-03-17 8:49 ` Leo Liang
2025-12-24 15:47 ` [PATCH v5 7/8] libfdt: Allow non-64b aligned memreserve entries Uros Stajic
2025-12-24 15:47 ` [PATCH v5 8/8] riscv: p8700: Add Coherence Manager (CM) and IOCU support Uros Stajic
7 siblings, 1 reply; 21+ messages in thread
From: Uros Stajic @ 2025-12-24 15:47 UTC (permalink / raw)
To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu, Uros Stajic
From: Chao-ying Fu <cfu@mips.com>
Add optional PHY reset support via GPIO defined in the device tree.
Improve robustness by handling probe errors and falling back to the
environment-provided MAC address if no hardware MAC is found.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
board/mips/boston-riscv/Kconfig | 4 ++++
drivers/net/pch_gbe.c | 37 +++++++++++++++++++++++++++++++--
drivers/net/pch_gbe.h | 1 +
3 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/board/mips/boston-riscv/Kconfig b/board/mips/boston-riscv/Kconfig
index 68c5fc50489..4d55d96603e 100644
--- a/board/mips/boston-riscv/Kconfig
+++ b/board/mips/boston-riscv/Kconfig
@@ -40,4 +40,8 @@ config PHY_REALTEK
bool
default y
+config TFTP_FILE_NAME_MAX_LEN
+ int "Maximum length of TFTP file name"
+ default 256
+
endif
diff --git a/drivers/net/pch_gbe.c b/drivers/net/pch_gbe.c
index adeca3d040d..dea8ab828ac 100644
--- a/drivers/net/pch_gbe.c
+++ b/drivers/net/pch_gbe.c
@@ -7,6 +7,7 @@
#include <cpu_func.h>
#include <dm.h>
+#include <env.h>
#include <errno.h>
#include <log.h>
#include <malloc.h>
@@ -15,6 +16,7 @@
#include <miiphy.h>
#include <linux/delay.h>
#include "pch_gbe.h"
+#include <asm/gpio.h>
#if !defined(CONFIG_PHYLIB)
# error "PCH Gigabit Ethernet driver requires PHYLIB - missing CONFIG_PHYLIB"
@@ -33,6 +35,13 @@ static void pch_gbe_mac_read(struct pch_gbe_regs *mac_regs, u8 *addr)
macid_lo = readl(&mac_regs->mac_adr[0].low) & 0xffff;
debug("pch_gbe: macid_hi %#x macid_lo %#x\n", macid_hi, macid_lo);
+ if (!macid_lo && !macid_hi) {
+ if (eth_env_get_enetaddr("ethaddr", addr))
+ return;
+
+ printf("No MAC found in either EG20T H/W or environment");
+ }
+
addr[0] = (u8)(macid_hi & 0xff);
addr[1] = (u8)((macid_hi >> 8) & 0xff);
addr[2] = (u8)((macid_hi >> 16) & 0xff);
@@ -74,6 +83,14 @@ static int pch_gbe_reset(struct udevice *dev)
priv->rx_idx = 0;
priv->tx_idx = 0;
+ if (dm_gpio_is_valid(&priv->gpio_phy_reset)) {
+ /* Reset the PHY */
+ dm_gpio_set_value(&priv->gpio_phy_reset, 1);
+ udelay(15000);
+ dm_gpio_set_value(&priv->gpio_phy_reset, 0);
+ udelay(5000);
+ }
+
writel(PCH_GBE_ALL_RST, &mac_regs->reset);
/*
@@ -450,6 +467,11 @@ static int pch_gbe_probe(struct udevice *dev)
plat->iobase = (ulong)iobase;
priv->mac_regs = (struct pch_gbe_regs *)iobase;
+ err = gpio_request_by_name(dev, "phy-reset-gpios", 0,
+ &priv->gpio_phy_reset, GPIOD_IS_OUT);
+ if (err && (err != -ENOENT))
+ return err;
+
/* Read MAC address from SROM and initialize dev->enetaddr with it */
pch_gbe_mac_read(priv->mac_regs, plat->enetaddr);
@@ -459,9 +481,17 @@ static int pch_gbe_probe(struct udevice *dev)
err = pch_gbe_reset(dev);
if (err)
- return err;
+ goto out_err;
+
+ err = pch_gbe_phy_init(dev);
+ if (err)
+ goto out_err;
- return pch_gbe_phy_init(dev);
+ return 0;
+out_err:
+ if (dm_gpio_is_valid(&priv->gpio_phy_reset))
+ dm_gpio_free(dev, &priv->gpio_phy_reset);
+ return err;
}
static int pch_gbe_remove(struct udevice *dev)
@@ -472,6 +502,9 @@ static int pch_gbe_remove(struct udevice *dev)
mdio_unregister(priv->bus);
mdio_free(priv->bus);
+ if (dm_gpio_is_valid(&priv->gpio_phy_reset))
+ dm_gpio_free(dev, &priv->gpio_phy_reset);
+
return 0;
}
diff --git a/drivers/net/pch_gbe.h b/drivers/net/pch_gbe.h
index 7e0fdbfd5a3..dcbb94094bc 100644
--- a/drivers/net/pch_gbe.h
+++ b/drivers/net/pch_gbe.h
@@ -292,6 +292,7 @@ struct pch_gbe_priv {
struct udevice *dev;
int rx_idx;
int tx_idx;
+ struct gpio_desc gpio_phy_reset;
};
#endif /* _PCH_GBE_H_ */
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH v5 6/8] net: pch_gbe: Add PHY reset and MAC address fallback for RISC-V
2025-12-24 15:47 ` [PATCH v5 6/8] net: pch_gbe: Add PHY reset and MAC address fallback for RISC-V Uros Stajic
@ 2026-03-17 8:49 ` Leo Liang
2026-03-27 13:49 ` Uros Stajic
0 siblings, 1 reply; 21+ messages in thread
From: Leo Liang @ 2026-03-17 8:49 UTC (permalink / raw)
To: Uros Stajic; +Cc: u-boot@lists.denx.de, Djordje Todorovic, Chao-ying Fu
On Wed, Dec 24, 2025 at 03:47:02PM +0000, Uros Stajic wrote:
> From: Chao-ying Fu <cfu@mips.com>
>
> Add optional PHY reset support via GPIO defined in the device tree.
>
> Improve robustness by handling probe errors and falling back to the
> environment-provided MAC address if no hardware MAC is found.
>
> Signed-off-by: Chao-ying Fu <cfu@mips.com>
> Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
> ---
> board/mips/boston-riscv/Kconfig | 4 ++++
> drivers/net/pch_gbe.c | 37 +++++++++++++++++++++++++++++++--
> drivers/net/pch_gbe.h | 1 +
> 3 files changed, 40 insertions(+), 2 deletions(-)
>
> diff --git a/board/mips/boston-riscv/Kconfig b/board/mips/boston-riscv/Kconfig
> index 68c5fc50489..4d55d96603e 100644
> --- a/board/mips/boston-riscv/Kconfig
> +++ b/board/mips/boston-riscv/Kconfig
> @@ -40,4 +40,8 @@ config PHY_REALTEK
> bool
> default y
>
> +config TFTP_FILE_NAME_MAX_LEN
> + int "Maximum length of TFTP file name"
> + default 256
> +
> endif
> diff --git a/drivers/net/pch_gbe.c b/drivers/net/pch_gbe.c
> index adeca3d040d..dea8ab828ac 100644
> --- a/drivers/net/pch_gbe.c
> +++ b/drivers/net/pch_gbe.c
> @@ -7,6 +7,7 @@
>
> #include <cpu_func.h>
> #include <dm.h>
> +#include <env.h>
> #include <errno.h>
> #include <log.h>
> #include <malloc.h>
> @@ -15,6 +16,7 @@
> #include <miiphy.h>
> #include <linux/delay.h>
> #include "pch_gbe.h"
> +#include <asm/gpio.h>
This should be <asm-generic/gpio.h>, right?
>
> #if !defined(CONFIG_PHYLIB)
> # error "PCH Gigabit Ethernet driver requires PHYLIB - missing CONFIG_PHYLIB"
> @@ -33,6 +35,13 @@ static void pch_gbe_mac_read(struct pch_gbe_regs *mac_regs, u8 *addr)
> macid_lo = readl(&mac_regs->mac_adr[0].low) & 0xffff;
> debug("pch_gbe: macid_hi %#x macid_lo %#x\n", macid_hi, macid_lo);
>
> + if (!macid_lo && !macid_hi) {
> + if (eth_env_get_enetaddr("ethaddr", addr))
> + return;
> +
> + printf("No MAC found in either EG20T H/W or environment");
> + }
> +
> addr[0] = (u8)(macid_hi & 0xff);
> addr[1] = (u8)((macid_hi >> 8) & 0xff);
> addr[2] = (u8)((macid_hi >> 16) & 0xff);
> @@ -74,6 +83,14 @@ static int pch_gbe_reset(struct udevice *dev)
> priv->rx_idx = 0;
> priv->tx_idx = 0;
>
> + if (dm_gpio_is_valid(&priv->gpio_phy_reset)) {
> + /* Reset the PHY */
> + dm_gpio_set_value(&priv->gpio_phy_reset, 1);
> + udelay(15000);
> + dm_gpio_set_value(&priv->gpio_phy_reset, 0);
> + udelay(5000);
> + }
> +
> writel(PCH_GBE_ALL_RST, &mac_regs->reset);
>
> /*
> @@ -450,6 +467,11 @@ static int pch_gbe_probe(struct udevice *dev)
> plat->iobase = (ulong)iobase;
> priv->mac_regs = (struct pch_gbe_regs *)iobase;
>
> + err = gpio_request_by_name(dev, "phy-reset-gpios", 0,
> + &priv->gpio_phy_reset, GPIOD_IS_OUT);
> + if (err && (err != -ENOENT))
> + return err;
> +
> /* Read MAC address from SROM and initialize dev->enetaddr with it */
> pch_gbe_mac_read(priv->mac_regs, plat->enetaddr);
>
> @@ -459,9 +481,17 @@ static int pch_gbe_probe(struct udevice *dev)
>
> err = pch_gbe_reset(dev);
> if (err)
> - return err;
> + goto out_err;
> +
> + err = pch_gbe_phy_init(dev);
> + if (err)
> + goto out_err;
>
> - return pch_gbe_phy_init(dev);
> + return 0;
> +out_err:
> + if (dm_gpio_is_valid(&priv->gpio_phy_reset))
> + dm_gpio_free(dev, &priv->gpio_phy_reset);
> + return err;
> }
>
> static int pch_gbe_remove(struct udevice *dev)
> @@ -472,6 +502,9 @@ static int pch_gbe_remove(struct udevice *dev)
> mdio_unregister(priv->bus);
> mdio_free(priv->bus);
>
> + if (dm_gpio_is_valid(&priv->gpio_phy_reset))
> + dm_gpio_free(dev, &priv->gpio_phy_reset);
> +
> return 0;
> }
>
> diff --git a/drivers/net/pch_gbe.h b/drivers/net/pch_gbe.h
> index 7e0fdbfd5a3..dcbb94094bc 100644
> --- a/drivers/net/pch_gbe.h
> +++ b/drivers/net/pch_gbe.h
> @@ -292,6 +292,7 @@ struct pch_gbe_priv {
> struct udevice *dev;
> int rx_idx;
> int tx_idx;
> + struct gpio_desc gpio_phy_reset;
> };
>
> #endif /* _PCH_GBE_H_ */
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH v5 6/8] net: pch_gbe: Add PHY reset and MAC address fallback for RISC-V
2026-03-17 8:49 ` Leo Liang
@ 2026-03-27 13:49 ` Uros Stajic
0 siblings, 0 replies; 21+ messages in thread
From: Uros Stajic @ 2026-03-27 13:49 UTC (permalink / raw)
To: Leo Liang; +Cc: u-boot@lists.denx.de, Djordje Todorovic
Hi Leo,
On 3/17/26 09:49, Leo Liang wrote:
> On Wed, Dec 24, 2025 at 03:47:02PM +0000, Uros Stajic wrote:
>> From: Chao-ying Fu <cfu@mips.com>
>>
>> Add optional PHY reset support via GPIO defined in the device tree.
>>
>> Improve robustness by handling probe errors and falling back to the
>> environment-provided MAC address if no hardware MAC is found.
>>
>> Signed-off-by: Chao-ying Fu <cfu@mips.com>
>> Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
>> ---
>> board/mips/boston-riscv/Kconfig | 4 ++++
>> drivers/net/pch_gbe.c | 37 +++++++++++++++++++++++++++++++--
>> drivers/net/pch_gbe.h | 1 +
>> 3 files changed, 40 insertions(+), 2 deletions(-)
>>
>> diff --git a/board/mips/boston-riscv/Kconfig b/board/mips/boston-riscv/Kconfig
>> index 68c5fc50489..4d55d96603e 100644
>> --- a/board/mips/boston-riscv/Kconfig
>> +++ b/board/mips/boston-riscv/Kconfig
>> @@ -40,4 +40,8 @@ config PHY_REALTEK
>> bool
>> default y
>>
>> +config TFTP_FILE_NAME_MAX_LEN
>> + int "Maximum length of TFTP file name"
>> + default 256
>> +
>> endif
>> diff --git a/drivers/net/pch_gbe.c b/drivers/net/pch_gbe.c
>> index adeca3d040d..dea8ab828ac 100644
>> --- a/drivers/net/pch_gbe.c
>> +++ b/drivers/net/pch_gbe.c
>> @@ -7,6 +7,7 @@
>>
>> #include <cpu_func.h>
>> #include <dm.h>
>> +#include <env.h>
>> #include <errno.h>
>> #include <log.h>
>> #include <malloc.h>
>> @@ -15,6 +16,7 @@
>> #include <miiphy.h>
>> #include <linux/delay.h>
>> #include "pch_gbe.h"
>> +#include <asm/gpio.h>
>
> This should be <asm-generic/gpio.h>, right?
>
Thanks, you're right. I'll switch it to <asm-generic/gpio.h> in the next
revision.
>>
>> #if !defined(CONFIG_PHYLIB)
>> # error "PCH Gigabit Ethernet driver requires PHYLIB - missing CONFIG_PHYLIB"
>> @@ -33,6 +35,13 @@ static void pch_gbe_mac_read(struct pch_gbe_regs *mac_regs, u8 *addr)
>> macid_lo = readl(&mac_regs->mac_adr[0].low) & 0xffff;
>> debug("pch_gbe: macid_hi %#x macid_lo %#x\n", macid_hi, macid_lo);
>>
>> + if (!macid_lo && !macid_hi) {
>> + if (eth_env_get_enetaddr("ethaddr", addr))
>> + return;
>> +
>> + printf("No MAC found in either EG20T H/W or environment");
>> + }
>> +
>> addr[0] = (u8)(macid_hi & 0xff);
>> addr[1] = (u8)((macid_hi >> 8) & 0xff);
>> addr[2] = (u8)((macid_hi >> 16) & 0xff);
>> @@ -74,6 +83,14 @@ static int pch_gbe_reset(struct udevice *dev)
>> priv->rx_idx = 0;
>> priv->tx_idx = 0;
>>
>> + if (dm_gpio_is_valid(&priv->gpio_phy_reset)) {
>> + /* Reset the PHY */
>> + dm_gpio_set_value(&priv->gpio_phy_reset, 1);
>> + udelay(15000);
>> + dm_gpio_set_value(&priv->gpio_phy_reset, 0);
>> + udelay(5000);
>> + }
>> +
>> writel(PCH_GBE_ALL_RST, &mac_regs->reset);
>>
>> /*
>> @@ -450,6 +467,11 @@ static int pch_gbe_probe(struct udevice *dev)
>> plat->iobase = (ulong)iobase;
>> priv->mac_regs = (struct pch_gbe_regs *)iobase;
>>
>> + err = gpio_request_by_name(dev, "phy-reset-gpios", 0,
>> + &priv->gpio_phy_reset, GPIOD_IS_OUT);
>> + if (err && (err != -ENOENT))
>> + return err;
>> +
>> /* Read MAC address from SROM and initialize dev->enetaddr with it */
>> pch_gbe_mac_read(priv->mac_regs, plat->enetaddr);
>>
>> @@ -459,9 +481,17 @@ static int pch_gbe_probe(struct udevice *dev)
>>
>> err = pch_gbe_reset(dev);
>> if (err)
>> - return err;
>> + goto out_err;
>> +
>> + err = pch_gbe_phy_init(dev);
>> + if (err)
>> + goto out_err;
>>
>> - return pch_gbe_phy_init(dev);
>> + return 0;
>> +out_err:
>> + if (dm_gpio_is_valid(&priv->gpio_phy_reset))
>> + dm_gpio_free(dev, &priv->gpio_phy_reset);
>> + return err;
>> }
>>
>> static int pch_gbe_remove(struct udevice *dev)
>> @@ -472,6 +502,9 @@ static int pch_gbe_remove(struct udevice *dev)
>> mdio_unregister(priv->bus);
>> mdio_free(priv->bus);
>>
>> + if (dm_gpio_is_valid(&priv->gpio_phy_reset))
>> + dm_gpio_free(dev, &priv->gpio_phy_reset);
>> +
>> return 0;
>> }
>>
>> diff --git a/drivers/net/pch_gbe.h b/drivers/net/pch_gbe.h
>> index 7e0fdbfd5a3..dcbb94094bc 100644
>> --- a/drivers/net/pch_gbe.h
>> +++ b/drivers/net/pch_gbe.h
>> @@ -292,6 +292,7 @@ struct pch_gbe_priv {
>> struct udevice *dev;
>> int rx_idx;
>> int tx_idx;
>> + struct gpio_desc gpio_phy_reset;
>> };
>>
>> #endif /* _PCH_GBE_H_ */
Best regards,
Uros
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v5 7/8] libfdt: Allow non-64b aligned memreserve entries
2025-12-24 15:44 [PATCH v5 0/8] riscv: Add support for P8700 platform on Boston board Uros Stajic
` (5 preceding siblings ...)
2025-12-24 15:47 ` [PATCH v5 6/8] net: pch_gbe: Add PHY reset and MAC address fallback for RISC-V Uros Stajic
@ 2025-12-24 15:47 ` Uros Stajic
2026-03-17 9:06 ` Leo Liang
2025-12-24 15:47 ` [PATCH v5 8/8] riscv: p8700: Add Coherence Manager (CM) and IOCU support Uros Stajic
7 siblings, 1 reply; 21+ messages in thread
From: Uros Stajic @ 2025-12-24 15:47 UTC (permalink / raw)
To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu, Uros Stajic
From: Chao-ying Fu <cfu@mips.com>
Although memreserve entries in an FDT are 64-bit aligned relative to the
start of the FDT, we cannot guarantee that the FDT itself is 64-bit aligned
in memory. This is especially common when using a FIT image, where the
alignment of the embedded DTB cannot be controlled.
On systems that do not support unaligned 64-bit memory accesses, this leads
to faults when accessing the memreserve section before the FDT is relocated.
To resolve this, copy the 64-bit values into suitably aligned on-stack
variables before accessing them.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
scripts/dtc/libfdt/fdt_ro.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c
index d65656aaa8b..1c18aea66ab 100644
--- a/scripts/dtc/libfdt/fdt_ro.c
+++ b/scripts/dtc/libfdt/fdt_ro.c
@@ -174,6 +174,7 @@ static const struct fdt_reserve_entry *fdt_mem_rsv(const void *fdt, int n)
int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
{
+ uint64_t u64;
const struct fdt_reserve_entry *re;
FDT_RO_PROBE(fdt);
@@ -181,8 +182,10 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
if (fdt_chk_extra() && !re)
return -FDT_ERR_BADOFFSET;
- *address = fdt64_to_cpu(re->address);
- *size = fdt64_to_cpu(re->size);
+ memcpy(&u64, &re->address, sizeof(u64));
+ *address = fdt64_to_cpu(u64);
+ memcpy(&u64, &re->size, sizeof(u64));
+ *size = fdt64_to_cpu(u64);
return 0;
}
@@ -190,9 +193,11 @@ int fdt_num_mem_rsv(const void *fdt)
{
int i;
const struct fdt_reserve_entry *re;
+ uint64_t u64;
for (i = 0; (re = fdt_mem_rsv(fdt, i)) != NULL; i++) {
- if (fdt64_to_cpu(re->size) == 0)
+ memcpy(&u64, &re->size, sizeof(u64));
+ if (fdt64_to_cpu(u64) == 0)
return i;
}
return -FDT_ERR_TRUNCATED;
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH v5 7/8] libfdt: Allow non-64b aligned memreserve entries
2025-12-24 15:47 ` [PATCH v5 7/8] libfdt: Allow non-64b aligned memreserve entries Uros Stajic
@ 2026-03-17 9:06 ` Leo Liang
2026-03-17 13:47 ` Tom Rini
0 siblings, 1 reply; 21+ messages in thread
From: Leo Liang @ 2026-03-17 9:06 UTC (permalink / raw)
To: Uros Stajic; +Cc: u-boot@lists.denx.de, Djordje Todorovic, Chao-ying Fu, trini
Hi Uros,
On Wed, Dec 24, 2025 at 03:47:17PM +0000, Uros Stajic wrote:
> From: Chao-ying Fu <cfu@mips.com>
>
> Although memreserve entries in an FDT are 64-bit aligned relative to the
> start of the FDT, we cannot guarantee that the FDT itself is 64-bit aligned
> in memory. This is especially common when using a FIT image, where the
> alignment of the embedded DTB cannot be controlled.
>
> On systems that do not support unaligned 64-bit memory accesses, this leads
> to faults when accessing the memreserve section before the FDT is relocated.
> To resolve this, copy the 64-bit values into suitably aligned on-stack
> variables before accessing them.
>
> Signed-off-by: Chao-ying Fu <cfu@mips.com>
> Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
> ---
> scripts/dtc/libfdt/fdt_ro.c | 11 ++++++++---
> 1 file changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c
> index d65656aaa8b..1c18aea66ab 100644
> --- a/scripts/dtc/libfdt/fdt_ro.c
> +++ b/scripts/dtc/libfdt/fdt_ro.c
> @@ -174,6 +174,7 @@ static const struct fdt_reserve_entry *fdt_mem_rsv(const void *fdt, int n)
>
> int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
> {
> + uint64_t u64;
> const struct fdt_reserve_entry *re;
>
> FDT_RO_PROBE(fdt);
> @@ -181,8 +182,10 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
> if (fdt_chk_extra() && !re)
> return -FDT_ERR_BADOFFSET;
>
> - *address = fdt64_to_cpu(re->address);
> - *size = fdt64_to_cpu(re->size);
> + memcpy(&u64, &re->address, sizeof(u64));
> + *address = fdt64_to_cpu(u64);
> + memcpy(&u64, &re->size, sizeof(u64));
> + *size = fdt64_to_cpu(u64);
There are API for unaligned access: fdt64_ld().
> return 0;
> }
>
> @@ -190,9 +193,11 @@ int fdt_num_mem_rsv(const void *fdt)
> {
> int i;
> const struct fdt_reserve_entry *re;
> + uint64_t u64;
>
> for (i = 0; (re = fdt_mem_rsv(fdt, i)) != NULL; i++) {
> - if (fdt64_to_cpu(re->size) == 0)
> + memcpy(&u64, &re->size, sizeof(u64));
> + if (fdt64_to_cpu(u64) == 0)
Ditto.
> return i;
> }
> return -FDT_ERR_TRUNCATED;
But other than that, this issue seemed to be discussed before
and decided to use API that does not support unaligned access.
https://github.com/dgibson/dtc/commit/a7c40409934971ac1bd934ccc411bc6932b86564
Hi Tom,
Should we accept this patch in u-boot?
Best regards,
Leo
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v5 7/8] libfdt: Allow non-64b aligned memreserve entries
2026-03-17 9:06 ` Leo Liang
@ 2026-03-17 13:47 ` Tom Rini
2026-03-27 13:50 ` Uros Stajic
0 siblings, 1 reply; 21+ messages in thread
From: Tom Rini @ 2026-03-17 13:47 UTC (permalink / raw)
To: Leo Liang, Uros Stajic, Djordje Todorovic, Chao-ying Fu
Cc: u-boot@lists.denx.de
[-- Attachment #1: Type: text/plain, Size: 1080 bytes --]
On Tue, Mar 17, 2026 at 05:06:55PM +0800, Leo Liang wrote:
> Hi Uros,
>
> On Wed, Dec 24, 2025 at 03:47:17PM +0000, Uros Stajic wrote:
> > From: Chao-ying Fu <cfu@mips.com>
> >
> > Although memreserve entries in an FDT are 64-bit aligned relative to the
> > start of the FDT, we cannot guarantee that the FDT itself is 64-bit aligned
> > in memory. This is especially common when using a FIT image, where the
> > alignment of the embedded DTB cannot be controlled.
> >
> > On systems that do not support unaligned 64-bit memory accesses, this leads
> > to faults when accessing the memreserve section before the FDT is relocated.
> > To resolve this, copy the 64-bit values into suitably aligned on-stack
> > variables before accessing them.
Yes, and so you must align the device tree first. We should have
addressed all of these problems in current master now. If we have not,
please explain what the use case you're encountering now is.
[snip]
> Hi Tom,
>
> Should we accept this patch in u-boot?
No, we cannot, thanks for checking.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v5 7/8] libfdt: Allow non-64b aligned memreserve entries
2026-03-17 13:47 ` Tom Rini
@ 2026-03-27 13:50 ` Uros Stajic
0 siblings, 0 replies; 21+ messages in thread
From: Uros Stajic @ 2026-03-27 13:50 UTC (permalink / raw)
To: Tom Rini, Leo Liang; +Cc: u-boot@lists.denx.de, Djordje Todorovic
Hi,
On 3/17/26 14:47, Tom Rini wrote:
> On Tue, Mar 17, 2026 at 05:06:55PM +0800, Leo Liang wrote:
>> Hi Uros,
>>
>> On Wed, Dec 24, 2025 at 03:47:17PM +0000, Uros Stajic wrote:
>>> From: Chao-ying Fu<cfu@mips.com>
>>>
>>> Although memreserve entries in an FDT are 64-bit aligned relative to the
>>> start of the FDT, we cannot guarantee that the FDT itself is 64-bit aligned
>>> in memory. This is especially common when using a FIT image, where the
>>> alignment of the embedded DTB cannot be controlled.
>>>
>>> On systems that do not support unaligned 64-bit memory accesses, this leads
>>> to faults when accessing the memreserve section before the FDT is relocated.
>>> To resolve this, copy the 64-bit values into suitably aligned on-stack
>>> variables before accessing them.
> Yes, and so you must align the device tree first. We should have
> addressed all of these problems in current master now. If we have not,
> please explain what the use case you're encountering now is.
>
> [snip]
>> Hi Tom,
>>
>> Should we accept this patch in u-boot?
> No, we cannot, thanks for checking.
>
> -- Tom
Thanks for checking. With current master I no longer see the issue that
originally motivated this patch, so I will drop it from v6.
Best regards,
Uros
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v5 8/8] riscv: p8700: Add Coherence Manager (CM) and IOCU support
2025-12-24 15:44 [PATCH v5 0/8] riscv: Add support for P8700 platform on Boston board Uros Stajic
` (6 preceding siblings ...)
2025-12-24 15:47 ` [PATCH v5 7/8] libfdt: Allow non-64b aligned memreserve entries Uros Stajic
@ 2025-12-24 15:47 ` Uros Stajic
7 siblings, 0 replies; 21+ messages in thread
From: Uros Stajic @ 2025-12-24 15:47 UTC (permalink / raw)
To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu, Uros Stajic
From: Chao-ying Fu <cfu@mips.com>
Add support for Coherence Manager (CM) and IOCU discovery and
configuration on the P8700 platform.
Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
arch/riscv/cpu/p8700/Makefile | 3 +
arch/riscv/cpu/p8700/cache.c | 6 ++
arch/riscv/cpu/p8700/cm-iocu.c | 75 ++++++++++++++++
arch/riscv/cpu/p8700/cm.c | 92 +++++++++++++++++++
arch/riscv/cpu/p8700/p8700.c | 21 +++++
arch/riscv/include/asm/arch-p8700/cm.h | 61 +++++++++++++
arch/riscv/include/asm/arch-p8700/p8700.h | 35 ++++++++
arch/riscv/include/asm/global_data.h | 4 +
board/mips/boston-riscv/Makefile | 1 +
board/mips/boston-riscv/iocu.c | 102 ++++++++++++++++++++++
10 files changed, 400 insertions(+)
create mode 100644 arch/riscv/cpu/p8700/cm-iocu.c
create mode 100644 arch/riscv/cpu/p8700/cm.c
create mode 100644 arch/riscv/cpu/p8700/p8700.c
create mode 100644 arch/riscv/include/asm/arch-p8700/cm.h
create mode 100644 board/mips/boston-riscv/iocu.c
diff --git a/arch/riscv/cpu/p8700/Makefile b/arch/riscv/cpu/p8700/Makefile
index 32c5e2dce21..45f68bbda3d 100644
--- a/arch/riscv/cpu/p8700/Makefile
+++ b/arch/riscv/cpu/p8700/Makefile
@@ -3,5 +3,8 @@
# Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
obj-y += cache.o
+obj-y += cm.o
+obj-y += cm-iocu.o
obj-y += cpu.o
obj-y += dram.o
+obj-y += p8700.o
diff --git a/arch/riscv/cpu/p8700/cache.c b/arch/riscv/cpu/p8700/cache.c
index 7559c688321..df6e6c9663e 100644
--- a/arch/riscv/cpu/p8700/cache.c
+++ b/arch/riscv/cpu/p8700/cache.c
@@ -48,6 +48,9 @@ static void probe_cache_config(void)
void flush_dcache_range(unsigned long start, unsigned long end)
{
+ if (p8700_dma_is_coherent())
+ return;
+
if (lsize == 0)
probe_cache_config();
@@ -71,6 +74,9 @@ void flush_dcache_range(unsigned long start, unsigned long end)
void invalidate_dcache_range(unsigned long start, unsigned long end)
{
+ if (p8700_dma_is_coherent())
+ return;
+
if (lsize == 0)
probe_cache_config();
diff --git a/arch/riscv/cpu/p8700/cm-iocu.c b/arch/riscv/cpu/p8700/cm-iocu.c
new file mode 100644
index 00000000000..5850647d20f
--- /dev/null
+++ b/arch/riscv/cpu/p8700/cm-iocu.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * MIPS Coherence Manager (CM) Support
+ *
+ * Copyright (c) 2016 Imagination Technologies Ltd.
+ */
+#include <asm/io.h>
+#include <asm/global_data.h>
+#include <asm/arch-p8700/cm.h>
+
+__weak bool plat_iocu_usable(unsigned int cluster, unsigned int iocu)
+{
+ return true;
+}
+
+static int init_cluster_iocus(unsigned int cluster)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ void __iomem *global_gcrs;
+ u32 cfg, num_iocus, num_iocus_usable, local_cluster;
+ int i;
+
+ local_cluster = mips_cluster_id();
+
+ global_gcrs = mips_cm_base();
+ if (cluster != local_cluster) {
+ // FIXME
+ return 1;
+ }
+
+ cfg = __raw_readl(global_gcrs + GCR_CONFIG);
+ num_iocus = cfg >> GCR_CONFIG_NUMIOCU_SHIFT;
+ num_iocus &= GCR_CONFIG_NUMIOCU_MASK;
+ gd->arch.num_iocus += num_iocus;
+
+ /* Discover how many IOCUs are usable */
+ num_iocus_usable = num_iocus;
+ for (i = num_iocus - 1; i >= 0; i--) {
+ if (!plat_iocu_usable(cluster, i))
+ num_iocus_usable--;
+ }
+ gd->arch.num_iocus_usable += num_iocus_usable;
+
+ /* If the cluster has no usable IOCUs there's nothing to do */
+ if (num_iocus_usable == 0) {
+ if (cluster != local_cluster)
+ power_down_cluster(cluster);
+
+ return 0;
+ }
+
+ /* If the IOCUs are in the local cluster we're good to go already */
+ if (cluster == local_cluster)
+ return 0;
+
+ /* Ensure that the cluster's L2 cache is initialised */
+ return init_cluster_l2(cluster);
+}
+
+int mips_cm_init_iocus(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ unsigned int cluster;
+ int err;
+
+ for (cluster = 0; cluster < mips_cm_num_clusters(); cluster++) {
+ err = init_cluster_iocus(cluster);
+ if (err) {
+ gd->arch.num_iocus_usable = err;
+ return 0;
+ }
+ }
+
+ return 0;
+}
diff --git a/arch/riscv/cpu/p8700/cm.c b/arch/riscv/cpu/p8700/cm.c
new file mode 100644
index 00000000000..ce7485c564d
--- /dev/null
+++ b/arch/riscv/cpu/p8700/cm.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * MIPS Coherence Manager (CM) Support
+ *
+ * Copyright (c) 2016 Imagination Technologies Ltd.
+ */
+
+#include <asm/io.h>
+#include <asm/arch-p8700/cm.h>
+#include <asm/arch-p8700/p8700.h>
+
+static void mips_cpc_init(void)
+{
+}
+
+__weak const struct mmio_region *get_mmio_regions(void)
+{
+ return NULL;
+}
+
+static void p8700_setup_mmio_limits(void)
+{
+ void __iomem *gcrs = mips_cm_base();
+ const struct mmio_region *rgn = get_mmio_regions();
+ unsigned int num_clusters = mips_cm_num_clusters();
+ unsigned int limit = MIPS_CM_MMIO_LIMIT / num_clusters;
+ unsigned int i, reg_off;
+
+ if (!rgn)
+ return;
+
+ if (num_clusters != 1) {
+ // FIXME! Need to support multiple clusters.
+ return;
+ }
+
+ reg_off = GCR_MMIO0_BOTTOM;
+
+ for (i = 0; rgn[i].addr_high; i++) {
+ __raw_writeq(rgn[i].addr_high & GCR_MMIO0_TOP_ADDR,
+ gcrs + reg_off + (GCR_MMIO0_TOP - GCR_MMIO0_BOTTOM));
+
+ __raw_writeq((rgn[i].addr_low & GCR_MMIO0_BOTTOM_ADDR) |
+ (rgn[i].port << GCR_MMIO0_BOTTOM_PORT_SHIFT) |
+ (rgn[i].enable ? GCR_MMIO0_BOTTOM_ENABLE : 0),
+ gcrs + reg_off);
+ reg_off += GCR_MMIO1_BOTTOM - GCR_MMIO0_BOTTOM;
+ }
+
+ __raw_writel(limit, gcrs + GCR_MMIO_REQ_LIMIT);
+}
+
+int power_up_cluster(unsigned int cluster)
+{
+ return 0;
+}
+
+int power_down_cluster(unsigned int cluster)
+{
+ return 0;
+}
+
+int init_cluster_l2(unsigned int cluster)
+{
+ return 0;
+}
+
+int mips_cm_init(void)
+{
+ int err;
+
+ mips_cpc_init();
+
+ err = mips_cm_init_iocus();
+ if (err)
+ return err;
+
+ p8700_setup_mmio_limits();
+
+ return 0;
+}
+
+int arch_cpu_init(void)
+{
+ int err;
+
+ err = mips_cm_init();
+ if (err)
+ return err;
+
+ return 0;
+}
diff --git a/arch/riscv/cpu/p8700/p8700.c b/arch/riscv/cpu/p8700/p8700.c
new file mode 100644
index 00000000000..18f30d10c19
--- /dev/null
+++ b/arch/riscv/cpu/p8700/p8700.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+ */
+
+#include <asm/io.h>
+#include <linux/types.h>
+#include <asm/arch-p8700/p8700.h>
+
+#define BOSTON_IOCU_NOC_OFFSET 0x10
+
+bool p8700_dma_is_coherent(void)
+{
+ u32 pcie0_off = readl((void __iomem *)BOSTON_PLAT_NOCPCIE0ADDR);
+ u32 pcie1_off = readl((void __iomem *)BOSTON_PLAT_NOCPCIE1ADDR);
+ u32 pcie2_off = readl((void __iomem *)BOSTON_PLAT_NOCPCIE2ADDR);
+
+ return pcie0_off == BOSTON_IOCU_NOC_OFFSET &&
+ pcie1_off == BOSTON_IOCU_NOC_OFFSET &&
+ pcie2_off == BOSTON_IOCU_NOC_OFFSET;
+}
diff --git a/arch/riscv/include/asm/arch-p8700/cm.h b/arch/riscv/include/asm/arch-p8700/cm.h
new file mode 100644
index 00000000000..ab5ea7385b2
--- /dev/null
+++ b/arch/riscv/include/asm/arch-p8700/cm.h
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+ */
+
+#ifndef __P8700_CM_H__
+#define __P8700_CM_H__
+
+#include <asm/arch-p8700/p8700.h>
+
+struct mmio_region {
+ phys_addr_t addr_low;
+ phys_addr_t addr_high;
+ unsigned int port : 4;
+ unsigned int enable : 1;
+};
+
+const struct mmio_region *get_mmio_regions(void);
+
+void setup_redirect(unsigned int cluster, unsigned int core,
+ unsigned int vp, unsigned int block);
+
+int mips_cm_init_iocus(void);
+
+int power_up_cluster(unsigned int cluster);
+int power_down_cluster(unsigned int cluster);
+int init_cluster_l2(unsigned int cluster);
+
+static inline void *mips_cm_base(void)
+{
+ return (void *)CM_BASE;
+}
+
+static inline void *mips_cpc_base(void)
+{
+ return (void *)CPC_BASE;
+}
+
+static inline unsigned int mips_cm_num_clusters(void)
+{
+ u32 cfg;
+
+ cfg = __raw_readl(mips_cm_base() + GCR_CONFIG);
+ cfg >>= GCR_CONFIG_NUMCLUSTERS_SHIFT;
+ cfg &= GCR_CONFIG_NUMCLUSTERS_MASK;
+
+ return cfg;
+}
+
+static inline unsigned int mips_cluster_id(void)
+{
+ u32 temp;
+
+ asm volatile("csrr %0, mhartid" : "=r"(temp));
+ temp >>= MHARTID_CLUSTER_SHIFT;
+ temp &= MHARTID_CLUSTER_MASK;
+
+ return temp;
+}
+
+#endif /* __P8700_CM_H__ */
diff --git a/arch/riscv/include/asm/arch-p8700/p8700.h b/arch/riscv/include/asm/arch-p8700/p8700.h
index 5ca9b4b9497..0b864afb635 100644
--- a/arch/riscv/include/asm/arch-p8700/p8700.h
+++ b/arch/riscv/include/asm/arch-p8700/p8700.h
@@ -65,6 +65,10 @@
#define CM_BASE 0x16100000
#define CPC_BASE (CM_BASE + 0x8000)
+/* Block offsets */
+#define GCR_OFF_GLOBAL 0x0000
+#define GCR_OFF_LOCAL 0x2000
+
/* CPC Block offsets */
#define CPC_OFF_LOCAL 0x2000
@@ -75,6 +79,33 @@
#define CPC_Cx_CMD 0x0000
#define CPC_Cx_CMD_RESET 0x4
+/* GCR_CONFIG */
+#define GCR_CONFIG 0x0000
+#define GCR_REV 0x0030
+#define GCR_CONFIG_NUMCLUSTERS_SHIFT 23
+#define GCR_CONFIG_NUMCLUSTERS_MASK 0x7f
+#define GCR_CONFIG_NUMIOCU_SHIFT 8
+#define GCR_CONFIG_NUMIOCU_MASK 0xf
+#define GCR_CONFIG_NUMCORES_SHIFT 0
+#define GCR_CONFIG_NUMCORES_MASK 0xff
+
+/* GCR_REV CM versions */
+#define GCR_REV_CM3 0x0800
+#define GCR_REV_CM3_5 0x0900
+
+#define GCR_MMIO_REQ_LIMIT 0x06f8
+#define GCR_MMIO0_BOTTOM 0x0700
+#define GCR_MMIO0_BOTTOM_ADDR (0xffffffffull << 16)
+#define GCR_MMIO0_BOTTOM_PORT_SHIFT 2
+#define GCR_MMIO0_BOTTOM_PORT (0xf << 2)
+#define GCR_MMIO0_BOTTOM_DISABLE_LIMIT (0x1 << 1)
+#define GCR_MMIO0_BOTTOM_ENABLE (0x1 << 0)
+#define GCR_MMIO0_TOP 0x0708
+#define GCR_MMIO0_TOP_ADDR (0xffffffffull << 16)
+#define GCR_MMIO1_BOTTOM 0x0710
+
+#define MIPS_CM_MMIO_LIMIT 4
+
#define P8700_GCR_C0_COH_EN 0x20f8
#define P8700_GCR_C1_COH_EN 0x21f8
#define P8700_GCR_C2_COH_EN 0x22f8
@@ -107,4 +138,8 @@
#define BOSTON_PLAT_NOCPCIE1ADDR (BOSTON_PLAT_BASE + 0x40)
#define BOSTON_PLAT_NOCPCIE2ADDR (BOSTON_PLAT_BASE + 0x44)
+#ifndef __ASSEMBLY__
+bool p8700_dma_is_coherent(void);
+#endif /* __ASSEMBLY__ */
+
#endif /* __P8700_H__ */
diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
index 33f2b5ec5c8..198eacd1e07 100644
--- a/arch/riscv/include/asm/global_data.h
+++ b/arch/riscv/include/asm/global_data.h
@@ -44,6 +44,10 @@ struct arch_global_data {
ulong smbios_start; /* Start address of SMBIOS table */
#endif
struct resume_data *resume;
+#if CONFIG_IS_ENABLED(P8700_RISCV)
+ int num_iocus;
+ int num_iocus_usable;
+#endif
};
#include <asm-generic/global_data.h>
diff --git a/board/mips/boston-riscv/Makefile b/board/mips/boston-riscv/Makefile
index 0615c677d23..c67c001d4e6 100644
--- a/board/mips/boston-riscv/Makefile
+++ b/board/mips/boston-riscv/Makefile
@@ -4,5 +4,6 @@
obj-y += boston-riscv.o
obj-y += checkboard.o
+obj-y += iocu.o
obj-y += lowlevel_init.o
obj-y += reset.o
diff --git a/board/mips/boston-riscv/iocu.c b/board/mips/boston-riscv/iocu.c
new file mode 100644
index 00000000000..807f09804a3
--- /dev/null
+++ b/board/mips/boston-riscv/iocu.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2016 Imagination Technologies Ltd.
+ */
+
+#include "boston-regs.h"
+#include <dm.h>
+#include <env_callback.h>
+#include <event.h>
+#include <asm/io.h>
+#include <asm/arch-p8700/cm.h>
+
+static const struct mmio_region mmio_regions[] = {
+ { 0x10000000, 0x160f0000, .enable = 1 },
+ { 0x17ff0000, 0x17ff0000, .enable = 1 },
+ { 0 },
+};
+
+const struct mmio_region *get_mmio_regions(void)
+{
+ return mmio_regions;
+}
+
+static int set_io_coherent(bool coherent)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ if (!coherent) {
+ printf("I/O: Non-Coherent (Forced by environment)\n");
+ goto noncoherent;
+ }
+
+ if (gd->arch.num_iocus_usable < 0) {
+ printf("I/O: Non-Coherent (IOCU init error %d)\n",
+ gd->arch.num_iocus_usable);
+ goto noncoherent;
+ }
+
+ if (gd->arch.num_iocus == 0) {
+ printf("I/O: Non-Coherent (No IOCU)\n");
+ goto noncoherent;
+ }
+
+ if (gd->arch.num_iocus_usable == 0) {
+ printf("I/O: Non-Coherent (IOCU not connected)\n");
+ goto noncoherent;
+ }
+
+ /*
+ * We have some number of connected IOCUs. Map all PCIe DMA access to
+ * hit the IOCU by offsetting the addresses as they pass from the PCIe
+ * controller to the NoC.
+ */
+ writel(0x10, (u32 *)BOSTON_PLAT_NOCPCIE0ADDR);
+ writel(0x10, (u32 *)BOSTON_PLAT_NOCPCIE1ADDR);
+ writel(0x10, (u32 *)BOSTON_PLAT_NOCPCIE2ADDR);
+
+ printf("I/O: Coherent\n");
+ return 0;
+
+noncoherent:
+ /* Map all PCIe DMA access to its default, non-IOCU, target */
+ writel(0x00, (u32 *)BOSTON_PLAT_NOCPCIE0ADDR);
+ writel(0x00, (u32 *)BOSTON_PLAT_NOCPCIE1ADDR);
+ writel(0x00, (u32 *)BOSTON_PLAT_NOCPCIE2ADDR);
+
+ return 0;
+}
+
+static int on_io_coherent(const char *name, const char *value,
+ enum env_op op, int flags)
+{
+ switch (op) {
+ case env_op_create:
+ case env_op_overwrite:
+ if (!strcmp(value, "0")) {
+ set_io_coherent(false);
+ } else if (!strcmp(value, "1")) {
+ set_io_coherent(true);
+ } else {
+ printf("### io.coherent must equal 0 or 1\n");
+ return -EINVAL;
+ }
+ return 0;
+
+ case env_op_delete:
+ set_io_coherent(true);
+ return 0;
+
+ default:
+ return 0;
+ }
+}
+
+U_BOOT_ENV_CALLBACK(io_coherent, on_io_coherent);
+
+static int p8700_misc_init_f(void)
+{
+ return set_io_coherent(env_get_yesno("io.coherent") != 0);
+}
+
+EVENT_SPY_SIMPLE(EVT_MISC_INIT_F, p8700_misc_init_f);
--
2.34.1
^ permalink raw reply related [flat|nested] 21+ messages in thread