aboutsummaryrefslogtreecommitdiff
path: root/plat/marvell/armada
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 04:59:52 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 04:59:52 +0000
commit2beb3a69f30a600ae3ec27334e189649379b9329 (patch)
tree2ce8a4e341ac9f98fb265347777487eda74eba48 /plat/marvell/armada
parent0f2974e30f5150b29f1dff5ec041d74ac687327c (diff)
parent138668cae2394deb5d695c70fe4aa9760c4458ee (diff)
downloadarm-trusted-firmware-2beb3a69f30a600ae3ec27334e189649379b9329.tar.gz
Change-Id: I4cf7f6eba068f9a96359b9ea4386cfb69e72d1ea
Diffstat (limited to 'plat/marvell/armada')
-rw-r--r--plat/marvell/armada/a3k/common/a3700_common.mk10
-rw-r--r--plat/marvell/armada/a3k/common/a3700_ea.c73
-rw-r--r--plat/marvell/armada/a8k/a70x0_mochabin/board/dram_port.c227
-rw-r--r--plat/marvell/armada/a8k/a70x0_mochabin/board/marvell_plat_config.c145
-rw-r--r--plat/marvell/armada/a8k/a70x0_mochabin/board/phy-porting-layer.h87
-rw-r--r--plat/marvell/armada/a8k/a70x0_mochabin/mvebu_def.h15
-rw-r--r--plat/marvell/armada/a8k/a70x0_mochabin/platform.mk20
-rw-r--r--plat/marvell/armada/a8k/common/a8k_common.mk6
-rw-r--r--plat/marvell/armada/a8k/common/ble/ble.mk1
9 files changed, 579 insertions, 5 deletions
diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk
index 0a8974293..d0e86886a 100644
--- a/plat/marvell/armada/a3k/common/a3700_common.mk
+++ b/plat/marvell/armada/a3k/common/a3700_common.mk
@@ -13,7 +13,7 @@ PLAT_INCLUDE_BASE := $(MARVELL_PLAT_INCLUDE_BASE)/$(PLAT_FAMILY)
PLAT_COMMON_BASE := $(PLAT_FAMILY_BASE)/common
MARVELL_DRV_BASE := drivers/marvell
MARVELL_COMMON_BASE := $(MARVELL_PLAT_BASE)/common
-HANDLE_EA_EL3_FIRST := 1
+ERRATA_A53_1530924 := 1
include plat/marvell/marvell.mk
@@ -53,7 +53,6 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \
$(PLAT_COMMON_BASE)/dram_win.c \
$(PLAT_COMMON_BASE)/io_addr_dec.c \
$(PLAT_COMMON_BASE)/marvell_plat_config.c \
- $(PLAT_COMMON_BASE)/a3700_ea.c \
$(PLAT_FAMILY_BASE)/$(PLAT)/plat_bl31_setup.c \
$(MARVELL_COMMON_BASE)/marvell_cci.c \
$(MARVELL_COMMON_BASE)/marvell_ddr_info.c \
@@ -63,6 +62,10 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \
$(PLAT_COMMON_BASE)/a3700_sip_svc.c \
$(MARVELL_DRV)
+ifeq ($(HANDLE_EA_EL3_FIRST),1)
+BL31_SOURCES += $(PLAT_COMMON_BASE)/a3700_ea.c
+endif
+
ifeq ($(CM3_SYSTEM_RESET),1)
BL31_SOURCES += $(PLAT_COMMON_BASE)/cm3_system_reset.c
endif
@@ -73,6 +76,7 @@ endif
ifdef WTP
+# Do not remove! Following checks are required to ensure correct TF-A builds, removing these checks leads to broken TF-A builds
$(if $(wildcard $(value WTP)/*),,$(error "'WTP=$(value WTP)' was specified, but '$(value WTP)' directory does not exist"))
$(if $(shell git -C $(value WTP) rev-parse --show-cdup 2>&1),$(error "'WTP=$(value WTP)' was specified, but '$(value WTP)' does not contain valid A3700-utils-marvell git repository"))
@@ -140,6 +144,7 @@ CRYPTOPP_LIBDIR ?= $(CRYPTOPP_PATH)
CRYPTOPP_INCDIR ?= $(CRYPTOPP_PATH)
$(TBB): FORCE
+# Do not remove! Following checks are required to ensure correct TF-A builds, removing these checks leads to broken TF-A builds
$(if $(CRYPTOPP_LIBDIR),,$(error "Platform '$(PLAT)' for WTP image tool requires CRYPTOPP_PATH or CRYPTOPP_LIBDIR. Please set CRYPTOPP_PATH or CRYPTOPP_LIBDIR to point to the right directory"))
$(if $(CRYPTOPP_INCDIR),,$(error "Platform '$(PLAT)' for WTP image tool requires CRYPTOPP_PATH or CRYPTOPP_INCDIR. Please set CRYPTOPP_PATH or CRYPTOPP_INCDIR to point to the right directory"))
$(if $(wildcard $(CRYPTOPP_LIBDIR)/*),,$(error "Either 'CRYPTOPP_PATH' or 'CRYPTOPP_LIB' was set to '$(CRYPTOPP_LIBDIR)', but '$(CRYPTOPP_LIBDIR)' does not exist"))
@@ -156,6 +161,7 @@ $(BUILD_PLAT)/wtmi.bin: $(WTMI_MULTI_IMG)
$(Q)cp -a $(WTMI_MULTI_IMG) $(BUILD_PLAT)/wtmi.bin
$(TIMDDRTOOL): FORCE
+# Do not remove! Following checks are required to ensure correct TF-A builds, removing these checks leads to broken TF-A builds
$(if $(value MV_DDR_PATH),,$(error "Platform '${PLAT}' for ddr tool requires MV_DDR_PATH. Please set MV_DDR_PATH to point to the right directory"))
$(if $(wildcard $(value MV_DDR_PATH)/*),,$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' directory does not exist"))
$(if $(shell git -C $(value MV_DDR_PATH) rev-parse --show-cdup 2>&1),$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' does not contain valid mv-ddr-marvell git repository"))
diff --git a/plat/marvell/armada/a3k/common/a3700_ea.c b/plat/marvell/armada/a3k/common/a3700_ea.c
index 3a4f7203b..bc12845a5 100644
--- a/plat/marvell/armada/a3k/common/a3700_ea.c
+++ b/plat/marvell/armada/a3k/common/a3700_ea.c
@@ -4,18 +4,87 @@
* SPDX-License-Identifier: BSD-3-Clause
* https://spdx.org/licenses
*/
+
+#include <inttypes.h>
+#include <stdint.h>
+
#include <common/bl_common.h>
#include <common/debug.h>
#include <arch_helpers.h>
#include <plat/common/platform.h>
+#include <bl31/ea_handle.h>
-#define ADVK_SERROR_SYNDROME 0xbf000002
+#define A53_SERR_INT_AXI_SLVERR_ON_EXTERNAL_ACCESS 0xbf000002
+
+#if !ENABLE_BACKTRACE
+static const char *get_el_str(unsigned int el)
+{
+ if (el == MODE_EL3) {
+ return "EL3";
+ } else if (el == MODE_EL2) {
+ return "EL2";
+ }
+ return "S-EL1";
+}
+#endif /* !ENABLE_BACKTRACE */
+/*
+ * This source file with custom plat_ea_handler function is compiled only when
+ * building TF-A with compile option HANDLE_EA_EL3_FIRST=1
+ */
void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
void *handle, uint64_t flags)
{
- if (syndrome == ADVK_SERROR_SYNDROME)
+ unsigned int level = (unsigned int)GET_EL(read_spsr_el3());
+
+ /*
+ * Asynchronous External Abort with syndrome 0xbf000002 on Cortex A53
+ * core means SError interrupt caused by AXI SLVERR on external access.
+ *
+ * In most cases this indicates a bug in U-Boot or Linux kernel driver
+ * pci-aardvark.c which implements access to A3700 PCIe config space.
+ * Driver does not wait for PCIe PIO transfer completion and try to
+ * start a new PCIe PIO transfer while previous has not finished yet.
+ * A3700 PCIe controller in this case sends SLVERR via AXI which results
+ * in a fatal Asynchronous SError interrupt on Cortex A53 CPU.
+ *
+ * Following patches fix that bug in U-Boot and Linux kernel drivers:
+ * https://source.denx.de/u-boot/u-boot/-/commit/eccbd4ad8e4e182638eafbfb87ac139c04f24a01
+ * https://git.kernel.org/stable/c/f18139966d072dab8e4398c95ce955a9742e04f7
+ *
+ * As a hacky workaround for unpatched U-Boot and Linux kernel drivers
+ * ignore all asynchronous aborts with that syndrome value received on
+ * CPU from level lower than EL3.
+ *
+ * Because these aborts are delivered on CPU asynchronously, they are
+ * imprecise and we cannot check the real reason of abort and neither
+ * who and why sent this abort. We expect that on A3700 it is always
+ * PCIe controller.
+ *
+ * Hence ignoring all aborts with this syndrome value is just a giant
+ * hack that we need only because of bugs in old U-Boot and Linux kernel
+ * versions and because it was decided that TF-A would implement this
+ * hack for U-Boot and Linux kernel it in this way. New patched U-Boot
+ * and kernel versions do not need it anymore.
+ *
+ * Links to discussion about this workaround:
+ * https://lore.kernel.org/linux-pci/20190316161243.29517-1-repk@triplefau.lt/
+ * https://lore.kernel.org/linux-pci/971be151d24312cc533989a64bd454b4@www.loen.fr/
+ * https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/1541
+ */
+ if (level < MODE_EL3 && ea_reason == ERROR_EA_ASYNC &&
+ syndrome == A53_SERR_INT_AXI_SLVERR_ON_EXTERNAL_ACCESS) {
+ ERROR_NL();
+ ERROR("Ignoring Asynchronous External Abort with"
+ " syndrome 0x%" PRIx64 " received on 0x%lx from %s\n",
+ syndrome, read_mpidr_el1(), get_el_str(level));
+ ERROR("SError interrupt: AXI SLVERR on external access\n");
+ ERROR("This indicates a bug in pci-aardvark.c driver\n");
+ ERROR("Please update U-Boot/Linux to the latest version\n");
+ ERROR_NL();
+ console_flush();
return;
+ }
plat_default_ea_handler(ea_reason, syndrome, cookie, handle, flags);
}
diff --git a/plat/marvell/armada/a8k/a70x0_mochabin/board/dram_port.c b/plat/marvell/armada/a8k/a70x0_mochabin/board/dram_port.c
new file mode 100644
index 000000000..68d335b63
--- /dev/null
+++ b/plat/marvell/armada/a8k/a70x0_mochabin/board/dram_port.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2021 Sartura Ltd.
+ * Copyright (C) 2021 Globalscale technologies, Inc.
+ * Copyright (C) 2021 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+
+#include <mv_ddr_if.h>
+#include <plat_marvell.h>
+
+/*
+ * This function may modify the default DRAM parameters
+ * based on information received from SPD or bootloader
+ * configuration located on non volatile storage
+ */
+void plat_marvell_dram_update_topology(void)
+{
+}
+
+/*
+ * This struct provides the DRAM training code with
+ * the appropriate board DRAM configuration
+ */
+#if DDR_TOPOLOGY == 0
+static struct mv_ddr_topology_map board_topology_map_2g = {
+/* 1CS 4Gb x4 devices of Samsung K4A4G085WF */
+ DEBUG_LEVEL_ERROR,
+ 0x1, /* active interfaces */
+ /* cs_mask, mirror, dqs_swap, ck_swap X subphys */
+ { { { {0x1, 0x2, 0, 0},
+ {0x1, 0x2, 0, 0},
+ {0x1, 0x2, 0, 0},
+ {0x1, 0x2, 0, 0},
+ {0x1, 0x2, 0, 0},
+ {0x1, 0x2, 0, 0},
+ {0x1, 0x2, 0, 0},
+ {0x1, 0x2, 0, 0},
+ {0x1, 0x2, 0, 0} },
+ SPEED_BIN_DDR_2400R, /* speed_bin */
+ MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */
+ MV_DDR_DIE_CAP_4GBIT, /* die capacity */
+ MV_DDR_FREQ_SAR, /* frequency */
+ 0, 0, /* cas_l, cas_wl */
+ MV_DDR_TEMP_LOW} }, /* temperature */
+ BUS_MASK_32BIT, /* subphys mask */
+ MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
+ NOT_COMBINED, /* ddr twin-die combined*/
+ { {0} }, /* raw spd data */
+ {0}, /* timing parameters */
+ { /* electrical configuration */
+ { /* memory electrical configuration */
+ MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */
+ {
+ MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */
+ MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */
+ },
+ {
+ MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */
+ MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */
+ },
+ MV_DDR_DIC_RZQ_DIV7 /* dic */
+ },
+ { /* phy electrical configuration */
+ MV_DDR_OHM_30, /* data_drv_p */
+ MV_DDR_OHM_30, /* data_drv_n */
+ MV_DDR_OHM_30, /* ctrl_drv_p */
+ MV_DDR_OHM_30, /* ctrl_drv_n */
+ {
+ MV_DDR_OHM_60, /* odt_p 1cs */
+ MV_DDR_OHM_120 /* odt_p 2cs */
+ },
+ {
+ MV_DDR_OHM_60, /* odt_n 1cs */
+ MV_DDR_OHM_120 /* odt_n 2cs */
+ },
+ },
+ { /* mac electrical configuration */
+ MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */
+ MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */
+ MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */
+ },
+ }
+};
+#endif
+
+#if DDR_TOPOLOGY == 1
+static struct mv_ddr_topology_map board_topology_map_4g = {
+/* 1CS 8Gb x4 devices of Samsung K4A8G085WC-BCTD */
+ DEBUG_LEVEL_ERROR,
+ 0x1, /* active interfaces */
+ /* cs_mask, mirror, dqs_swap, ck_swap X subphys */
+ { { { {0x1, 0x2, 0, 0},
+ {0x1, 0x2, 0, 0},
+ {0x1, 0x2, 0, 0},
+ {0x1, 0x2, 0, 0},
+ {0x1, 0x2, 0, 0},
+ {0x1, 0x2, 0, 0},
+ {0x1, 0x2, 0, 0},
+ {0x1, 0x2, 0, 0},
+ {0x1, 0x2, 0, 0} },
+ SPEED_BIN_DDR_2400R, /* speed_bin */
+ MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */
+ MV_DDR_DIE_CAP_8GBIT, /* die capacity */
+ MV_DDR_FREQ_SAR, /* frequency */
+ 0, 0, /* cas_l, cas_wl */
+ MV_DDR_TEMP_LOW} }, /* temperature */
+ BUS_MASK_32BIT, /* subphys mask */
+ MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
+ NOT_COMBINED, /* ddr twin-die combined*/
+ { {0} }, /* raw spd data */
+ {0}, /* timing parameters */
+ { /* electrical configuration */
+ { /* memory electrical configuration */
+ MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */
+ {
+ MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */
+ MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */
+ },
+ {
+ MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */
+ MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */
+ },
+ MV_DDR_DIC_RZQ_DIV7 /* dic */
+ },
+ { /* phy electrical configuration */
+ MV_DDR_OHM_30, /* data_drv_p */
+ MV_DDR_OHM_30, /* data_drv_n */
+ MV_DDR_OHM_30, /* ctrl_drv_p */
+ MV_DDR_OHM_30, /* ctrl_drv_n */
+ {
+ MV_DDR_OHM_60, /* odt_p 1cs */
+ MV_DDR_OHM_120 /* odt_p 2cs */
+ },
+ {
+ MV_DDR_OHM_60, /* odt_n 1cs */
+ MV_DDR_OHM_120 /* odt_n 2cs */
+ },
+ },
+ { /* mac electrical configuration */
+ MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */
+ MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */
+ MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */
+ },
+ }
+};
+#endif
+
+#if DDR_TOPOLOGY == 2
+static struct mv_ddr_topology_map board_topology_map_8g = {
+/* 2CS 8Gb x8 devices of Micron MT40A1G8WE-083E IT */
+ DEBUG_LEVEL_ERROR,
+ 0x1, /* active interfaces */
+ /* cs_mask, mirror, dqs_swap, ck_swap X subphys */
+ { { { {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0} },
+ SPEED_BIN_DDR_2400R, /* speed_bin */
+ MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */
+ MV_DDR_DIE_CAP_8GBIT, /* die capacity */
+ MV_DDR_FREQ_SAR, /* frequency */
+ 0, 0, /* cas_l, cas_wl */
+ MV_DDR_TEMP_LOW} }, /* temperature */
+ BUS_MASK_32BIT, /* subphys mask */
+ MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
+ NOT_COMBINED, /* ddr twin-die combined*/
+ { {0} }, /* raw spd data */
+ {0}, /* timing parameters */
+ { /* electrical configuration */
+ { /* memory electrical configuration */
+ MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */
+ {
+ MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */
+ MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */
+ },
+ {
+ MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */
+ MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */
+ },
+ MV_DDR_DIC_RZQ_DIV7 /* dic */
+ },
+ { /* phy electrical configuration */
+ MV_DDR_OHM_30, /* data_drv_p */
+ MV_DDR_OHM_30, /* data_drv_n */
+ MV_DDR_OHM_30, /* ctrl_drv_p */
+ MV_DDR_OHM_30, /* ctrl_drv_n */
+ {
+ MV_DDR_OHM_60, /* odt_p 1cs */
+ MV_DDR_OHM_120 /* odt_p 2cs */
+ },
+ {
+ MV_DDR_OHM_60, /* odt_n 1cs */
+ MV_DDR_OHM_120 /* odt_n 2cs */
+ },
+ },
+ { /* mac electrical configuration */
+ MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */
+ MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */
+ MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */
+ },
+ }
+};
+#endif
+
+struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
+{
+/* a70x0_mochabin board supports 3 DDR4 models (2G/1CS, 4G/1CS, 8G/2CS) */
+#if DDR_TOPOLOGY == 0
+ return &board_topology_map_2g;
+#elif DDR_TOPOLOGY == 1
+ return &board_topology_map_4g;
+#elif DDR_TOPOLOGY == 2
+ return &board_topology_map_8g;
+#else
+ #error "Unknown DDR topology"
+#endif
+}
diff --git a/plat/marvell/armada/a8k/a70x0_mochabin/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a70x0_mochabin/board/marvell_plat_config.c
new file mode 100644
index 000000000..1ed63237a
--- /dev/null
+++ b/plat/marvell/armada/a8k/a70x0_mochabin/board/marvell_plat_config.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2021 Sartura Ltd.
+ * Copyright (C) 2021 Globalscale technologies, Inc.
+ * Copyright (C) 2021 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <armada_common.h>
+
+/*
+ * If bootrom is currently at BLE there's no need to include the memory
+ * maps structure at this point
+ */
+#include <mvebu_def.h>
+#ifndef IMAGE_BLE
+
+/*****************************************************************************
+ * AMB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win amb_memory_map[] = {
+ /* CP0 SPI1 CS0 Direct Mode access */
+ {0xf900, 0x1000000, AMB_SPI1_CS0_ID},
+};
+
+int marvell_get_amb_memory_map(struct addr_map_win **win,
+ uint32_t *size, uintptr_t base)
+{
+ *win = amb_memory_map;
+ if (*win == NULL)
+ *size = 0;
+ else
+ *size = ARRAY_SIZE(amb_memory_map);
+
+ return 0;
+}
+#endif
+
+/*****************************************************************************
+ * IO_WIN Configuration
+ *****************************************************************************
+ */
+struct addr_map_win io_win_memory_map[] = {
+#ifndef IMAGE_BLE
+ /* MCI 0 indirect window */
+ {MVEBU_MCI_REG_BASE_REMAP(0), 0x100000, MCI_0_TID},
+ /* MCI 1 indirect window */
+ {MVEBU_MCI_REG_BASE_REMAP(1), 0x100000, MCI_1_TID},
+#endif
+};
+
+uint32_t marvell_get_io_win_gcr_target(int ap_index)
+{
+ return PIDI_TID;
+}
+
+int marvell_get_io_win_memory_map(int ap_index, struct addr_map_win **win,
+ uint32_t *size)
+{
+ *win = io_win_memory_map;
+ if (*win == NULL)
+ *size = 0;
+ else
+ *size = ARRAY_SIZE(io_win_memory_map);
+
+ return 0;
+}
+
+#ifndef IMAGE_BLE
+/*****************************************************************************
+ * IOB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win iob_memory_map[] = {
+ /* PEX1_X1 window */
+ {0x00000000f7000000, 0x1000000, PEX1_TID},
+ /* PEX2_X1 window */
+ {0x00000000f8000000, 0x1000000, PEX2_TID},
+ {0x00000000c0000000, 0x30000000, PEX2_TID},
+ {0x0000000800000000, 0x100000000, PEX2_TID},
+ /* PEX0_X4 window */
+ {0x00000000f6000000, 0x1000000, PEX0_TID},
+ /* SPI1_CS0 (RUNIT) window */
+ {0x00000000f9000000, 0x1000000, RUNIT_TID},
+};
+
+int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size,
+ uintptr_t base)
+{
+ *win = iob_memory_map;
+ *size = ARRAY_SIZE(iob_memory_map);
+
+ return 0;
+}
+#endif
+
+/*****************************************************************************
+ * CCU Configuration
+ *****************************************************************************
+ */
+struct addr_map_win ccu_memory_map[] = { /* IO window */
+#ifdef IMAGE_BLE
+ {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */
+#else
+#if LLC_SRAM
+ /* This entry is prepared for OP-TEE OS that enables the LLC SRAM
+ * and changes the window target to SRAM_TID.
+ */
+ {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, DRAM_0_TID},
+#endif
+ {0x00000000f2000000, 0xe000000, IO_0_TID},
+ {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */
+ {0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */
+#endif
+};
+
+uint32_t marvell_get_ccu_gcr_target(int ap)
+{
+ return DRAM_0_TID;
+}
+
+int marvell_get_ccu_memory_map(int ap_index, struct addr_map_win **win,
+ uint32_t *size)
+{
+ *win = ccu_memory_map;
+ *size = ARRAY_SIZE(ccu_memory_map);
+
+ return 0;
+}
+
+#ifdef IMAGE_BLE
+/*****************************************************************************
+ * SKIP IMAGE Configuration
+ *****************************************************************************
+ */
+#if PLAT_RECOVERY_IMAGE_ENABLE
+void *plat_marvell_get_skip_image_data(void)
+{
+ /* No recovery button on a70x0_mochabin board */
+ return NULL;
+}
+#endif
+#endif
diff --git a/plat/marvell/armada/a8k/a70x0_mochabin/board/phy-porting-layer.h b/plat/marvell/armada/a8k/a70x0_mochabin/board/phy-porting-layer.h
new file mode 100644
index 000000000..ab76c3105
--- /dev/null
+++ b/plat/marvell/armada/a8k/a70x0_mochabin/board/phy-porting-layer.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2021 Sartura Ltd.
+ * Copyright (C) 2021 Globalscale technologies, Inc.
+ * Copyright (C) 2021 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __PHY_PORTING_LAYER_H
+#define __PHY_PORTING_LAYER_H
+
+#define MAX_LANE_NR 6
+
+static const struct xfi_params
+ xfi_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = {
+ /* AP0 */
+ {
+ /* CP 0 */
+ {
+ { 0 }, /* Comphy0 */
+ { 0 }, /* Comphy1 */
+ { 0 }, /* Comphy2 */
+ { 0 }, /* Comphy3 */
+ { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, .align90 = 0x60,
+ .g1_dfe_res = 0x1, .g1_amp = 0x1c, .g1_emph = 0xe,
+ .g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1, .g1_tx_emph_en = 0x1,
+ .g1_tx_emph = 0x0, .g1_rx_selmuff = 0x1, .g1_rx_selmufi = 0x0,
+ .g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2,
+ .valid = 1 }, /* Comphy4 */
+ { 0 }, /* Comphy5 */
+ },
+ },
+};
+
+static const struct sata_params
+ sata_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = {
+ /* AP0 */
+ {
+ /* CP 0 */
+ {
+ { 0 }, /* Comphy0 */
+ { 0 }, /* Comphy1 */
+ { .g1_amp = 0x8, .g2_amp = 0xa, .g3_amp = 0x1e,
+ .g1_emph = 0x1, .g2_emph = 0x2, .g3_emph = 0xe,
+ .g1_emph_en = 0x1, .g2_emph_en = 0x1, .g3_emph_en = 0x1,
+ .g1_tx_amp_adj = 0x1, .g2_tx_amp_adj = 0x1, .g3_tx_amp_adj = 0x1,
+ .g1_tx_emph_en = 0x0, .g2_tx_emph_en = 0x0, .g3_tx_emph_en = 0x0,
+ .g1_tx_emph = 0x1, .g2_tx_emph = 0x1, .g3_tx_emph = 0x1,
+ .g3_dfe_res = 0x1, .g3_ffe_res_sel = 0x4, .g3_ffe_cap_sel = 0xf,
+ .align90 = 0x61,
+ .g1_rx_selmuff = 0x3, .g2_rx_selmuff = 0x3, .g3_rx_selmuff = 0x3,
+ .g1_rx_selmufi = 0x0, .g2_rx_selmufi = 0x0, .g3_rx_selmufi = 0x3,
+ .g1_rx_selmupf = 0x1, .g2_rx_selmupf = 0x1, .g3_rx_selmupf = 0x2,
+ .g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0, .g3_rx_selmupi = 0x2,
+ .polarity_invert = COMPHY_POLARITY_NO_INVERT,
+ .valid = 0x1
+ }, /* Comphy2 */
+ { .g1_amp = 0x8, .g2_amp = 0xa, .g3_amp = 0x1e,
+ .g1_emph = 0x1, .g2_emph = 0x2, .g3_emph = 0xe,
+ .g1_emph_en = 0x1, .g2_emph_en = 0x1, .g3_emph_en = 0x1,
+ .g1_tx_amp_adj = 0x1, .g2_tx_amp_adj = 0x1, .g3_tx_amp_adj = 0x1,
+ .g1_tx_emph_en = 0x0, .g2_tx_emph_en = 0x0, .g3_tx_emph_en = 0x0,
+ .g1_tx_emph = 0x1, .g2_tx_emph = 0x1, .g3_tx_emph = 0x1,
+ .g3_dfe_res = 0x1, .g3_ffe_res_sel = 0x4, .g3_ffe_cap_sel = 0xf,
+ .align90 = 0x61,
+ .g1_rx_selmuff = 0x3, .g2_rx_selmuff = 0x3, .g3_rx_selmuff = 0x3,
+ .g1_rx_selmufi = 0x0, .g2_rx_selmufi = 0x0, .g3_rx_selmufi = 0x3,
+ .g1_rx_selmupf = 0x1, .g2_rx_selmupf = 0x1, .g3_rx_selmupf = 0x2,
+ .g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0, .g3_rx_selmupi = 0x2,
+ .polarity_invert = COMPHY_POLARITY_NO_INVERT,
+ .valid = 0x1
+ }, /* Comphy3 */
+ { 0 }, /* Comphy4 */
+ { 0 }, /* Comphy5 */
+ },
+ },
+};
+
+static const struct usb_params
+ usb_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = {
+ [0 ... AP_NUM-1][0 ... CP_NUM-1][0 ... MAX_LANE_NR-1] = {
+ .polarity_invert = COMPHY_POLARITY_NO_INVERT
+ },
+};
+
+#endif /* __PHY_PORTING_LAYER_H */
diff --git a/plat/marvell/armada/a8k/a70x0_mochabin/mvebu_def.h b/plat/marvell/armada/a8k/a70x0_mochabin/mvebu_def.h
new file mode 100644
index 000000000..768f73596
--- /dev/null
+++ b/plat/marvell/armada/a8k/a70x0_mochabin/mvebu_def.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2021 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef MVEBU_DEF_H
+#define MVEBU_DEF_H
+
+#include <a8k_plat_def.h>
+
+#define CP_COUNT 1 /* A70x0 has single CP0 */
+
+#endif /* MVEBU_DEF_H */
diff --git a/plat/marvell/armada/a8k/a70x0_mochabin/platform.mk b/plat/marvell/armada/a8k/a70x0_mochabin/platform.mk
new file mode 100644
index 000000000..2495591ae
--- /dev/null
+++ b/plat/marvell/armada/a8k/a70x0_mochabin/platform.mk
@@ -0,0 +1,20 @@
+#
+# Copyright (C) 2021 Marvell International Ltd.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+# https://spdx.org/licenses
+#
+
+PCI_EP_SUPPORT := 0
+
+CP_NUM := 1
+$(eval $(call add_define,CP_NUM))
+
+DOIMAGE_SEC := tools/doimage/secure/sec_img_7K.cfg
+
+MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c
+
+BOARD_DIR := $(shell dirname $(lastword $(MAKEFILE_LIST)))
+include plat/marvell/armada/a8k/common/a8k_common.mk
+
+include plat/marvell/armada/common/marvell_common.mk
diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk
index 30e6280e7..4d8a87fd1 100644
--- a/plat/marvell/armada/a8k/common/a8k_common.mk
+++ b/plat/marvell/armada/a8k/common/a8k_common.mk
@@ -75,6 +75,10 @@ endif
# This define specifies DDR type for BLE
$(eval $(call add_define,CONFIG_DDR4))
+# This define specifies DDR topology for BLE
+DDR_TOPOLOGY ?= 0
+$(eval $(call add_define,DDR_TOPOLOGY))
+
MARVELL_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
drivers/arm/gic/v2/gicv2_main.c \
drivers/arm/gic/v2/gicv2_helpers.c \
@@ -166,7 +170,7 @@ endif
BLE_PATH ?= $(PLAT_COMMON_BASE)/ble
include ${BLE_PATH}/ble.mk
-$(eval $(call MAKE_BL,e))
+$(eval $(call MAKE_BL,ble))
clean realclean distclean: mrvl_clean
diff --git a/plat/marvell/armada/a8k/common/ble/ble.mk b/plat/marvell/armada/a8k/common/ble/ble.mk
index 87e2ce020..160e98f12 100644
--- a/plat/marvell/armada/a8k/common/ble/ble.mk
+++ b/plat/marvell/armada/a8k/common/ble/ble.mk
@@ -28,6 +28,7 @@ $(BLE_OBJS): PLAT_INCLUDES += -I$(MV_DDR_PATH)
$(BLE_OBJS): $(MV_DDR_LIB)
$(MV_DDR_LIB): FORCE
+# Do not remove! Following checks are required to ensure correct TF-A builds, removing these checks leads to broken TF-A builds
$(if $(value MV_DDR_PATH),,$(error "Platform '$(PLAT)' for BLE requires MV_DDR_PATH. Please set MV_DDR_PATH to point to the right directory"))
$(if $(wildcard $(value MV_DDR_PATH)/*),,$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' directory does not exist"))
$(if $(shell git -C $(value MV_DDR_PATH) rev-parse --show-cdup 2>&1),$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' does not contain valid mv-ddr-marvell git repository"))