Merge "feat(s32g274a): add ncore support" into integration
diff --git a/plat/nxp/s32/s32g274ardb2/include/s32cc-ncore.h b/plat/nxp/s32/s32g274ardb2/include/s32cc-ncore.h
new file mode 100644
index 0000000..0c0870f
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/include/s32cc-ncore.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2019-2021, 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef S32G2_NCORE_H
+#define S32G2_NCORE_H
+
+#include <stdbool.h>
+
+#define NCORE_BASE_ADDR UL(0x50400000)
+
+#define A53_CLUSTER0_CAIU U(0)
+#define A53_CLUSTER1_CAIU U(1)
+
+/**
+ * Directory Unit Registers
+ *
+ * The directory provides a point of serialization for establishing transaction
+ * ordering and sequences coherence operations and memory accesses.
+ */
+#define NCORE_DIRU(N) (NCORE_BASE_ADDR + UL(0x80000) + ((N) * UL(0x1000)))
+
+/* DIRU Snoop Filtering Enable */
+#define NCORE_DIRUSFE(N) (NCORE_DIRU(N) + UL(0x10))
+#define NCORE_DIRUSFE_SFEN(SF) BIT_32(SF)
+
+/* DIRU Caching Agent Snoop Enable */
+#define NCORE_DIRUCASE(N) (NCORE_DIRU(N) + UL(0x40))
+#define NCORE_DIRUCASE_CASNPEN(CAIU) BIT_32(CAIU)
+
+/* DIRU Snoop Filter Maintenance Control */
+#define NCORE_DIRUSFMC(N) (NCORE_DIRU(N) + UL(0x80))
+#define NCORE_DIRUSFMC_SFID(SF) ((SF) << 16U)
+#define NCORE_DIRUSFMC_SFMNTOP_ALL U(0x0)
+
+/* DIRU Snoop Filter Maintenance Activity */
+#define NCORE_DIRUSFMA(N) (NCORE_DIRU(N) + UL(0x84))
+#define NCORE_DIRUSFMA_MNTOPACTV BIT_32(0)
+
+/**
+ * Coherent Agent Interface Unit Registers
+ *
+ * CAI provides a means for a fully-coherent agent to be connected to the Ncore.
+ * The CAI behaves as a fully-coherent slave.
+ */
+#define NCORE_CAIU(N) (NCORE_BASE_ADDR + ((N) * UL(0x1000)))
+#define NCORE_CAIU0_BASE_ADDR NCORE_BASE_ADDR
+
+/* CAIU Transaction Control */
+#define NCORE_CAIUTC_OFF UL(0x0)
+#define NCORE_CAIUTC_ISOLEN_SHIFT U(1)
+#define NCORE_CAIUTC_ISOLEN_MASK BIT_32(NCORE_CAIUTC_ISOLEN_SHIFT)
+
+#define NCORE_CAIUTC(N) (NCORE_CAIU(N) + NCORE_CAIUTC_OFF)
+
+/* CAIU Identification */
+#define NCORE_CAIUID(n) (NCORE_CAIU(n) + UL(0xFFC))
+#define NCORE_CAIUID_TYPE GENMASK_32(U(19), U(16))
+#define NCORE_CAIUID_TYPE_ACE_DVM U(0x0)
+
+/**
+ * Coherent Subsystem Registers
+ */
+#define NCORE_CSR (NCORE_BASE_ADDR + UL(0xFF000))
+
+/* Coherent Subsystem ACE DVM Snoop Enable */
+#define NCORE_CSADSE (NCORE_CSR + UL(0x40))
+#define NCORE_CSADSE_DVMSNPEN(CAIU) BIT_32(CAIU)
+
+/* Coherent Subsystem Identification */
+#define NCORE_CSID (NCORE_CSR + UL(0xFFC))
+#define NCORE_CSID_NUMSFS_SHIFT U(18)
+#define NCORE_CSID_NUMSFS_MASK GENMASK_32(U(22), NCORE_CSID_NUMSFS_SHIFT)
+#define NCORE_CSID_NUMSFS(CSIDR) (((CSIDR) & NCORE_CSID_NUMSFS_MASK) \
+ >> NCORE_CSID_NUMSFS_SHIFT)
+
+/* Coherent Subsystem Unit Identification */
+#define NCORE_CSUID (NCORE_CSR + UL(0xFF8))
+#define NCORE_CSUID_NUMCMIUS_SHIFT U(24)
+#define NCORE_CSUID_NUMCMIUS_MASK GENMASK_32(U(29), NCORE_CSUID_NUMCMIUS_SHIFT)
+#define NCORE_CSUID_NUMCMIUS(CSUIDR) (((CSUIDR) & NCORE_CSUID_NUMCMIUS_MASK) \
+ >> NCORE_CSUID_NUMCMIUS_SHIFT)
+#define NCORE_CSUID_NUMDIRUS_SHIFT U(16)
+#define NCORE_CSUID_NUMDIRUS_MASK GENMASK_32(U(21), NCORE_CSUID_NUMDIRUS_SHIFT)
+#define NCORE_CSUID_NUMDIRUS(CSUIDR) (((CSUIDR) & NCORE_CSUID_NUMDIRUS_MASK) \
+ >> NCORE_CSUID_NUMDIRUS_SHIFT)
+#define NCORE_CSUID_NUMNCBUS_SHIFT U(8)
+#define NCORE_CSUID_NUMNCBUS_MASK GENMASK_32(U(13), NCORE_CSUID_NUMNCBUS_SHIFT)
+#define NCORE_CSUID_NUMNCBUS(CSUIDR) (((CSUIDR) & NCORE_CSUID_NUMNCBUS_MASK) \
+ >> NCORE_CSUID_NUMNCBUS_SHIFT)
+
+#ifndef __ASSEMBLER__
+void ncore_caiu_online(uint32_t caiu);
+void ncore_caiu_offline(uint32_t caiu);
+void ncore_init(void);
+bool ncore_is_caiu_online(uint32_t caiu);
+void ncore_disable_caiu_isolation(uint32_t caiu);
+#endif /* __ASSEMBLER__ */
+
+#endif /* S32G2_NCORE_H */
diff --git a/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c b/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
index 705832c..4645f01 100644
--- a/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
+++ b/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
@@ -11,6 +11,7 @@
#include <plat_console.h>
#include <s32cc-clk-drv.h>
#include <plat_io_storage.h>
+#include <s32cc-ncore.h>
#define SIUL2_PC09_MSCR UL(0x4009C2E4)
#define SIUL2_PC10_MSCR UL(0x4009C2E8)
@@ -62,6 +63,14 @@
linflex_config_pinctrl();
console_s32g2_register();
+ /* Restore (clear) the CAIUTC[IsolEn] bit for the primary cluster, which
+ * we have manually set during early BL2 boot.
+ */
+ ncore_disable_caiu_isolation(A53_CLUSTER0_CAIU);
+
+ ncore_init();
+ ncore_caiu_online(A53_CLUSTER0_CAIU);
+
plat_s32g2_io_setup();
}
diff --git a/plat/nxp/s32/s32g274ardb2/plat_helpers.S b/plat/nxp/s32/s32g274ardb2/plat_helpers.S
index 10c0035..7121900 100644
--- a/plat/nxp/s32/s32g274ardb2/plat_helpers.S
+++ b/plat/nxp/s32/s32g274ardb2/plat_helpers.S
@@ -6,10 +6,7 @@
#include <asm_macros.S>
#include <platform_def.h>
-
-#define S32G_NCORE_CAIU0_BASE_ADDR UL(0x50400000)
-#define S32G_NCORE_CAIUTC_OFF U(0x0)
-#define S32G_NCORE_CAIUTC_ISOLEN_SHIFT U(1)
+#include <s32cc-ncore.h>
.globl plat_crash_console_flush
.globl plat_crash_console_init
@@ -104,12 +101,12 @@
* Clobber list: x0, x1, x2
*/
func plat_reset_handler
- mov x0, #S32G_NCORE_CAIU0_BASE_ADDR
- ldr w1, [x0, #S32G_NCORE_CAIUTC_OFF]
+ mov x0, #NCORE_CAIU0_BASE_ADDR
+ ldr w1, [x0, #NCORE_CAIUTC_OFF]
movz w2, #1
- lsl w2, w2, #S32G_NCORE_CAIUTC_ISOLEN_SHIFT
+ lsl w2, w2, #NCORE_CAIUTC_ISOLEN_SHIFT
orr w1, w1, w2
- str w1, [x0, #S32G_NCORE_CAIUTC_OFF]
+ str w1, [x0, #NCORE_CAIUTC_OFF]
ret
endfunc plat_reset_handler
diff --git a/plat/nxp/s32/s32g274ardb2/platform.mk b/plat/nxp/s32/s32g274ardb2/platform.mk
index 7dc287d..7d6e960 100644
--- a/plat/nxp/s32/s32g274ardb2/platform.mk
+++ b/plat/nxp/s32/s32g274ardb2/platform.mk
@@ -53,6 +53,7 @@
${PLAT_S32G274ARDB2}/plat_bl2_el3_setup.c \
${PLAT_S32G274ARDB2}/plat_bl2_image_desc.c \
${PLAT_S32G274ARDB2}/plat_io_storage.c \
+ ${PLAT_S32G274ARDB2}/s32cc_ncore.c \
common/desc_image_load.c \
drivers/io/io_fip.c \
drivers/io/io_memmap.c \
diff --git a/plat/nxp/s32/s32g274ardb2/s32cc_ncore.c b/plat/nxp/s32/s32g274ardb2/s32cc_ncore.c
new file mode 100644
index 0000000..aa60ac4
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/s32cc_ncore.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2019-2021, 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <s32cc-ncore.h>
+
+static void ncore_diru_online(uint32_t diru)
+{
+ uint32_t numsfs, sf;
+
+ numsfs = NCORE_CSID_NUMSFS(mmio_read_32(NCORE_CSID)) + 1U;
+
+ /* Initialize all entries maintenance operation for each snoop filter */
+ for (sf = 0U; sf < numsfs; sf++) {
+ mmio_write_32(NCORE_DIRUSFMC(diru), NCORE_DIRUSFMC_SFID(sf) |
+ NCORE_DIRUSFMC_SFMNTOP_ALL);
+
+ while ((mmio_read_32(NCORE_DIRUSFMA(diru)) & NCORE_DIRUSFMA_MNTOPACTV) != 0U) {
+ }
+
+ mmio_setbits_32(NCORE_DIRUSFE(diru), NCORE_DIRUSFE_SFEN(sf));
+ }
+}
+
+void ncore_disable_caiu_isolation(uint32_t caiu)
+{
+ /* Exit from low-power state */
+ mmio_clrbits_32(NCORE_CAIUTC(caiu), NCORE_CAIUTC_ISOLEN_MASK);
+}
+
+static void set_caiu(uint32_t caiu, bool on)
+{
+ uint32_t dirucase, csadser, caiuidr;
+ uint32_t numdirus, diru;
+
+ /* Enable or disable snoop messages to the CAI for each DIRU */
+ numdirus = NCORE_CSUID_NUMDIRUS(mmio_read_32(NCORE_CSUID));
+ for (diru = 0; diru < numdirus; diru++) {
+ dirucase = mmio_read_32(NCORE_DIRUCASE(diru));
+
+ if (on) {
+ dirucase |= NCORE_DIRUCASE_CASNPEN(caiu);
+ } else {
+ dirucase &= ~NCORE_DIRUCASE_CASNPEN(caiu);
+ }
+
+ mmio_write_32(NCORE_DIRUCASE(diru), dirucase);
+ }
+
+ /* Enable or disable DVM messages to the CAI */
+ caiuidr = mmio_read_32(NCORE_CAIUID(caiu));
+ if ((caiuidr & NCORE_CAIUID_TYPE) == NCORE_CAIUID_TYPE_ACE_DVM) {
+ csadser = mmio_read_32(NCORE_CSADSE);
+
+ if (on) {
+ csadser |= NCORE_CSADSE_DVMSNPEN(caiu);
+ } else {
+ csadser &= ~NCORE_CSADSE_DVMSNPEN(caiu);
+ }
+
+ mmio_write_32(NCORE_CSADSE, csadser);
+ }
+}
+
+void ncore_caiu_online(uint32_t caiu)
+{
+ set_caiu(caiu, true);
+}
+
+void ncore_caiu_offline(uint32_t caiu)
+{
+ set_caiu(caiu, false);
+}
+
+bool ncore_is_caiu_online(uint32_t caiu)
+{
+ uint32_t stat = mmio_read_32(NCORE_CSADSE);
+
+ return ((stat & NCORE_CSADSE_DVMSNPEN(caiu)) != 0U);
+}
+
+void ncore_init(void)
+{
+ uint32_t csuidr = mmio_read_32(NCORE_CSUID);
+ uint32_t numdirus, diru;
+
+ numdirus = NCORE_CSUID_NUMDIRUS(csuidr);
+ for (diru = 0U; diru < numdirus; diru++) {
+ /**
+ * Transition the directory to an online state by ensuring that
+ * all DIRUs within the interface are operational.
+ */
+ ncore_diru_online(diru);
+ }
+}