aboutsummaryrefslogtreecommitdiff
path: root/plat/renesas
diff options
context:
space:
mode:
authorMarek Vasut <marek.vasut+renesas@gmail.com>2019-02-12 00:09:46 +0100
committerMarek Vasut <marek.vasut+renesas@gmail.com>2019-02-20 16:18:08 +0100
commit0969397f295621aa26b3d14b76dd397d22be58bf (patch)
treed09641e1c1bb15c72eaf67452cd0eb400de77418 /plat/renesas
parent41bd188266d78807bf4b78d7ef31c83fa51a58cd (diff)
downloadtrusted-firmware-a-0969397f295621aa26b3d14b76dd397d22be58bf.tar.gz
rcar_gen3: plat: Prevent PCIe hang during L1X config access
In case the PCIe controller receives a L1_Enter_PM DLLP, it will disable the internal PLLs. The system software cannot predict it and can attempt to perform device config space access across the PCIe link while the controller is in this transitional state. If such condition happens, the PCIe controller register access will trigger ARM64 SError exception. This patch adds checks for which PCIe controller is enabled, checks whether the PCIe controller is in such a transitional state and if so, first completes the transition and then restarts the instruction which caused the SError. Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
Diffstat (limited to 'plat/renesas')
-rw-r--r--plat/renesas/rcar/platform.mk7
-rw-r--r--plat/renesas/rcar/rcar_common.c69
2 files changed, 74 insertions, 2 deletions
diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
index a54a60a371..97d6ddc7bb 100644
--- a/plat/renesas/rcar/platform.mk
+++ b/plat/renesas/rcar/platform.mk
@@ -13,6 +13,9 @@ GENERATE_COT := 1
BL2_AT_EL3 := 1
ENABLE_SVE_FOR_NS := 0
+CRASH_REPORTING := 1
+HANDLE_EA_EL3_FIRST := 1
+
$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
ifeq (${SPD},none)
@@ -322,8 +325,8 @@ PLAT_INCLUDES := -Idrivers/staging/renesas/rcar/ddr \
-Iplat/renesas/rcar/include \
-Iplat/renesas/rcar
-PLAT_BL_COMMON_SOURCES := drivers/renesas/rcar/iic_dvfs/iic_dvfs.c
-
+PLAT_BL_COMMON_SOURCES := drivers/renesas/rcar/iic_dvfs/iic_dvfs.c \
+ plat/renesas/rcar/rcar_common.c
RCAR_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
drivers/arm/gic/v2/gicv2_main.c \
diff --git a/plat/renesas/rcar/rcar_common.c b/plat/renesas/rcar/rcar_common.c
new file mode 100644
index 0000000000..b83df8b26f
--- /dev/null
+++ b/plat/renesas/rcar/rcar_common.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2019, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <drivers/console.h>
+#include <lib/xlat_tables/xlat_mmu_helpers.h>
+#include <plat/common/platform.h>
+
+#include <lib/mmio.h>
+
+#define CPG_BASE 0xE6150000
+#define CPG_MSTPSR3 0x0048
+#define MSTP318 (1 << 18)
+#define MSTP319 (1 << 19)
+#define PMSR 0x5c
+#define PMSR_L1FAEG (1 << 31)
+#define PMSR_PMEL1RX (1 << 23)
+#define PMCTLR 0x60
+#define PMSR_L1IATN (1 << 31)
+
+static int rcar_pcie_fixup(unsigned int controller)
+{
+ uint32_t rcar_pcie_base[] = { 0xfe011000, 0xee811000 };
+ uint32_t addr = rcar_pcie_base[controller];
+ uint32_t cpg, pmsr;
+ int ret = 0;
+
+ /* Test if PCIECx is enabled */
+ cpg = mmio_read_32(CPG_BASE + CPG_MSTPSR3);
+ if (cpg & (MSTP318 << !controller))
+ return ret;
+
+ pmsr = mmio_read_32(addr + PMSR);
+
+ if ((pmsr & PMSR_PMEL1RX) && ((pmsr & 0x70000) != 0x30000)) {
+ /* Fix applicable */
+ mmio_write_32(addr + PMCTLR, PMSR_L1IATN);
+ while (!(mmio_read_32(addr + PMSR) & PMSR_L1FAEG))
+ ;
+ mmio_write_32(addr + PMSR, PMSR_L1FAEG | PMSR_PMEL1RX);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+/* RAS functions common to AArch64 ARM platforms */
+void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
+ void *handle, uint64_t flags)
+{
+ unsigned int fixed = 0;
+
+ fixed |= rcar_pcie_fixup(0);
+ fixed |= rcar_pcie_fixup(1);
+
+ if (fixed)
+ return;
+
+ ERROR("Unhandled External Abort received on 0x%lx at EL3!\n",
+ read_mpidr_el1());
+ ERROR(" exception reason=%u syndrome=0x%llx\n", ea_reason, syndrome);
+
+ panic();
+}