summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/generic/Kconfig7
-rw-r--r--platform/generic/andes/ae350.c26
-rw-r--r--platform/generic/andes/andes_pma.c4
-rw-r--r--platform/generic/configs/defconfig2
-rw-r--r--platform/generic/eswin/eic770x.c8
-rw-r--r--platform/generic/include/andes/andes.h4
-rw-r--r--platform/generic/include/thead/c9xx_errata.h1
-rw-r--r--platform/generic/metanoia/mt2824/mt2824.c31
-rw-r--r--platform/generic/metanoia/mt2824/objects.mk10
-rw-r--r--platform/generic/sophgo/sg2042.c32
-rw-r--r--platform/generic/thead/thead-generic.c31
11 files changed, 129 insertions, 27 deletions
diff --git a/platform/generic/Kconfig b/platform/generic/Kconfig
index d594b140..64fc4a64 100644
--- a/platform/generic/Kconfig
+++ b/platform/generic/Kconfig
@@ -51,6 +51,13 @@ config PLATFORM_ESWIN_EIC770X
bool "ESWIN EIC770X support"
default n
+config PLATFORM_METANOIA_MT2824
+ bool "Metanoia MT2824 support"
+ select ANDES_PMA
+ select ANDES_SBI
+ select ANDES_PMU
+ default n
+
config PLATFORM_OPENHWGROUP_OPENPITON
bool "OpenHWGroup Openpiton support"
default n
diff --git a/platform/generic/andes/ae350.c b/platform/generic/andes/ae350.c
index 4cf7e26d..7aafe545 100644
--- a/platform/generic/andes/ae350.c
+++ b/platform/generic/andes/ae350.c
@@ -34,6 +34,16 @@ void ae350_non_ret_save(struct sbi_scratch *scratch)
andes_hdata->pmacfg2 = csr_read_num(CSR_PMACFG0 + 2);
for (int i = 0; i < 16; i++)
andes_hdata->pmaaddrX[i] = csr_read_num(CSR_PMAADDR0 + i);
+
+ andes_hdata->saved = true;
+}
+
+void ae350_non_ret_discard(struct sbi_scratch *scratch)
+{
+ struct andes_hart_data *andes_hdata = sbi_scratch_offset_ptr(scratch,
+ andes_hart_data_offset);
+
+ andes_hdata->saved = false;
}
void ae350_non_ret_restore(struct sbi_scratch *scratch)
@@ -41,6 +51,9 @@ void ae350_non_ret_restore(struct sbi_scratch *scratch)
struct andes_hart_data *andes_hdata = sbi_scratch_offset_ptr(scratch,
andes_hart_data_offset);
+ if (!andes_hdata->saved)
+ return;
+
csr_write(CSR_MCACHE_CTL, andes_hdata->mcache_ctl);
csr_write(CSR_MMISC_CTL, andes_hdata->mmisc_ctl);
csr_write(CSR_MPFT_CTL, andes_hdata->mpft_ctl);
@@ -52,6 +65,8 @@ void ae350_non_ret_restore(struct sbi_scratch *scratch)
csr_write_num(CSR_PMACFG0 + 2, andes_hdata->pmacfg2);
for (int i = 0; i < 16; i++)
csr_write_num(CSR_PMAADDR0 + i, andes_hdata->pmaaddrX[i]);
+
+ andes_hdata->saved = false;
}
void ae350_enable_coherency_warmboot(void)
@@ -62,18 +77,17 @@ void ae350_enable_coherency_warmboot(void)
static int ae350_early_init(bool cold_boot)
{
- u32 hartid = current_hartid();
- u32 sleep_type = atcsmu_get_sleep_type(hartid);
-
if (cold_boot) {
andes_hart_data_offset = sbi_scratch_alloc_offset(sizeof(struct andes_hart_data));
if (!andes_hart_data_offset)
return SBI_ENOMEM;
}
- /* Don't restore Andes CSRs during boot or wake up from light sleep */
- if (sbi_init_count(current_hartindex()) && sleep_type == SBI_SUSP_SLEEP_TYPE_SUSPEND)
- ae350_non_ret_restore(sbi_scratch_thishart_ptr());
+ /*
+ * This is a no-op unless this hart actually saved them, so it is safe
+ * to call on every path.
+ */
+ ae350_non_ret_restore(sbi_scratch_thishart_ptr());
return generic_early_init(cold_boot);
}
diff --git a/platform/generic/andes/andes_pma.c b/platform/generic/andes/andes_pma.c
index ba9a35bb..28d33a2f 100644
--- a/platform/generic/andes/andes_pma.c
+++ b/platform/generic/andes/andes_pma.c
@@ -82,8 +82,8 @@ static void decode_pmaaddrx(int entry_id, unsigned long *start,
*/
pmaaddr = csr_read_num(CSR_PMAADDR0 + entry_id);
k = sbi_ffz(pmaaddr);
- *size = 1 << (k + 3);
- *start = (pmaaddr - (1 << k) + 1) << 2;
+ *size = 1UL << (k + 3);
+ *start = (pmaaddr - (1UL << k) + 1) << 2;
}
static bool has_pma_region_overlap(unsigned long start, unsigned long size)
diff --git a/platform/generic/configs/defconfig b/platform/generic/configs/defconfig
index 341f6b25..98829884 100644
--- a/platform/generic/configs/defconfig
+++ b/platform/generic/configs/defconfig
@@ -2,6 +2,7 @@ CONFIG_PLATFORM_ALLWINNER_D1=y
CONFIG_PLATFORM_ANDES_AE350=y
CONFIG_PLATFORM_ANDES_QILAI=y
CONFIG_PLATFORM_ESWIN_EIC770X=y
+CONFIG_PLATFORM_METANOIA_MT2824=y
CONFIG_PLATFORM_OPENHWGROUP_ARIANE=y
CONFIG_PLATFORM_OPENHWGROUP_OPENPITON=y
CONFIG_PLATFORM_RENESAS_RZFIVE=y
@@ -51,6 +52,7 @@ CONFIG_FDT_RESET_ATCWDT200=y
CONFIG_FDT_RESET_GPIO=y
CONFIG_FDT_RESET_LITEX=y
CONFIG_FDT_RESET_HTIF=y
+CONFIG_FDT_RESET_METANOIA=y
CONFIG_FDT_RESET_RPMI=y
CONFIG_FDT_RESET_SG2042_HWMON_MCU=y
CONFIG_FDT_RESET_SPACEMIT_P1=y
diff --git a/platform/generic/eswin/eic770x.c b/platform/generic/eswin/eic770x.c
index 3fe3d090..c71198a8 100644
--- a/platform/generic/eswin/eic770x.c
+++ b/platform/generic/eswin/eic770x.c
@@ -380,9 +380,9 @@ static int eswin_eic7700_final_init(bool cold_boot)
return 0;
}
-static int eswin_eic7700_pmp_configure(struct sbi_scratch *scratch)
+static int eswin_eic7700_pmp_configure(struct sbi_scratch *scratch,
+ struct sbi_domain *dom)
{
- struct sbi_domain *dom = sbi_domain_thishart_ptr();
struct sbi_domain_memregion *reg, *prev = NULL;
unsigned int pmp_idx, pmp_max;
unsigned int i, j;
@@ -453,7 +453,8 @@ no_more_pmp:
return SBI_EFAIL;
}
-static void eswin_eic7700_pmp_unconfigure(struct sbi_scratch *scratch)
+static void eswin_eic7700_pmp_unconfigure(struct sbi_scratch *scratch,
+ struct sbi_domain *dom)
{
/* Enable P550 internal + System Port */
sbi_hart_pmp_set(PMP_FREE_A_START + PMP_FREE_A_COUNT - 1, 0, 0,
@@ -469,6 +470,7 @@ static void eswin_eic7700_pmp_unconfigure(struct sbi_scratch *scratch)
static struct sbi_hart_protection eswin_eic7700_pmp_protection = {
.name = "eic7700_pmp",
.rating = -1UL,
+ .type = SBI_HART_PROTECTION_TYPE_MEMORY,
.configure = eswin_eic7700_pmp_configure,
.unconfigure = eswin_eic7700_pmp_unconfigure,
};
diff --git a/platform/generic/include/andes/andes.h b/platform/generic/include/andes/andes.h
index dd245171..dfa9f3c1 100644
--- a/platform/generic/include/andes/andes.h
+++ b/platform/generic/include/andes/andes.h
@@ -96,9 +96,13 @@ struct andes_hart_data {
unsigned long pmacfg0;
unsigned long pmacfg2;
unsigned long pmaaddrX[16];
+
+ /* Set when the CSRs above hold a saved copy awaiting restore */
+ bool saved;
};
void ae350_non_ret_save(struct sbi_scratch *scratch);
+void ae350_non_ret_discard(struct sbi_scratch *scratch);
void ae350_non_ret_restore(struct sbi_scratch *scratch);
void ae350_enable_coherency_warmboot(void);
diff --git a/platform/generic/include/thead/c9xx_errata.h b/platform/generic/include/thead/c9xx_errata.h
index 40c1587b..7a419e41 100644
--- a/platform/generic/include/thead/c9xx_errata.h
+++ b/platform/generic/include/thead/c9xx_errata.h
@@ -8,6 +8,7 @@
*/
#define THEAD_QUIRK_ERRATA_TLB_FLUSH BIT(0)
#define THEAD_QUIRK_ERRATA_THEAD_PMU BIT(1)
+#define THEAD_QUIRK_ERRATA_JTLB BIT(2)
void thead_register_tlb_flush_trap_handler(void);
diff --git a/platform/generic/metanoia/mt2824/mt2824.c b/platform/generic/metanoia/mt2824/mt2824.c
new file mode 100644
index 00000000..a34304b9
--- /dev/null
+++ b/platform/generic/metanoia/mt2824/mt2824.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (C) 2026 Metanoia Communication Inc.
+ *
+ * Authors:
+ * Jun Chang <[email protected]>
+ */
+
+#include <andes/andes_pmu.h>
+#include <andes/andes_sbi.h>
+#include <platform_override.h>
+
+static int metanoia_mt2824_platform_init(const void *fdt, int nodeoff,
+ const struct fdt_match *match)
+{
+ generic_platform_ops.extensions_init = andes_pmu_extensions_init;
+ generic_platform_ops.pmu_init = andes_pmu_init;
+ generic_platform_ops.vendor_ext_provider = andes_sbi_vendor_ext_provider;
+
+ return 0;
+}
+
+static const struct fdt_match metanoia_mt2824_match[] = {
+ { .compatible = "metanoia,mt2824" },
+ { /* sentinel */ }
+};
+
+const struct fdt_driver metanoia_mt2824 = {
+ .match_table = metanoia_mt2824_match,
+ .init = metanoia_mt2824_platform_init,
+};
diff --git a/platform/generic/metanoia/mt2824/objects.mk b/platform/generic/metanoia/mt2824/objects.mk
new file mode 100644
index 00000000..b97c7775
--- /dev/null
+++ b/platform/generic/metanoia/mt2824/objects.mk
@@ -0,0 +1,10 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (C) 2026 Metanoia Communication Inc.
+#
+
+ifeq ($(PLATFORM_RISCV_XLEN), 64)
+carray-platform_override_modules-$(CONFIG_PLATFORM_METANOIA_MT2824) += metanoia_mt2824
+platform-objs-$(CONFIG_PLATFORM_METANOIA_MT2824) += metanoia/mt2824/mt2824.o
+endif
diff --git a/platform/generic/sophgo/sg2042.c b/platform/generic/sophgo/sg2042.c
index ac8840e8..81b28376 100644
--- a/platform/generic/sophgo/sg2042.c
+++ b/platform/generic/sophgo/sg2042.c
@@ -31,21 +31,6 @@ static int sophgo_sg2042_early_init(bool cold_boot)
thead_register_tlb_flush_trap_handler();
- /*
- * Sophgo sg2042 soc use separate 16 timers while initiating,
- * merge them as a single domain to avoid wasting.
- */
- if (cold_boot)
- return sbi_domain_root_add_memrange(
- (ulong)SOPHGO_SG2042_TIMER_BASE,
- SOPHGO_SG2042_TIMER_SIZE *
- SOPHGO_SG2042_TIMER_NUM,
- MTIMER_REGION_ALIGN,
- (SBI_DOMAIN_MEMREGION_MMIO |
- SBI_DOMAIN_MEMREGION_M_READABLE |
- SBI_DOMAIN_MEMREGION_M_WRITABLE));
-
-
return 0;
}
@@ -57,6 +42,23 @@ static int sophgo_sg2042_extensions_init(bool cold_boot)
if (rc)
return rc;
+ /*
+ * SG2042 has 16 separate timers. Add one combined region before the
+ * MTIMER driver adds the individual regions.
+ */
+ if (cold_boot) {
+ rc = sbi_domain_root_add_memrange(
+ (ulong)SOPHGO_SG2042_TIMER_BASE,
+ SOPHGO_SG2042_TIMER_SIZE *
+ SOPHGO_SG2042_TIMER_NUM,
+ MTIMER_REGION_ALIGN,
+ (SBI_DOMAIN_MEMREGION_MMIO |
+ SBI_DOMAIN_MEMREGION_M_READABLE |
+ SBI_DOMAIN_MEMREGION_M_WRITABLE));
+ if (rc)
+ return rc;
+ }
+
thead_c9xx_register_pmu_device();
return 0;
}
diff --git a/platform/generic/thead/thead-generic.c b/platform/generic/thead/thead-generic.c
index fef0871b..c83eb55c 100644
--- a/platform/generic/thead/thead-generic.c
+++ b/platform/generic/thead/thead-generic.c
@@ -11,8 +11,10 @@
#include <thead/c9xx_pmu.h>
#include <sbi/sbi_const.h>
#include <sbi/sbi_platform.h>
+#include <sbi/sbi_pmu.h>
#include <sbi/sbi_scratch.h>
#include <sbi/sbi_string.h>
+#include <sbi/sbi_tlb.h>
#include <sbi_utils/fdt/fdt_helper.h>
struct thead_generic_quirks {
@@ -39,15 +41,38 @@ static int thead_pmu_extensions_init(bool cold_boot)
return 0;
}
+static void thead_jtlb_local_sfence_vma(struct sbi_tlb_info *tinfo)
+{
+ sbi_pmu_ctr_incr_fw(SBI_PMU_FW_SFENCE_VMA_RCVD);
+ __asm__ __volatile__("sfence.vma");
+}
+
+static void thead_jtlb_local_sfence_vma_asid(struct sbi_tlb_info *tinfo)
+{
+ sbi_pmu_ctr_incr_fw(SBI_PMU_FW_SFENCE_VMA_ASID_RCVD);
+ /* Flush entire MM context for a given ASID */
+ __asm__ __volatile__("sfence.vma x0, %0"
+ :
+ : "r"(tinfo->asid)
+ : "memory");
+}
+
static int thead_generic_platform_init(const void *fdt, int nodeoff,
const struct fdt_match *match)
{
const struct thead_generic_quirks *quirks = match->data;
+ static struct sbi_tlb_local_operations tlb_local_ops;
if (quirks->errata & THEAD_QUIRK_ERRATA_TLB_FLUSH)
generic_platform_ops.early_init = thead_tlb_flush_early_init;
if (quirks->errata & THEAD_QUIRK_ERRATA_THEAD_PMU)
generic_platform_ops.extensions_init = thead_pmu_extensions_init;
+ if (quirks->errata &THEAD_QUIRK_ERRATA_JTLB) {
+ sbi_memcpy(&tlb_local_ops, sbi_tlb_get_local_operations(), sizeof(tlb_local_ops));
+ tlb_local_ops.local_sfence_vma = thead_jtlb_local_sfence_vma;
+ tlb_local_ops.local_sfence_vma_asid = thead_jtlb_local_sfence_vma_asid;
+ sbi_tlb_set_local_operations(&tlb_local_ops);
+ }
return 0;
}
@@ -60,13 +85,17 @@ static const struct thead_generic_quirks thead_pmu_quirks = {
.errata = THEAD_QUIRK_ERRATA_THEAD_PMU,
};
+static const struct thead_generic_quirks thead_pmu_jtlb_quirks = {
+ .errata = THEAD_QUIRK_ERRATA_THEAD_PMU | THEAD_QUIRK_ERRATA_JTLB,
+};
+
static const struct fdt_match thead_generic_match[] = {
{ .compatible = "canaan,kendryte-k230", .data = &thead_pmu_quirks },
{ .compatible = "sophgo,cv1800b", .data = &thead_pmu_quirks },
{ .compatible = "sophgo,cv1812h", .data = &thead_pmu_quirks },
{ .compatible = "sophgo,sg2000", .data = &thead_pmu_quirks },
{ .compatible = "sophgo,sg2002", .data = &thead_pmu_quirks },
- { .compatible = "sophgo,sg2044", .data = &thead_pmu_quirks },
+ { .compatible = "sophgo,sg2044", .data = &thead_pmu_jtlb_quirks },
{ .compatible = "thead,th1520", .data = &thead_th1520_quirks },
{ },
};