fix(s32g274a): workaround for ERR051700 erratum
ERR051700 erratum is present on all S32CC-based SoCs and relates to
reset. Releasing multiple Software Resettable Domains (SRDs) from
reset simultaneously, may cause a false error in the fault control
unit.
The workaround is to clear the SRD resets sequentially instead of
simultaneously.
Change-Id: I883bc223bf6834907259e6964a5702d7186e4c7f
Signed-off-by: Alexandru-Catalin Ionita <alexandru-catalin.ionita@nxp.com>
Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc@nxp.com>
diff --git a/docs/plat/s32g274a.rst b/docs/plat/s32g274a.rst
index 3aa858e..d3f31ca 100644
--- a/docs/plat/s32g274a.rst
+++ b/docs/plat/s32g274a.rst
@@ -95,5 +95,17 @@
-d "${BOOT_IMAGE}" \
fip.s32
+SoC Errata Workarounds
+----------------------
+
+The S32G274A port of the TF-A includes compilation flags that can be used to
+control the workaround for the SoC. These flags are used similarly to how the
+:ref:`arm_cpu_macros_errata_workarounds` are used. The list of workarounds
+includes the following switches:
+
+- ``ERRATA_S32_051700``: This applies erratum ERR051700 workaround to
+ SoCs part of the S32 Common Chassis family, and therefore it needs to
+ be enabled for the S32G and S32R devices.
+
.. _s32g2: https://www.nxp.com/products/processors-and-microcontrollers/s32-automotive-platform/s32g-vehicle-network-processors/s32g2-processors-for-vehicle-networking:S32G2
.. _s32g274ardb2: https://www.nxp.com/design/design-center/designs/s32g2-vehicle-networking-reference-design:S32G-VNP-RDB2
diff --git a/drivers/nxp/clk/s32cc/include/s32cc-mc-rgm.h b/drivers/nxp/clk/s32cc/include/s32cc-mc-rgm.h
new file mode 100644
index 0000000..5ff55fb
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/include/s32cc-mc-rgm.h
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright 2020-2021, 2023-2024 NXP
+ */
+#ifndef S32CC_MC_RGM_H
+#define S32CC_MC_RGM_H
+
+#include <stdint.h>
+
+void mc_rgm_periph_reset(uintptr_t rgm, uint32_t part, uint32_t value);
+
+#endif /* MC_RGM_H */
diff --git a/drivers/nxp/clk/s32cc/mc_rgm.c b/drivers/nxp/clk/s32cc/mc_rgm.c
new file mode 100644
index 0000000..cbf4022
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/mc_rgm.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2023-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <s32cc-mc-rgm.h>
+
+#define MC_RGM_PRST(MC_RGM, PER) ((MC_RGM) + 0x40UL + ((PER) * 0x8UL))
+
+/* ERR051700
+ * Releasing more than one Software Resettable Domain (SRD)
+ * from reset simultaneously, by clearing the corresponding
+ * peripheral MC_RGM_PRSTn[PERIPH_x_RST] reset control may
+ * cause a false setting of the Fault Collection and
+ * Control Unit (FCCU) Non-Critical Fault (NCF) flag
+ * corresponding to a Memory-Test-Repair (MTR) Error
+ */
+#if (ERRATA_S32_051700 == 1)
+void mc_rgm_periph_reset(uintptr_t rgm, uint32_t part, uint32_t value)
+{
+ uint32_t current_bit_checked, i;
+ uint32_t current_regs, mask;
+ int bit_index;
+
+ current_regs = mmio_read_32(MC_RGM_PRST(rgm, part));
+ /* Create a mask with all changed bits */
+ mask = current_regs ^ value;
+
+ while (mask != 0U) {
+ bit_index = __builtin_ffs(mask);
+ if (bit_index < 1) {
+ break;
+ }
+
+ i = (uint32_t)bit_index - 1U;
+ current_bit_checked = BIT_32(i);
+
+ /* Check if we assert or de-assert.
+ * Also wait for completion.
+ */
+ if ((value & current_bit_checked) != 0U) {
+ mmio_setbits_32(MC_RGM_PRST(rgm, part),
+ current_bit_checked);
+ while ((mmio_read_32(MC_RGM_PRST(rgm, part)) &
+ current_bit_checked) == 0U)
+ ;
+ } else {
+ mmio_clrbits_32(MC_RGM_PRST(rgm, part),
+ current_bit_checked);
+ while ((mmio_read_32(MC_RGM_PRST(rgm, part)) &
+ current_bit_checked) != 0U)
+ ;
+ }
+
+ mask &= ~current_bit_checked;
+ }
+}
+#else /* ERRATA_S32_051700 */
+void mc_rgm_periph_reset(uintptr_t rgm, uint32_t part, uint32_t value)
+{
+ mmio_write_32(MC_RGM_PRST(rgm, part), value);
+}
+#endif /* ERRATA_S32_051700 */
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk.mk b/drivers/nxp/clk/s32cc/s32cc_clk.mk
index 7a65ea6..2a9a376 100644
--- a/drivers/nxp/clk/s32cc/s32cc_clk.mk
+++ b/drivers/nxp/clk/s32cc/s32cc_clk.mk
@@ -9,6 +9,7 @@
-I${PLAT_DRIVERS_PATH}/clk/s32cc/include \
CLK_SOURCES := \
+ ${PLAT_DRIVERS_PATH}/clk/s32cc/mc_rgm.c \
${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_clk_drv.c \
${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_clk_modules.c \
${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_clk_utils.c \
diff --git a/plat/nxp/s32/s32g274ardb2/platform.mk b/plat/nxp/s32/s32g274ardb2/platform.mk
index 316ed2c..9f43405 100644
--- a/plat/nxp/s32/s32g274ardb2/platform.mk
+++ b/plat/nxp/s32/s32g274ardb2/platform.mk
@@ -15,6 +15,10 @@
include ${PLAT_COMMON_PATH}/plat_make_helper/plat_build_macros.mk
+# Flag to apply S32 erratum ERR051700. This erratum applies to all S32
+# revisions.
+S32_ERRATA_LIST += ERRATA_S32_051700
+
PLAT_INCLUDES = \
-I${PLAT_S32G274ARDB2}/include
@@ -39,7 +43,6 @@
include ${PLAT_DRIVERS_PATH}/drivers.mk
-
BL_COMMON_SOURCES += \
${PLAT_S32G274ARDB2}/plat_console.c \
${PLAT_S32G274ARDB2}/plat_helpers.S \
@@ -64,3 +67,8 @@
lib/cpus/aarch64/cortex_a53.S \
plat/common/plat_gicv3.c \
plat/common/plat_psci_common.c \
+
+# process all errata flags
+$(eval $(call default_zeros, $(S32_ERRATA_LIST)))
+$(eval $(call add_defines, $(S32_ERRATA_LIST)))
+$(eval $(call assert_booleans, $(S32_ERRATA_LIST)))