Merge "refactor(bl): remove un-necessary variable" into integration
diff --git a/.editorconfig b/.editorconfig
index 12f786d..1b29c88 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -70,3 +70,6 @@
# [PEP8] Maximum Line Length
# "Limit all lines to a maximum of 79 characters."
max_line_length = 79
+
+[.git/COMMIT_EDITMSG]
+max_line_length = 72
diff --git a/Makefile b/Makefile
index 179e07a..f736a3b 100644
--- a/Makefile
+++ b/Makefile
@@ -597,19 +597,11 @@
################################################################################
# FEAT_RME
ifeq (${ENABLE_RME},1)
- # RME doesn't support BRBE
- ENABLE_BRBE_FOR_NS := 0
-
# RME doesn't support PIE
ifneq (${ENABLE_PIE},0)
$(error ENABLE_RME does not support PIE)
endif
- # RME doesn't support BRBE
- ifneq (${ENABLE_BRBE_FOR_NS},0)
- $(error ENABLE_RME does not support BRBE.)
- endif
-
# RME requires AARCH64
ifneq (${ARCH},aarch64)
$(error ENABLE_RME requires AArch64)
@@ -654,6 +646,13 @@
endif
################################################################################
+# Make 128-Bit sysreg read/writes availabe when FEAT_D128 is enabled.
+################################################################################
+ifneq (${ENABLE_FEAT_D128}, 0)
+ BL_COMMON_SOURCES += lib/extensions/sysreg128/sysreg128.S
+endif
+
+################################################################################
# Platform specific Makefile might provide us ARCH_MAJOR/MINOR use that to come
# up with appropriate march values for compiler.
################################################################################
@@ -1177,6 +1176,7 @@
HW_ASSISTED_COHERENCY \
MEASURED_BOOT \
DICE_PROTECTION_ENVIRONMENT \
+ RMMD_ENABLE_EL3_TOKEN_SIGN \
DRTM_SUPPORT \
NS_TIMER_SWITCH \
OVERRIDE_LIBC \
@@ -1263,11 +1263,14 @@
ENABLE_FEAT_RNG_TRAP \
ENABLE_FEAT_SEL2 \
ENABLE_FEAT_TCR2 \
+ ENABLE_FEAT_THE \
ENABLE_FEAT_SB \
ENABLE_FEAT_S2PIE \
ENABLE_FEAT_S1PIE \
ENABLE_FEAT_S2POE \
ENABLE_FEAT_S1POE \
+ ENABLE_FEAT_SCTLR2 \
+ ENABLE_FEAT_D128 \
ENABLE_FEAT_GCS \
ENABLE_FEAT_VHE \
ENABLE_FEAT_MPAM \
@@ -1331,6 +1334,7 @@
ENABLE_PMF \
ENABLE_PSCI_STAT \
ENABLE_RME \
+ RMMD_ENABLE_EL3_TOKEN_SIGN \
ENABLE_RUNTIME_INSTRUMENTATION \
ENABLE_SME_FOR_NS \
ENABLE_SME2_FOR_NS \
@@ -1419,10 +1423,13 @@
ENABLE_FEAT_CSV2_3 \
ENABLE_FEAT_PAN \
ENABLE_FEAT_TCR2 \
+ ENABLE_FEAT_THE \
ENABLE_FEAT_S2PIE \
ENABLE_FEAT_S1PIE \
ENABLE_FEAT_S2POE \
ENABLE_FEAT_S1POE \
+ ENABLE_FEAT_SCTLR2 \
+ ENABLE_FEAT_D128 \
ENABLE_FEAT_GCS \
ENABLE_FEAT_MTE2 \
FEATURE_DETECTION \
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index e47b082..7423805 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -229,7 +229,6 @@
save_x30
apply_at_speculative_wa
sync_and_handle_pending_serror
- unmask_async_ea
handle_sync_exception
end_vector_entry sync_exception_aarch64
@@ -237,7 +236,6 @@
save_x30
apply_at_speculative_wa
sync_and_handle_pending_serror
- unmask_async_ea
b handle_interrupt_exception
end_vector_entry irq_aarch64
@@ -245,7 +243,6 @@
save_x30
apply_at_speculative_wa
sync_and_handle_pending_serror
- unmask_async_ea
b handle_interrupt_exception
end_vector_entry fiq_aarch64
@@ -258,7 +255,6 @@
save_x30
apply_at_speculative_wa
sync_and_handle_pending_serror
- unmask_async_ea
b handle_lower_el_async_ea
#else
b report_unhandled_exception
@@ -279,7 +275,6 @@
save_x30
apply_at_speculative_wa
sync_and_handle_pending_serror
- unmask_async_ea
handle_sync_exception
end_vector_entry sync_exception_aarch32
@@ -287,7 +282,6 @@
save_x30
apply_at_speculative_wa
sync_and_handle_pending_serror
- unmask_async_ea
b handle_interrupt_exception
end_vector_entry irq_aarch32
@@ -295,7 +289,6 @@
save_x30
apply_at_speculative_wa
sync_and_handle_pending_serror
- unmask_async_ea
b handle_interrupt_exception
end_vector_entry fiq_aarch32
@@ -308,7 +301,6 @@
save_x30
apply_at_speculative_wa
sync_and_handle_pending_serror
- unmask_async_ea
b handle_lower_el_async_ea
#else
b report_unhandled_exception
diff --git a/changelog.yaml b/changelog.yaml
index 5224441..3591f02 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -900,6 +900,9 @@
- title: Console
scope: console
+ - title: Delay Timer
+ scope: delay-timer
+
- title: Generic Clock
scope: clk
diff --git a/common/feat_detect.c b/common/feat_detect.c
index 9b9f7b4..6aa5e2e 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -257,6 +257,24 @@
}
+static unsigned int read_feat_the_id_field(void)
+{
+ return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_THE_SHIFT,
+ ID_AA64PFR1_EL1_THE_MASK);
+}
+
+static unsigned int read_feat_sctlr2_id_field(void)
+{
+ return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_SCTLR2_SHIFT,
+ ID_AA64MMFR3_EL1_SCTLR2_MASK);
+}
+
+static unsigned int read_feat_d128_id_field(void)
+{
+ return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_D128_SHIFT,
+ ID_AA64MMFR3_EL1_D128_MASK);
+}
+
/***********************************************************************************
* TF-A supports many Arm architectural features starting from arch version
* (8.0 till 8.7+). These features are mostly enabled through build flags. This
@@ -365,6 +383,10 @@
"CSV2_3", 3, 3);
check_feature(ENABLE_FEAT_DEBUGV8P9, read_feat_debugv8p9_id_field(),
"DEBUGV8P9", 11, 11);
+ check_feature(ENABLE_FEAT_THE, read_feat_the_id_field(),
+ "THE", 1, 1);
+ check_feature(ENABLE_FEAT_SCTLR2, read_feat_sctlr2_id_field(),
+ "SCTLR2", 1, 1);
/* v9.0 features */
check_feature(ENABLE_BRBE_FOR_NS, read_feat_brbe_id_field(),
@@ -378,6 +400,10 @@
check_feature(ENABLE_SME2_FOR_NS, read_feat_sme_id_field(),
"SME2", 2, 2);
+ /* v9.3 features */
+ check_feature(ENABLE_FEAT_D128, read_feat_d128_id_field(),
+ "D128", 1, 1);
+
/* v9.4 features */
check_feature(ENABLE_FEAT_GCS, read_feat_gcs_id_field(), "GCS", 1, 1);
check_feature(ENABLE_RME, read_feat_rme_id_field(), "RME", 1, 1);
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 4d08a7f..03526a6 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -49,12 +49,14 @@
:|G|: `laurenw-arm`_
:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
:|G|: `madhukar-Arm`_
-:|M|: Raghu Krishnamurthy <raghu.ncstate@icloud.com>
+:|M|: Raghu Krishnamurthy <raghuoss@raghushome.com>
:|G|: `raghuncstate`_
:|M|: Manish Badarkhe <manish.badarkhe@arm.com>
:|G|: `ManishVB-Arm`_
:|M|: Yann Gautier <yann.gautier@st.com>
:|G|: `Yann-lms`_
+:|M|: Govindraj Raja <govindraj.raja@arm.com>
+:|G|: `govindraj-arm`_
LTS Maintainers
---------------
@@ -1016,7 +1018,7 @@
:|G|: `sandrine-bailleux-arm`_
:|M|: Joanna Farley <joanna.farley@arm.com>
:|G|: `joannafarley-arm`_
-:|M|: Raghu Krishnamurthy <raghu.ncstate@icloud.com>
+:|M|: Raghu Krishnamurthy <raghuoss@raghushome.com>
:|G|: `raghuncstate`_
:|M|: Varun Wadekar <vwadekar@nvidia.com>
:|G|: `vwadekar`_
@@ -1055,6 +1057,7 @@
.. _divin-raj: https://github.com/divin-raj
.. _etienne-lms: https://github.com/etienne-lms
.. _glneo: https://github.com/glneo
+.. _govindraj-arm: https://github.com/govindraj-arm
.. _gprocopciucnxp: https://github.com/gprocopciucnxp
.. _grandpaul: https://github.com/grandpaul
.. _harrisonmutai-arm: https://github.com/harrisonmutai-arm
diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst
index 7fe58f8..9d6bbf6 100644
--- a/docs/about/release-information.rst
+++ b/docs/about/release-information.rst
@@ -72,6 +72,8 @@
+-----------------+---------------------------+------------------------------+
| v2.12 | 4th week of Nov '24 | 2nd week of Nov '24 |
+-----------------+---------------------------+------------------------------+
+| v2.13 | 4th week of May '25 | 2nd week of May '25 |
++-----------------+---------------------------+------------------------------+
Removal of Deprecated Interfaces
--------------------------------
@@ -111,9 +113,9 @@
+-----------------------+--------------------------------+
| Build Option | Deprecated from TF-A Version |
+=======================+================================+
-| CTX_INCLUDE_MTE_REGS | 2.11 |
+| | |
+-----------------------+--------------------------------+
-| ENABLE_FEAT_MTE | 2.11 |
+| | |
+-----------------------+--------------------------------+
--------------
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index 220c3ce..a181204 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -110,7 +110,7 @@
- Only Arm's FVP platform is supported to use with the TF-A reference software
stack.
- When ``SPMD_SPM_AT_SEL2=1``, the reference software stack assumes enablement
- of FEAT_PAuth, FEAT_BTI and FEAT_MTE architecture extensions.
+ of FEAT_PAuth, FEAT_BTI and FEAT_MTE2 architecture extensions.
- ``(*) CTX_INCLUDE_EL2_REGS``, this flag is |TF-A| internal and informational
in this table. When set, it provides the generic support for saving/restoring
EL2 registers required when S-EL2 firmware is present.
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 203bf0f..772447a 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -455,6 +455,31 @@
the values 0 to 2, to align with the ``ENABLE_FEAT`` mechanism.
Default value is ``0``.
+- ``ENABLE_FEAT_THE``: Numeric value to enable support for FEAT_THE
+ (Translation Hardening Extension) at EL2 and below, setting the bit
+ SCR_EL3.RCWMASKEn in EL3 to allow access to RCWMASK_EL1 and RCWSMASK_EL1
+ registers and context switch them.
+ Its an optional architectural feature and is available from v8.8 and upwards.
+ This flag can take the values 0 to 2, to align with the ``ENABLE_FEAT``
+ mechanism. Default value is ``0``.
+
+- ``ENABLE_FEAT_SCTLR2``: Numeric value to enable support for FEAT_SCTLR2
+ (Extension to SCTLR_ELx) at EL2 and below, setting the bit
+ SCR_EL3.SCTLR2En in EL3 to allow access to SCTLR2_ELx registers and
+ context switch them. This feature is OPTIONAL from Armv8.0 implementations
+ and mandatory in Armv8.9 implementations.
+ This flag can take the values 0 to 2, to align with the ``ENABLE_FEAT``
+ mechanism. Default value is ``0``.
+
+- ``ENABLE_FEAT_D128``: Numeric value to enable support for FEAT_D128
+ at EL2 and below, setting the bit SCT_EL3.D128En in EL3 to allow access to
+ 128 bit version of system registers like PAR_EL1, TTBR0_EL1, TTBR1_EL1,
+ TTBR0_EL2, TTBR1_EL2, TTBR0_EL12, TTBR1_EL12 , VTTBR_EL2, RCWMASK_EL1, and
+ RCWSMASK_EL1. Its an optional architectural feature and is available from
+ 9.3 and upwards.
+ This flag can take the values 0 to 2, to align with the ``ENABLE_FEAT``
+ mechanism. Default value is ``0``.
+
- ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
support in GCC for TF-A. This option is currently only supported for
AArch64. Default is 0.
diff --git a/drivers/arm/dcc/dcc_console.c b/drivers/arm/dcc/dcc_console.c
index 19c3450..841c1fd 100644
--- a/drivers/arm/dcc/dcc_console.c
+++ b/drivers/arm/dcc/dcc_console.c
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2015-2021, Xilinx Inc.
+ * Copyright (c) 2015-2022, Xilinx Inc.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
* Written by Michal Simek.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -45,7 +46,7 @@
#define TIMEOUT_COUNT_US U(0x10624)
struct dcc_console {
- struct console console;
+ console_t console;
};
static inline uint32_t __dcc_getstatus(void)
@@ -147,13 +148,14 @@
},
};
-int console_dcc_register(void)
+int console_dcc_register(console_t *console)
{
- return console_register(&dcc_console.console);
+ memcpy(console, &dcc_console.console, sizeof(console_t));
+ return console_register(console);
}
-void console_dcc_unregister(void)
+void console_dcc_unregister(console_t *console)
{
- dcc_console_flush(&dcc_console.console);
- (void)console_unregister(&dcc_console.console);
+ dcc_console_flush(console);
+ (void)console_unregister(console);
}
diff --git a/drivers/cadence/emmc/cdns_sdmmc.c b/drivers/cadence/emmc/cdns_sdmmc.c
index d2cd4d6..892d333 100644
--- a/drivers/cadence/emmc/cdns_sdmmc.c
+++ b/drivers/cadence/emmc/cdns_sdmmc.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,35 +19,6 @@
#include <lib/mmio.h>
#include <lib/utils.h>
-/* Card busy and present */
-#define CARD_BUSY 1
-#define CARD_NOT_BUSY 0
-
-/* 500 ms delay to read the RINST register */
-#define DELAY_MS_SRS_READ 500
-#define DELAY_RES 10
-
-/* SRS12 error mask */
-#define SRS12_ERR_MASK 0xFFFF8000
-
-/* Check DV dfi_init val=0 */
-#define IO_MASK_END_DATA 0x0
-
-/* Check DV dfi_init val=2; DDR Mode */
-#define IO_MASK_END_DATA_DDR 0x2
-#define IO_MASK_START_DATA 0x0
-#define DATA_SELECT_OE_END_DATA 0x1
-
-#define TIMEOUT 100000
-
-/* General define */
-#define SDHC_REG_MASK UINT_MAX
-#define SD_HOST_BLOCK_SIZE 0x200
-#define DTCVVAL_DEFAULT_VAL 0xE
-#define CDMMC_DMA_MAX_BUFFER_SIZE 64*1024
-#define CDNSMMC_ADDRESS_MASK U(0x0f)
-#define CONFIG_CDNS_DESC_COUNT 8
-
void cdns_init(void);
int cdns_send_cmd(struct mmc_cmd *cmd);
int cdns_set_ios(unsigned int clk, unsigned int width);
@@ -62,7 +34,8 @@
.read = cdns_read,
.write = cdns_write,
};
-
+void sd_host_adma_prepare(struct cdns_idmac_desc *desc_ptr, uintptr_t buf,
+ size_t size);
struct cdns_sdmmc_params cdns_params;
struct cdns_sdmmc_combo_phy sdmmc_combo_phy_reg;
struct cdns_sdmmc_sdhc sdmmc_sdhc_reg;
@@ -89,45 +62,22 @@
}
} while ((data & (1 << SDMMC_CDN_ICS)) == 0);
- return 0;
-}
-
-int cdns_busy(void)
-{
- unsigned int data;
-
- data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS09);
- return (data & STATUS_DATA_BUSY) ? CARD_BUSY : CARD_NOT_BUSY;
-}
-
-int cdns_vol_reset(void)
-{
- /* Reset embedded card */
- mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
- udelay(250);
- mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), (7 << SDMMC_CDN_BVS) | (0 << SDMMC_CDN_BP));
- udelay(500);
-
- /* Turn on supply voltage */
- /* BVS = 7, BP = 1, BP2 only in UHS2 mode */
- mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
- udelay(250);
return 0;
}
void cdns_set_sdmmc_var(struct cdns_sdmmc_combo_phy *combo_phy_reg,
- struct cdns_sdmmc_sdhc *sdhc_reg)
+ struct cdns_sdmmc_sdhc *sdhc_reg)
{
/* Values are taken by the reference of cadence IP documents */
combo_phy_reg->cp_clk_wr_delay = 0;
combo_phy_reg->cp_clk_wrdqs_delay = 0;
- combo_phy_reg->cp_data_select_oe_end = 0;
+ combo_phy_reg->cp_data_select_oe_end = 1;
combo_phy_reg->cp_dll_bypass_mode = 1;
combo_phy_reg->cp_dll_locked_mode = 0;
- combo_phy_reg->cp_dll_start_point = 0;
+ combo_phy_reg->cp_dll_start_point = 254;
combo_phy_reg->cp_gate_cfg_always_on = 1;
combo_phy_reg->cp_io_mask_always_on = 0;
- combo_phy_reg->cp_io_mask_end = 0;
+ combo_phy_reg->cp_io_mask_end = 5;
combo_phy_reg->cp_io_mask_start = 0;
combo_phy_reg->cp_rd_del_sel = 52;
combo_phy_reg->cp_read_dqs_cmd_delay = 0;
@@ -142,38 +92,58 @@
sdhc_reg->sdhc_extended_rd_mode = 1;
sdhc_reg->sdhc_extended_wr_mode = 1;
- sdhc_reg->sdhc_hcsdclkadj = 0;
+ sdhc_reg->sdhc_hcsdclkadj = 3;
sdhc_reg->sdhc_idelay_val = 0;
sdhc_reg->sdhc_rdcmd_en = 1;
sdhc_reg->sdhc_rddata_en = 1;
- sdhc_reg->sdhc_rw_compensate = 9;
+ sdhc_reg->sdhc_rw_compensate = 10;
sdhc_reg->sdhc_sdcfsh = 0;
- sdhc_reg->sdhc_sdcfsl = 1;
+ sdhc_reg->sdhc_sdcfsl = 0;
sdhc_reg->sdhc_wrcmd0_dly = 1;
sdhc_reg->sdhc_wrcmd0_sdclk_dly = 0;
sdhc_reg->sdhc_wrcmd1_dly = 0;
sdhc_reg->sdhc_wrcmd1_sdclk_dly = 0;
- sdhc_reg->sdhc_wrdata0_dly = 1;
+ sdhc_reg->sdhc_wrdata0_dly = 0;
sdhc_reg->sdhc_wrdata0_sdclk_dly = 0;
sdhc_reg->sdhc_wrdata1_dly = 0;
sdhc_reg->sdhc_wrdata1_sdclk_dly = 0;
}
-static int cdns_program_phy_reg(struct cdns_sdmmc_combo_phy *combo_phy_reg,
- struct cdns_sdmmc_sdhc *sdhc_reg)
+int cdns_program_phy_reg(struct cdns_sdmmc_combo_phy *combo_phy_reg,
+ struct cdns_sdmmc_sdhc *sdhc_reg)
{
uint32_t value = 0;
int ret = 0;
+ uint32_t timeout = 0;
+
+ /* HRS00 - Software Reset */
+ mmio_write_32((cdns_params.reg_base + SDHC_CDNS_HRS00), SDHC_CDNS_HRS00_SWR);
+
+ /* Waiting for SDHC_CDNS_HRS00_SWR reset */
+ timeout = TIMEOUT;
+ do {
+ udelay(250);
+ if (--timeout <= 0) {
+ NOTICE(" SDHC Software Reset failed!!!\n");
+ panic();
+ }
+ } while (((mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS00) &
+ SDHC_CDNS_HRS00_SWR) == 1));
+
+ /* Step 1, switch on DLL_RESET */
+ value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09);
+ value &= ~SDHC_PHY_SW_RESET;
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09, value);
/* program PHY_DQS_TIMING_REG */
value = (CP_USE_EXT_LPBK_DQS(combo_phy_reg->cp_use_ext_lpbk_dqs)) |
(CP_USE_LPBK_DQS(combo_phy_reg->cp_use_lpbk_dqs)) |
(CP_USE_PHONY_DQS(combo_phy_reg->cp_use_phony_dqs)) |
(CP_USE_PHONY_DQS_CMD(combo_phy_reg->cp_use_phony_dqs_cmd));
- ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
- COMBO_PHY_REG + PHY_DQS_TIMING_REG, MMC_REG_BASE +
- SDHC_CDNS_HRS05, value);
- if (ret != 0) {
+ ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04,
+ COMBO_PHY_REG + PHY_DQS_TIMING_REG,
+ cdns_params.reg_base + SDHC_CDNS_HRS05, value);
+ if (ret != 0U) {
return ret;
}
@@ -183,73 +153,90 @@
(CP_RD_DEL_SEL(combo_phy_reg->cp_rd_del_sel)) |
(CP_UNDERRUN_SUPPRESS(combo_phy_reg->cp_underrun_suppress)) |
(CP_GATE_CFG_ALWAYS_ON(combo_phy_reg->cp_gate_cfg_always_on));
- ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
- COMBO_PHY_REG + PHY_GATE_LPBK_CTRL_REG, MMC_REG_BASE +
- SDHC_CDNS_HRS05, value);
- if (ret != 0) {
- return ret;
+ ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04,
+ COMBO_PHY_REG + PHY_GATE_LPBK_CTRL_REG,
+ cdns_params.reg_base + SDHC_CDNS_HRS05, value);
+ if (ret != 0U) {
+ return -ret;
}
/* program PHY_DLL_MASTER_CTRL_REG */
- value = (CP_DLL_BYPASS_MODE(combo_phy_reg->cp_dll_bypass_mode))
- | (CP_DLL_START_POINT(combo_phy_reg->cp_dll_start_point));
- ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
- COMBO_PHY_REG + PHY_DLL_MASTER_CTRL_REG, MMC_REG_BASE
- + SDHC_CDNS_HRS05, value);
- if (ret != 0) {
+ value = (CP_DLL_BYPASS_MODE(combo_phy_reg->cp_dll_bypass_mode)) | (2 << 20) |
+ (CP_DLL_START_POINT(combo_phy_reg->cp_dll_start_point));
+ ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04,
+ COMBO_PHY_REG + PHY_DLL_MASTER_CTRL_REG,
+ cdns_params.reg_base + SDHC_CDNS_HRS05, value);
+ if (ret != 0U) {
return ret;
}
/* program PHY_DLL_SLAVE_CTRL_REG */
- value = (CP_READ_DQS_CMD_DELAY(combo_phy_reg->cp_read_dqs_cmd_delay))
- | (CP_CLK_WRDQS_DELAY(combo_phy_reg->cp_clk_wrdqs_delay))
- | (CP_CLK_WR_DELAY(combo_phy_reg->cp_clk_wr_delay))
- | (CP_READ_DQS_DELAY(combo_phy_reg->cp_read_dqs_delay));
- ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
- COMBO_PHY_REG + PHY_DLL_SLAVE_CTRL_REG, MMC_REG_BASE
- + SDHC_CDNS_HRS05, value);
- if (ret != 0) {
+ value = (CP_READ_DQS_CMD_DELAY(combo_phy_reg->cp_read_dqs_cmd_delay)) |
+ (CP_CLK_WRDQS_DELAY(combo_phy_reg->cp_clk_wrdqs_delay)) |
+ (CP_CLK_WR_DELAY(combo_phy_reg->cp_clk_wr_delay)) |
+ (CP_READ_DQS_DELAY(combo_phy_reg->cp_read_dqs_delay));
+ ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04,
+ COMBO_PHY_REG + PHY_DLL_SLAVE_CTRL_REG,
+ cdns_params.reg_base + SDHC_CDNS_HRS05, value);
+ if (ret != 0U) {
return ret;
}
/* program PHY_CTRL_REG */
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS04, COMBO_PHY_REG
- + PHY_CTRL_REG);
- value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS05);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS04, COMBO_PHY_REG + PHY_CTRL_REG);
+ value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS05);
/* phony_dqs_timing=0 */
value &= ~(CP_PHONY_DQS_TIMING_MASK << CP_PHONY_DQS_TIMING_SHIFT);
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS05, value);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS05, value);
/* switch off DLL_RESET */
do {
- value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
+ value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09);
value |= SDHC_PHY_SW_RESET;
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, value);
- value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09, value);
+ value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09);
/* polling PHY_INIT_COMPLETE */
} while ((value & SDHC_PHY_INIT_COMPLETE) != SDHC_PHY_INIT_COMPLETE);
/* program PHY_DQ_TIMING_REG */
- combo_phy_reg->cp_io_mask_end = 0U;
- value = (CP_IO_MASK_ALWAYS_ON(combo_phy_reg->cp_io_mask_always_on))
- | (CP_IO_MASK_END(combo_phy_reg->cp_io_mask_end))
- | (CP_IO_MASK_START(combo_phy_reg->cp_io_mask_start))
- | (CP_DATA_SELECT_OE_END(combo_phy_reg->cp_data_select_oe_end));
+ value = (CP_IO_MASK_ALWAYS_ON(combo_phy_reg->cp_io_mask_always_on)) |
+ (CP_IO_MASK_END(combo_phy_reg->cp_io_mask_end)) |
+ (CP_IO_MASK_START(combo_phy_reg->cp_io_mask_start)) |
+ (CP_DATA_SELECT_OE_END(combo_phy_reg->cp_data_select_oe_end));
- ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
- COMBO_PHY_REG + PHY_DQ_TIMING_REG, MMC_REG_BASE
- + SDHC_CDNS_HRS05, value);
- if (ret != 0) {
+ ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04,
+ COMBO_PHY_REG + PHY_DQ_TIMING_REG,
+ cdns_params.reg_base + SDHC_CDNS_HRS05, value);
+ if (ret != 0U) {
return ret;
}
+
+ value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09);
+ value |= (HRS_09_EXTENDED_RD_MODE | HRS_09_EXTENDED_WR_MODE |
+ HRS_09_RDCMD_EN | HRS_09_RDDATA_EN);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09, value);
+
+ value = 0;
+ value = SDHC_HCSDCLKADJ(HRS_10_HCSDCLKADJ_VAL);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS10, value);
+
+ value = 0;
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS16, value);
+
+ value = (10 << 16);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS07, value);
+
return 0;
}
int cdns_read(int lba, uintptr_t buf, size_t size)
{
- inv_dcache_range(buf, size);
+ return 0;
+}
+int cdns_write(int lba, uintptr_t buf, size_t size)
+{
return 0;
}
@@ -260,120 +247,79 @@
int cdns_prepare(int dma_start_addr, uintptr_t dma_buff, size_t size)
{
- data_cmd = true;
- struct cdns_idmac_desc *desc;
- uint32_t desc_cnt, i;
- uint64_t desc_base;
-
+ struct cdns_idmac_desc *cdns_desc_data;
assert(((dma_buff & CDNSMMC_ADDRESS_MASK) == 0) &&
- (cdns_params.desc_size > 0) &&
- ((MMC_REG_BASE & MMC_BLOCK_MASK) == 0) &&
- ((cdns_params.desc_base & MMC_BLOCK_MASK) == 0) &&
- ((cdns_params.desc_size & MMC_BLOCK_MASK) == 0));
-
- flush_dcache_range(dma_buff, size);
-
- desc_cnt = (size + (CDMMC_DMA_MAX_BUFFER_SIZE) - 1) / (CDMMC_DMA_MAX_BUFFER_SIZE);
- assert(desc_cnt * sizeof(struct cdns_idmac_desc) < cdns_params.desc_size);
-
- if (desc_cnt > CONFIG_CDNS_DESC_COUNT) {
- ERROR("Requested data transfer length %ld is greater than configured length %d",
- size, (CONFIG_CDNS_DESC_COUNT * CDMMC_DMA_MAX_BUFFER_SIZE));
- return -EINVAL;
- }
-
- desc = (struct cdns_idmac_desc *)cdns_params.desc_base;
- desc_base = (uint64_t)desc;
- i = 0;
-
- while ((i + 1) < desc_cnt) {
- desc->attr = ADMA_DESC_ATTR_VALID | ADMA_DESC_TRANSFER_DATA;
- desc->reserved = 0;
- desc->len = MAX_64KB_PAGE;
- desc->addr_lo = (dma_buff & UINT_MAX) + (CDMMC_DMA_MAX_BUFFER_SIZE * i);
-#if CONFIG_DMA_ADDR_T_64BIT == 1
- desc->addr_hi = (dma_buff >> 32) & 0xffffffff;
-#endif
- size -= CDMMC_DMA_MAX_BUFFER_SIZE;
- desc++;
- i++;
- }
+ (cdns_params.desc_size > 0));
- desc->attr = ADMA_DESC_ATTR_VALID | ADMA_DESC_TRANSFER_DATA |
- ADMA_DESC_ATTR_END;
- desc->reserved = 0;
- desc->len = size;
-#if CONFIG_DMA_ADDR_T_64BIT == 1
- desc->addr_lo = (dma_buff & UINT_MAX) + (CDMMC_DMA_MAX_BUFFER_SIZE * i);
- desc->addr_hi = (dma_buff >> 32) & UINT_MAX;
-#else
- desc->addr_lo = (dma_buff & UINT_MAX);
-#endif
+ cdns_desc_data = (struct cdns_idmac_desc *)cdns_params.desc_base;
+ sd_host_adma_prepare(cdns_desc_data, dma_buff, size);
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS22, (uint32_t)desc_base);
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS23, (uint32_t)(desc_base >> 32));
- flush_dcache_range(cdns_params.desc_base,
- desc_cnt * CDMMC_DMA_MAX_BUFFER_SIZE);
-
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS01,
- ((512 << BLOCK_SIZE) | ((size/512) << BLK_COUNT_CT) | SDMA_BUF));
return 0;
}
-static void cdns_host_set_clk(int clk)
+void cdns_host_set_clk(uint32_t clk)
{
uint32_t ret = 0;
uint32_t sdclkfsval = 0;
- uint32_t dtcvval = DTCVVAL_DEFAULT_VAL;
+ uint32_t dtcvval = 0xE;
- sdclkfsval = (cdns_params.clk_rate / 2000) / clk;
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, 0);
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
- (sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE));
+ sdclkfsval = (SD_HOST_CLK / 2) / clk;
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11, 0);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11,
+ (dtcvval << SDMMC_CDN_DTCV) | (sdclkfsval << SDMMC_CDN_SDCLKFS) |
+ (1 << SDMMC_CDN_ICE));
- ret = cdns_wait_ics(5000, MMC_REG_BASE + SDHC_CDNS_SRS11);
- if (ret != 0U) {
- ERROR("Waiting SDMMC_CDN_ICS timeout");
+ ret = cdns_wait_ics(5000, cdns_params.reg_base + SDHC_CDNS_SRS11);
+ if (ret != 0) {
+ ERROR("Waiting ICS timeout");
}
-
/* Enable DLL reset */
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) &
- ~SDHC_DLL_RESET_MASK);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09,
+ mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) & ~0x00000001);
/* Set extended_wr_mode */
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, (mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09)
- & SDHC_EXTENDED_WR_MODE_MASK) | (1 << EXTENDED_WR_MODE));
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09,
+ (mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) & 0xFFFFFFF7) |
+ (1 << EXTENDED_WR_MODE));
/* Release DLL reset */
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
- + SDHC_CDNS_HRS09) | 1);
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
- + SDHC_CDNS_HRS09) | (3 << RDCMD_EN));
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09,
+ mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) | PHY_SW_RESET_EN);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09,
+ mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) | RDCMD_EN);
do {
- mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
- } while (~mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) & (1 << 1));
+ mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09);
+ } while (~mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) &
+ (PHY_INIT_COMPLETE_BIT));
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
- (sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE) | (1 << SDMMC_CDN_SDCE));
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS13, UINT_MAX);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
+ (sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE) |
+ (1 << SDMMC_CDN_SDCE));
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS13, 0xFFFFFFFF);
}
int cdns_set_ios(unsigned int clk, unsigned int width)
{
+ uint32_t _status = 0;
+ _status = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
switch (width) {
case MMC_BUS_WIDTH_1:
- mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), LEDC_OFF);
+ _status &= ~(BIT4);
break;
+
case MMC_BUS_WIDTH_4:
- mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), DTW_4BIT);
+ _status |= BIT4;
break;
+
case MMC_BUS_WIDTH_8:
- mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), EDTW_8BIT);
+ _status |= BIT8;
break;
+
default:
assert(0);
break;
}
+ mmio_write_32((cdns_params.reg_base + SDHC_CDNS_SRS10), _status);
cdns_host_set_clk(clk);
return 0;
@@ -388,6 +334,7 @@
value |= data;
mmio_write_32(addr, value);
value = mmio_read_32(addr);
+
if (value != data) {
ERROR("SD host address is not set properly\n");
return -ENXIO;
@@ -396,429 +343,403 @@
return 0;
}
-int cdns_write(int lba, uintptr_t buf, size_t size)
-{
- return 0;
-}
-static int cdns_init_hrs_io(struct cdns_sdmmc_combo_phy *combo_phy_reg,
- struct cdns_sdmmc_sdhc *sdhc_reg)
+
+void sd_host_oper_mode(enum sd_opr_modes opr_mode)
{
- uint32_t value = 0;
- int ret = 0;
- /* program HRS09, register 42 */
- value = (SDHC_RDDATA_EN(sdhc_reg->sdhc_rddata_en))
- | (SDHC_RDCMD_EN(sdhc_reg->sdhc_rdcmd_en))
- | (SDHC_EXTENDED_WR_MODE(sdhc_reg->sdhc_extended_wr_mode))
- | (SDHC_EXTENDED_RD_MODE(sdhc_reg->sdhc_extended_rd_mode));
- ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS09, value);
- if (ret != 0) {
- ERROR("Program HRS09 failed");
- return ret;
- }
+ uint32_t reg = 0;
- /* program HRS10, register 43 */
- value = (SDHC_HCSDCLKADJ(sdhc_reg->sdhc_hcsdclkadj));
- ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS10, value);
- if (ret != 0) {
- ERROR("Program HRS10 failed");
- return ret;
- }
+ switch (opr_mode) {
+ case SD_HOST_OPR_MODE_HV4E_0_SDMA_32:
+ reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+ reg &= ~(DMA_SEL_BIT);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+ reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+ reg &= ~(HV4E | BIT_AD_64);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+ break;
- /* program HRS16, register 48 */
- value = (SDHC_WRDATA1_SDCLK_DLY(sdhc_reg->sdhc_wrdata1_sdclk_dly))
- | (SDHC_WRDATA0_SDCLK_DLY(sdhc_reg->sdhc_wrdata0_sdclk_dly))
- | (SDHC_WRCMD1_SDCLK_DLY(sdhc_reg->sdhc_wrcmd1_sdclk_dly))
- | (SDHC_WRCMD0_SDCLK_DLY(sdhc_reg->sdhc_wrcmd0_sdclk_dly))
- | (SDHC_WRDATA1_DLY(sdhc_reg->sdhc_wrdata1_dly))
- | (SDHC_WRDATA0_DLY(sdhc_reg->sdhc_wrdata0_dly))
- | (SDHC_WRCMD1_DLY(sdhc_reg->sdhc_wrcmd1_dly))
- | (SDHC_WRCMD0_DLY(sdhc_reg->sdhc_wrcmd0_dly));
- ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS16, value);
- if (ret != 0) {
- ERROR("Program HRS16 failed");
- return ret;
- }
+ case SD_HOST_OPR_MODE_HV4E_1_SDMA_32:
+ reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+ reg &= ~(DMA_SEL_BIT);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+ reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+ reg &= ~(HV4E | BIT_AD_64);
+ reg |= (HV4E);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+ break;
- /* program HRS07, register 40 */
- value = (SDHC_RW_COMPENSATE(sdhc_reg->sdhc_rw_compensate))
- | (SDHC_IDELAY_VAL(sdhc_reg->sdhc_idelay_val));
- ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS07, value);
- if (ret != 0) {
- ERROR("Program HRS07 failed");
- return ret;
- }
+ case SD_HOST_OPR_MODE_HV4E_1_SDMA_64:
+ reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+ reg &= ~(DMA_SEL_BIT);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+ reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+ reg |= (HV4E | BIT_AD_64);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+ break;
- return ret;
+ case SD_HOST_OPR_MODE_HV4E_0_ADMA_32:
+ reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+ reg &= ~(DMA_SEL_BIT);
+ reg |= DMA_SEL_BIT_2;
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+ reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+ reg &= ~(HV4E | BIT_AD_64);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+ break;
+
+ case SD_HOST_OPR_MODE_HV4E_0_ADMA_64:
+ reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+ reg &= ~(DMA_SEL_BIT);
+ reg |= DMA_SEL_BIT_3;
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+ reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+ reg &= ~(HV4E | BIT_AD_64);
+ reg |= BIT_AD_64;
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+ break;
+
+ case SD_HOST_OPR_MODE_HV4E_1_ADMA_32:
+ reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+ reg &= ~(DMA_SEL_BIT);
+ reg |= DMA_SEL_BIT_2;
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+ reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+ reg &= ~(HV4E | BIT_AD_64);
+ reg |= HV4E;
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+ break;
+
+ case SD_HOST_OPR_MODE_HV4E_1_ADMA_64:
+ reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+ reg &= ~(DMA_SEL_BIT);
+ reg |= DMA_SEL_BIT_2;
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+ reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+ reg |= (HV4E | BIT_AD_64);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+ break;
+ }
}
-static int cdns_hc_set_clk(struct cdns_sdmmc_params *cdn_sdmmc_dev_mode_params)
+void card_reset(bool power_enable)
{
- uint32_t ret = 0;
- uint32_t dtcvval, sdclkfsval;
+ uint32_t reg_value = 0;
- dtcvval = DTC_VAL;
- sdclkfsval = 0;
+ /* Reading SRS10 value before writing */
+ reg_value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
- if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_DS) ||
- (cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR12) ||
- (cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_SDR_BC)) {
- sdclkfsval = 4;
- } else if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_HS) ||
- (cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR25) ||
- (cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_DDR50) ||
- (cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_SDR)) {
- sdclkfsval = 2;
- } else if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR50) ||
- (cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_DDR) ||
- (cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_HS400) ||
- (cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_HS400es)) {
- sdclkfsval = 1;
- } else if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR104) ||
- (cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_HS200)) {
- sdclkfsval = 0;
+ if (power_enable == true) {
+ reg_value &= ~((7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
+ reg_value = ((1 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
+ } else {
+ reg_value &= ~((7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
}
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg_value);
+}
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, 0);
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
- (sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE));
- ret = cdns_wait_ics(5000, MMC_REG_BASE + SDHC_CDNS_SRS11);
- if (ret != 0U) {
- ERROR("Waiting SDMMC_CDN_ICS timeout");
- return ret;
- }
+void high_speed_enable(bool mode)
+{
- /* Enable DLL reset */
- mmio_write_32((MMC_REG_BASE + SDHC_CDNS_HRS09), mmio_read_32(MMC_REG_BASE
- + SDHC_CDNS_HRS09) & ~SDHC_DLL_RESET_MASK);
- /* Set extended_wr_mode */
- mmio_write_32((MMC_REG_BASE + SDHC_CDNS_HRS09),
- (mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) & SDHC_EXTENDED_WR_MODE_MASK) |
- (1 << EXTENDED_WR_MODE));
- /* Release DLL reset */
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
- + SDHC_CDNS_HRS09) | 1);
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
- + SDHC_CDNS_HRS09) | (3 << RDCMD_EN));
- do {
- mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
- } while (~mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) & (1 << 1));
+ uint32_t reg_value = 0;
+ /* Reading SRS10 value before writing */
+ reg_value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
- (sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE) | (1 << SDMMC_CDN_SDCE));
+ if (mode == true) {
+ reg_value |= HS_EN;
+ } else {
+ reg_value &= ~HS_EN;
+ }
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS13, UINT_MAX);
- return 0;
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg_value);
}
int cdns_reset(void)
{
- uint32_t data = 0;
+ volatile uint32_t data = 0;
uint32_t count = 0;
- uint32_t value = 0;
-
- value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS11);
- value &= ~(0xFFFF);
- value |= 0x0;
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, value);
- udelay(500);
/* Software reset */
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS00, 1);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11, SRS11_SRFA);
/* Wait status command response ready */
do {
- data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS00);
+ data = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS00);
count++;
- if (count >= 5000) {
+ if (count >= CDNS_TIMEOUT) {
return -ETIMEDOUT;
}
- /* Wait for HRS00.SWR */
- } while ((data & 1) == 1);
-
- /* Step 1, switch on DLL_RESET */
- value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
- value &= ~SDHC_PHY_SW_RESET;
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, value);
+ /* Wait for SRS11 */
+ } while (((SRS11_SRFA_CHK(data)) & 1) == 1);
return 0;
}
+void sdmmc_host_init(bool uhs2_enable)
+{
+ uint32_t timeout;
+
+ /* SRS11 - Host Control default value set */
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11, 0x0);
+
+ /* Waiting for detect card */
+ timeout = TIMEOUT;
+ do {
+ udelay(250);
+ if (--timeout <= 0) {
+ NOTICE(" SDHC Card Detecion failed!!!\n");
+ panic();
+ }
+ } while (((mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS09) & CHECK_CARD) == 0));
+
+ /* UHS2 Host setting */
+ if (uhs2_enable == true) {
+ /** need to implement*/
+ }
+
+ /* Card reset */
+
+ card_reset(1);
+ udelay(2500);
+ card_reset(0);
+ udelay(2500);
+ card_reset(1);
+ udelay(2500);
+
+ /* Enable Interrupt Flags*/
+ mmio_write_32((cdns_params.reg_base + SDHC_CDNS_SRS13), ~0);
+ high_speed_enable(true);
+}
+
int cdns_sd_host_init(struct cdns_sdmmc_combo_phy *mmc_combo_phy_reg,
-struct cdns_sdmmc_sdhc *mmc_sdhc_reg)
+ struct cdns_sdmmc_sdhc *mmc_sdhc_reg)
{
int ret = 0;
ret = cdns_reset();
- if (ret != 0) {
+ if (ret != 0U) {
ERROR("Program phy reg init failed");
return ret;
}
ret = cdns_program_phy_reg(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
- if (ret != 0) {
+ if (ret != 0U) {
ERROR("Program phy reg init failed");
return ret;
}
-
- ret = cdns_init_hrs_io(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
- if (ret != 0) {
- ERROR("Program init for HRS reg is failed");
- return ret;
- }
-
- ret = cdns_sd_card_detect();
- if (ret != 0) {
- ERROR("SD card does not detect");
- return ret;
- }
+ sdmmc_host_init(0);
+ cdns_host_set_clk(100000);
- ret = cdns_vol_reset();
- if (ret != 0) {
- ERROR("eMMC card reset failed");
- return ret;
- }
-
- ret = cdns_hc_set_clk(&cdns_params);
- if (ret != 0) {
- ERROR("hc set clk failed");
- return ret;
- }
+ sd_host_oper_mode(SD_HOST_OPR_MODE_HV4E_0_ADMA_64);
return 0;
}
-void cdns_srs10_value_toggle(uint8_t write_val, uint8_t prev_val)
-{
- uint32_t data_op = 0U;
-
- data_op = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS10);
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS10, (data_op & (prev_val << 0)));
- mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS10);
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS10, data_op | (write_val << 0));
-}
-
-void cdns_srs11_srs15_config(uint32_t srs11_val, uint32_t srs15_val)
-{
- uint32_t data = 0U;
-
- data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS11);
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (data | srs11_val));
- data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS15);
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS15, (data | srs15_val));
-}
-
int cdns_send_cmd(struct mmc_cmd *cmd)
{
- uint32_t op = 0, ret = 0;
- uint8_t write_value = 0, prev_val = 0;
- uint32_t value;
- int32_t timeout;
- uint32_t cmd_indx;
- uint32_t status = 0, srs15_val = 0, srs11_val = 0;
+ uint32_t cmd_flags = 0;
+ uint32_t timeout = 0;
uint32_t status_check = 0;
+ uint32_t mode = 0;
+ uint32_t status;
assert(cmd);
- cmd_indx = (cmd->cmd_idx) << COM_IDX;
-
- if (data_cmd) {
- switch (cmd->cmd_idx) {
- case SD_SWITCH:
- op = DATA_PRESENT;
- write_value = ADMA2_32 | DT_WIDTH;
- prev_val = ADMA2_32 | DT_WIDTH;
- cdns_srs10_value_toggle(write_value, prev_val);
- srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
- srs15_val = BIT_AD_64 | HV4E | V18SE;
- cdns_srs11_srs15_config(srs11_val, srs15_val);
- break;
- case SD_WRITE_SINGLE_BLOCK:
- case SD_READ_SINGLE_BLOCK:
- op = DATA_PRESENT;
- write_value = ADMA2_32 | HS_EN | DT_WIDTH | LEDC;
- prev_val = ADMA2_32 | HS_EN | DT_WIDTH;
- cdns_srs10_value_toggle(write_value, prev_val);
- srs15_val = PVE | BIT_AD_64 | HV4E | SDR104_MODE | V18SE;
- srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
- cdns_srs11_srs15_config(srs11_val, srs15_val);
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS00, SAAR);
- break;
+ cmd_flags = CDNS_HOST_CMD_INHIBIT | CDNS_HOST_DATA_INHIBIT;
- case SD_WRITE_MULTIPLE_BLOCK:
- case SD_READ_MULTIPLE_BLOCK:
- op = DATA_PRESENT | AUTO_CMD_EN | MULTI_BLK_READ;
- write_value = ADMA2_32 | HS_EN | DT_WIDTH | LEDC;
- prev_val = ADMA2_32 | HS_EN | DT_WIDTH;
- cdns_srs10_value_toggle(write_value, prev_val);
- srs15_val = PVE | BIT_AD_64 | HV4E | SDR104_MODE | V18SE;
- srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
- cdns_srs11_srs15_config(srs11_val, srs15_val);
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS00, SAAR);
- break;
+ if ((cmd->cmd_idx == SD_STOP_TRANSMISSION) && (!data_cmd)) {
+ cmd_flags &= ~CDNS_HOST_DATA_INHIBIT;
+ }
- case SD_APP_SEND_SCR:
- op = DATA_PRESENT;
- write_value = ADMA2_32 | LEDC;
- prev_val = LEDC;
- cdns_srs10_value_toggle(write_value, prev_val);
- srs15_val = BIT_AD_64 | HV4E | V18SE;
- srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
- cdns_srs11_srs15_config(srs11_val, srs15_val);
- break;
+ timeout = TIMEOUT;
+ do {
+ udelay(100);
+ if (--timeout <= 0) {
+ udelay(50);
+ NOTICE("Timeout occur data and cmd line %x\n",
+ mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS09));
+ panic();
+ }
+ } while ((mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS09) & (cmd_flags)));
- case SD_SEND_IF_COND:
- op = DATA_PRESENT | CMD_IDX_CHK_ENABLE;
- write_value = LEDC;
- prev_val = 0x0;
- cdns_srs10_value_toggle(write_value, prev_val);
- srs15_val = HV4E;
- srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
- cdns_srs11_srs15_config(srs11_val, srs15_val);
- break;
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS12, 0xFFFFFFFF);
+ cmd_flags = 0;
+ cmd_flags = (cmd->cmd_idx) << COM_IDX;
- default:
- write_value = LEDC;
- prev_val = 0x0;
- cdns_srs10_value_toggle(write_value, prev_val);
- op = 0;
- break;
- }
+ if ((cmd->resp_type & MMC_RSP_136) != 0) {
+ cmd_flags |= RES_TYPE_SEL_136;
+ } else if (((cmd->resp_type & MMC_RSP_48) != 0) &&
+ ((cmd->resp_type & MMC_RSP_BUSY) != 0)) {
+ cmd_flags |= RES_TYPE_SEL_48_B;
+ } else if ((cmd->resp_type & MMC_RSP_48) != 0) {
+ cmd_flags |= RES_TYPE_SEL_48;
} else {
- switch (cmd->cmd_idx) {
- case SD_GO_IDLE_STATE:
- write_value = LEDC;
- prev_val = 0x0;
- cdns_srs10_value_toggle(write_value, prev_val);
- srs15_val = HV4E;
- srs11_val = SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
- cdns_srs11_srs15_config(srs11_val, srs15_val);
- break;
+ cmd_flags &= ~RES_TYPE_SEL_NO;
+ }
+
+ if ((cmd->resp_type & MMC_RSP_CRC) != 0) {
+ cmd_flags |= CMD_CHECK_RESP_CRC;
+ }
- case SD_ALL_SEND_CID:
- write_value = LEDC;
- prev_val = 0x0;
- cdns_srs10_value_toggle(write_value, prev_val);
- srs15_val = HV4E | V18SE;
- srs11_val = SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
- cdns_srs11_srs15_config(srs11_val, srs15_val);
- break;
+ if ((cmd->resp_type & MMC_RSP_CMD_IDX) != 0) {
+ cmd_flags |= CMD_IDX_CHK_ENABLE;
+ }
+
+ if ((cmd->cmd_idx == MMC_ACMD(51)) || (cmd->cmd_idx == MMC_CMD(17)) ||
+ (cmd->cmd_idx == MMC_CMD(18)) || (cmd->cmd_idx == MMC_CMD(24)) ||
+ (cmd->cmd_idx == MMC_CMD(25))) {
+ mmio_write_8((cdns_params.reg_base + DTCV_OFFSET), DTCV_VAL);
+ cmd_flags |= DATA_PRESENT;
+ mode |= BLK_CNT_EN;
+
+ mode |= (DMA_ENABLED);
+ if ((cmd->cmd_idx == SD_WRITE_MULTIPLE_BLOCK) ||
+ (cmd->cmd_idx == SD_READ_MULTIPLE_BLOCK)) {
+ mode |= (MULTI_BLK_READ);
+ } else {
+ mode &= ~(MULTI_BLK_READ);
+ }
+ if ((cmd->cmd_idx == SD_WRITE_MULTIPLE_BLOCK) ||
+ (cmd->cmd_idx == SD_WRITE_SINGLE_BLOCK)) {
+ mode &= ~CMD_READ;
+ } else {
+ mode |= CMD_READ;
+ }
+ mmio_write_16(cdns_params.reg_base + SDHC_CDNS_SRS03, mode);
- case SD_SEND_IF_COND:
- op = CMD_IDX_CHK_ENABLE;
- write_value = LEDC;
- prev_val = 0x0;
- cdns_srs10_value_toggle(write_value, prev_val);
- srs15_val = HV4E;
- srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
- cdns_srs11_srs15_config(srs11_val, srs15_val);
- break;
+ } else {
+ mmio_write_8((cdns_params.reg_base + DTCV_OFFSET), DTCV_VAL);
+ }
- case SD_STOP_TRANSMISSION:
- op = CMD_STOP_ABORT_CMD;
- break;
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS02, cmd->cmd_arg);
+ mmio_write_16((cdns_params.reg_base + CICE_OFFSET),
+ SDHCI_MAKE_CMD(cmd->cmd_idx, cmd_flags));
- case SD_SEND_STATUS:
- break;
+ timeout = TIMEOUT;
- case 1:
- cmd->cmd_arg = 0;
- break;
+ do {
+ udelay(CDNS_TIMEOUT);
+ status = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS12);
+ } while (((status & (INT_CMD_DONE | ERROR_INT)) == 0) && (timeout-- > 0));
- case SD_SELECT_CARD:
- op = MULTI_BLK_READ;
- break;
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS12, (SRS_12_CC_EN));
+ status_check = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS12) & 0xffff8000;
+ if (status_check != 0U) {
+ timeout = TIMEOUT;
+ ERROR("SD host controller send command failed, SRS12 = %x", status_check);
+ return -1;
+ }
- case SD_APP_CMD:
- default:
- write_value = LEDC;
- prev_val = 0x0;
- cdns_srs10_value_toggle(write_value, prev_val);
- op = 0;
- break;
+ if (!((cmd_flags & RES_TYPE_SEL_NO) == 0)) {
+ cmd->resp_data[0] = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS04);
+ if ((cmd_flags & RES_TYPE_SEL_NO) == RES_TYPE_SEL_136) {
+ cmd->resp_data[1] = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS05);
+ cmd->resp_data[2] = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS06);
+ cmd->resp_data[3] = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS07);
+ /* 136-bit: RTS=01b, Response field R[127:8] - RESP3[23:0],
+ * RESP2[31:0], RESP1[31:0], RESP0[31:0]
+ * Subsystem expects 128 bits response but cadence SDHC sends
+ * 120 bits response from R[127:8]. Bits manupulation to address
+ * the correct responses for the 136 bit response type.
+ */
+ cmd->resp_data[3] = ((cmd->resp_data[3] << 8) |
+ ((cmd->resp_data[2] >> 24) &
+ CDNS_CSD_BYTE_MASK));
+ cmd->resp_data[2] = ((cmd->resp_data[2] << 8) |
+ ((cmd->resp_data[1] >> 24) &
+ CDNS_CSD_BYTE_MASK));
+ cmd->resp_data[1] = ((cmd->resp_data[1] << 8) |
+ ((cmd->resp_data[0] >> 24) &
+ CDNS_CSD_BYTE_MASK));
+ cmd->resp_data[0] = (cmd->resp_data[0] << 8);
}
}
- switch (cmd->resp_type) {
- case MMC_RESPONSE_NONE:
- op |= CMD_READ | MULTI_BLK_READ | DMA_ENABLED | BLK_CNT_EN;
- break;
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS12, (SRS_12_CC_EN));
- case MMC_RESPONSE_R2:
- op |= CMD_READ | MULTI_BLK_READ | DMA_ENABLED | BLK_CNT_EN |
- RES_TYPE_SEL_136 | CMD_CHECK_RESP_CRC;
- break;
+ return 0;
+}
- case MMC_RESPONSE_R3:
- op |= CMD_READ | MULTI_BLK_READ | DMA_ENABLED | BLK_CNT_EN |
- RES_TYPE_SEL_48;
- break;
+void sd_host_adma_prepare(struct cdns_idmac_desc *desc_ptr, uint64_t buf,
+ size_t size)
+{
+ uint32_t full_desc_cnt = 0;
+ uint32_t non_full_desc_cnt = 0;
+ uint64_t desc_address;
+ uint32_t block_count;
+ uint32_t transfer_block_size;
- case MMC_RESPONSE_R1:
- if ((cmd->cmd_idx == SD_WRITE_SINGLE_BLOCK) || (cmd->cmd_idx
- == SD_WRITE_MULTIPLE_BLOCK)) {
- op |= DMA_ENABLED | BLK_CNT_EN | RES_TYPE_SEL_48
- | CMD_CHECK_RESP_CRC | CMD_IDX_CHK_ENABLE;
- } else {
- op |= DMA_ENABLED | BLK_CNT_EN | CMD_READ | RES_TYPE_SEL_48
- | CMD_CHECK_RESP_CRC | CMD_IDX_CHK_ENABLE;
+ full_desc_cnt = (size / PAGE_BUFFER_LEN);
+ non_full_desc_cnt = (size % PAGE_BUFFER_LEN);
+ for (int i = 0; i < full_desc_cnt; i++) {
+ desc_ptr->attr = (ADMA_DESC_TRANSFER_DATA | ADMA_DESC_ATTR_VALID);
+ desc_ptr->len = 0; // 0 means 64kb page size it will take
+ desc_ptr->addr_lo = 0;
+#if CONFIG_DMA_ADDR_T_64BIT == 1
+ desc_ptr->addr_hi = (uint32_t)((buf >> 32) & 0xffffffff);
+#endif
+ if (non_full_desc_cnt == 0) {
+ desc_ptr->attr |= (ADMA_DESC_ATTR_END);
}
- break;
-
- default:
- op |= DMA_ENABLED | BLK_CNT_EN | CMD_READ | MULTI_BLK_READ |
- RES_TYPE_SEL_48 | CMD_CHECK_RESP_CRC | CMD_IDX_CHK_ENABLE;
- break;
+ buf += PAGE_BUFFER_LEN;
}
- timeout = TIMEOUT;
- do {
- udelay(100);
- ret = cdns_busy();
- if (--timeout <= 0) {
- udelay(50);
- panic();
+ if (non_full_desc_cnt != 0) {
+ desc_ptr->attr =
+ (ADMA_DESC_TRANSFER_DATA | ADMA_DESC_ATTR_END | ADMA_DESC_ATTR_VALID);
+ desc_ptr->addr_lo = buf & 0xffffffff;
+ desc_ptr->len = size;
+#if CONFIG_DMA_ADDR_T_64BIT == 1
+ desc_ptr->addr_hi = (uint32_t)((buf >> 32) & 0xffffffff);
+#endif
+ desc_address = (uint64_t)desc_ptr;
+ if (size > MMC_MAX_BLOCK_LEN) {
+ transfer_block_size = MMC_MAX_BLOCK_LEN;
+ } else {
+ transfer_block_size = size;
}
- } while (ret);
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS12, UINT_MAX);
+ block_count = (size / transfer_block_size);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS01,
+ ((transfer_block_size << BLOCK_SIZE) | SDMA_BUF |
+ (block_count << BLK_COUNT_CT)));
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS22,
+ (uint32_t)desc_address & 0xFFFFFFFF);
+ mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS23,
+ (uint32_t)(desc_address >> 32 & 0xFFFFFFFF));
+ }
+}
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS02, cmd->cmd_arg);
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS14, 0x00000000);
- if (cmd_indx == 1)
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS03, SDHC_CDNS_SRS03_VALUE);
- else
- mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS03, op | cmd_indx);
+int cdns_mmc_init(struct cdns_sdmmc_params *params,
+ struct mmc_device_info *info)
+{
- timeout = TIMEOUT;
- do {
- udelay(500);
- value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS12);
- } while (((value & (INT_CMD_DONE | ERROR_INT)) == 0) && (timeout-- > 0));
+ int result = 0;
- timeout = TIMEOUT;
+ assert((params != NULL) &&
+ ((params->reg_base & MMC_BLOCK_MASK) == 0) &&
+ ((params->desc_size & MMC_BLOCK_MASK) == 0) &&
+ ((params->reg_pinmux & MMC_BLOCK_MASK) == 0) &&
+ ((params->reg_phy & MMC_BLOCK_MASK) == 0) &&
+ (params->desc_size > 0) &&
+ (params->clk_rate > 0) &&
+ ((params->bus_width == MMC_BUS_WIDTH_1) ||
+ (params->bus_width == MMC_BUS_WIDTH_4) ||
+ (params->bus_width == MMC_BUS_WIDTH_8)));
- if (data_cmd) {
- data_cmd = false;
- do {
- udelay(250);
- } while (((value & TRAN_COMP) == 0) && (timeout-- > 0));
- }
+ memcpy(&cdns_params, params, sizeof(struct cdns_sdmmc_params));
- status_check = value & SRS12_ERR_MASK;
- if (status_check != 0U) {
- ERROR("SD host controller send command failed, SRS12 = %x", status);
- return -1;
+ cdns_set_sdmmc_var(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
+ result = cdns_sd_host_init(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
+ if (result < 0) {
+ return result;
}
- if ((op & RES_TYPE_SEL_48) || (op & RES_TYPE_SEL_136)) {
- cmd->resp_data[0] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS04);
- if (op & RES_TYPE_SEL_136) {
- cmd->resp_data[1] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS05);
- cmd->resp_data[2] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS06);
- cmd->resp_data[3] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS07);
- }
- }
+ cdns_params.cdn_sdmmc_dev_type = info->mmc_dev_type;
+ cdns_params.cdn_sdmmc_dev_mode = SD_DS;
- return 0;
+ result = mmc_init(&cdns_sdmmc_ops, params->clk_rate, params->bus_width,
+ params->flags, info);
+
+ return result;
}
diff --git a/drivers/delay_timer/delay_timer.c b/drivers/delay_timer/delay_timer.c
index a3fd7bf..bdbbbf6 100644
--- a/drivers/delay_timer/delay_timer.c
+++ b/drivers/delay_timer/delay_timer.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -80,3 +80,25 @@
timer_ops = ops_ptr;
}
+
+/***********************************************************
+ * Initialize the timer in us
+ ***********************************************************/
+uint64_t timeout_init_us(uint32_t usec)
+{
+ assert(timer_ops != NULL);
+ assert(timer_ops->timeout_init_us != NULL);
+
+ return timer_ops->timeout_init_us(usec);
+}
+
+/***********************************************************
+ * check the given timeout elapsed or not.
+ ***********************************************************/
+bool timeout_elapsed(uint64_t cnt)
+{
+ assert(timer_ops != NULL);
+ assert(timer_ops->timeout_elapsed != NULL);
+
+ return timer_ops->timeout_elapsed(cnt);
+}
diff --git a/drivers/delay_timer/generic_delay_timer.c b/drivers/delay_timer/generic_delay_timer.c
index ca522e0..0407e38 100644
--- a/drivers/delay_timer/generic_delay_timer.c
+++ b/drivers/delay_timer/generic_delay_timer.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -18,7 +18,26 @@
static timer_ops_t ops;
-static uint32_t get_timer_value(void)
+static uint64_t timeout_cnt_us2cnt(uint32_t us)
+{
+ return ((uint64_t)us * (uint64_t)read_cntfrq_el0()) / 1000000ULL;
+}
+
+static uint64_t generic_delay_timeout_init_us(uint32_t us)
+{
+ uint64_t cnt = timeout_cnt_us2cnt(us);
+
+ cnt += read_cntpct_el0();
+
+ return cnt;
+}
+
+static bool generic_delay_timeout_elapsed(uint64_t expire_cnt)
+{
+ return read_cntpct_el0() > expire_cnt;
+}
+
+static uint32_t generic_delay_get_timer_value(void)
{
/*
* Generic delay timer implementation expects the timer to be a down
@@ -31,9 +50,11 @@
void generic_delay_timer_init_args(uint32_t mult, uint32_t div)
{
- ops.get_timer_value = get_timer_value;
+ ops.get_timer_value = generic_delay_get_timer_value;
ops.clk_mult = mult;
ops.clk_div = div;
+ ops.timeout_init_us = generic_delay_timeout_init_us;
+ ops.timeout_elapsed = generic_delay_timeout_elapsed;
timer_init(&ops);
@@ -59,4 +80,3 @@
generic_delay_timer_init_args(mult, div);
}
-
diff --git a/fdts/stm32mp25-bl2.dtsi b/fdts/stm32mp25-bl2.dtsi
index e250e3f..e6662d0 100644
--- a/fdts/stm32mp25-bl2.dtsi
+++ b/fdts/stm32mp25-bl2.dtsi
@@ -31,6 +31,7 @@
bl32_extra2_uuid = "8ea87bb1-cfa2-3f4d-85fd-e7bba50220d9";
bl33_uuid = "d6d0eea7-fcea-d54b-9782-9934f234b6e4";
hw_cfg_uuid = "08b8f1d9-c9cf-9349-a962-6fbc6b7265cc";
+ soc_fw_cfg_uuid = "9979814b-0376-fb46-8c8e-8d267f7859e0";
tos_fw_cfg_uuid = "26257c1a-dbc6-7f47-8d96-c4c4b0248021";
nt_fw_cfg_uuid = "28da9815-93e8-7e44-ac66-1aaf801550f9";
};
diff --git a/fdts/stm32mp25-bl31.dtsi b/fdts/stm32mp25-bl31.dtsi
new file mode 100644
index 0000000..fa63f63
--- /dev/null
+++ b/fdts/stm32mp25-bl31.dtsi
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ */
+
+/ {
+ soc@0 {
+ rifsc@42080000 {
+ /delete-node/ mmc@48220000;
+ /delete-node/ mmc@48230000;
+ };
+ };
+};
diff --git a/fdts/stm32mp25-fw-config.dtsi b/fdts/stm32mp25-fw-config.dtsi
index 102980d..2f83f24 100644
--- a/fdts/stm32mp25-fw-config.dtsi
+++ b/fdts/stm32mp25-fw-config.dtsi
@@ -31,6 +31,10 @@
id = <BL31_IMAGE_ID>;
};
+ soc_fw-config {
+ id = <SOC_FW_CONFIG_ID>;
+ };
+
tos_fw {
id = <BL32_IMAGE_ID>;
};
diff --git a/fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi b/fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi
index e41c6b9..5bfcf8d 100644
--- a/fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi
+++ b/fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi
@@ -11,6 +11,10 @@
/ {
dtb-registry {
+ soc_fw-config {
+ load-address = <0x0 0x81ff0000>;
+ max-size = <0x10000>;
+ };
tos_fw {
load-address = <0x0 0x82000000>;
max-size = <0x2000000>;
diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h
index d32ead4..d2591dd 100644
--- a/include/arch/aarch32/arch.h
+++ b/include/arch/aarch32/arch.h
@@ -697,8 +697,7 @@
/* PAR fields */
#define PAR_F_SHIFT U(0)
#define PAR_F_MASK ULL(0x1)
-#define PAR_ADDR_SHIFT U(12)
-#define PAR_ADDR_MASK (BIT_64(40) - ULL(1)) /* 40-bits-wide page address */
+#define PAR_ADDR_MASK GENMASK_64(39, 12) /* 28-bits-wide page address */
/*******************************************************************************
* Definitions for system register interface to AMU for FEAT_AMUv1
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
index abe34a4..a29b672 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.h
@@ -194,5 +194,7 @@
static inline bool is_feat_ebep_present(void) { return false; }
__attribute__((always_inline))
static inline bool is_feat_sebep_present(void) { return false; }
+__attribute__((always_inline))
+static inline bool is_feat_d128_present(void) { return false; }
#endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index d8ad881..3f0120c 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -331,6 +331,7 @@
#define PARANGE_0100 U(44)
#define PARANGE_0101 U(48)
#define PARANGE_0110 U(52)
+#define PARANGE_0111 U(56)
#define ID_AA64MMFR0_EL1_ECV_SHIFT U(60)
#define ID_AA64MMFR0_EL1_ECV_MASK ULL(0xf)
@@ -394,6 +395,10 @@
/* ID_AA64MMFR3_EL1 definitions */
#define ID_AA64MMFR3_EL1 S3_0_C0_C7_3
+#define ID_AA64MMFR3_EL1_D128_SHIFT U(32)
+#define ID_AA64MMFR3_EL1_D128_MASK ULL(0xf)
+#define D128_IMPLEMENTED ULL(0x1)
+
#define ID_AA64MMFR3_EL1_S2POE_SHIFT U(20)
#define ID_AA64MMFR3_EL1_S2POE_MASK ULL(0xf)
@@ -406,6 +411,10 @@
#define ID_AA64MMFR3_EL1_S1PIE_SHIFT U(8)
#define ID_AA64MMFR3_EL1_S1PIE_MASK ULL(0xf)
+#define ID_AA64MMFR3_EL1_SCTLR2_SHIFT U(4)
+#define ID_AA64MMFR3_EL1_SCTLR2_MASK ULL(0xf)
+#define SCTLR2_IMPLEMENTED ULL(1)
+
#define ID_AA64MMFR3_EL1_TCRX_SHIFT U(0)
#define ID_AA64MMFR3_EL1_TCRX_MASK ULL(0xf)
@@ -433,6 +442,10 @@
#define ID_AA64PFR1_EL1_GCS_MASK ULL(0xf)
#define GCS_IMPLEMENTED ULL(1)
+#define ID_AA64PFR1_EL1_THE_SHIFT U(48)
+#define ID_AA64PFR1_EL1_THE_MASK ULL(0xf)
+#define THE_IMPLEMENTED ULL(1)
+
#define RNG_TRAP_IMPLEMENTED ULL(0x1)
/* ID_AA64PFR2_EL1 definitions */
@@ -586,10 +599,13 @@
#define SCR_FGTEN2_BIT (UL(1) << 59)
#define SCR_NSE_BIT (ULL(1) << SCR_NSE_SHIFT)
#define SCR_GPF_BIT (UL(1) << 48)
+#define SCR_D128En_BIT (UL(1) << 47)
#define SCR_TWEDEL_SHIFT U(30)
#define SCR_TWEDEL_MASK ULL(0xf)
#define SCR_PIEN_BIT (UL(1) << 45)
+#define SCR_SCTLR2En_BIT (UL(1) << 44)
#define SCR_TCR2EN_BIT (UL(1) << 43)
+#define SCR_RCWMASKEn_BIT (UL(1) << 42)
#define SCR_TRNDR_BIT (UL(1) << 40)
#define SCR_GCSEn_BIT (UL(1) << 39)
#define SCR_HXEn_BIT (UL(1) << 38)
@@ -623,6 +639,8 @@
/* MDCR_EL3 definitions */
#define MDCR_EBWE_BIT (ULL(1) << 43)
+#define MDCR_E3BREC (ULL(1) << 38)
+#define MDCR_E3BREW (ULL(1) << 37)
#define MDCR_EnPMSN_BIT (ULL(1) << 36)
#define MDCR_MPMX_BIT (ULL(1) << 35)
#define MDCR_MCCD_BIT (ULL(1) << 34)
@@ -1167,8 +1185,9 @@
/* PAR_EL1 fields */
#define PAR_F_SHIFT U(0)
#define PAR_F_MASK ULL(0x1)
-#define PAR_ADDR_SHIFT U(12)
-#define PAR_ADDR_MASK (BIT(40) - ULL(1)) /* 40-bits-wide page address */
+
+#define PAR_D128_ADDR_MASK GENMASK(55, 12) /* 44-bits-wide page address */
+#define PAR_ADDR_MASK GENMASK(51, 12) /* 40-bits-wide page address */
/*******************************************************************************
* Definitions for system register interface to SPE
@@ -1473,6 +1492,18 @@
#define TRFCR_EL1 S3_0_C1_C2_1
/*******************************************************************************
+ * FEAT_THE - Translation Hardening Extension Registers
+ ******************************************************************************/
+#define RCWMASK_EL1 S3_0_C13_C0_6
+#define RCWSMASK_EL1 S3_0_C13_C0_3
+
+/*******************************************************************************
+ * FEAT_SCTLR2 - Extension to SCTLR_ELx Registers
+ ******************************************************************************/
+#define SCTLR2_EL2 S3_4_C1_C0_3
+#define SCTLR2_EL1 S3_0_C1_C0_3
+
+/*******************************************************************************
* Definitions for DynamicIQ Shared Unit registers
******************************************************************************/
#define CLUSTERPWRDN_EL1 S3_0_c15_c3_6
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index f03c9d5..ec38d76 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -134,6 +134,12 @@
* +----------------------------+
* | FEAT_FGT2 |
* +----------------------------+
+ * | FEAT_THE |
+ * +----------------------------+
+ * | FEAT_SCTLR2 |
+ * +----------------------------+
+ * | FEAT_D128 |
+ * +----------------------------+
*/
__attribute__((always_inline))
@@ -262,6 +268,20 @@
CREATE_FEATURE_FUNCS(feat_s1pie, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S1PIE_SHIFT,
ID_AA64MMFR3_EL1_S1PIE_MASK, 1U, ENABLE_FEAT_S1PIE)
+/* FEAT_THE: Translation Hardening Extension */
+CREATE_FEATURE_FUNCS(feat_the, id_aa64pfr1_el1, ID_AA64PFR1_EL1_THE_SHIFT,
+ ID_AA64PFR1_EL1_THE_MASK, THE_IMPLEMENTED, ENABLE_FEAT_THE)
+
+/* FEAT_SCTLR2 */
+CREATE_FEATURE_FUNCS(feat_sctlr2, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_SCTLR2_SHIFT,
+ ID_AA64MMFR3_EL1_SCTLR2_MASK, SCTLR2_IMPLEMENTED,
+ ENABLE_FEAT_SCTLR2)
+
+/* FEAT_D128 */
+CREATE_FEATURE_FUNCS(feat_d128, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_D128_SHIFT,
+ ID_AA64MMFR3_EL1_D128_MASK, D128_IMPLEMENTED,
+ ENABLE_FEAT_D128)
+
__attribute__((always_inline))
static inline bool is_feat_sxpie_supported(void)
{
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index a892654..9c36e4b 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -13,6 +13,7 @@
#include <string.h>
#include <arch.h>
+#include <lib/extensions/sysreg128.h>
/**********************************************************************
* Macros which create inline functions to read or write CPU system
@@ -263,7 +264,12 @@
#define write_daifclr(val) SYSREG_WRITE_CONST(daifclr, val)
#define write_daifset(val) SYSREG_WRITE_CONST(daifset, val)
+#if ENABLE_FEAT_D128
+DECLARE_SYSREG128_RW_FUNCS(par_el1)
+#else
DEFINE_SYSREG_RW_FUNCS(par_el1)
+#endif
+
DEFINE_IDREG_READ_FUNC(id_pfr1_el1)
DEFINE_IDREG_READ_FUNC(id_aa64isar0_el1)
DEFINE_IDREG_READ_FUNC(id_aa64isar1_el1)
@@ -443,13 +449,21 @@
DEFINE_SYSREG_RW_FUNCS(tcr_el2)
DEFINE_SYSREG_RW_FUNCS(tcr_el3)
+#if ENABLE_FEAT_D128
+DECLARE_SYSREG128_RW_FUNCS(ttbr0_el1)
+DECLARE_SYSREG128_RW_FUNCS(ttbr1_el1)
+DECLARE_SYSREG128_RW_FUNCS(ttbr0_el2)
+DECLARE_SYSREG128_RW_FUNCS(ttbr1_el2)
+DECLARE_SYSREG128_RW_FUNCS(vttbr_el2)
+#else
DEFINE_SYSREG_RW_FUNCS(ttbr0_el1)
-DEFINE_SYSREG_RW_FUNCS(ttbr0_el2)
-DEFINE_SYSREG_RW_FUNCS(ttbr0_el3)
-
DEFINE_SYSREG_RW_FUNCS(ttbr1_el1)
-
+DEFINE_SYSREG_RW_FUNCS(ttbr0_el2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(ttbr1_el2, TTBR1_EL2)
DEFINE_SYSREG_RW_FUNCS(vttbr_el2)
+#endif
+
+DEFINE_SYSREG_RW_FUNCS(ttbr0_el3)
DEFINE_SYSREG_RW_FUNCS(cptr_el2)
DEFINE_SYSREG_RW_FUNCS(cptr_el3)
@@ -574,7 +588,6 @@
/* Armv8.1 VHE Registers */
DEFINE_RENAME_SYSREG_RW_FUNCS(contextidr_el2, CONTEXTIDR_EL2)
-DEFINE_RENAME_SYSREG_RW_FUNCS(ttbr1_el2, TTBR1_EL2)
/* Armv8.2 ID Registers */
DEFINE_RENAME_IDREG_READ_FUNC(id_aa64mmfr2_el1, ID_AA64MMFR2_EL1)
@@ -670,6 +683,19 @@
DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el1, GCSPR_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el0, GCSPR_EL0)
+/* FEAT_THE Registers */
+#if ENABLE_FEAT_D128
+DECLARE_SYSREG128_RW_FUNCS(rcwmask_el1)
+DECLARE_SYSREG128_RW_FUNCS(rcwsmask_el1)
+#else
+DEFINE_RENAME_SYSREG_RW_FUNCS(rcwmask_el1, RCWMASK_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(rcwsmask_el1, RCWSMASK_EL1)
+#endif
+
+/* FEAT_SCTLR2 Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el1, SCTLR2_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el2, SCTLR2_EL2)
+
/* DynamIQ Control registers */
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmcr_el1, CLUSTERPMCR_EL1)
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 60c5a0c..1666e3b 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -59,24 +59,18 @@
* zero here but are updated ahead of transitioning to a lower EL in the
* function cm_init_context_common().
*
- * SCR_EL3.SIF: Set to one to disable instruction fetches from
- * Non-secure memory.
- *
- * SCR_EL3.EA: Set to one to route External Aborts and SError Interrupts
- * to EL3 when executing at any EL.
- *
* SCR_EL3.EEL2: Set to one if S-EL2 is present and enabled.
*
* NOTE: Modifying EEL2 bit along with EA bit ensures that we mitigate
* against ERRATA_V2_3099206.
* ---------------------------------------------------------------------
*/
- mov_imm x0, (SCR_RESET_VAL | SCR_EA_BIT | SCR_SIF_BIT)
+ mov_imm x0, SCR_RESET_VAL
#if IMAGE_BL31 && defined(SPD_spmd) && SPMD_SPM_AT_SEL2
- mrs x1, id_aa64pfr0_el1
- and x1, x1, #(ID_AA64PFR0_SEL2_MASK << ID_AA64PFR0_SEL2_SHIFT)
- cbz x1, 1f
- orr x0, x0, #SCR_EEL2_BIT
+ mrs x1, id_aa64pfr0_el1
+ and x1, x1, #(ID_AA64PFR0_SEL2_MASK << ID_AA64PFR0_SEL2_SHIFT)
+ cbz x1, 1f
+ orr x0, x0, #SCR_EEL2_BIT
#endif
1:
msr scr_el3, x0
@@ -84,22 +78,11 @@
/* ---------------------------------------------------------------------
* Initialise MDCR_EL3, setting all fields rather than relying on hw.
* Some fields are architecturally UNKNOWN on reset.
- *
- * MDCR_EL3.SDD: Set to one to disable AArch64 Secure self-hosted debug.
- * Debug exceptions, other than Breakpoint Instruction exceptions, are
- * disabled from all ELs in Secure state.
*/
- mov_imm x0, (MDCR_EL3_RESET_VAL | MDCR_SDD_BIT)
+ mov_imm x0, MDCR_EL3_RESET_VAL
msr mdcr_el3, x0
/* ---------------------------------------------------------------------
- * Enable External Aborts and SError Interrupts now that the exception
- * vectors have been setup.
- * ---------------------------------------------------------------------
- */
- msr daifclr, #DAIF_ABT_BIT
-
- /* ---------------------------------------------------------------------
* Initialise CPTR_EL3, setting all fields rather than relying on hw.
* All fields are architecturally UNKNOWN on reset.
* ---------------------------------------------------------------------
@@ -107,28 +90,6 @@
mov_imm x0, CPTR_EL3_RESET_VAL
msr cptr_el3, x0
- /*
- * If Data Independent Timing (DIT) functionality is implemented,
- * always enable DIT in EL3.
- * First assert that the FEAT_DIT build flag matches the feature id
- * register value for DIT.
- */
-#if ENABLE_FEAT_DIT
-#if ENABLE_ASSERTIONS || ENABLE_FEAT_DIT > 1
- mrs x0, id_aa64pfr0_el1
- ubfx x0, x0, #ID_AA64PFR0_DIT_SHIFT, #ID_AA64PFR0_DIT_LENGTH
-#if ENABLE_FEAT_DIT > 1
- cbz x0, 1f
-#else
- cmp x0, #DIT_IMPLEMENTED
- ASM_ASSERT(eq)
-#endif
-
-#endif /* ENABLE_ASSERTIONS */
- mov x0, #DIT_BIT
- msr DIT, x0
-1:
-#endif
.endm
/* -----------------------------------------------------------------------------
@@ -270,6 +231,12 @@
el3_arch_init_common
+ /* ---------------------------------------------------------------------
+ * Set the el3 execution context(i.e. root_context).
+ * ---------------------------------------------------------------------
+ */
+ setup_el3_execution_context
+
.if \_secondary_cold_boot
/* -------------------------------------------------------------
* Check if this is a primary or secondary CPU cold boot.
@@ -460,4 +427,68 @@
end:
.endm
+/*-----------------------------------------------------------------------------
+ * Helper macro to configure EL3 registers we care about, while executing
+ * at EL3/Root world. Root world has its own execution environment and
+ * needs to have its settings configured to be independent of other worlds.
+ * -----------------------------------------------------------------------------
+ */
+ .macro setup_el3_execution_context
+
+ /* ---------------------------------------------------------------------
+ * The following registers need to be part of separate root context
+ * as their values are of importance during EL3 execution.
+ * Hence these registers are overwritten to their intital values,
+ * irrespective of whichever world they return from to ensure EL3 has a
+ * consistent execution context throughout the lifetime of TF-A.
+ *
+ * DAIF.A: Enable External Aborts and SError Interrupts at EL3.
+ *
+ * MDCR_EL3.SDD: Set to one to disable AArch64 Secure self-hosted debug.
+ * Debug exceptions, other than Breakpoint Instruction exceptions, are
+ * disabled from all ELs in Secure state.
+ *
+ * SCR_EL3.EA: Set to one to enable SError interrupts at EL3.
+ *
+ * SCR_EL3.SIF: Set to one to disable instruction fetches from
+ * Non-secure memory.
+ *
+ * PMCR_EL0.DP: Set to one so that the cycle counter,
+ * PMCCNTR_EL0 does not count when event counting is prohibited.
+ * Necessary on PMUv3 <= p7 where MDCR_EL3.{SCCD,MCCD} are not
+ * available.
+ *
+ * PSTATE.DIT: Set to one to enable the Data Independent Timing (DIT)
+ * functionality, if implemented in EL3.
+ * ---------------------------------------------------------------------
+ */
+ msr daifclr, #DAIF_ABT_BIT
+
+ mrs x15, mdcr_el3
+ orr x15, x15, #MDCR_SDD_BIT
+ msr mdcr_el3, x15
+
+ mrs x15, scr_el3
+ orr x15, x15, #SCR_EA_BIT
+ orr x15, x15, #SCR_SIF_BIT
+ msr scr_el3, x15
+
+ mrs x15, pmcr_el0
+ orr x15, x15, #PMCR_EL0_DP_BIT
+ msr pmcr_el0, x15
+
+#if ENABLE_FEAT_DIT
+#if ENABLE_FEAT_DIT > 1
+ mrs x15, id_aa64pfr0_el1
+ ubfx x15, x15, #ID_AA64PFR0_DIT_SHIFT, #ID_AA64PFR0_DIT_LENGTH
+ cbz x15, 1f
+#endif
+ mov x15, #DIT_BIT
+ msr DIT, x15
+ 1:
+#endif
+
+ isb
+ .endm
+
#endif /* EL3_COMMON_MACROS_S */
diff --git a/include/common/par.h b/include/common/par.h
new file mode 100644
index 0000000..c8d67a3
--- /dev/null
+++ b/include/common/par.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PAR_H
+#define PAR_H
+
+#include<arch_features.h>
+#include<lib/extensions/sysreg128.h>
+
+static inline uint64_t get_par_el1_pa(sysreg_t par)
+{
+ uint64_t pa = par & UINT64_MAX;
+ /* PA, bits [51:12] is Output address */
+ uint64_t mask = PAR_ADDR_MASK;
+
+#if ENABLE_FEAT_D128
+ /* If D128 is in use, the PA is in the upper 64-bit word of PAR_EL1 */
+ if (is_feat_d128_supported() && (par & PAR_EL1_D128)) {
+ pa = (par >> 64) & UINT64_MAX;
+ /* PA, bits [55:12] is Output address */
+ mask = PAR_D128_ADDR_MASK;
+ }
+#endif
+ return pa & mask;
+}
+
+#endif /* PAR_H */
diff --git a/include/drivers/arm/dcc.h b/include/drivers/arm/dcc.h
index 072bed5..7f71932 100644
--- a/include/drivers/arm/dcc.h
+++ b/include/drivers/arm/dcc.h
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2021, Xilinx Inc.
+ * Copyright (c) 2021-2022, Xilinx Inc.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,7 +15,7 @@
* Initialize a new dcc console instance and register it with the console
* framework.
*/
-int console_dcc_register(void);
-void console_dcc_unregister(void);
+int console_dcc_register(console_t *console);
+void console_dcc_unregister(console_t *console);
-#endif /* DCC */
+#endif /* DCC_H */
diff --git a/include/drivers/cadence/cdns_sdmmc.h b/include/drivers/cadence/cdns_sdmmc.h
index 8bf3b78..f8d616f 100644
--- a/include/drivers/cadence/cdns_sdmmc.h
+++ b/include/drivers/cadence/cdns_sdmmc.h
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,23 +11,26 @@
#include <drivers/cadence/cdns_combo_phy.h>
#include <drivers/mmc.h>
-#include "socfpga_plat_def.h"
#if MMC_DEVICE_TYPE == 0
-#define CONFIG_DMA_ADDR_T_64BIT 0
+#define CONFIG_DMA_ADDR_T_64BIT 0
#endif
-#define MMC_REG_BASE SOCFPGA_MMC_REG_BASE
-#define COMBO_PHY_REG 0x0
-#define SDHC_EXTENDED_WR_MODE_MASK 0xFFFFFFF7
-#define SDHC_DLL_RESET_MASK 0x00000001
+#define MMC_REG_BASE SOCFPGA_MMC_REG_BASE
+#define COMBO_PHY_REG 0x0
+#define SDHC_EXTENDED_WR_MODE_MASK 0xFFFFFFF7
+#define SDHC_DLL_RESET_MASK 0x00000001
+#define MMC_MAX_BLOCK_LEN 512U
+
/* HRS09 */
#define SDHC_PHY_SW_RESET BIT(0)
-#define SDHC_PHY_INIT_COMPLETE BIT(1)
-#define SDHC_EXTENDED_RD_MODE(x) ((x) << 2)
+#define SDHC_PHY_INIT_COMPLETE BIT(1)
+#define SDHC_EXTENDED_RD_MODE(x) ((x) << 2)
#define EXTENDED_WR_MODE 3
-#define SDHC_EXTENDED_WR_MODE(x) ((x) << 3)
-#define RDCMD_EN 15
+#define SDHC_EXTENDED_WR_MODE(x) ((x) << 3)
+#define RDCMD_EN (3 << 15)
+#define PHY_SW_RESET_EN (1 << 0)
+#define PHY_INIT_COMPLETE_BIT (1 << 1)
#define SDHC_RDCMD_EN(x) ((x) << 15)
#define SDHC_RDDATA_EN(x) ((x) << 16)
@@ -38,9 +42,9 @@
/* • 1111b - Reserved */
/* • 1110b - t_sdmclk*2(27+2) */
/* • 1101b - t_sdmclk*2(26+2) */
-#define READ_CLK 0xa << 16
-#define WRITE_CLK 0xe << 16
-#define DTC_VAL 0xE
+#define READ_CLK 0xa << 16
+#define WRITE_CLK 0xe << 16
+#define DTC_VAL 0xE
/* SRS00 */
/* System Address / Argument 2 / 32-bit block count
@@ -49,18 +53,18 @@
* • SDMA system memory address
* • Auto CMD23 Argument
*/
-#define SAAR (1)
+#define SAAR (1)
/* SRS01 */
/* Transfer Block Size
* This field defines block size for block data transfers
*/
-#define BLOCK_SIZE 0
+#define BLOCK_SIZE 0
/* SDMA Buffer Boundary
* System address boundary can be set for SDMA engine.
*/
-#define SDMA_BUF 7 << 12
+#define SDMA_BUF 7 << 12
/* Block Count For Current Transfer
* To set the number of data blocks can be defined for next transfer
@@ -68,93 +72,108 @@
#define BLK_COUNT_CT 16
/* SRS03 */
-#define CMD_START (U(1) << 31)
+#define CMD_START (U(1) << 31)
#define CMD_USE_HOLD_REG (1 << 29)
#define CMD_UPDATE_CLK_ONLY (1 << 21)
#define CMD_SEND_INIT (1 << 15)
#define CMD_STOP_ABORT_CMD (4 << 22)
#define CMD_RESUME_CMD (2 << 22)
#define CMD_SUSPEND_CMD (1 << 22)
-#define DATA_PRESENT (1 << 21)
-#define CMD_IDX_CHK_ENABLE (1 << 20)
-#define CMD_WRITE (0 << 4)
-#define CMD_READ (1 << 4)
+#define DATA_PRESENT (0x20)
+#define CMD_IDX_CHK_ENABLE (0x10)
+#define CMD_WRITE (0 << 4)
+#define CMD_READ (1 << 4)
#define MULTI_BLK_READ (1 << 5)
-#define RESP_ERR (1 << 7)
-#define CMD_CHECK_RESP_CRC (1 << 19)
-#define RES_TYPE_SEL_48 (2 << 16)
-#define RES_TYPE_SEL_136 (1 << 16)
-#define RES_TYPE_SEL_48_B (3 << 16)
-#define RES_TYPE_SEL_NO (0 << 16)
-#define DMA_ENABLED (1 << 0)
-#define BLK_CNT_EN (1 << 1)
-#define AUTO_CMD_EN (2 << 2)
-#define COM_IDX 24
-#define ERROR_INT (1 << 15)
-#define INT_SBE (1 << 13)
-#define INT_HLE (1 << 12)
-#define INT_FRUN (1 << 11)
-#define INT_DRT (1 << 9)
-#define INT_RTO (1 << 8)
-#define INT_DCRC (1 << 7)
-#define INT_RCRC (1 << 6)
-#define INT_RXDR (1 << 5)
-#define INT_TXDR (1 << 4)
-#define INT_DTO (1 << 3)
+#define RESP_ERR (1 << 7)
+#define CMD_CHECK_RESP_CRC (0x08)
+#define RES_TYPE_SEL_48 (0x2)
+#define RES_TYPE_SEL_136 (0x1)
+#define RES_TYPE_SEL_48_B (0x3)
+#define RES_TYPE_SEL_NO (0x3)
+#define DMA_ENABLED (1 << 0)
+#define BLK_CNT_EN (1 << 1)
+#define AUTO_CMD_EN (2 << 2)
+#define COM_IDX 24
+#define ERROR_INT (1 << 15)
+#define INT_SBE (1 << 13)
+#define INT_HLE (1 << 12)
+#define INT_FRUN (1 << 11)
+#define INT_DRT (1 << 9)
+#define INT_RTO (1 << 8)
+#define INT_DCRC (1 << 7)
+#define INT_RCRC (1 << 6)
+#define INT_RXDR (1 << 5)
+#define INT_TXDR (1 << 4)
+#define INT_DTO (1 << 3)
#define INT_CMD_DONE (1 << 0)
-#define TRAN_COMP (1 << 1)
+#define TRAN_COMP (1 << 1)
/* SRS09 */
#define STATUS_DATA_BUSY BIT(2)
+#define CI 16
+#define CHECK_CARD BIT(CI)
/* SRS10 */
+#define BIT1 (0 << 1)
+#define BIT4 (1 << 1)
+#define BIT8 (1 << 5)
+
/* LED Control
* State of this bit directly drives led port of the host
* in order to control the external LED diode
* Default value 0 << 1
*/
-#define LEDC BIT(0)
-#define LEDC_OFF 0 << 1
+#define LEDC BIT(0)
+#define LEDC_OFF (0 << 1)
/* Data Transfer Width
* Bit used to configure DAT bus width to 1 or 4
* Default value 1 << 1
*/
-#define DT_WIDTH BIT(1)
-#define DTW_4BIT 1 << 1
+#define DT_WIDTH BIT(1)
+#define DTW_4BIT (1 << 1)
/* Extended Data Transfer Width
* This bit is to enable/disable 8-bit DAT bus width mode
* Default value 1 << 5
*/
-#define EDTW_8BIT 1 << 5
+#define EDTW_8BIT BIT(5)
/* High Speed Enable
* Selects operating mode to Default Speed (HSE=0) or High Speed (HSE=1)
*/
-#define HS_EN BIT(2)
+#define HS_EN BIT(2)
/* here 0 defines the 64 Kb size */
#define MAX_64KB_PAGE 0
-#define EMMC_DESC_SIZE (1<<20)
-
+#define EMMC_DESC_SIZE (1<<20)
+#define DTCV_OFFSET (0x22E)
+#define DTCV_VAL (0xE)
+#define CICE_OFFSET (0x20E)
+#define SRS_12_CC_EN (1 << 0)
/* SRS11 */
/* Software Reset For All
* When set to 1, the entire slot is reset
* After completing the reset operation, SRFA bit is automatically cleared
*/
-#define SRFA BIT(24)
+#define SRFA BIT(24)
/* Software Reset For CMD Line
* When set to 1, resets the logic related to the command generation and response checking
*/
-#define SRCMD BIT(25)
+#define SRCMD BIT(25)
/* Software Reset For DAT Line
* When set to 1, resets the logic related to the data path,
* including data buffers and the DMA logic
*/
-#define SRDAT BIT(26)
+#define SRDAT BIT(26)
+
+
+/* SRS12 */
+/* Error mask */
+#define SRS12_ERR_MASK 0xFFFF8000U
+#define CDNS_CSD_BYTE_MASK 0x000000FFU
/* SRS15 */
/* UHS Mode Select
@@ -165,40 +184,43 @@
* • 011b - SDR104
* • 100b - DDR50
*/
-#define SDR12_MODE 0 << 16
-#define SDR25_MODE 1 << 16
-#define SDR50_MODE 2 << 16
-#define SDR104_MODE 3 << 16
-#define DDR50_MODE 4 << 16
+#define SDR12_MODE 0 << 16
+#define SDR25_MODE 1 << 16
+#define SDR50_MODE 2 << 16
+#define SDR104_MODE 3 << 16
+#define DDR50_MODE 4 << 16
/* 1.8V Signaling Enable
* • 0 - for Default Speed, High Speed mode
* • 1 - for UHS-I mode
*/
-#define V18SE BIT(19)
+#define V18SE BIT(19)
/* CMD23 Enable
* In result of Card Identification process,
* Host Driver set this bit to 1 if Card supports CMD23
*/
-#define CMD23_EN BIT(27)
+#define CMD23_EN BIT(27)
/* Host Version 4.00 Enable
* • 0 - Version 3.00
* • 1 - Version 4.00
*/
-#define HV4E BIT(28)
+#define HV4E BIT(28)
/* Conf depends on SRS15.HV4E */
-#define SDMA 0 << 3
-#define ADMA2_32 2 << 3
-#define ADMA2_64 3 << 3
+#define SDMA 0 << 3
+#define ADMA2_32 2 << 3
+#define ADMA2_64 3 << 3
+#define DMA_SEL_BIT 3 << 3
+#define DMA_SEL_BIT_2 2 << 3
+#define DMA_SEL_BIT_3 3 << 3
/* Preset Value Enable
* Setting this bit to 1 triggers an automatically update of SRS11
*/
-#define PVE BIT(31)
+#define PVE BIT(31)
-#define BIT_AD_32 0 << 29
-#define BIT_AD_64 1 << 29
+#define BIT_AD_32 0 << 29
+#define BIT_AD_64 1 << 29
/* SW RESET REG*/
#define SDHC_CDNS_HRS00 (0x00)
@@ -206,7 +228,7 @@
/* PHY access port */
#define SDHC_CDNS_HRS04 0x10
-#define SDHC_CDNS_HRS04_ADDR GENMASK(5, 0)
+#define SDHC_CDNS_HRS04_ADDR GENMASK(5, 0)
/* PHY data access port */
#define SDHC_CDNS_HRS05 0x14
@@ -233,14 +255,51 @@
#define SDHC_CDNS_SRS13 0x234
#define SDHC_CDNS_SRS14 0x238
#define SDHC_CDNS_SRS15 0x23c
+#define SDHC_CDNS_SRS16 0x240
#define SDHC_CDNS_SRS21 0x254
#define SDHC_CDNS_SRS22 0x258
#define SDHC_CDNS_SRS23 0x25c
+#define SDHC_CDNS_SRS24 0x260
+#define SDHC_CDNS_SRS25 0x264
+
+/* SRS00 */
+#define SAAR (1)
+
+/* SRS03 */
+#define CMD_START (U(1) << 31)
+#define CMD_USE_HOLD_REG (1 << 29)
+#define CMD_UPDATE_CLK_ONLY (1 << 21)
+#define CMD_SEND_INIT (1 << 15)
+#define CMD_STOP_ABORT_CMD (4 << 22)
+#define CMD_RESUME_CMD (2 << 22)
+#define CMD_SUSPEND_CMD (1 << 22)
+#define DMA_ENABLED (1 << 0)
+#define BLK_CNT_EN (1 << 1)
+#define AUTO_CMD_EN (2 << 2)
+#define COM_IDX 24
+#define ERROR_INT (1 << 15)
+#define INT_SBE (1 << 13)
+#define INT_HLE (1 << 12)
+#define INT_FRUN (1 << 11)
+#define INT_DRT (1 << 9)
+#define INT_RTO (1 << 8)
+#define INT_DCRC (1 << 7)
+#define INT_RCRC (1 << 6)
+#define INT_RXDR (1 << 5)
+#define INT_TXDR (1 << 4)
+#define INT_DTO (1 << 3)
+#define INT_CMD_DONE (1 << 0)
+#define TRAN_COMP (1 << 1)
+#define CDNS_HOST_CMD_INHIBIT (BIT(0))
+#define CDNS_HOST_DATA_INHIBIT (BIT(1))
+#define ACE_CMD_12 (BIT(2))
+
+#define PAGE_BUFFER_LEN (64 * 1024)
/* HRS07 */
#define SDHC_CDNS_HRS07 0x1c
#define SDHC_IDELAY_VAL(x) ((x) << 0)
-#define SDHC_RW_COMPENSATE(x) ((x) << 16)
+#define SDHC_RW_COMPENSATE(x) ((x) << 16)
/* PHY reset port */
#define SDHC_CDNS_HRS09 0x24
@@ -254,50 +313,49 @@
/* Pinmux headers will reomove after ATF driver implementation */
#define PINMUX_SDMMC_SEL 0x0
-#define PIN0SEL 0x00
-#define PIN1SEL 0x04
-#define PIN2SEL 0x08
-#define PIN3SEL 0x0C
-#define PIN4SEL 0x10
-#define PIN5SEL 0x14
-#define PIN6SEL 0x18
-#define PIN7SEL 0x1C
-#define PIN8SEL 0x20
-#define PIN9SEL 0x24
-#define PIN10SEL 0x28
+#define PIN0SEL 0x00
+#define PIN1SEL 0x04
+#define PIN2SEL 0x08
+#define PIN3SEL 0x0C
+#define PIN4SEL 0x10
+#define PIN5SEL 0x14
+#define PIN6SEL 0x18
+#define PIN7SEL 0x1C
+#define PIN8SEL 0x20
+#define PIN9SEL 0x24
+#define PIN10SEL 0x28
/* HRS16 */
#define SDHC_WRCMD0_DLY(x) ((x) << 0)
#define SDHC_WRCMD1_DLY(x) ((x) << 4)
#define SDHC_WRDATA0_DLY(x) ((x) << 8)
#define SDHC_WRDATA1_DLY(x) ((x) << 12)
-#define SDHC_WRCMD0_SDCLK_DLY(x) ((x) << 16)
-#define SDHC_WRCMD1_SDCLK_DLY(x) ((x) << 20)
-#define SDHC_WRDATA0_SDCLK_DLY(x) ((x) << 24)
-#define SDHC_WRDATA1_SDCLK_DLY(x) ((x) << 28)
+#define SDHC_WRCMD0_SDCLK_DLY(x) ((x) << 16)
+#define SDHC_WRCMD1_SDCLK_DLY(x) ((x) << 20)
+#define SDHC_WRDATA0_SDCLK_DLY(x) ((x) << 24)
+#define SDHC_WRDATA1_SDCLK_DLY(x) ((x) << 28)
/* Shared Macros */
#define SDMMC_CDN(_reg) (SDMMC_CDN_REG_BASE + \
(SDMMC_CDN_##_reg))
/* MMC Peripheral Definition */
-#define SOCFPGA_MMC_BLOCK_SIZE U(8192)
-#define SOCFPGA_MMC_BLOCK_MASK (SOCFPGA_MMC_BLOCK_SIZE - U(1))
-#define SOCFPGA_MMC_BOOT_CLK_RATE (400 * 1000)
+#define SOCFPGA_MMC_BLOCK_MASK (SOCFPGA_MMC_BLOCK_SIZE - U(1))
+#define SOCFPGA_MMC_BOOT_CLK_RATE (400 * 1000)
#define MMC_RESPONSE_NONE 0
-#define SDHC_CDNS_SRS03_VALUE 0x01020013
+#define SDHC_CDNS_SRS03_VALUE 0x01020013
/* Value randomly chosen for eMMC RCA, it should be > 1 */
-#define MMC_FIX_RCA 6
+#define MMC_FIX_RCA 6
#define RCA_SHIFT_OFFSET 16
-#define CMD_EXTCSD_PARTITION_CONFIG 179
-#define CMD_EXTCSD_BUS_WIDTH 183
-#define CMD_EXTCSD_HS_TIMING 185
+#define CMD_EXTCSD_PARTITION_CONFIG 179
+#define CMD_EXTCSD_BUS_WIDTH 183
+#define CMD_EXTCSD_HS_TIMING 185
#define CMD_EXTCSD_SEC_CNT 212
-#define PART_CFG_BOOT_PARTITION1_ENABLE (U(1) << 3)
-#define PART_CFG_PARTITION1_ACCESS (U(1) << 0)
+#define PART_CFG_BOOT_PARTITION1_ENABLE (U(1) << 3)
+#define PART_CFG_PARTITION1_ACCESS (U(1) << 0)
/* Values in EXT CSD register */
#define MMC_BUS_WIDTH_1 U(0)
@@ -305,8 +363,8 @@
#define MMC_BUS_WIDTH_8 U(2)
#define MMC_BUS_WIDTH_DDR_4 U(5)
#define MMC_BUS_WIDTH_DDR_8 U(6)
-#define MMC_BOOT_MODE_BACKWARD (U(0) << 3)
-#define MMC_BOOT_MODE_HS_TIMING (U(1) << 3)
+#define MMC_BOOT_MODE_BACKWARD (U(0) << 3)
+#define MMC_BOOT_MODE_HS_TIMING (U(1) << 3)
#define MMC_BOOT_MODE_DDR (U(2) << 3)
#define EXTCSD_SET_CMD (U(0) << 24)
@@ -315,14 +373,14 @@
#define EXTCSD_WRITE_BYTES (U(3) << 24)
#define EXTCSD_CMD(x) (((x) & 0xff) << 16)
#define EXTCSD_VALUE(x) (((x) & 0xff) << 8)
-#define EXTCSD_CMD_SET_NORMAL U(1)
+#define EXTCSD_CMD_SET_NORMAL U(1)
-#define CSD_TRAN_SPEED_UNIT_MASK GENMASK(2, 0)
-#define CSD_TRAN_SPEED_MULT_MASK GENMASK(6, 3)
-#define CSD_TRAN_SPEED_MULT_SHIFT 3
+#define CSD_TRAN_SPEED_UNIT_MASK GENMASK(2, 0)
+#define CSD_TRAN_SPEED_MULT_MASK GENMASK(6, 3)
+#define CSD_TRAN_SPEED_MULT_SHIFT 3
-#define STATUS_CURRENT_STATE(x) (((x) & 0xf) << 9)
-#define STATUS_READY_FOR_DATA BIT(8)
+#define STATUS_CURRENT_STATE(x) (((x) & 0xf) << 9)
+#define STATUS_READY_FOR_DATA BIT(8)
#define STATUS_SWITCH_ERROR BIT(7)
#define MMC_GET_STATE(x) (((x) >> 9) & 0xf)
#define MMC_STATE_IDLE 0
@@ -343,12 +401,51 @@
#define VHS_2_7_3_6_V BIT(8)
/*ADMA table component*/
-#define ADMA_DESC_ATTR_VALID BIT(0)
+#define ADMA_DESC_ATTR_VALID BIT(0)
#define ADMA_DESC_ATTR_END BIT(1)
#define ADMA_DESC_ATTR_INT BIT(2)
#define ADMA_DESC_ATTR_ACT1 BIT(4)
#define ADMA_DESC_ATTR_ACT2 BIT(5)
-#define ADMA_DESC_TRANSFER_DATA ADMA_DESC_ATTR_ACT2
+#define ADMA_DESC_TRANSFER_DATA ADMA_DESC_ATTR_ACT2
+
+#define HRS_09_EXTENDED_RD_MODE (1 << 2)
+#define HRS_09_EXTENDED_WR_MODE (1 << 3)
+#define HRS_09_RDCMD_EN (1 << 15)
+#define HRS_09_RDDATA_EN (1 << 16)
+#define HRS_10_HCSDCLKADJ_VAL (3)
+
+#define SRS11_SRFA (1 << 24)
+#define SRS11_SRFA_CHK(x) (x >> 24)
+#define CDNS_TIMEOUT (5000)
+
+#define SDHCI_MAKE_CMD(c, f) (((c & 0xff) << 8) | (f & 0xff))
+
+/* Card busy and present */
+#define CARD_BUSY 1
+#define CARD_NOT_BUSY 0
+
+/* 500 ms delay to read the RINST register */
+#define DELAY_MS_SRS_READ 500
+#define DELAY_RES 10
+
+/* Check DV dfi_init val=0 */
+#define IO_MASK_END_DATA 0x0
+
+/* Check DV dfi_init val=2; DDR Mode */
+#define IO_MASK_END_DATA_DDR 0x2
+#define IO_MASK_START_DATA 0x0
+#define DATA_SELECT_OE_END_DATA 0x1
+
+#define TIMEOUT 100000
+
+/* General define */
+#define SDHC_REG_MASK UINT_MAX
+#define SD_HOST_BLOCK_SIZE 0x200
+#define DTCVVAL_DEFAULT_VAL 0xE
+#define CDMMC_DMA_MAX_BUFFER_SIZE 64*1024
+#define CDNSMMC_ADDRESS_MASK U(0x0f)
+#define CONFIG_CDNS_DESC_COUNT 8
+#define SD_HOST_CLK 200000000
enum sd_opcode {
SD_GO_IDLE_STATE = 0,
@@ -389,6 +486,16 @@
SD_APP_SEND_SCR = 51,
};
+enum sd_opr_modes {
+ SD_HOST_OPR_MODE_HV4E_0_SDMA_32 = 0,
+ SD_HOST_OPR_MODE_HV4E_1_SDMA_32,
+ SD_HOST_OPR_MODE_HV4E_1_SDMA_64,
+ SD_HOST_OPR_MODE_HV4E_0_ADMA_32,
+ SD_HOST_OPR_MODE_HV4E_0_ADMA_64,
+ SD_HOST_OPR_MODE_HV4E_1_ADMA_32,
+ SD_HOST_OPR_MODE_HV4E_1_ADMA_64,
+};
+
struct cdns_sdmmc_sdhc {
uint32_t sdhc_extended_rd_mode;
uint32_t sdhc_extended_wr_mode;
@@ -440,9 +547,6 @@
uint32_t combophy;
};
-/* read and write API */
-size_t sdmmc_read_blocks(int lba, uintptr_t buf, size_t size);
-size_t sdmmc_write_blocks(int lba, const uintptr_t buf, size_t size);
struct cdns_idmac_desc {
/*8 bit attribute*/
@@ -468,4 +572,8 @@
struct cdns_sdmmc_sdhc *mmc_sdhc_reg);
void cdns_set_sdmmc_var(struct cdns_sdmmc_combo_phy *combo_phy_reg,
struct cdns_sdmmc_sdhc *sdhc_reg);
+int cdns_mmc_init(struct cdns_sdmmc_params *params, struct mmc_device_info *info);
+int cdns_program_phy_reg(struct cdns_sdmmc_combo_phy *combo_phy_reg,
+ struct cdns_sdmmc_sdhc *sdhc_reg);
+void cdns_host_set_clk(uint32_t clk);
#endif
diff --git a/include/drivers/delay_timer.h b/include/drivers/delay_timer.h
index 20a5543..e9fdfb7 100644
--- a/include/drivers/delay_timer.h
+++ b/include/drivers/delay_timer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2019, Linaro Limited
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -25,27 +25,12 @@
uint32_t (*get_timer_value)(void);
uint32_t clk_mult;
uint32_t clk_div;
+ uint64_t (*timeout_init_us)(uint32_t usec);
+ bool (*timeout_elapsed)(uint64_t cnt);
} timer_ops_t;
-static inline uint64_t timeout_cnt_us2cnt(uint32_t us)
-{
- return ((uint64_t)us * (uint64_t)read_cntfrq_el0()) / 1000000ULL;
-}
-
-static inline uint64_t timeout_init_us(uint32_t us)
-{
- uint64_t cnt = timeout_cnt_us2cnt(us);
-
- cnt += read_cntpct_el0();
-
- return cnt;
-}
-
-static inline bool timeout_elapsed(uint64_t expire_cnt)
-{
- return read_cntpct_el0() > expire_cnt;
-}
-
+uint64_t timeout_init_us(uint32_t usec);
+bool timeout_elapsed(uint64_t cnt);
void mdelay(uint32_t msec);
void udelay(uint32_t usec);
void timer_init(const timer_ops_t *ops_ptr);
diff --git a/include/lib/cpus/aarch64/cortex_a720_ae.h b/include/lib/cpus/aarch64/cortex_a720_ae.h
new file mode 100644
index 0000000..c88b1f9
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_a720_ae.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_A720_AE_H
+#define CORTEX_A720_AE_H
+
+#define CORTEX_A720_AE_MIDR U(0x410FD890)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A720_AE_CPUECTLR_EL1 S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_A720_AE_CPUPWRCTLR_EL1 S3_0_C15_C2_7
+#define CORTEX_A720_AE_CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1)
+
+#endif /* CORTEX_A720_AE_H */
diff --git a/include/lib/cpus/aarch64/cortex_arcadia.h b/include/lib/cpus/aarch64/cortex_arcadia.h
new file mode 100644
index 0000000..8b74de2
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_arcadia.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CORTEX_ARCADIA_H
+#define CORTEX_ARCADIA_H
+
+#define CORTEX_ARCADIA_MIDR U(0x410FD8F0)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_ARCADIA_CPUECTLR_EL1 S3_0_C15_C1_4
+#define CORTEX_ARCADIA_CPUECTLR_EL1_EXTLLC_BIT U(0)
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CORTEX_ARCADIA_CPUPWRCTLR_EL1 S3_0_C15_C2_7
+#define CORTEX_ARCADIA_CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1)
+
+#endif /* CORTEX_ARCADIA_H */
diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S
index 98294b9..5e92934 100644
--- a/include/lib/cpus/aarch64/cpu_macros.S
+++ b/include/lib/cpus/aarch64/cpu_macros.S
@@ -433,7 +433,7 @@
*
* _get_rev:
* Optional parameter that determines whether to insert a call to the CPU revision fetching
- * procedure. Stores the result of this in the temporary register x10.
+ * procedure. Stores the result of this in the temporary register x10 to allow for chaining
*
* clobbers: x0-x10 (PCS compliant)
*/
diff --git a/include/lib/el3_runtime/context_el1.h b/include/lib/el3_runtime/context_el1.h
index 038de25..4379bcf 100644
--- a/include/lib/el3_runtime/context_el1.h
+++ b/include/lib/el3_runtime/context_el1.h
@@ -7,6 +7,8 @@
#ifndef CONTEXT_EL1_H
#define CONTEXT_EL1_H
+#include <lib/extensions/sysreg128.h>
+
#ifndef __ASSEMBLER__
/*******************************************************************************
@@ -28,15 +30,12 @@
uint64_t csselr_el1;
uint64_t sp_el1;
uint64_t esr_el1;
- uint64_t ttbr0_el1;
- uint64_t ttbr1_el1;
uint64_t mair_el1;
uint64_t amair_el1;
uint64_t actlr_el1;
uint64_t tpidr_el1;
uint64_t tpidr_el0;
uint64_t tpidrro_el0;
- uint64_t par_el1;
uint64_t far_el1;
uint64_t afsr0_el1;
uint64_t afsr1_el1;
@@ -44,6 +43,9 @@
uint64_t vbar_el1;
uint64_t mdccint_el1;
uint64_t mdscr_el1;
+ sysreg_t par_el1;
+ sysreg_t ttbr0_el1;
+ sysreg_t ttbr1_el1;
} el1_common_regs_t;
typedef struct el1_aarch32_regs {
@@ -107,6 +109,15 @@
uint64_t gcspr_el0;
} el1_gcs_regs_t;
+typedef struct el1_the_regs {
+ sysreg_t rcwmask_el1;
+ sysreg_t rcwsmask_el1;
+} el1_the_regs_t;
+
+typedef struct el1_sctlr2_regs {
+ uint64_t sctlr2_el1;
+} el1_sctlr2_regs_t;
+
typedef struct el1_sysregs {
el1_common_regs_t common;
@@ -155,6 +166,14 @@
el1_gcs_regs_t gcs;
#endif
+#if ENABLE_FEAT_THE
+ el1_the_regs_t the;
+#endif
+
+#if ENABLE_FEAT_SCTLR2
+ el1_sctlr2_regs_t sctlr2;
+#endif
+
} el1_sysregs_t;
@@ -266,6 +285,25 @@
#define read_el1_ctx_gcs(ctx, reg) ULL(0)
#define write_el1_ctx_gcs(ctx, reg, val)
#endif /* ENABLE_FEAT_GCS */
+
+#if ENABLE_FEAT_THE
+#define read_el1_ctx_the(ctx, reg) (((ctx)->the).reg)
+#define write_el1_ctx_the(ctx, reg, val) ((((ctx)->the).reg) \
+ = (uint64_t) (val))
+#else
+#define read_el1_ctx_the(ctx, reg) ULL(0)
+#define write_el1_ctx_the(ctx, reg, val)
+#endif /* ENABLE_FEAT_THE */
+
+#if ENABLE_FEAT_SCTLR2
+#define read_el1_ctx_sctlr2(ctx, reg) (((ctx)->sctlr2).reg)
+#define write_el1_ctx_sctlr2(ctx, reg, val) ((((ctx)->sctlr2).reg) \
+ = (uint64_t) (val))
+#else
+#define read_el1_ctx_sctlr2(ctx, reg) ULL(0)
+#define write_el1_ctx_sctlr2(ctx, reg, val)
+#endif /* ENABLE_FEAT_SCTLR2 */
+
/******************************************************************************/
#endif /* __ASSEMBLER__ */
diff --git a/include/lib/el3_runtime/context_el2.h b/include/lib/el3_runtime/context_el2.h
index 14c1fb6..7374e39 100644
--- a/include/lib/el3_runtime/context_el2.h
+++ b/include/lib/el3_runtime/context_el2.h
@@ -7,7 +7,10 @@
#ifndef CONTEXT_EL2_H
#define CONTEXT_EL2_H
+#include <lib/extensions/sysreg128.h>
+
#ifndef __ASSEMBLER__
+
/*******************************************************************************
* EL2 Registers:
* AArch64 EL2 system register context structure for preserving the
@@ -40,12 +43,12 @@
uint64_t sp_el2;
uint64_t tcr_el2;
uint64_t tpidr_el2;
- uint64_t ttbr0_el2;
uint64_t vbar_el2;
uint64_t vmpidr_el2;
uint64_t vpidr_el2;
uint64_t vtcr_el2;
- uint64_t vttbr_el2;
+ sysreg_t vttbr_el2;
+ sysreg_t ttbr0_el2;
} el2_common_regs_t;
typedef struct el2_mte2_regs {
@@ -75,7 +78,7 @@
typedef struct el2_vhe_regs {
uint64_t contextidr_el2;
- uint64_t ttbr1_el2;
+ sysreg_t ttbr1_el2;
} el2_vhe_regs_t;
typedef struct el2_ras_regs {
@@ -135,6 +138,10 @@
uint64_t mpamvpmv_el2;
} el2_mpam_regs_t;
+typedef struct el2_sctlr2_regs {
+ uint64_t sctlr2_el2;
+} el2_sctlr2_regs_t;
+
typedef struct el2_sysregs {
el2_common_regs_t common;
@@ -203,6 +210,10 @@
el2_mpam_regs_t mpam;
#endif
+#if ENABLE_FEAT_SCTLR2
+ el2_sctlr2_regs_t sctlr2;
+#endif
+
} el2_sysregs_t;
/*
@@ -214,6 +225,9 @@
#define write_el2_ctx_common(ctx, reg, val) ((((ctx)->common).reg) \
= (uint64_t) (val))
+#define write_el2_ctx_sysreg128(ctx, reg, val) ((((ctx)->common).reg) \
+ = (sysreg_t) (val))
+
#if ENABLE_FEAT_MTE2
#define read_el2_ctx_mte2(ctx, reg) (((ctx)->mte2).reg)
#define write_el2_ctx_mte2(ctx, reg, val) ((((ctx)->mte2).reg) \
@@ -254,6 +268,9 @@
#define read_el2_ctx_vhe(ctx, reg) (((ctx)->vhe).reg)
#define write_el2_ctx_vhe(ctx, reg, val) ((((ctx)->vhe).reg) \
= (uint64_t) (val))
+
+#define write_el2_ctx_vhe_sysreg128(ctx, reg, val) ((((ctx)->vhe).reg) \
+ = (sysreg_t) (val))
#else
#define read_el2_ctx_vhe(ctx, reg) ULL(0)
#define write_el2_ctx_vhe(ctx, reg, val)
@@ -358,6 +375,15 @@
#define write_el2_ctx_mpam(ctx, reg, val)
#endif /* CTX_INCLUDE_MPAM_REGS */
+#if ENABLE_FEAT_SCTLR2
+#define read_el2_ctx_sctlr2(ctx, reg) (((ctx)->sctlr2).reg)
+#define write_el2_ctx_sctlr2(ctx, reg, val) ((((ctx)->sctlr2).reg) \
+ = (uint64_t) (val))
+#else
+#define read_el2_ctx_sctlr2(ctx, reg) ULL(0)
+#define write_el2_ctx_sctlr2(ctx, reg, val)
+#endif /* ENABLE_FEAT_SCTLR2 */
+
/******************************************************************************/
#endif /* __ASSEMBLER__ */
diff --git a/include/lib/el3_runtime/cpu_data.h b/include/lib/el3_runtime/cpu_data.h
index 2c7b619..8b54806 100644
--- a/include/lib/el3_runtime/cpu_data.h
+++ b/include/lib/el3_runtime/cpu_data.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -59,8 +59,19 @@
#define CPU_DATA_CRASH_BUF_END CPU_DATA_CRASH_BUF_OFFSET
#endif
+/* buffer space for EHF data is sizeof(pe_exc_data_t) */
+#define CPU_DATA_EHF_DATA_SIZE 8
+#define CPU_DATA_EHF_DATA_BUF_OFFSET CPU_DATA_CRASH_BUF_END
+
+#if defined(IMAGE_BL31) && EL3_EXCEPTION_HANDLING
+#define CPU_DATA_EHF_DATA_BUF_END (CPU_DATA_EHF_DATA_BUF_OFFSET + \
+ CPU_DATA_EHF_DATA_SIZE)
+#else
+#define CPU_DATA_EHF_DATA_BUF_END CPU_DATA_EHF_DATA_BUF_OFFSET
+#endif /* EL3_EXCEPTION_HANDLING */
+
/* cpu_data size is the data size rounded up to the platform cache line size */
-#define CPU_DATA_SIZE (((CPU_DATA_CRASH_BUF_END + \
+#define CPU_DATA_SIZE (((CPU_DATA_EHF_DATA_BUF_END + \
CACHE_WRITEBACK_GRANULE - 1) / \
CACHE_WRITEBACK_GRANULE) * \
CACHE_WRITEBACK_GRANULE)
@@ -68,7 +79,7 @@
#if ENABLE_RUNTIME_INSTRUMENTATION
/* Temporary space to store PMF timestamps from assembly code */
#define CPU_DATA_PMF_TS_COUNT 1
-#define CPU_DATA_PMF_TS0_OFFSET CPU_DATA_CRASH_BUF_END
+#define CPU_DATA_PMF_TS0_OFFSET CPU_DATA_EHF_DATA_BUF_END
#define CPU_DATA_PMF_TS0_IDX 0
#endif
@@ -159,6 +170,12 @@
assert_cpu_data_crash_stack_offset_mismatch);
#endif
+#if defined(IMAGE_BL31) && EL3_EXCEPTION_HANDLING
+CASSERT(CPU_DATA_EHF_DATA_BUF_OFFSET == __builtin_offsetof
+ (cpu_data_t, ehf_data),
+ assert_cpu_data_ehf_stack_offset_mismatch);
+#endif
+
CASSERT(CPU_DATA_SIZE == sizeof(cpu_data_t),
assert_cpu_data_size_mismatch);
diff --git a/include/lib/extensions/sysreg128.h b/include/lib/extensions/sysreg128.h
new file mode 100644
index 0000000..8854856
--- /dev/null
+++ b/include/lib/extensions/sysreg128.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SYSREG128_H
+#define SYSREG128_H
+
+#ifndef __ASSEMBLER__
+
+#if ENABLE_FEAT_D128
+#include <stdint.h>
+
+typedef uint128_t sysreg_t;
+
+#define PAR_EL1_D128 (((sysreg_t)(1ULL)) << (64))
+
+#define _DECLARE_SYSREG128_READ_FUNC(_name) \
+uint128_t read_ ## _name(void);
+
+#define _DECLARE_SYSREG128_WRITE_FUNC(_name) \
+void write_ ## _name(uint128_t v);
+
+#define DECLARE_SYSREG128_RW_FUNCS(_name) \
+ _DECLARE_SYSREG128_READ_FUNC(_name) \
+ _DECLARE_SYSREG128_WRITE_FUNC(_name)
+#else
+
+typedef uint64_t sysreg_t;
+
+#endif /* ENABLE_FEAT_D128 */
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* SYSREG128_H */
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index ae5aa23..118b537 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -15,6 +15,7 @@
#endif
#if ENABLE_RME
#include <services/rmm_core_manifest.h>
+#include <services/rmm_el3_token_sign.h>
#endif
#include <drivers/fwu/fwu_metadata.h>
#if TRNG_SUPPORT
@@ -376,6 +377,15 @@
uint64_t *remaining_len);
int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
unsigned int type);
+/* The following 3 functions are to be implement if
+ * RMMD_ENABLE_EL3_TOKEN_SIGN=1.
+ * The following three functions are expected to return E_RMM_* error codes.
+ */
+int plat_rmmd_el3_token_sign_get_rak_pub(uintptr_t buf, size_t *len,
+ unsigned int type);
+int plat_rmmd_el3_token_sign_push_req(
+ const struct el3_token_sign_request *req);
+int plat_rmmd_el3_token_sign_pull_resp(struct el3_token_sign_response *resp);
size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared);
int plat_rmmd_load_manifest(struct rmm_manifest *manifest);
#endif
diff --git a/include/services/rmm_el3_token_sign.h b/include/services/rmm_el3_token_sign.h
new file mode 100644
index 0000000..154940c
--- /dev/null
+++ b/include/services/rmm_el3_token_sign.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2024, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RMM_EL3_TOKEN_SIGN_H
+#define RMM_EL3_TOKEN_SIGN_H
+
+#include <stdint.h>
+#include <lib/cassert.h>
+#include <services/rmmd_svc.h>
+
+/*
+ * Defines member of structure and reserves space
+ * for the next member with specified offset.
+ */
+/* cppcheck-suppress [misra-c2012-20.7] */
+#define SET_MEMBER(member, start, end) \
+ union { \
+ member; \
+ unsigned char reserved##end[((end) - (start))]; \
+ }
+
+#define EL3_TOKEN_RESPONSE_MAX_SIG_LEN U(512)
+
+struct el3_token_sign_request {
+ SET_MEMBER(uint32_t sig_alg_id, 0x0, 0x8);
+ SET_MEMBER(uint64_t rec_granule, 0x8, 0x10);
+ SET_MEMBER(uint64_t req_ticket, 0x10, 0x18);
+ SET_MEMBER(uint32_t hash_alg_id, 0x18, 0x20);
+ SET_MEMBER(uint8_t hash_buf[SHA512_DIGEST_SIZE], 0x20, 0x60);
+};
+
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, sig_alg_id) == 0x0U,
+ assert_el3_token_sign_request_sig_alg_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, rec_granule) == 0x8U,
+ assert_el3_token_sign_request_rec_granule_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, req_ticket) == 0x10U,
+ assert_el3_token_sign_request_req_ticket_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, hash_alg_id) == 0x18U,
+ assert_el3_token_sign_request_hash_alg_id_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, hash_buf) == 0x20U,
+ assert_el3_token_sign_request_hash_buf_mismatch);
+
+
+struct el3_token_sign_response {
+ SET_MEMBER(uint64_t rec_granule, 0x0, 0x8);
+ SET_MEMBER(uint64_t req_ticket, 0x8, 0x10);
+ SET_MEMBER(uint16_t sig_len, 0x10, 0x12);
+ SET_MEMBER(uint8_t signature_buf[EL3_TOKEN_RESPONSE_MAX_SIG_LEN], 0x12, 0x212);
+};
+
+CASSERT(__builtin_offsetof(struct el3_token_sign_response, rec_granule) == 0x0U,
+ assert_el3_token_sign_resp_rec_granule_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_response, req_ticket) == 0x8U,
+ assert_el3_token_sign_resp_req_ticket_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_response, sig_len) == 0x10U,
+ assert_el3_token_sign_resp_sig_len_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_response, signature_buf) == 0x12U,
+ assert_el3_token_sign_resp_sig_buf_mismatch);
+
+#endif /* RMM_EL3_TOKEN_SIGN_H */
diff --git a/include/services/rmmd_svc.h b/include/services/rmmd_svc.h
index 635c28e..0cc8628 100644
--- a/include/services/rmmd_svc.h
+++ b/include/services/rmmd_svc.h
@@ -129,8 +129,43 @@
/* 0x1B3 */
#define RMM_ATTEST_GET_PLAT_TOKEN SMC64_RMMD_EL3_FID(U(3))
+/* Starting RMM-EL3 interface version 0.4 */
+#define RMM_EL3_FEATURES SMC64_RMMD_EL3_FID(U(4))
+#define RMM_EL3_FEAT_REG_0_IDX U(0)
+/* Bit 0 of FEAT_REG_0 */
+/* 1 - the feature is present in EL3 , 0 - the feature is absent */
+#define RMM_EL3_FEAT_REG_0_EL3_TOKEN_SIGN_MASK U(0x1)
+
+/*
+ * Function codes to support attestation where EL3 is used to sign
+ * realm attestation tokens. In this model, the private key is not
+ * exposed to the RMM.
+ * The arguments to this SMC are:
+ * arg0 - Function ID.
+ * arg1 - Opcode, one of:
+ * RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP,
+ * RMM_EL3_TOKEN_SIGN_PULL_RESP_OP,
+ * RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
+ * arg2 - Pointer to buffer with request/response structures,
+ * which is in the RMM<->EL3 shared buffer.
+ * arg3 - Buffer size of memory pointed by arg2.
+ * arg4 - ECC Curve, when opcode is RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
+ * The return arguments are:
+ * ret0 - Status/Error
+ * ret1 - Size of public key if opcode is RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
+ */
+#define RMM_EL3_TOKEN_SIGN SMC64_RMMD_EL3_FID(U(5))
+
+/* Opcodes for RMM_EL3_TOKEN_SIGN */
+#define RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP U(1)
+#define RMM_EL3_TOKEN_SIGN_PULL_RESP_OP U(2)
+#define RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP U(3)
+
/* ECC Curve types for attest key generation */
-#define ATTEST_KEY_CURVE_ECC_SECP384R1 0
+#define ATTEST_KEY_CURVE_ECC_SECP384R1 U(0)
+
+/* Identifier for the hash algorithm used for attestation signing */
+#define EL3_TOKEN_SIGN_HASH_ALG_SHA384 U(1)
/*
* RMM_BOOT_COMPLETE originates on RMM when the boot finishes (either cold
@@ -153,7 +188,7 @@
* Increase this when a bug is fixed, or a feature is added without
* breaking compatibility.
*/
-#define RMM_EL3_IFC_VERSION_MINOR (U(3))
+#define RMM_EL3_IFC_VERSION_MINOR (U(4))
#define RMM_EL3_INTERFACE_VERSION \
(((RMM_EL3_IFC_VERSION_MAJOR << 16) & 0x7FFFF) | \
diff --git a/lib/cpus/aarch64/cortex_a57.S b/lib/cpus/aarch64/cortex_a57.S
index 374cc5d..fecb56f 100644
--- a/lib/cpus/aarch64/cortex_a57.S
+++ b/lib/cpus/aarch64/cortex_a57.S
@@ -57,7 +57,7 @@
msr osdlr_el1, x0
isb
- apply_erratum cortex_a57, ERRATUM(817169), ERRATA_A57_817169
+ apply_erratum cortex_a57, ERRATUM(817169), ERRATA_A57_817169, NO_GET_CPU_REV
dsb sy
ret
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index 4c33dda..b9f6081 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -216,7 +216,7 @@
* ----------------------------------------------------
*/
func cortex_a710_core_pwr_dwn
- apply_erratum cortex_a710, ERRATUM(2008768), ERRATA_A710_2008768
+ apply_erratum cortex_a710, ERRATUM(2008768), ERRATA_A710_2008768, NO_GET_CPU_REV
apply_erratum cortex_a710, ERRATUM(2291219), ERRATA_A710_2291219, NO_GET_CPU_REV
/* ---------------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a720_ae.S b/lib/cpus/aarch64/cortex_a720_ae.S
new file mode 100644
index 0000000..42d49c3
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_a720_ae.S
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_a720_ae.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex-A720AE must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex-A720AE supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start cortex_a720_ae
+ /* Disable speculative loads */
+ msr SSBS, xzr
+cpu_reset_func_end cortex_a720_ae
+
+ /* ----------------------------------------------------
+ * HW will do the cache maintenance while powering down
+ * ----------------------------------------------------
+ */
+func cortex_a720_ae_core_pwr_dwn
+ /* ---------------------------------------------------
+ * Enable CPU power down bit in power control register
+ * ---------------------------------------------------
+ */
+ sysreg_bit_set CORTEX_A720_AE_CPUPWRCTLR_EL1, CORTEX_A720_AE_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+
+ isb
+ ret
+endfunc cortex_a720_ae_core_pwr_dwn
+
+ /* ---------------------------------------------
+ * This function provides Cortex-A720AE specific
+ * register information for crash reporting.
+ * It needs to return with x6 pointing to
+ * a list of register names in ascii and
+ * x8 - x15 having values of registers to be
+ * reported.
+ * ---------------------------------------------
+ */
+.section .rodata.cortex_a720_ae_regs, "aS"
+cortex_a720_ae_regs: /* The ascii list of register names to be reported */
+ .asciz "cpuectlr_el1", ""
+
+func cortex_a720_ae_cpu_reg_dump
+ adr x6, cortex_a720_ae_regs
+ mrs x8, CORTEX_A720_AE_CPUECTLR_EL1
+ ret
+endfunc cortex_a720_ae_cpu_reg_dump
+
+declare_cpu_ops cortex_a720_ae, CORTEX_A720_AE_MIDR, \
+ cortex_a720_ae_reset_func, \
+ cortex_a720_ae_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S
index 97e036e..017086a 100644
--- a/lib/cpus/aarch64/cortex_a76.S
+++ b/lib/cpus/aarch64/cortex_a76.S
@@ -505,7 +505,7 @@
*/
sysreg_bit_set CORTEX_A76_CPUPWRCTLR_EL1, CORTEX_A76_CORE_PWRDN_EN_MASK
- apply_erratum cortex_a76, ERRATUM(2743102), ERRATA_A76_2743102
+ apply_erratum cortex_a76, ERRATUM(2743102), ERRATA_A76_2743102, NO_GET_CPU_REV
isb
ret
diff --git a/lib/cpus/aarch64/cortex_a77.S b/lib/cpus/aarch64/cortex_a77.S
index d1fc41a..f53b646 100644
--- a/lib/cpus/aarch64/cortex_a77.S
+++ b/lib/cpus/aarch64/cortex_a77.S
@@ -161,7 +161,7 @@
sysreg_bit_set CORTEX_A77_CPUPWRCTLR_EL1, \
CORTEX_A77_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
- apply_erratum cortex_a77, ERRATUM(2743100), ERRATA_A77_2743100
+ apply_erratum cortex_a77, ERRATUM(2743100), ERRATA_A77_2743100, NO_GET_CPU_REV
isb
ret
diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S
index 5a63e78..1de570a 100644
--- a/lib/cpus/aarch64/cortex_a78.S
+++ b/lib/cpus/aarch64/cortex_a78.S
@@ -192,7 +192,7 @@
func cortex_a78_core_pwr_dwn
sysreg_bit_set CORTEX_A78_CPUPWRCTLR_EL1, CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
- apply_erratum cortex_a78, ERRATUM(2772019), ERRATA_A78_2772019
+ apply_erratum cortex_a78, ERRATUM(2772019), ERRATA_A78_2772019, NO_GET_CPU_REV
isb
ret
diff --git a/lib/cpus/aarch64/cortex_a78c.S b/lib/cpus/aarch64/cortex_a78c.S
index 97d5743..260cc73 100644
--- a/lib/cpus/aarch64/cortex_a78c.S
+++ b/lib/cpus/aarch64/cortex_a78c.S
@@ -132,7 +132,7 @@
*/
sysreg_bit_set CORTEX_A78C_CPUPWRCTLR_EL1, CORTEX_A78C_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
- apply_erratum cortex_a78c, ERRATUM(2772121), ERRATA_A78C_2772121
+ apply_erratum cortex_a78c, ERRATUM(2772121), ERRATA_A78C_2772121, NO_GET_CPU_REV
isb
ret
diff --git a/lib/cpus/aarch64/cortex_arcadia.S b/lib/cpus/aarch64/cortex_arcadia.S
new file mode 100644
index 0000000..c97d87d
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_arcadia.S
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <cortex_arcadia.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex-ARCADIA must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex-ARCADIA supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start cortex_arcadia
+ /* Disable speculative loads */
+ msr SSBS, xzr
+cpu_reset_func_end cortex_arcadia
+
+ /* ----------------------------------------------------
+ * HW will do the cache maintenance while powering down
+ * ----------------------------------------------------
+ */
+func cortex_arcadia_core_pwr_dwn
+ /* ---------------------------------------------------
+ * Enable CPU power down bit in power control register
+ * ---------------------------------------------------
+ */
+ sysreg_bit_set CORTEX_ARCADIA_CPUPWRCTLR_EL1, CORTEX_ARCADIA_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+ isb
+ ret
+endfunc cortex_arcadia_core_pwr_dwn
+
+ /* ---------------------------------------------
+ * This function provides Cortex-Arcadia specific
+ * register information for crash reporting.
+ * It needs to return with x6 pointing to
+ * a list of register names in ascii and
+ * x8 - x15 having values of registers to be
+ * reported.
+ * ---------------------------------------------
+ */
+.section .rodata.cortex_arcadia_regs, "aS"
+cortex_arcadia_regs: /* The ascii list of register names to be reported */
+ .asciz "cpuectlr_el1", ""
+
+func cortex_arcadia_cpu_reg_dump
+ adr x6, cortex_arcadia_regs
+ mrs x8, CORTEX_ARCADIA_CPUECTLR_EL1
+ ret
+endfunc cortex_arcadia_cpu_reg_dump
+
+declare_cpu_ops cortex_arcadia, CORTEX_ARCADIA_MIDR, \
+ cortex_arcadia_reset_func, \
+ cortex_arcadia_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
index ab0b19d..ac60903 100644
--- a/lib/cpus/aarch64/cortex_x2.S
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -126,10 +126,10 @@
check_erratum_ls cortex_x2, ERRATUM(2742423), CPU_REV(2, 1)
-workaround_reset_start cortex_x2, ERRATUM(2768515), ERRATA_X2_2768515
+workaround_runtime_start cortex_x2, ERRATUM(2768515), ERRATA_X2_2768515
/* dsb before isb of power down sequence */
dsb sy
-workaround_reset_end cortex_x2, ERRATUM(2768515)
+workaround_runtime_end cortex_x2, ERRATUM(2768515)
check_erratum_ls cortex_x2, ERRATUM(2768515), CPU_REV(2, 1)
@@ -172,12 +172,7 @@
*/
sysreg_bit_set CORTEX_X2_CPUPWRCTLR_EL1, CORTEX_X2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-#if ERRATA_X2_2768515
- mov x15, x30
- bl cpu_get_rev_var
- bl erratum_cortex_x2_2768515_wa
- mov x30, x15
-#endif /* ERRATA_X2_2768515 */
+ apply_erratum cortex_x2, ERRATUM(2768515), ERRATA_X2_2768515, NO_GET_CPU_REV
isb
ret
endfunc cortex_x2_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_x3.S b/lib/cpus/aarch64/cortex_x3.S
index 248f107..a81c4cf 100644
--- a/lib/cpus/aarch64/cortex_x3.S
+++ b/lib/cpus/aarch64/cortex_x3.S
@@ -114,13 +114,13 @@
* ----------------------------------------------------
*/
func cortex_x3_core_pwr_dwn
- apply_erratum cortex_x3, ERRATUM(2313909), ERRATA_X3_2313909
+ apply_erratum cortex_x3, ERRATUM(2313909), ERRATA_X3_2313909, NO_GET_CPU_REV
/* ---------------------------------------------------
* Enable CPU power down bit in power control register
* ---------------------------------------------------
*/
sysreg_bit_set CORTEX_X3_CPUPWRCTLR_EL1, CORTEX_X3_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
- apply_erratum cortex_x3, ERRATUM(2743088), ERRATA_X3_2743088
+ apply_erratum cortex_x3, ERRATUM(2743088), ERRATA_X3_2743088, NO_GET_CPU_REV
isb
ret
endfunc cortex_x3_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_x4.S b/lib/cpus/aarch64/cortex_x4.S
index 8820de5..320fd90 100644
--- a/lib/cpus/aarch64/cortex_x4.S
+++ b/lib/cpus/aarch64/cortex_x4.S
@@ -111,7 +111,7 @@
*/
sysreg_bit_set CORTEX_X4_CPUPWRCTLR_EL1, CORTEX_X4_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
- apply_erratum cortex_x4, ERRATUM(2740089), ERRATA_X4_2740089
+ apply_erratum cortex_x4, ERRATUM(2740089), ERRATA_X4_2740089, NO_GET_CPU_REV
isb
ret
diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S
index 50e1ae3..f727226 100644
--- a/lib/cpus/aarch64/neoverse_n1.S
+++ b/lib/cpus/aarch64/neoverse_n1.S
@@ -236,7 +236,7 @@
*/
sysreg_bit_set NEOVERSE_N1_CPUPWRCTLR_EL1, NEOVERSE_N1_CORE_PWRDN_EN_MASK
- apply_erratum neoverse_n1, ERRATUM(2743102), ERRATA_N1_2743102
+ apply_erratum neoverse_n1, ERRATUM(2743102), ERRATA_N1_2743102, NO_GET_CPU_REV
isb
ret
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index 7d7cc44..d2237f1 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -265,8 +265,7 @@
cpu_reset_func_end neoverse_n2
func neoverse_n2_core_pwr_dwn
-
- apply_erratum neoverse_n2, ERRATUM(2009478), ERRATA_N2_2009478
+ apply_erratum neoverse_n2, ERRATUM(2009478), ERRATA_N2_2009478, NO_GET_CPU_REV
apply_erratum neoverse_n2, ERRATUM(2326639), ERRATA_N2_2326639, NO_GET_CPU_REV
/* ---------------------------------------------------
@@ -276,7 +275,7 @@
*/
sysreg_bit_set NEOVERSE_N2_CPUPWRCTLR_EL1, NEOVERSE_N2_CORE_PWRDN_EN_BIT
- apply_erratum neoverse_n2, ERRATUM(2743089), ERRATA_N2_2743089
+ apply_erratum neoverse_n2, ERRATUM(2743089), ERRATA_N2_2743089, NO_GET_CPU_REV
isb
ret
diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S
index 89299b7..1ec3e94 100644
--- a/lib/cpus/aarch64/neoverse_v1.S
+++ b/lib/cpus/aarch64/neoverse_v1.S
@@ -253,7 +253,7 @@
* ---------------------------------------------
*/
sysreg_bit_set NEOVERSE_V1_CPUPWRCTLR_EL1, NEOVERSE_V1_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
- apply_erratum neoverse_v1, ERRATUM(2743093), ERRATA_V1_2743093
+ apply_erratum neoverse_v1, ERRATUM(2743093), ERRATA_V1_2743093, NO_GET_CPU_REV
isb
ret
diff --git a/lib/cpus/aarch64/neoverse_v2.S b/lib/cpus/aarch64/neoverse_v2.S
index d8c32a4..ca66f8d 100644
--- a/lib/cpus/aarch64/neoverse_v2.S
+++ b/lib/cpus/aarch64/neoverse_v2.S
@@ -100,7 +100,7 @@
* ---------------------------------------------------
*/
sysreg_bit_set NEOVERSE_V2_CPUPWRCTLR_EL1, NEOVERSE_V2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
- apply_erratum neoverse_v2, ERRATUM(2801372), ERRATA_V2_2801372
+ apply_erratum neoverse_v2, ERRATUM(2801372), ERRATA_V2_2801372, NO_GET_CPU_REV
isb
ret
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index ab9d4b6..a353a87 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -400,9 +400,6 @@
/* PMUv3 is presumed to be always present */
mrs x9, pmcr_el0
str x9, [sp, #CTX_EL3STATE_OFFSET + CTX_PMCR_EL0]
- /* Disable cycle counter when event counting is prohibited */
- orr x9, x9, #PMCR_EL0_DP_BIT
- msr pmcr_el0, x9
isb
#if CTX_INCLUDE_PAUTH_REGS
/* ----------------------------------------------------------
@@ -444,12 +441,7 @@
*/
func prepare_el3_entry
save_gp_pmcr_pauth_regs
- enable_serror_at_el3
- /*
- * Set the PSTATE bits not described in the Aarch64.TakeException
- * pseudocode to their default values.
- */
- set_unset_pstate_bits
+ setup_el3_execution_context
ret
endfunc prepare_el3_entry
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 6210356..d2222fa 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -33,6 +33,7 @@
#include <lib/extensions/sme.h>
#include <lib/extensions/spe.h>
#include <lib/extensions/sve.h>
+#include <lib/extensions/sysreg128.h>
#include <lib/extensions/sys_reg_trace.h>
#include <lib/extensions/tcr2.h>
#include <lib/extensions/trbe.h>
@@ -260,6 +261,29 @@
*/
scr_el3 |= get_scr_el3_from_routing_model(NON_SECURE);
#endif
+
+ if (is_feat_the_supported()) {
+ /* Set the RCWMASKEn bit in SCR_EL3 to enable access to
+ * RCWMASK_EL1 and RCWSMASK_EL1 registers.
+ */
+ scr_el3 |= SCR_RCWMASKEn_BIT;
+ }
+
+ if (is_feat_sctlr2_supported()) {
+ /* Set the SCTLR2En bit in SCR_EL3 to enable access to
+ * SCTLR2_ELx registers.
+ */
+ scr_el3 |= SCR_SCTLR2En_BIT;
+ }
+
+ if (is_feat_d128_supported()) {
+ /* Set the D128En bit in SCR_EL3 to enable access to 128-bit
+ * versions of TTBR0_EL1, TTBR1_EL1, RCWMASK_EL1, RCWSMASK_EL1,
+ * PAR_EL1 and TTBR1_EL2, TTBR0_EL2 and VTTBR_EL2 registers.
+ */
+ scr_el3 |= SCR_D128En_BIT;
+ }
+
write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
/* Initialize EL2 context registers */
@@ -760,13 +784,6 @@
*/
trf_enable(ctx);
}
-
- if (is_feat_brbe_supported()) {
- /*
- * Enable FEAT_BRBE for Non-Secure and prohibit for Secure state.
- */
- brbe_enable(ctx);
- }
#endif /* IMAGE_BL31 */
}
@@ -792,6 +809,10 @@
debugv8p9_extended_bp_wp_enable(ctx);
}
+ if (is_feat_brbe_supported()) {
+ brbe_enable(ctx);
+ }
+
pmuv3_enable(ctx);
#endif /* IMAGE_BL31 */
}
@@ -1310,12 +1331,13 @@
write_el2_ctx_common(ctx, sp_el2, read_sp_el2());
write_el2_ctx_common(ctx, tcr_el2, read_tcr_el2());
write_el2_ctx_common(ctx, tpidr_el2, read_tpidr_el2());
- write_el2_ctx_common(ctx, ttbr0_el2, read_ttbr0_el2());
write_el2_ctx_common(ctx, vbar_el2, read_vbar_el2());
write_el2_ctx_common(ctx, vmpidr_el2, read_vmpidr_el2());
write_el2_ctx_common(ctx, vpidr_el2, read_vpidr_el2());
write_el2_ctx_common(ctx, vtcr_el2, read_vtcr_el2());
- write_el2_ctx_common(ctx, vttbr_el2, read_vttbr_el2());
+
+ write_el2_ctx_sysreg128(ctx, ttbr0_el2, read_ttbr0_el2());
+ write_el2_ctx_sysreg128(ctx, vttbr_el2, read_vttbr_el2());
}
static void el2_sysregs_context_restore_common(el2_sysregs_t *ctx)
@@ -1391,7 +1413,7 @@
if (is_feat_vhe_supported()) {
write_el2_ctx_vhe(el2_sysregs_ctx, contextidr_el2,
read_contextidr_el2());
- write_el2_ctx_vhe(el2_sysregs_ctx, ttbr1_el2, read_ttbr1_el2());
+ write_el2_ctx_vhe_sysreg128(el2_sysregs_ctx, ttbr1_el2, read_ttbr1_el2());
}
if (is_feat_ras_supported()) {
@@ -1437,6 +1459,10 @@
write_el2_ctx_gcs(el2_sysregs_ctx, gcscr_el2, read_gcscr_el2());
write_el2_ctx_gcs(el2_sysregs_ctx, gcspr_el2, read_gcspr_el2());
}
+
+ if (is_feat_sctlr2_supported()) {
+ write_el2_ctx_sctlr2(el2_sysregs_ctx, sctlr2_el2, read_sctlr2_el2());
+ }
}
/*******************************************************************************
@@ -1524,6 +1550,10 @@
write_gcscr_el2(read_el2_ctx_gcs(el2_sysregs_ctx, gcscr_el2));
write_gcspr_el2(read_el2_ctx_gcs(el2_sysregs_ctx, gcspr_el2));
}
+
+ if (is_feat_sctlr2_supported()) {
+ write_sctlr2_el2(read_el2_ctx_sctlr2(el2_sysregs_ctx, sctlr2_el2));
+ }
}
#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
@@ -1712,6 +1742,16 @@
write_el1_ctx_gcs(ctx, gcspr_el1, read_gcspr_el1());
write_el1_ctx_gcs(ctx, gcspr_el0, read_gcspr_el0());
}
+
+ if (is_feat_the_supported()) {
+ write_el1_ctx_the(ctx, rcwmask_el1, read_rcwmask_el1());
+ write_el1_ctx_the(ctx, rcwsmask_el1, read_rcwsmask_el1());
+ }
+
+ if (is_feat_sctlr2_supported()) {
+ write_el1_ctx_sctlr2(ctx, sctlr2_el1, read_sctlr2_el1());
+ }
+
}
static void el1_sysregs_context_restore(el1_sysregs_t *ctx)
@@ -1807,6 +1847,16 @@
write_gcspr_el1(read_el1_ctx_gcs(ctx, gcspr_el1));
write_gcspr_el0(read_el1_ctx_gcs(ctx, gcspr_el0));
}
+
+ if (is_feat_the_supported()) {
+ write_rcwmask_el1(read_el1_ctx_the(ctx, rcwmask_el1));
+ write_rcwsmask_el1(read_el1_ctx_the(ctx, rcwsmask_el1));
+ }
+
+ if (is_feat_sctlr2_supported()) {
+ write_sctlr2_el1(read_el1_ctx_sctlr2(ctx, sctlr2_el1));
+ }
+
}
/*******************************************************************************
diff --git a/lib/extensions/brbe/brbe.c b/lib/extensions/brbe/brbe.c
index dde0266..fef6647 100644
--- a/lib/extensions/brbe/brbe.c
+++ b/lib/extensions/brbe/brbe.c
@@ -16,11 +16,13 @@
/*
* MDCR_EL3.SBRBE = 0b01
- *
* Allows BRBE usage in non-secure world and prohibited in
* secure world.
+ *
+ * MDCR_EL3.{E3BREW, E3BREC} = 0b00
+ * Branch recording at EL3 is disabled
*/
- mdcr_el3_val &= ~(MDCR_SBRBE_MASK << MDCR_SBRBE_SHIFT);
+ mdcr_el3_val &= ~((MDCR_SBRBE_MASK << MDCR_SBRBE_SHIFT) | MDCR_E3BREW | MDCR_E3BREC);
mdcr_el3_val |= (0x1UL << MDCR_SBRBE_SHIFT);
write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
}
diff --git a/lib/extensions/sysreg128/sysreg128.S b/lib/extensions/sysreg128/sysreg128.S
new file mode 100644
index 0000000..08cff2f
--- /dev/null
+++ b/lib/extensions/sysreg128/sysreg128.S
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <lib/extensions/sysreg128.h>
+
+ .global read_par_el1
+ .global write_par_el1
+ .global read_ttbr0_el1
+ .global write_ttbr0_el1
+ .global read_ttbr1_el1
+ .global write_ttbr1_el1
+ .global read_ttbr0_el2
+ .global write_ttbr0_el2
+ .global read_ttbr1_el2
+ .global write_ttbr1_el2
+ .global read_vttbr_el2
+ .global write_vttbr_el2
+ .global read_rcwmask_el1
+ .global write_rcwmask_el1
+ .global read_rcwsmask_el1
+ .global write_rcwsmask_el1
+
+/*
+ * _mrrs - Move System register to two adjacent general-purpose
+ * registers.
+ * Instruction: MRRS <Xt>, <Xt+1>, (<systemreg>|S<op0>_<op1>_<Cn>_<Cm>_<op2>)
+ *
+ * Arguments/Opcode bit field:
+ * regins: System register opcode.
+ *
+ * Clobbers: x0,x1,x2
+ */
+.macro _mrrs regins:req
+#if ENABLE_FEAT_D128 == 2
+ mrs x0, ID_AA64MMFR3_EL1
+ tst x0, #(ID_AA64MMFR3_EL1_D128_MASK << ID_AA64MMFR3_EL1_D128_SHIFT)
+ bne 1f
+ /* If FEAT_D128 is not implemented then use mrs */
+ .inst 0xD5300000 | (\regins)
+ ret
+#endif
+1:
+ .inst 0xD5700000 | (\regins)
+ ret
+.endm
+
+/*
+ * _msrr - Move two adjacent general-purpose registers to System register.
+ * Instruction: MSRR (<systemreg>|S<op0>_<op1>_<Cn>_<Cm>_<op2>), <Xt>, <Xt+1>
+ *
+ * Arguments/Opcode bit field:
+ * regins: System register opcode.
+ *
+ * Clobbers: x0,x1,x2
+ */
+.macro _msrr regins:req
+ /* If FEAT_D128 is not implemented use msr, dont tamper
+ * x0, x1 as they maybe used for mrrs */
+#if ENABLE_FEAT_D128 == 2
+ mrs x2, ID_AA64MMFR3_EL1
+ tst x2, #(ID_AA64MMFR3_EL1_D128_MASK << ID_AA64MMFR3_EL1_D128_SHIFT)
+ bne 1f
+ /* If FEAT_D128 is not implemented then use msr */
+ .inst 0xD5100000 | (\regins)
+ ret
+#endif
+1:
+ .inst 0xD5500000 | (\regins)
+ ret
+.endm
+
+func read_par_el1
+ _mrrs 0x87400 /* S3_0_C7_C4_0 */
+endfunc read_par_el1
+
+func write_par_el1
+ _msrr 0x87400
+endfunc write_par_el1
+
+func read_ttbr0_el1
+ _mrrs 0x82000 /* S3_0_C2_C0_0 */
+endfunc read_ttbr0_el1
+
+func write_ttbr0_el1
+ _msrr 0x82000
+endfunc write_ttbr0_el1
+
+func read_ttbr1_el1
+ _mrrs 0x82020 /* S3_0_C2_C0_1 */
+endfunc read_ttbr1_el1
+
+func write_ttbr1_el1
+ _msrr 0x82020
+endfunc write_ttbr1_el1
+
+func read_ttbr0_el2
+ _mrrs 0xC2000 /* S3_4_C2_C0_0 */
+endfunc read_ttbr0_el2
+
+func write_ttbr0_el2
+ _msrr 0xC2000
+endfunc write_ttbr0_el2
+
+func read_ttbr1_el2
+ _mrrs 0xC2020 /* S3_4_C2_C0_1 */
+endfunc read_ttbr1_el2
+
+func write_ttbr1_el2
+ _msrr 0xC2020
+endfunc write_ttbr1_el2
+
+func read_vttbr_el2
+ _mrrs 0xC2100 /* S3_4_C2_C1_0 */
+endfunc read_vttbr_el2
+
+func write_vttbr_el2
+ _msrr 0xC2100
+endfunc write_vttbr_el2
+
+func read_rcwmask_el1
+ _mrrs 0x8D0C0 /* S3_0_C13_C0_6 */
+endfunc read_rcwmask_el1
+
+func write_rcwmask_el1
+ _msrr 0x8D0C0
+endfunc write_rcwmask_el1
+
+func read_rcwsmask_el1
+ _mrrs 0x8D060 /* S3_0_C13_C0_3 */
+endfunc read_rcwsmask_el1
+
+func write_rcwsmask_el1
+ _msrr 0x8D060
+endfunc write_rcwsmask_el1
diff --git a/lib/psci/aarch64/psci_helpers.S b/lib/psci/aarch64/psci_helpers.S
index 3b77ab2..cca08c1 100644
--- a/lib/psci/aarch64/psci_helpers.S
+++ b/lib/psci/aarch64/psci_helpers.S
@@ -1,11 +1,12 @@
/*
- * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <asm_macros.S>
#include <assert_macros.S>
+#include <cpu_macros.S>
#include <lib/psci/psci.h>
#include <platform_def.h>
@@ -124,9 +125,8 @@
* -----------------------------------------------------------------------
*/
func psci_power_down_wfi
-#if ERRATA_A510_2684597
- bl apply_cpu_pwr_dwn_errata
-#endif
+ apply_erratum cortex_a510, ERRATUM(2684597), ERRATA_A510_2684597
+
dsb sy // ensure write buffer empty
1:
wfi
diff --git a/lib/psci/aarch64/runtime_errata.S b/lib/psci/aarch64/runtime_errata.S
deleted file mode 100644
index 89e3e12..0000000
--- a/lib/psci/aarch64/runtime_errata.S
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <asm_macros.S>
-#include <cortex_a510.h>
-#include <cpu_macros.S>
-
-/*
- * void apply_cpu_pwr_dwn_errata(void);
- *
- * This function applies various CPU errata during power down.
- */
- .globl apply_cpu_pwr_dwn_errata
-func apply_cpu_pwr_dwn_errata
- mov x19, x30
- bl cpu_get_rev_var
- mov x18, x0
-
-#if ERRATA_A510_2684597
- bl erratum_cortex_a510_2684597_wa
-#endif
-
- ret x19
-endfunc apply_cpu_pwr_dwn_errata
diff --git a/lib/psci/psci_lib.mk b/lib/psci/psci_lib.mk
index c71580f..527ad3a 100644
--- a/lib/psci/psci_lib.mk
+++ b/lib/psci/psci_lib.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -21,8 +21,7 @@
lib/psci/${ARCH}/psci_helpers.S
ifeq (${ARCH}, aarch64)
-PSCI_LIB_SOURCES += lib/el3_runtime/aarch64/context.S \
- lib/psci/aarch64/runtime_errata.S
+PSCI_LIB_SOURCES += lib/el3_runtime/aarch64/context.S
endif
ifeq (${USE_COHERENT_MEM}, 1)
diff --git a/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c
index f4195f4..f207266 100644
--- a/lib/xlat_tables/aarch64/xlat_tables.c
+++ b/lib/xlat_tables/aarch64/xlat_tables.c
@@ -66,7 +66,7 @@
*/
static const unsigned int pa_range_bits_arr[] = {
PARANGE_0000, PARANGE_0001, PARANGE_0010, PARANGE_0011, PARANGE_0100,
- PARANGE_0101, PARANGE_0110
+ PARANGE_0101, PARANGE_0110, PARANGE_0111
};
static unsigned long long get_max_supported_pa(void)
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index 18e001b..7321fd7 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
@@ -109,7 +109,7 @@
*/
static const unsigned int pa_range_bits_arr[] = {
PARANGE_0000, PARANGE_0001, PARANGE_0010, PARANGE_0011, PARANGE_0100,
- PARANGE_0101, PARANGE_0110
+ PARANGE_0101, PARANGE_0110, PARANGE_0111
};
unsigned long long xlat_arch_get_max_supported_pa(void)
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index 675779f..39f6223 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -90,7 +90,7 @@
# Enable the features which are mandatory from ARCH version 8.9 and upwards.
ifeq "8.9" "$(word 1, $(sort 8.9 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-armv8-9-a-feats := ENABLE_FEAT_TCR2 ENABLE_FEAT_DEBUGV8P9
+armv8-9-a-feats := ENABLE_FEAT_TCR2 ENABLE_FEAT_DEBUGV8P9 ENABLE_FEAT_SCTLR2
# 8.8 Compliant
armv8-9-a-feats += ${armv8-8-a-feats}
FEAT_LIST := ${armv8-9-a-feats}
@@ -219,6 +219,9 @@
# Flag to enable access to TCR2 (FEAT_TCR2).
ENABLE_FEAT_TCR2 ?= 0
+# Flag to enable access to SCTLR2 (FEAT_SCTLR2).
+ENABLE_FEAT_SCTLR2 ?= 0
+
#
################################################################################
# Optional Features defaulted to 0 or 2, if they are not enabled from
@@ -307,13 +310,6 @@
# registers, by setting SCR_EL3.TRNDR.
ENABLE_FEAT_RNG_TRAP ?= 0
-ifeq ($(CTX_INCLUDE_MTE_REGS),1)
- $(warning CTX_INCLUDE_MTE_REGS option is deprecated, Check ENABLE_FEAT_MTE2 usage)
-endif
-ifneq ($(ENABLE_FEAT_MTE),)
- $(warning ENABLE_FEAT_MTE option is deprecated, Check ENABLE_FEAT_MTE2 usage)
-endif
-
# Enable FEAT_MTE2. This must be set to 1 if the platform wants
# to use this feature and is enabled at ELX.
ENABLE_FEAT_MTE2 ?= 0
@@ -341,6 +337,13 @@
ENABLE_FEAT_FGT2 ?= 0
#----
+# 8.8
+#----
+
+# Flag to enable FEAT_THE (Translation Hardening Extension)
+ENABLE_FEAT_THE ?= 0
+
+#----
# 8.9
#----
@@ -403,6 +406,12 @@
ENABLE_BRBE_FOR_NS ?= 0
#----
+# 9.3
+#----
+# Flag to enable access to Arm v9.3 FEAT_D128 extension
+ENABLE_FEAT_D128 ?= 0
+
+#----
#9.4
#----
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 8c884b4..584542c 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -409,3 +409,6 @@
# Allow platforms to save/restore DSU PMU registers over a power cycle.
# Disabled by default and must be enabled by individual platforms.
PRESERVE_DSU_PMU_REGS := 0
+
+# Enable RMMD to forward attestation requests from RMM to EL3.
+RMMD_ENABLE_EL3_TOKEN_SIGN := 0
diff --git a/plat/allwinner/sun50i_a64/platform.mk b/plat/allwinner/sun50i_a64/platform.mk
index e3c7c52..cced7f0 100644
--- a/plat/allwinner/sun50i_a64/platform.mk
+++ b/plat/allwinner/sun50i_a64/platform.mk
@@ -4,6 +4,10 @@
# SPDX-License-Identifier: BSD-3-Clause
#
+# To report supported idle states
+# this has to be defined before allwinner-common.mk
+SUNXI_AMEND_DTB := 1
+
# The differences between the platform are covered by the include files.
include plat/allwinner/common/allwinner-common.mk
diff --git a/plat/allwinner/sun50i_a64/platform_defaults.mk b/plat/allwinner/sun50i_a64/platform_defaults.mk
new file mode 100644
index 0000000..5b61029
--- /dev/null
+++ b/plat/allwinner/sun50i_a64/platform_defaults.mk
@@ -0,0 +1,9 @@
+#
+# Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# LTO has to be enabled on this platform due to memory constraints
+ENABLE_LTO := 1
+
diff --git a/plat/amd/versal2/aarch64/common.c b/plat/amd/versal2/aarch64/common.c
index 3ab3dca..5fce01e 100644
--- a/plat/amd/versal2/aarch64/common.c
+++ b/plat/amd/versal2/aarch64/common.c
@@ -31,7 +31,7 @@
MAP_REGION_FLAT(DEVICE2_BASE, DEVICE2_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(CRF_BASE, CRF_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(IPI_BASE, IPI_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
-#if defined(TRANSFER_LIST)
+#if TRANSFER_LIST
MAP_REGION_FLAT(FW_HANDOFF_BASE, FW_HANDOFF_BASE + FW_HANDOFF_SIZE,
MT_MEMORY | MT_RW | MT_NS),
#endif
diff --git a/plat/amd/versal2/bl31_setup.c b/plat/amd/versal2/bl31_setup.c
index 970fca9..47d4c2c 100644
--- a/plat/amd/versal2/bl31_setup.c
+++ b/plat/amd/versal2/bl31_setup.c
@@ -20,12 +20,14 @@
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
#include <plat_arm.h>
+#include <plat_console.h>
#include <scmi.h>
#include <def.h>
#include <plat_fdt.h>
#include <plat_private.h>
#include <plat_startup.h>
+#include <plat_xfer_list.h>
#include <pm_api_sys.h>
#include <pm_client.h>
@@ -125,30 +127,7 @@
uart_clock = get_uart_clk();
- if (CONSOLE_IS(pl011_0) || CONSOLE_IS(pl011_1)) {
- static console_t _runtime_console;
-
- /* Initialize the console to provide early debug support */
- rc = console_pl011_register(UART_BASE, uart_clock,
- UART_BAUDRATE,
- &_runtime_console);
- if (rc == 0) {
- panic();
- }
-
- console_set_scope(&_runtime_console, CONSOLE_FLAG_BOOT |
- CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
- } else if (CONSOLE_IS(dcc)) {
- /* Initialize the dcc console for debug.
- * dcc is over jtag and does not configures uart0 or uart1.
- */
- rc = console_dcc_register();
- if (rc == 0) {
- panic();
- }
- } else {
- /* Making MISRA C 2012 15.7 compliant */
- }
+ setup_console();
NOTICE("TF-A running on %s %d.%d\n", board_name_decode(),
platform_version / 10U, platform_version % 10U);
@@ -168,7 +147,12 @@
SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
- bl31_set_default_config();
+
+ rc = transfer_list_populate_ep_info(&bl32_image_ep_info, &bl33_image_ep_info);
+ if (rc == TL_OPS_NON || rc == TL_OPS_CUS) {
+ NOTICE("BL31: TL not found, using default config\n");
+ bl31_set_default_config();
+ }
long rev_var = cpu_get_rev_var();
@@ -188,7 +172,7 @@
uint32_t i;
/* Validate 'handler' and 'id' parameters */
- if (handler == NULL || index >= MAX_INTR_EL3) {
+ if ((handler == NULL) || (index >= MAX_INTR_EL3)) {
return -EINVAL;
}
@@ -254,6 +238,8 @@
if (rc != 0) {
panic();
}
+
+ console_switch_state(CONSOLE_FLAG_RUNTIME);
}
/*
@@ -262,10 +248,6 @@
void bl31_plat_arch_setup(void)
{
const mmap_region_t bl_regions[] = {
-#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
- MAP_REGION_FLAT(XILINX_OF_BOARD_DTB_ADDR, XILINX_OF_BOARD_DTB_MAX_SIZE,
- MT_MEMORY | MT_RW | MT_NS),
-#endif
MAP_REGION_FLAT(BL31_BASE, BL31_END - BL31_BASE,
MT_MEMORY | MT_RW | MT_SECURE),
MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,
diff --git a/plat/amd/versal2/include/def.h b/plat/amd/versal2/include/def.h
index 67244a4..f3a7907 100644
--- a/plat/amd/versal2/include/def.h
+++ b/plat/amd/versal2/include/def.h
@@ -15,12 +15,23 @@
#define MAX_INTR_EL3 2
/* List all consoles */
-#define CONSOLE_ID_pl011 U(1)
-#define CONSOLE_ID_pl011_0 U(1)
-#define CONSOLE_ID_pl011_1 U(2)
-#define CONSOLE_ID_dcc U(3)
+#define VERSAL2_CONSOLE_ID_none 0
+#define VERSAL2_CONSOLE_ID_pl011 1
+#define VERSAL2_CONSOLE_ID_pl011_0 1
+#define VERSAL2_CONSOLE_ID_pl011_1 2
+#define VERSAL2_CONSOLE_ID_dcc 3
+#define VERSAL2_CONSOLE_ID_dtb 4
-#define CONSOLE_IS(con) (CONSOLE_ID_ ## con == CONSOLE)
+#define CONSOLE_IS(con) (VERSAL2_CONSOLE_ID_ ## con == VERSAL2_CONSOLE)
+
+/* Runtime console */
+#define RT_CONSOLE_ID_pl011 1
+#define RT_CONSOLE_ID_pl011_0 1
+#define RT_CONSOLE_ID_pl011_1 2
+#define RT_CONSOLE_ID_dcc 3
+#define RT_CONSOLE_ID_dtb 4
+
+#define RT_CONSOLE_IS(con) (RT_CONSOLE_ID_ ## con == CONSOLE_RUNTIME)
/* List all platforms */
#define SILICON U(0)
@@ -143,11 +154,35 @@
#define UART_BAUDRATE 115200
-#if CONSOLE_IS(pl011_1)
-#define UART_BASE UART1_BASE
+#if CONSOLE_IS(pl011) || CONSOLE_IS(dtb)
+#define UART_BASE UART0_BASE
+# define UART_TYPE CONSOLE_PL011
+#elif CONSOLE_IS(pl011_1)
+#define UART_BASE UART1_BASE
+# define UART_TYPE CONSOLE_PL011
+#elif CONSOLE_IS(dcc)
+# define UART_BASE 0x0
+# define UART_TYPE CONSOLE_DCC
+#elif CONSOLE_IS(none)
+# define UART_TYPE CONSOLE_NONE
+#else
+# error "invalid VERSAL2_CONSOLE"
+#endif
+
+/* Runtime console */
+#if defined(CONSOLE_RUNTIME)
+#if RT_CONSOLE_IS(pl011) || RT_CONSOLE_IS(dtb)
+# define RT_UART_BASE UART0_BASE
+# define RT_UART_TYPE CONSOLE_PL011
+#elif RT_CONSOLE_IS(pl011_1)
+# define RT_UART_BASE UART1_BASE
+# define RT_UART_TYPE CONSOLE_PL011
+#elif RT_CONSOLE_IS(dcc)
+# define RT_UART_BASE 0x0
+# define RT_UART_TYPE CONSOLE_DCC
#else
-/* Default console is UART0 */
-#define UART_BASE UART0_BASE
+# error "invalid CONSOLE_RUNTIME"
+#endif
#endif
#endif /* DEF_H */
diff --git a/plat/amd/versal2/include/platform_def.h b/plat/amd/versal2/include/platform_def.h
index 090fe46..42c9b08 100644
--- a/plat/amd/versal2/include/platform_def.h
+++ b/plat/amd/versal2/include/platform_def.h
@@ -91,7 +91,7 @@
#define PLAT_OCM_BASE U(0xBBF00000)
#define PLAT_OCM_LIMIT U(0xBC000000)
-#if defined(TRANSFER_LIST)
+#if TRANSFER_LIST
/*
* FIXME: This address should come from firmware before TF-A
* Having this to make sure the transfer list functionality works
diff --git a/plat/amd/versal2/platform.mk b/plat/amd/versal2/platform.mk
index 3892fcb..3114976 100644
--- a/plat/amd/versal2/platform.mk
+++ b/plat/amd/versal2/platform.mk
@@ -6,6 +6,9 @@
PLAT_PATH := plat/amd/versal2
+override NEED_BL1 := no
+override NEED_BL2 := no
+
# A78 Erratum for SoC
ERRATA_A78_AE_1941500 := 1
ERRATA_A78_AE_1951502 := 1
@@ -28,6 +31,10 @@
override CTX_INCLUDE_AARCH32_REGS := 0
+# Platform to support Dynamic XLAT Table by default
+override PLAT_XLAT_TABLES_DYNAMIC := 1
+$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
+
ifdef MEM_BASE
$(eval $(call add_define,MEM_BASE))
@@ -57,13 +64,28 @@
USE_COHERENT_MEM := 0
HW_ASSISTED_COHERENCY := 1
-CONSOLE ?= pl011
-ifeq (${CONSOLE}, $(filter ${CONSOLE},pl011 pl011_0 pl011_1 dcc))
+VERSAL2_CONSOLE ?= pl011
+ifeq (${VERSAL2_CONSOLE}, $(filter ${VERSAL2_CONSOLE},pl011 pl011_0 pl011_1 dcc dtb none))
+ else
+ $(error "Please define VERSAL2_CONSOLE")
+ endif
+
+$(eval $(call add_define_val,VERSAL2_CONSOLE,VERSAL2_CONSOLE_ID_${VERSAL2_CONSOLE}))
+
+# Runtime console in default console in DEBUG build
+ifeq ($(DEBUG), 1)
+CONSOLE_RUNTIME ?= pl011
+endif
+
+# Runtime console
+ifdef CONSOLE_RUNTIME
+ifeq (${CONSOLE_RUNTIME}, $(filter ${CONSOLE_RUNTIME},pl011 pl011_0 pl011_1 dcc dtb))
+$(eval $(call add_define_val,CONSOLE_RUNTIME,RT_CONSOLE_ID_${CONSOLE_RUNTIME}))
else
- $(error Please define CONSOLE)
+ $(error "Please define CONSOLE_RUNTIME")
+endif
endif
-$(eval $(call add_define_val,CONSOLE,CONSOLE_ID_${CONSOLE}))
ifdef XILINX_OF_BOARD_DTB_ADDR
$(eval $(call add_define,XILINX_OF_BOARD_DTB_ADDR))
@@ -109,6 +131,9 @@
BL31_SOURCES += ${PLAT_PATH}/plat_psci.c
BL31_SOURCES += plat/xilinx/common/plat_fdt.c \
+ common/fdt_wrappers.c \
+ plat/xilinx/common/plat_fdt.c \
+ plat/xilinx/common/plat_console.c \
plat/xilinx/common/plat_startup.c \
plat/xilinx/common/ipi.c \
plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c \
@@ -126,3 +151,9 @@
CORTEX_A78_AE_H_INC := 1
$(eval $(call add_define, CORTEX_A78_AE_H_INC))
endif
+
+# Enable Handoff protocol using transfer lists
+TRANSFER_LIST := 1
+
+include lib/transfer_list/transfer_list.mk
+BL31_SOURCES += plat/xilinx/common/plat_xfer_list.c
diff --git a/plat/amd/versal2/scmi.c b/plat/amd/versal2/scmi.c
index 7f4b6df..6375df3 100644
--- a/plat/amd/versal2/scmi.c
+++ b/plat/amd/versal2/scmi.c
@@ -51,8 +51,8 @@
CLOCK_CELL(CLK_SERIAL1_0, CLK_SERIAL1_0, "uart1_uartclk", true, 100000000),
CLOCK_CELL(CLK_SERIAL1_1, CLK_SERIAL1_1, "uart1_apb_pclk", true, 100000000),
CLOCK_CELL(CLK_UFS0_0, CLK_UFS0_0, "ufs_core_clk", true, 100000000),
- CLOCK_CELL(CLK_UFS0_1, CLK_UFS0_1, "ufs_phy_clk", true, 100000000),
- CLOCK_CELL(CLK_UFS0_2, CLK_UFS0_2, "ufs_ref_pclk", true, 100000000),
+ CLOCK_CELL(CLK_UFS0_1, CLK_UFS0_1, "ufs_phy_clk", true, 26000000),
+ CLOCK_CELL(CLK_UFS0_2, CLK_UFS0_2, "ufs_ref_pclk", true, 26000000),
CLOCK_CELL(CLK_USB0_0, CLK_USB0_0, "usb0_bus_clk", true, 100000000),
CLOCK_CELL(CLK_USB0_1, CLK_USB0_1, "usb0_ref_clk", true, 100000000),
CLOCK_CELL(CLK_USB0_2, CLK_USB0_2, "usb0_dwc_clk", true, 100000000),
@@ -269,7 +269,7 @@
const char *plat_scmi_clock_get_name(unsigned int agent_id, unsigned int scmi_id)
{
- struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+ const struct scmi_clk *clock = clk_find(agent_id, scmi_id);
const char *ret;
if (clock == NULL) {
@@ -287,7 +287,7 @@
unsigned long *array, size_t *nb_elts,
uint32_t start_idx)
{
- struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+ const struct scmi_clk *clock = clk_find(agent_id, scmi_id);
if (clock == NULL) {
return SCMI_NOT_FOUND;
@@ -312,7 +312,7 @@
unsigned long plat_scmi_clock_get_rate(unsigned int agent_id, unsigned int scmi_id)
{
- struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+ const struct scmi_clk *clock = clk_find(agent_id, scmi_id);
unsigned long ret;
if ((clock == NULL)) {
@@ -341,7 +341,7 @@
int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id)
{
- struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+ const struct scmi_clk *clock = clk_find(agent_id, scmi_id);
int32_t ret;
if ((clock == NULL)) {
@@ -647,8 +647,13 @@
for (i = 0U; i < ARRAY_SIZE(scmi0_clock); i++) {
/* Keep i2c on 100MHz to calculate rates properly */
- if (i >= CLK_I2C0_0 && i <= CLK_I2C7_0)
+ if ((i >= CLK_I2C0_0) && (i <= CLK_I2C7_0))
continue;
+
+ /* Keep UFS clocks to default values to get the expected rates */
+ if (i >= CLK_UFS0_0 && i <= CLK_UFS0_2)
+ continue;
+
/*
* SPP supports multiple versions.
* The cpu_clock value is set to corresponding SPP
diff --git a/plat/arm/board/fvp/fvp_el3_token_sign.c b/plat/arm/board/fvp/fvp_el3_token_sign.c
new file mode 100644
index 0000000..282f94a
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_el3_token_sign.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2024, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <string.h>
+
+#include <plat/common/platform.h>
+#include <services/rmm_el3_token_sign.h>
+
+static struct el3_token_sign_request el3_req = { 0 };
+static bool el3_req_valid;
+
+/*
+ * According to https://www.secg.org/sec1-v2.pdf 2.3.3
+ * the size of the ECDSA P384 public key is 97 bytes,
+ * with the first byte being 0x04.
+ */
+static uint8_t sample_attest_pub_key[] = {
+ 0x04, 0x76, 0xf9, 0x88, 0x09, 0x1b, 0xe5, 0x85, 0xed, 0x41,
+ 0x80, 0x1a, 0xec, 0xfa, 0xb8, 0x58, 0x54, 0x8c, 0x63, 0x05,
+ 0x7e, 0x16, 0xb0, 0xe6, 0x76, 0x12, 0x0b, 0xbd, 0x0d, 0x2f,
+ 0x9c, 0x29, 0xe0, 0x56, 0xc5, 0xd4, 0x1a, 0x01, 0x30, 0xeb,
+ 0x9c, 0x21, 0x51, 0x78, 0x99, 0xdc, 0x23, 0x14, 0x6b, 0x28,
+ 0xe1, 0xb0, 0x62, 0xbd, 0x3e, 0xa4, 0xb3, 0x15, 0xfd, 0x21,
+ 0x9f, 0x1c, 0xbb, 0x52, 0x8c, 0xb6, 0xe7, 0x4c, 0xa4, 0x9b,
+ 0xe1, 0x67, 0x73, 0x73, 0x4f, 0x61, 0xa1, 0xca, 0x61, 0x03,
+ 0x1b, 0x2b, 0xbf, 0x3d, 0x91, 0x8f, 0x2f, 0x94, 0xff, 0xc4,
+ 0x22, 0x8e, 0x50, 0x91, 0x95, 0x44, 0xae
+};
+
+/*
+ * FVP does not support HES, so provide 0's as keys.
+ */
+int plat_rmmd_el3_token_sign_get_rak_pub(uintptr_t buf, size_t *len,
+ unsigned int type)
+{
+ (void)type;
+ if (*len < sizeof(sample_attest_pub_key)) {
+ return E_RMM_INVAL;
+ }
+
+ if (type != ATTEST_KEY_CURVE_ECC_SECP384R1) {
+ ERROR("Invalid ECC curve specified\n");
+ return E_RMM_INVAL;
+ }
+
+ *len = sizeof(sample_attest_pub_key);
+
+ (void)memcpy((void *)buf, sample_attest_pub_key,
+ sizeof(sample_attest_pub_key));
+
+ return 0;
+}
+
+int plat_rmmd_el3_token_sign_push_req(const struct el3_token_sign_request *req)
+{
+ /*
+ * TODO: Today this function is called with a lock held on the
+ * RMM<->EL3 shared buffer. In the future, we may move to a
+ * different design that may require handling multi-threaded
+ * calls to this function, for example, if we have a per CPU
+ * buffer between RMM and EL3.
+ */
+ if (el3_req_valid) {
+ return E_RMM_AGAIN;
+ }
+
+ el3_req = *req;
+
+ if ((el3_req.hash_alg_id != EL3_TOKEN_SIGN_HASH_ALG_SHA384) ||
+ (el3_req.sig_alg_id != ATTEST_KEY_CURVE_ECC_SECP384R1)) {
+ return E_RMM_INVAL;
+ }
+
+ el3_req_valid = true;
+
+ return 0;
+}
+
+int plat_rmmd_el3_token_sign_pull_resp(struct el3_token_sign_response *resp)
+{
+ if (!el3_req_valid) {
+ return E_RMM_AGAIN;
+ }
+
+ resp->rec_granule = el3_req.rec_granule;
+ resp->req_ticket = el3_req.req_ticket;
+ resp->sig_len = (uint16_t)sizeof(resp->signature_buf);
+ /* TODO: Provide real signature */
+ memset(resp->signature_buf, 0, sizeof(resp->signature_buf));
+
+ el3_req_valid = false;
+
+ return 0;
+}
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index feae802..6f53a81 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -56,6 +56,7 @@
ENABLE_BRBE_FOR_NS := 2
ENABLE_TRBE_FOR_NS := 2
+ ENABLE_FEAT_D128 := 2
endif
ENABLE_SYS_REG_TRACE_FOR_NS := 2
@@ -71,11 +72,13 @@
ENABLE_FEAT_ECV := 2
ENABLE_FEAT_FGT := 2
ENABLE_FEAT_FGT2 := 2
+ENABLE_FEAT_THE := 2
ENABLE_FEAT_TCR2 := 2
ENABLE_FEAT_S2PIE := 2
ENABLE_FEAT_S1PIE := 2
ENABLE_FEAT_S2POE := 2
ENABLE_FEAT_S1POE := 2
+ENABLE_FEAT_SCTLR2 := 2
ENABLE_FEAT_MTE2 := 2
# The FVP platform depends on this macro to build with correct GIC driver.
@@ -194,6 +197,7 @@
lib/cpus/aarch64/cortex_a710.S \
lib/cpus/aarch64/cortex_a715.S \
lib/cpus/aarch64/cortex_a720.S \
+ lib/cpus/aarch64/cortex_a720_ae.S \
lib/cpus/aarch64/neoverse_n_common.S \
lib/cpus/aarch64/neoverse_n1.S \
lib/cpus/aarch64/neoverse_n2.S \
@@ -209,10 +213,11 @@
#Build AArch64-only CPUs with no FVP model yet.
ifeq (${BUILD_CPUS_WITH_NO_FVP_MODEL},1)
- FVP_CPU_LIBS += lib/cpus/aarch64/neoverse_n3.S \
+ FVP_CPU_LIBS += lib/cpus/aarch64/neoverse_n3.S \
lib/cpus/aarch64/cortex_gelas.S \
lib/cpus/aarch64/nevis.S \
- lib/cpus/aarch64/travis.S
+ lib/cpus/aarch64/travis.S \
+ lib/cpus/aarch64/cortex_arcadia.S
endif
else
@@ -264,7 +269,8 @@
plat/arm/board/fvp/fvp_cpu_pwr.c
BL31_SOURCES += plat/arm/board/fvp/fvp_plat_attest_token.c \
- plat/arm/board/fvp/fvp_realm_attest_key.c
+ plat/arm/board/fvp/fvp_realm_attest_key.c \
+ plat/arm/board/fvp/fvp_el3_token_sign.c
endif
ifeq (${ENABLE_FEAT_RNG_TRAP},1)
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index 613f508..86fce0e 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -222,8 +222,11 @@
#define TC_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\
V2M_FLASH0_SIZE, \
MT_DEVICE | MT_RO | MT_SECURE)
-
+#if TARGET_PLATFORM == 2
+#define PLAT_ARM_NSTIMER_FRAME_ID U(0)
+#else
#define PLAT_ARM_NSTIMER_FRAME_ID U(1)
+#endif
#define PLAT_ARM_TRUSTED_ROM_BASE 0x0
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index 21cc39c..2d4165c 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -12,6 +12,8 @@
#include <arch_helpers.h>
#include <common/debug.h>
#include <common/romlib.h>
+#include <common/par.h>
+#include <lib/extensions/sysreg128.h>
#include <lib/mmio.h>
#include <lib/smccc.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
@@ -196,7 +198,8 @@
*/
int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode)
{
- uint64_t par, pa;
+ uint64_t pa;
+ sysreg_t par;
u_register_t scr_el3;
/* Doing Non-secure address translation requires SCR_EL3.NS set */
@@ -230,7 +233,7 @@
return -1;
/* Extract Physical Address from PAR */
- pa = (par & (PAR_ADDR_MASK << PAR_ADDR_SHIFT));
+ pa = get_par_el1_pa(par);
/* Perform NS entry point validation on the physical address */
return arm_validate_ns_entrypoint(pa);
diff --git a/plat/imx/imx8m/imx8m_ccm.c b/plat/imx/imx8m/imx8m_ccm.c
index 10a00c9..6b14446 100644
--- a/plat/imx/imx8m/imx8m_ccm.c
+++ b/plat/imx/imx8m/imx8m_ccm.c
@@ -17,16 +17,16 @@
} imx8m_uart_info[] = {
{ /* UART 1 */
.ccm_reg = 0x4490,
- .uart_base = 0x30860000,
+ .uart_base = IMX_UART1_BASE,
}, { /* UART 2 */
.ccm_reg = 0x44a0,
- .uart_base = 0x30890000,
+ .uart_base = IMX_UART2_BASE,
}, { /* UART 3 */
.ccm_reg = 0x44b0,
- .uart_base = 0x30880000,
+ .uart_base = IMX_UART3_BASE,
}, { /* UART 4 */
.ccm_reg = 0x44c0,
- .uart_base = 0x30a60000,
+ .uart_base = IMX_UART4_BASE,
}
};
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
index f6e46eb..03edc6e 100644
--- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
@@ -62,7 +62,7 @@
{0},
};
-static const struct imx_rdc_cfg rdc[] = {
+static struct imx_rdc_cfg rdc[] = {
/* Master domain assignment */
RDC_MDAn(RDC_MDA_M4, DID1),
@@ -164,14 +164,14 @@
imx_aipstz_init(aipstz);
- imx_rdc_init(rdc);
-
- imx_csu_init(csu_cfg);
-
if (console_base == 0U) {
console_base = imx8m_uart_get_base();
}
+ imx_rdc_init(rdc, console_base);
+
+ imx_csu_init(csu_cfg);
+
console_imx_uart_register(console_base, IMX_BOOT_UART_CLK_IN_HZ,
IMX_CONSOLE_BAUDRATE, &console);
/* This console is only used for boot stage */
diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h
index 2fa6199..e6ad8fe 100644
--- a/plat/imx/imx8m/imx8mm/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mm/include/platform_def.h
@@ -85,6 +85,11 @@
#define PLAT_CRASH_UART_CLK_IN_HZ 24000000
#define IMX_CONSOLE_BAUDRATE 115200
+#define IMX_UART1_BASE U(0x30860000)
+#define IMX_UART2_BASE U(0x30890000)
+#define IMX_UART3_BASE U(0x30880000)
+#define IMX_UART4_BASE U(0x30a60000)
+
#define IMX_AIPSTZ1 U(0x301f0000)
#define IMX_AIPSTZ2 U(0x305f0000)
#define IMX_AIPSTZ3 U(0x309f0000)
diff --git a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
index befa769..42d173e 100644
--- a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
@@ -48,7 +48,7 @@
{0},
};
-static const struct imx_rdc_cfg rdc[] = {
+static struct imx_rdc_cfg rdc[] = {
/* Master domain assignment */
RDC_MDAn(RDC_MDA_M7, DID1),
@@ -136,7 +136,11 @@
imx_aipstz_init(aipstz);
- imx_rdc_init(rdc);
+ if (console_base == 0U) {
+ console_base = imx8m_uart_get_base();
+ }
+
+ imx_rdc_init(rdc, console_base);
imx_csu_init(csu_cfg);
@@ -152,10 +156,6 @@
val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x2c);
mmio_write_32(IMX_IOMUX_GPR_BASE + 0x2c, val | 0x3DFF0000);
- if (console_base == 0U) {
- console_base = imx8m_uart_get_base();
- }
-
console_imx_uart_register(console_base, IMX_BOOT_UART_CLK_IN_HZ,
IMX_CONSOLE_BAUDRATE, &console);
/* This console is only used for boot stage */
diff --git a/plat/imx/imx8m/imx8mn/include/platform_def.h b/plat/imx/imx8m/imx8mn/include/platform_def.h
index 569432d..b76bdbf 100644
--- a/plat/imx/imx8m/imx8mn/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mn/include/platform_def.h
@@ -68,6 +68,11 @@
#define PLAT_CRASH_UART_CLK_IN_HZ 24000000
#define IMX_CONSOLE_BAUDRATE 115200
+#define IMX_UART1_BASE U(0x30860000)
+#define IMX_UART2_BASE U(0x30890000)
+#define IMX_UART3_BASE U(0x30880000)
+#define IMX_UART4_BASE U(0x30a60000)
+
#define IMX_AIPSTZ1 U(0x301f0000)
#define IMX_AIPSTZ2 U(0x305f0000)
#define IMX_AIPSTZ3 U(0x309f0000)
diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
index ffad3d1..141c94b 100644
--- a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
@@ -49,7 +49,7 @@
{0},
};
-static const struct imx_rdc_cfg rdc[] = {
+static struct imx_rdc_cfg rdc[] = {
/* Master domain assignment */
RDC_MDAn(RDC_MDA_M7, DID1),
@@ -166,7 +166,11 @@
imx_aipstz_init(aipstz);
- imx_rdc_init(rdc);
+ if (console_base == 0U) {
+ console_base = imx8m_uart_get_base();
+ }
+
+ imx_rdc_init(rdc, console_base);
imx_csu_init(csu_cfg);
@@ -175,10 +179,6 @@
val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x2c);
mmio_write_32(IMX_IOMUX_GPR_BASE + 0x2c, val | 0x3DFF0000);
- if (console_base == 0U) {
- console_base = imx8m_uart_get_base();
- }
-
console_imx_uart_register(console_base, IMX_BOOT_UART_CLK_IN_HZ,
IMX_CONSOLE_BAUDRATE, &console);
/* This console is only used for boot stage */
diff --git a/plat/imx/imx8m/imx8mp/include/platform_def.h b/plat/imx/imx8m/imx8mp/include/platform_def.h
index 84a7e00..78f3d5b 100644
--- a/plat/imx/imx8m/imx8mp/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mp/include/platform_def.h
@@ -86,6 +86,11 @@
#define PLAT_CRASH_UART_CLK_IN_HZ 24000000
#define IMX_CONSOLE_BAUDRATE 115200
+#define IMX_UART1_BASE U(0x30860000)
+#define IMX_UART2_BASE U(0x30890000)
+#define IMX_UART3_BASE U(0x30880000)
+#define IMX_UART4_BASE U(0x30a60000)
+
#define IMX_AIPSTZ1 U(0x301f0000)
#define IMX_AIPSTZ2 U(0x305f0000)
#define IMX_AIPSTZ3 U(0x309f0000)
diff --git a/plat/imx/imx8m/imx8mq/include/platform_def.h b/plat/imx/imx8m/imx8mq/include/platform_def.h
index b04f391..61c0e8e 100644
--- a/plat/imx/imx8m/imx8mq/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mq/include/platform_def.h
@@ -65,6 +65,11 @@
#define PLAT_CRASH_UART_CLK_IN_HZ 25000000
#define IMX_CONSOLE_BAUDRATE 115200
+#define IMX_UART1_BASE U(0x30860000)
+#define IMX_UART2_BASE U(0x30890000)
+#define IMX_UART3_BASE U(0x30880000)
+#define IMX_UART4_BASE U(0x30a60000)
+
#define IMX_AIPS_BASE U(0x30200000)
#define IMX_AIPS_SIZE U(0xC00000)
#define IMX_AIPS1_BASE U(0x30200000)
diff --git a/plat/imx/imx8m/imx_rdc.c b/plat/imx/imx8m/imx_rdc.c
index 85de191..de15956 100644
--- a/plat/imx/imx8m/imx_rdc.c
+++ b/plat/imx/imx8m/imx_rdc.c
@@ -4,13 +4,78 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <errno.h>
+
#include <lib/mmio.h>
#include <imx_rdc.h>
+struct imx_uart {
+ int index;
+ unsigned int uart_base;
+};
+
+static const struct imx_uart imx8m_uart_info[] = {
+ { /* UART 1 */
+ .index = RDC_PDAP_UART1,
+ .uart_base = IMX_UART1_BASE,
+ }, { /* UART 2 */
+ .index = RDC_PDAP_UART2,
+ .uart_base = IMX_UART2_BASE,
+ }, { /* UART 3 */
+ .index = RDC_PDAP_UART3,
+ .uart_base = IMX_UART3_BASE,
+ }, { /* UART 4 */
+ .index = RDC_PDAP_UART4,
+ .uart_base = IMX_UART4_BASE,
+ }
+};
+
+static int imx_rdc_uart_get_pdap_index(unsigned int uart_base)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(imx8m_uart_info); i++) {
+ if (imx8m_uart_info[i].uart_base == uart_base) {
+ return imx8m_uart_info[i].index;
+ }
+ }
+
+ return -ENODEV;
+}
+
-void imx_rdc_init(const struct imx_rdc_cfg *rdc_cfg)
+static void imx_rdc_console_access_enable(struct imx_rdc_cfg *rdc_cfg,
+ unsigned int console_base)
{
- const struct imx_rdc_cfg *rdc = rdc_cfg;
+ struct imx_rdc_cfg *rdc;
+ int console_pdap_index;
+
+ console_pdap_index = imx_rdc_uart_get_pdap_index(console_base);
+ if (console_pdap_index < 0) {
+ return;
+ }
+
+ for (rdc = rdc_cfg; rdc->type != RDC_INVALID; rdc++) {
+ if (rdc->type != RDC_PDAP || rdc->index != console_pdap_index) {
+ continue;
+ }
+
+ if (rdc->index == console_pdap_index &&
+ rdc->setting.rdc_pdap == (D0R | D0W)) {
+ return;
+ }
+
+ if (rdc->index == console_pdap_index) {
+ rdc->setting.rdc_pdap = D0R | D0W;
+ }
+ }
+}
+
+void imx_rdc_init(struct imx_rdc_cfg *rdc_cfg, unsigned int console_base)
+{
+ struct imx_rdc_cfg *rdc = rdc_cfg;
+
+ imx_rdc_console_access_enable(rdc, console_base);
while (rdc->type != RDC_INVALID) {
switch (rdc->type) {
diff --git a/plat/imx/imx8m/include/imx_rdc.h b/plat/imx/imx8m/include/imx_rdc.h
index a6e10a7..fbdcbf2 100644
--- a/plat/imx/imx8m/include/imx_rdc.h
+++ b/plat/imx/imx8m/include/imx_rdc.h
@@ -67,7 +67,7 @@
.setting.rdc_mem_region[2] = (mrc), \
}
-void imx_rdc_init(const struct imx_rdc_cfg *cfg);
+void imx_rdc_init(struct imx_rdc_cfg *cfg, unsigned int console_base);
#endif /* IMX_RDC_H */
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c
index 36820b2..084539e 100644
--- a/plat/intel/soc/agilex/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex/bl2_plat_setup.c
@@ -129,11 +129,13 @@
switch (boot_source) {
case BOOT_SOURCE_SDMMC:
+ NOTICE("SDMMC boot\n");
dw_mmc_init(¶ms, &mmc_info);
socfpga_io_setup(boot_source, PLAT_SDMMC_DATA_BASE);
break;
case BOOT_SOURCE_QSPI:
+ NOTICE("QSPI boot\n");
cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c
index 6e45158..4c10e7b 100644
--- a/plat/intel/soc/agilex/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex/bl31_plat_setup.c
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,12 +14,16 @@
#include <drivers/ti/uart/uart_16550.h>
#include <lib/mmio.h>
#include <lib/xlat_tables/xlat_tables.h>
+#include <plat/common/platform.h>
#include "ccu/ncore_ccu.h"
#include "socfpga_mailbox.h"
#include "socfpga_private.h"
#include "socfpga_sip_svc.h"
+/* Get non-secure SPSR for BL33. Zephyr and Linux */
+uint32_t arm_get_spsr_for_bl33_entry(void);
+
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
@@ -59,9 +64,7 @@
u_register_t arg2, u_register_t arg3)
{
static console_t console;
-
mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
-
console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
PLAT_BAUDRATE, &console);
/*
@@ -69,6 +72,33 @@
*/
void *from_bl2 = (void *) arg0;
+#if RESET_TO_BL31
+ /* There are no parameters from BL2 if BL31 is a reset vector */
+ assert(from_bl2 == NULL);
+ void *plat_params_from_bl2 = (void *) arg3;
+
+ assert(plat_params_from_bl2 == NULL);
+
+ /* Populate entry point information for BL33 */
+ SET_PARAM_HEAD(&bl33_image_ep_info,
+ PARAM_EP,
+ VERSION_1,
+ 0);
+
+# if ARM_LINUX_KERNEL_AS_BL33
+ /*
+ * According to the file ``Documentation/arm64/booting.txt`` of the
+ * Linux kernel tree, Linux expects the physical address of the device
+ * tree blob (DTB) in x0, while x1-x3 are reserved for future use and
+ * must be 0.
+ */
+ bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
+ bl33_image_ep_info.args.arg1 = 0U;
+ bl33_image_ep_info.args.arg2 = 0U;
+ bl33_image_ep_info.args.arg3 = 0U;
+# endif
+
+#else /* RESET_TO_BL31 */
bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
assert(params_from_bl2 != NULL);
@@ -76,28 +106,38 @@
* Copy BL32 (if populated by BL31) and BL33 entry point information.
* They are stored in Secure RAM, in BL31's address space.
*/
-
if (params_from_bl2->h.type == PARAM_BL_PARAMS &&
params_from_bl2->h.version >= VERSION_2) {
-
bl_params_node_t *bl_params = params_from_bl2->head;
-
while (bl_params) {
if (bl_params->image_id == BL33_IMAGE_ID)
bl33_image_ep_info = *bl_params->ep_info;
-
bl_params = bl_params->next_params_info;
}
} else {
struct socfpga_bl31_params *arg_from_bl2 =
(struct socfpga_bl31_params *) from_bl2;
-
assert(arg_from_bl2->h.type == PARAM_BL31);
assert(arg_from_bl2->h.version >= VERSION_1);
-
bl32_image_ep_info = *arg_from_bl2->bl32_ep_info;
bl33_image_ep_info = *arg_from_bl2->bl33_ep_info;
}
+
+ bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
+ bl33_image_ep_info.args.arg1 = 0U;
+ bl33_image_ep_info.args.arg2 = 0U;
+ bl33_image_ep_info.args.arg3 = 0U;
+#endif
+
+ /*
+ * Tell BL31 where the non-trusted software image
+ * is located and the entry state information
+ */
+# if ARM_LINUX_KERNEL_AS_BL33
+ bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+ bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
+#endif
+
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
}
@@ -172,8 +212,34 @@
#endif
{0}
};
-
setup_page_tables(bl_regions, plat_agilex_mmap);
enable_mmu_el3(0);
}
+/* Get non-secure image entrypoint for BL33. Zephyr and Linux */
+uintptr_t plat_get_ns_image_entrypoint(void)
+{
+#ifdef PRELOADED_BL33_BASE
+ return PRELOADED_BL33_BASE;
+#else
+ return PLAT_NS_IMAGE_OFFSET;
+#endif
+}
+
+/* Get non-secure SPSR for BL33. Zephyr and Linux */
+uint32_t arm_get_spsr_for_bl33_entry(void)
+{
+ unsigned int mode;
+ uint32_t spsr;
+
+ /* Figure out what mode we enter the non-secure world in */
+ mode = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1;
+
+ /*
+ * TODO: Consider the possibility of specifying the SPSR in
+ * the FIP ToC and allowing the platform to have a say as
+ * well.
+ */
+ spsr = SPSR_64((uint64_t)mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+ return spsr;
+}
diff --git a/plat/intel/soc/agilex/include/agilex_memory_controller.h b/plat/intel/soc/agilex/include/agilex_memory_controller.h
index 9db4292..f0bbeea 100644
--- a/plat/intel/soc/agilex/include/agilex_memory_controller.h
+++ b/plat/intel/soc/agilex/include/agilex_memory_controller.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,7 +28,7 @@
#define AGX_MPFE_HMC_ADP_ECCCTRL1 0xf8011100
#define AGX_MPFE_HMC_ADP_ECCCTRL2 0xf8011104
#define AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT 0xf8011218
-#define AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE 0x000000ff
+#define AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE 0x0000000f
#define AGX_MPFE_HMC_ADP_RSTHANDSHAKECTRL 0xf8011214
diff --git a/plat/intel/soc/agilex/include/agilex_system_manager.h b/plat/intel/soc/agilex/include/agilex_system_manager.h
index 20a62be..78aabde 100644
--- a/plat/intel/soc/agilex/include/agilex_system_manager.h
+++ b/plat/intel/soc/agilex/include/agilex_system_manager.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -121,7 +122,7 @@
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_8 0x220
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_9 0x224
#define SOCFPGA_SYSMGR_MPFE_CONFIG 0x228
-#define SOCFPGA_SYSMGR_MPFE_status 0x22C
+#define SOCFPGA_SYSMGR_MPFE_STATUS 0x22C
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_0 0x230
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_1 0x234
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_2 0x238
diff --git a/plat/intel/soc/agilex/include/socfpga_plat_def.h b/plat/intel/soc/agilex/include/socfpga_plat_def.h
index 9ef7598..840ffdd 100644
--- a/plat/intel/soc/agilex/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex/include/socfpga_plat_def.h
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,10 +15,16 @@
/* Platform Setting */
#define PLATFORM_MODEL PLAT_SOCFPGA_AGILEX
-#define BOOT_SOURCE BOOT_SOURCE_SDMMC
+/* 1 = Flush cache, 0 = No cache flush.
+ * Default for Agilex is No cache flush.
+ * For Agilex FP8, set to Flush cache.
+ */
+#define CACHE_FLUSH 0
#define PLAT_PRIMARY_CPU 0
#define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT MPIDR_AFF1_SHIFT
#define PLAT_CPU_ID_MPIDR_AFF_SHIFT MPIDR_AFF0_SHIFT
+#define PLAT_HANDOFF_OFFSET 0xFFE3F000
+#define PLAT_TIMER_BASE_ADDR 0xFFD01000
/* FPGA config helpers */
#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x400000
@@ -27,6 +34,25 @@
#define CAD_QSPIDATA_OFST 0xff900000
#define CAD_QSPI_OFFSET 0xff8d2000
+/* FIP Setting */
+#define PLAT_FIP_BASE (0)
+#if ARM_LINUX_KERNEL_AS_BL33
+#define PLAT_FIP_MAX_SIZE (0x8000000)
+#else
+#define PLAT_FIP_MAX_SIZE (0x1000000)
+#endif
+
+/* SDMMC Setting */
+#if ARM_LINUX_KERNEL_AS_BL33
+#define PLAT_MMC_DATA_BASE (0x10000000)
+#define PLAT_MMC_DATA_SIZE (0x100000)
+#define SOCFPGA_MMC_BLOCK_SIZE U(32768)
+#else
+#define PLAT_MMC_DATA_BASE (0xffe3c000)
+#define PLAT_MMC_DATA_SIZE (0x2000
+#define SOCFPGA_MMC_BLOCK_SIZE U(8192)
+#endif
+
/* Register Mapping */
#define SOCFPGA_CCU_NOC_REG_BASE 0xf7000000
#define SOCFPGA_F2SDRAMMGR_REG_BASE U(0xf8024000)
@@ -97,7 +123,7 @@
/*******************************************************************************
* SDMMC related pointer function
******************************************************************************/
-#define SDMMC_READ_BLOCKS mmc_read_blocks
+#define SDMMC_READ_BLOCKS sdmmc_read_blocks
#define SDMMC_WRITE_BLOCKS mmc_write_blocks
/*******************************************************************************
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index 21cc6a3..d534b2e 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -28,6 +28,7 @@
plat/intel/soc/common/aarch64/platform_common.c \
plat/intel/soc/common/aarch64/plat_helpers.S \
plat/intel/soc/common/drivers/ccu/ncore_ccu.c \
+ plat/intel/soc/common/drivers/sdmmc/sdmmc.c \
plat/intel/soc/common/lib/sha/sha.c \
plat/intel/soc/common/socfpga_delay_timer.c
@@ -87,6 +88,24 @@
$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
+# Configs for Boot Source
+SOCFPGA_BOOT_SOURCE_SDMMC ?= 0
+SOCFPGA_BOOT_SOURCE_QSPI ?= 0
+SOCFPGA_BOOT_SOURCE_NAND ?= 0
+
+$(eval $(call assert_booleans,\
+ $(sort \
+ SOCFPGA_BOOT_SOURCE_SDMMC \
+ SOCFPGA_BOOT_SOURCE_QSPI \
+ SOCFPGA_BOOT_SOURCE_NAND \
+)))
+$(eval $(call add_defines,\
+ $(sort \
+ SOCFPGA_BOOT_SOURCE_SDMMC \
+ SOCFPGA_BOOT_SOURCE_QSPI \
+ SOCFPGA_BOOT_SOURCE_NAND \
+)))
+
# Configs for VAB Authentication
SOCFPGA_SECURE_VAB_AUTH := 0
$(eval $(call assert_boolean,SOCFPGA_SECURE_VAB_AUTH))
diff --git a/plat/intel/soc/agilex5/bl2_plat_setup.c b/plat/intel/soc/agilex5/bl2_plat_setup.c
index 265ee57..fe5dc6e 100644
--- a/plat/intel/soc/agilex5/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex5/bl2_plat_setup.c
@@ -20,9 +20,11 @@
#include <lib/xlat_tables/xlat_tables_v2.h>
#include "agilex5_clock_manager.h"
+#include "agilex5_ddr.h"
#include "agilex5_memory_controller.h"
#include "agilex5_mmc.h"
#include "agilex5_pinmux.h"
+#include "agilex5_power_manager.h"
#include "agilex5_system_manager.h"
#include "ccu/ncore_ccu.h"
#include "combophy/combophy.h"
@@ -66,33 +68,84 @@
boot_source_type boot_source = BOOT_SOURCE;
-void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
- u_register_t x2, u_register_t x4)
+void bl2_el3_early_platform_setup(u_register_t x0 __unused,
+ u_register_t x1 __unused,
+ u_register_t x2 __unused,
+ u_register_t x3 __unused)
{
static console_t console;
-
- handoff reverse_handoff_ptr = { 0 };
+ handoff reverse_handoff_ptr;
- generic_delay_timer_init();
- config_clkmgr_handoff(&reverse_handoff_ptr);
- mailbox_init();
+ /* Enable nonsecure access for peripherals and other misc components */
enable_nonsecure_access();
+ /* Bring all the required peripherals out of reset */
deassert_peripheral_reset();
- if (combo_phy_init(&reverse_handoff_ptr) != 0) {
- ERROR("Combo Phy initialization failed\n");
- }
+ /*
+ * Initialize the UART console early in BL2 EL3 boot flow to get
+ * the error/notice messages wherever required.
+ */
console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
- PLAT_BAUDRATE, &console);
+ PLAT_BAUDRATE, &console);
+
+ /* Generic delay timer init */
+ generic_delay_timer_init();
+
+ socfpga_delay_timer_init();
+
+ /* Get the handoff data */
+ if ((socfpga_get_handoff(&reverse_handoff_ptr)) != 0) {
+ ERROR("SOCFPGA: Failed to get the correct handoff data\n");
+ panic();
+ }
+
+ /* Configure the pinmux */
+ config_pinmux(&reverse_handoff_ptr);
+
+ /* Configure OCRAM to NON SECURE ACCESS */
+ mmio_write_32(OCRAM_REGION_0_REG_BASE, OCRAM_NON_SECURE_ENABLE);
+ mmio_write_32(SOCFPGA_L4_PER_SCR_REG_BASE + SOCFPGA_SDMMC_SECU_BIT,
+ SOCFPGA_SDMMC_SECU_BIT_ENABLE);
+ mmio_write_32(SOCFPGA_L4_SYS_SCR_REG_BASE + SOCFPGA_SDMMC_SECU_BIT,
+ SOCFPGA_SDMMC_SECU_BIT_ENABLE);
+ mmio_write_32(SOCFPGA_LWSOC2FPGA_SCR_REG_BASE,
+ SOCFPGA_LWSOC2FPGA_ENABLE);
- /* Store magic number */
- // TODO: Temp workaround to ungate testing
- // mmio_write_32(L2_RESET_DONE_REG, PLAT_L2_RESET_REQ);
+ /* Configure the clock manager */
+ if ((config_clkmgr_handoff(&reverse_handoff_ptr)) != 0) {
+ ERROR("SOCFPGA: Failed to initialize the clock manager\n");
+ panic();
+ }
+
+ /* Configure power manager PSS SRAM power gate */
+ config_pwrmgr_handoff(&reverse_handoff_ptr);
+
+ /* Initialize the mailbox to enable communication between HPS and SDM */
+ mailbox_init();
+
+ /* Perform a handshake with certain peripherals before issuing a reset */
+ config_hps_hs_before_warm_reset();
+
+ /* TODO: watchdog init */
+ //watchdog_init(clkmgr_get_rate(CLKMGR_WDT_CLK_ID));
+
+ /* Initialize the CCU module for hardware cache coherency */
+ init_ncore_ccu();
+
+ socfpga_emac_init();
+
+ /* DDR and IOSSM driver init */
+ agilex5_ddr_init(&reverse_handoff_ptr);
+
+ if (combo_phy_init(&reverse_handoff_ptr) != 0) {
+ ERROR("SOCFPGA: Combo Phy initialization failed\n");
+ }
+ /* Enable FPGA bridges as required */
if (!intel_mailbox_is_fpga_not_ready()) {
socfpga_bridges_enable(SOC2FPGA_MASK | LWHPS2FPGA_MASK |
- FPGA2SOC_MASK | F2SDRAM0_MASK);
+ FPGA2SOC_MASK | F2SDRAM0_MASK);
}
}
@@ -101,7 +154,8 @@
handoff reverse_handoff_ptr;
unsigned long offset = 0;
- struct cdns_sdmmc_params params = EMMC_INIT_PARAMS((uintptr_t) &cdns_desc, get_mmc_clk());
+ struct cdns_sdmmc_params params = EMMC_INIT_PARAMS((uintptr_t) &cdns_desc,
+ clkmgr_get_rate(CLKMGR_SDMMC_CLK_ID));
mmc_info.mmc_dev_type = MMC_DEVICE_TYPE;
mmc_info.ocr_voltage = OCR_3_3_3_4 | OCR_3_2_3_3;
@@ -112,7 +166,7 @@
switch (boot_source) {
case BOOT_SOURCE_SDMMC:
NOTICE("SDMMC boot\n");
- sdmmc_init(&reverse_handoff_ptr, ¶ms, &mmc_info);
+ cdns_mmc_init(¶ms, &mmc_info);
socfpga_io_setup(boot_source, PLAT_SDMMC_DATA_BASE);
break;
diff --git a/plat/intel/soc/agilex5/bl31_plat_setup.c b/plat/intel/soc/agilex5/bl31_plat_setup.c
index 96c4161..c090117 100644
--- a/plat/intel/soc/agilex5/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex5/bl31_plat_setup.c
@@ -58,9 +58,8 @@
mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
- PLAT_BAUDRATE, &console);
+ PLAT_BAUDRATE, &console);
- init_ncore_ccu();
setup_smmu_stream_id();
/*
@@ -191,8 +190,8 @@
uint32_t boot_core = 0x00;
uint32_t cpuid = 0x00;
- cpuid = read_mpidr();
- boot_core = (mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00);
+ cpuid = MPIDR_AFFLVL1_VAL(read_mpidr());
+ boot_core = ((mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00) >> 10);
NOTICE("BL31: Boot Core = %x\n", boot_core);
NOTICE("BL31: CPU ID = %x\n", cpuid);
INFO("BL31: Invalidate Data cache\n");
@@ -235,6 +234,9 @@
unsigned int pchctlr_new = 0x00;
uint32_t boot_core = 0x00;
+ /* Store magic number for SMP secondary cores boot */
+ mmio_write_32(L2_RESET_DONE_REG, SMP_SEC_CORE_BOOT_REQ);
+
boot_core = (mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00);
/* Update the p-channel based on cpu id */
pch_cpu = 1 << cpu_id;
diff --git a/plat/intel/soc/agilex5/include/agilex5_cache.h b/plat/intel/soc/agilex5/include/agilex5_cache.h
index 095d99e..f7801b9 100644
--- a/plat/intel/soc/agilex5/include/agilex5_cache.h
+++ b/plat/intel/soc/agilex5/include/agilex5_cache.h
@@ -8,5 +8,6 @@
#define AGX5_CACHE_H
void invalidate_dcache_all(void);
+void invalidate_cache_low_el(void);
#endif /* AGX5_CACHE_H */
diff --git a/plat/intel/soc/agilex5/include/agilex5_clock_manager.h b/plat/intel/soc/agilex5/include/agilex5_clock_manager.h
index 566a80d..1165c90 100644
--- a/plat/intel/soc/agilex5/include/agilex5_clock_manager.h
+++ b/plat/intel/soc/agilex5/include/agilex5_clock_manager.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,141 +11,304 @@
#include "socfpga_handoff.h"
/* Clock Manager Registers */
-#define CLKMGR_OFFSET 0x10d10000
+#define CLKMGR_BASE 0x10D10000
+#define CLKMGR_CTRL 0x00
+#define CLKMGR_STAT 0x04
+#define CLKMGR_TESTIOCTROL 0x08
+#define CLKMGR_INTRGEN 0x0C
+#define CLKMGR_INTRMSK 0x10
+#define CLKMGR_INTRCLR 0x14
+#define CLKMGR_INTRSTS 0x18
+#define CLKMGR_INTRSTK 0x1C
+#define CLKMGR_INTRRAW 0x20
-#define CLKMGR_CTRL 0x0
-#define CLKMGR_STAT 0x4
-#define CLKMGR_TESTIOCTROL 0x8
-#define CLKMGR_INTRGEN 0xc
-#define CLKMGR_INTRMSK 0x10
-#define CLKMGR_INTRCLR 0x14
-#define CLKMGR_INTRSTS 0x18
-#define CLKMGR_INTRSTK 0x1c
-#define CLKMGR_INTRRAW 0x20
+/* Clock manager control related macros */
+#define CLKMGR(_reg) (CLKMGR_BASE + (CLKMGR_##_reg))
+#define CLKMGR_STAT_MAINPLLLOCKED BIT(8)
+#define CLKMGR_STAT_PERPLLLOCKED BIT(16)
+
+#define CLKMGR_INTRCLR_MAINLOCKLOST BIT(2)
+#define CLKMGR_INTRCLR_PERLOCKLOST BIT(3)
+
+#define CLKMGR_STAT_ALLPLLLOCKED (CLKMGR_STAT_MAINPLLLOCKED | \
+ CLKMGR_STAT_PERPLLLOCKED)
/* Main PLL Group */
-#define CLKMGR_MAINPLL 0x10d10024
-#define CLKMGR_MAINPLL_EN 0x0
-#define CLKMGR_MAINPLL_ENS 0x4
-#define CLKMGR_MAINPLL_BYPASS 0xc
-#define CLKMGR_MAINPLL_BYPASSS 0x10
-#define CLKMGR_MAINPLL_BYPASSR 0x14
-#define CLKMGR_MAINPLL_NOCCLK 0x1c
-#define CLKMGR_MAINPLL_NOCDIV 0x20
-#define CLKMGR_MAINPLL_PLLGLOB 0x24
-#define CLKMGR_MAINPLL_FDBCK 0x28
-#define CLKMGR_MAINPLL_MEM 0x2c
-#define CLKMGR_MAINPLL_MEMSTAT 0x30
-#define CLKMGR_MAINPLL_VCOCALIB 0x34
-#define CLKMGR_MAINPLL_PLLC0 0x38
-#define CLKMGR_MAINPLL_PLLC1 0x3c
-#define CLKMGR_MAINPLL_PLLC2 0x40
-#define CLKMGR_MAINPLL_PLLC3 0x44
-#define CLKMGR_MAINPLL_PLLM 0x48
-#define CLKMGR_MAINPLL_FHOP 0x4c
-#define CLKMGR_MAINPLL_SSC 0x50
-#define CLKMGR_MAINPLL_LOSTLOCK 0x54
+#define CLKMGR_MAINPLL_BASE 0x10D10024
+#define CLKMGR_MAINPLL_EN 0x00
+#define CLKMGR_MAINPLL_ENS 0x04
+#define CLKMGR_MAINPLL_ENR 0x08
+#define CLKMGR_MAINPLL_BYPASS 0x0C
+#define CLKMGR_MAINPLL_BYPASSS 0x10
+#define CLKMGR_MAINPLL_BYPASSR 0x14
+#define CLKMGR_MAINPLL_NOCCLK 0x1C
+#define CLKMGR_MAINPLL_NOCDIV 0x20
+#define CLKMGR_MAINPLL_PLLGLOB 0x24
+#define CLKMGR_MAINPLL_FDBCK 0x28
+#define CLKMGR_MAINPLL_MEM 0x2C
+#define CLKMGR_MAINPLL_MEMSTAT 0x30
+#define CLKMGR_MAINPLL_VCOCALIB 0x34
+#define CLKMGR_MAINPLL_PLLC0 0x38
+#define CLKMGR_MAINPLL_PLLC1 0x3C
+#define CLKMGR_MAINPLL_PLLC2 0x40
+#define CLKMGR_MAINPLL_PLLC3 0x44
+#define CLKMGR_MAINPLL_PLLM 0x48
+#define CLKMGR_MAINPLL_FHOP 0x4C
+#define CLKMGR_MAINPLL_SSC 0x50
+#define CLKMGR_MAINPLL_LOSTLOCK 0x54
+
+#define CLKMGR_MAINPLL(_reg) (CLKMGR_MAINPLL_BASE + \
+ (CLKMGR_MAINPLL_##_reg))
+
+#define CLKMGR_XPLL_LOSTLOCK_BYPASSCLEAR BIT(0)
+#define CLKMGR_XPLLGLOB_CLR_LOSTLOCK_BYPASS BIT(29)
/* Peripheral PLL Group */
-#define CLKMGR_PERPLL 0x10d1007c
-#define CLKMGR_PERPLL_EN 0x0
-#define CLKMGR_PERPLL_ENS 0x4
-#define CLKMGR_PERPLL_BYPASS 0xc
-#define CLKMGR_PERPLL_EMACCTL 0x18
-#define CLKMGR_PERPLL_GPIODIV 0x1c
-#define CLKMGR_PERPLL_PLLGLOB 0x20
-#define CLKMGR_PERPLL_FDBCK 0x24
-#define CLKMGR_PERPLL_MEM 0x28
-#define CLKMGR_PERPLL_MEMSTAT 0x2c
-#define CLKMGR_PERPLL_PLLC0 0x30
-#define CLKMGR_PERPLL_PLLC1 0x34
-#define CLKMGR_PERPLL_VCOCALIB 0x38
-#define CLKMGR_PERPLL_PLLC2 0x3c
-#define CLKMGR_PERPLL_PLLC3 0x40
-#define CLKMGR_PERPLL_PLLM 0x44
-#define CLKMGR_PERPLL_LOSTLOCK 0x50
+#define CLKMGR_PERPLL_BASE 0x10D1007C
+#define CLKMGR_PERPLL_EN 0x00
+#define CLKMGR_PERPLL_ENS 0x04
+#define CLKMGR_PERPLL_ENR 0x08
+#define CLKMGR_PERPLL_BYPASS 0x0C
+#define CLKMGR_PERPLL_BYPASSS 0x10
+#define CLKMGR_PERPLL_BYPASSR 0x14
+#define CLKMGR_PERPLL_EMACCTL 0x18
+#define CLKMGR_PERPLL_GPIODIV 0x1C
+#define CLKMGR_PERPLL_PLLGLOB 0x20
+#define CLKMGR_PERPLL_FDBCK 0x24
+#define CLKMGR_PERPLL_MEM 0x28
+#define CLKMGR_PERPLL_MEMSTAT 0x2C
+#define CLKMGR_PERPLL_VCOCALIB 0x30
+#define CLKMGR_PERPLL_PLLC0 0x34
+#define CLKMGR_PERPLL_PLLC1 0x38
+#define CLKMGR_PERPLL_PLLC2 0x3C
+#define CLKMGR_PERPLL_PLLC3 0x40
+#define CLKMGR_PERPLL_PLLM 0x44
+#define CLKMGR_PERPLL_FHOP 0x48
+#define CLKMGR_PERPLL_SSC 0x4C
+#define CLKMGR_PERPLL_LOSTLOCK 0x50
+
+#define CLKMGR_PERPLL(_reg) (CLKMGR_PERPLL_BASE + \
+ (CLKMGR_PERPLL_##_reg))
/* Altera Group */
-#define CLKMGR_ALTERA 0x10d100d0
-#define CLKMGR_ALTERA_JTAG 0x0
-#define CLKMGR_ALTERA_EMACACTR 0x4
-#define CLKMGR_ALTERA_EMACBCTR 0x8
-#define CLKMGR_ALTERA_EMACPTPCTR 0xc
-#define CLKMGR_ALTERA_GPIODBCTR 0x10
-#define CLKMGR_ALTERA_S2FUSER0CTR 0x18
-#define CLKMGR_ALTERA_S2FUSER1CTR 0x1c
-#define CLKMGR_ALTERA_PSIREFCTR 0x20
-#define CLKMGR_ALTERA_EXTCNTRST 0x24
-#define CLKMGR_ALTERA_USB31CTR 0x28
-#define CLKMGR_ALTERA_DSUCTR 0x2c
-#define CLKMGR_ALTERA_CORE01CTR 0x30
-#define CLKMGR_ALTERA_CORE23CTR 0x34
-#define CLKMGR_ALTERA_CORE2CTR 0x38
-#define CLKMGR_ALTERA_CORE3CTR 0x3c
+#define CLKMGR_ALTERA_BASE 0x10D100D0
+#define CLKMGR_ALTERA_JTAG 0x00
+#define CLKMGR_ALTERA_EMACACTR 0x04
+#define CLKMGR_ALTERA_EMACBCTR 0x08
+#define CLKMGR_ALTERA_EMACPTPCTR 0x0C
+#define CLKMGR_ALTERA_GPIODBCTR 0x10
+#define CLKMGR_ALTERA_S2FUSER0CTR 0x18
+#define CLKMGR_ALTERA_S2FUSER1CTR 0x1C
+#define CLKMGR_ALTERA_PSIREFCTR 0x20
+#define CLKMGR_ALTERA_EXTCNTRST 0x24
+#define CLKMGR_ALTERA_USB31CTR 0x28
+#define CLKMGR_ALTERA_DSUCTR 0x2C
+#define CLKMGR_ALTERA_CORE01CTR 0x30
+#define CLKMGR_ALTERA_CORE23CTR 0x34
+#define CLKMGR_ALTERA_CORE2CTR 0x38
+#define CLKMGR_ALTERA_CORE3CTR 0x3C
+#define CLKMGR_ALTERA_SERIAL_CON_PLL_CTR 0x40
+
+#define CLKMGR_ALTERA(_reg) (CLKMGR_ALTERA_BASE + \
+ (CLKMGR_ALTERA_##_reg))
-/* Membus */
-#define CLKMGR_MEM_REQ BIT(24)
-#define CLKMGR_MEM_WR BIT(25)
-#define CLKMGR_MEM_ERR BIT(26)
-#define CLKMGR_MEM_WDAT_OFFSET 16
-#define CLKMGR_MEM_ADDR 0x4027
-#define CLKMGR_MEM_WDAT 0x80
+#define CLKMGR_ALTERA_EXTCNTRST_EMACACNTRST BIT(0)
+#define CLKMGR_ALTERA_EXTCNTRST_EMACBCNTRST BIT(1)
+#define CLKMGR_ALTERA_EXTCNTRST_EMACPTPCNTRST BIT(2)
+#define CLKMGR_ALTERA_EXTCNTRST_GPIODBCNTRST BIT(3)
+#define CLKMGR_ALTERA_EXTCNTRST_S2FUSER0CNTRST BIT(5)
+#define CLKMGR_ALTERA_EXTCNTRST_S2FUSER1CNTRST BIT(6)
+#define CLKMGR_ALTERA_EXTCNTRST_PSIREFCNTRST BIT(7)
+#define CLKMGR_ALTERA_EXTCNTRST_USB31REFCNTRST BIT(8)
+#define CLKMGR_ALTERA_EXTCNTRST_DSUCNTRST BIT(10)
+#define CLKMGR_ALTERA_EXTCNTRST_CORE01CNTRST BIT(11)
+#define CLKMGR_ALTERA_EXTCNTRST_CORE2CNTRST BIT(12)
+#define CLKMGR_ALTERA_EXTCNTRST_CORE3CNTRST BIT(13)
+
+#define CLKMGR_ALTERA_EXTCNTRST_ALLCNTRST \
+ (CLKMGR_ALTERA_EXTCNTRST_EMACACNTRST | \
+ CLKMGR_ALTERA_EXTCNTRST_EMACBCNTRST | \
+ CLKMGR_ALTERA_EXTCNTRST_EMACPTPCNTRST | \
+ CLKMGR_ALTERA_EXTCNTRST_GPIODBCNTRST | \
+ CLKMGR_ALTERA_EXTCNTRST_S2FUSER0CNTRST |\
+ CLKMGR_ALTERA_EXTCNTRST_S2FUSER1CNTRST |\
+ CLKMGR_ALTERA_EXTCNTRST_PSIREFCNTRST | \
+ CLKMGR_ALTERA_EXTCNTRST_USB31REFCNTRST |\
+ CLKMGR_ALTERA_EXTCNTRST_DSUCNTRST | \
+ CLKMGR_ALTERA_EXTCNTRST_CORE01CNTRST | \
+ CLKMGR_ALTERA_EXTCNTRST_CORE2CNTRST | \
+ CLKMGR_ALTERA_EXTCNTRST_CORE3CNTRST)
+
+#define CLKMGR_ALTERA_CORE0 0
+#define CLKMGR_ALTERA_CORE1 1
+#define CLKMGR_ALTERA_CORE2 2
+#define CLKMGR_ALTERA_CORE3 3
+
+/* PLL membus configuration macros */
+#define CLKMGR_MEM_REQ BIT(24)
+#define CLKMGR_MEM_WR BIT(25)
+#define CLKMGR_MEM_ERR BIT(26)
+#define CLKMGR_MEM_WDAT_OFFSET 16
+#define CLKMGR_MEM_ADDR_MASK GENMASK(15, 0)
+#define CLKMGR_MEM_ADDR_START 0x00004000
+#define CLKMGR_PLLCFG_SRC_SYNC_MODE 0x27
+#define CLKMGR_PLLCFG_OVRSHOOT_FREQ_LOCK 0xB3
+#define CLKMGR_PLLCFG_LOCK_SETTLE_TIME 0xE6
+#define CLKMGR_PLLCFG_DUTYCYCLE_CLKSLICE0 0x03
+#define CLKMGR_PLLCFG_DUTYCYCLE_CLKSLICE1 0x07
/* Clock Manager Macros */
-#define CLKMGR_CTRL_BOOTMODE_SET_MSK 0x00000001
-#define CLKMGR_STAT_BUSY_E_BUSY 0x1
-#define CLKMGR_STAT_BUSY(x) (((x) & 0x00000001) >> 0)
-#define CLKMGR_STAT_MAINPLLLOCKED(x) (((x) & 0x00000100) >> 8)
-#define CLKMGR_STAT_PERPLLLOCKED(x) (((x) & 0x00010000) >> 16)
-#define CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK 0x00000004
-#define CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK 0x00000008
-#define CLKMGR_INTOSC_HZ 460000000
+#define CLKMGR_CTRL_BOOTMODE_SET_MSK 0x00000001
+#define CLKMGR_STAT_BUSY_E_BUSY 0x1
+#define CLKMGR_STAT_BUSY(x) (((x) & 0x00000001) >> 0)
+#define CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK 0x00000004
+#define CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK 0x00000008
+#define CLKMGR_INTOSC_HZ 460000000
+#define CLKMGR_CTRL_BOOTMODE BIT(0)
+#define CLKMGR_STAT_MAINPLL_LOCKED BIT(8)
+#define CLKMGR_STAT_MAIN_TRANS BIT(9)
+#define CLKMGR_STAT_PERPLL_LOCKED BIT(16)
+#define CLKMGR_STAT_PERF_TRANS BIT(17)
+#define CLKMGR_STAT_BOOTMODE BIT(24)
+#define CLKMGR_STAT_BOOTCLKSRC BIT(25)
+#define CLKMGR_STAT_ALLPLL_LOCKED_MASK (CLKMGR_STAT_MAINPLL_LOCKED | \
+ CLKMGR_STAT_PERPLL_LOCKED)
/* Main PLL Macros */
-#define CLKMGR_MAINPLL_EN_RESET 0x0000005e
-#define CLKMGR_MAINPLL_ENS_RESET 0x0000005e
-
-/* Peripheral PLL Macros */
-#define CLKMGR_PERPLL_EN_RESET 0x040007FF
-#define CLKMGR_PERPLL_ENS_RESET 0x040007FF
+#define CLKMGR_MAINPLL_EN_RESET 0x0000005E
+#define CLKMGR_MAINPLL_ENS_RESET 0x0000005E
+#define CLKMGR_MAINPLL_PLLGLOB_PD_N BIT(0)
+#define CLKMGR_MAINPLL_PLLGLOB_RST_N BIT(1)
+#define CLKMGR_MAINPLL_PLLCX_EN BIT(27)
+#define CLKMGR_MAINPLL_PLLCX_MUTE BIT(28)
-#define CLKMGR_PERPLL_EN_SDMMCCLK BIT(5)
-#define CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET(x) (((x) << 0) & 0x0000ffff)
+#define CLKMGR_PERPLL_EN_SDMMCCLK BIT(5)
+#define CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET(x) (((x) << 0) & 0x0000FFFF)
+#define CLKMGR_PERPLL_PLLGLOB_PD_N BIT(0)
+#define CLKMGR_PERPLL_PLLGLOB_RST_N BIT(1)
+#define CLKMGR_PERPLL_PLLCX_EN BIT(27)
+#define CLKMGR_PERPLL_PLLCX_MUTE BIT(28)
/* Altera Macros */
-#define CLKMGR_ALTERA_EXTCNTRST_RESET 0xff
+#define CLKMGR_ALTERA_EXTCNTRST_RESET 0xFF
/* Shared Macros */
-#define CLKMGR_PSRC(x) (((x) & 0x00030000) >> 16)
-#define CLKMGR_PSRC_MAIN 0
-#define CLKMGR_PSRC_PER 1
+#define CLKMGR_PLLGLOB_PSRC(x) (((x) & 0x00030000) >> 16)
+#define CLKMGR_PSRC_MAIN 0
+#define CLKMGR_PSRC_PER 1
+
+#define CLKMGR_PLLGLOB_PSRC_EOSC1 0x0
+#define CLKMGR_PLLGLOB_PSRC_INTOSC 0x1
+#define CLKMGR_PLLGLOB_PSRC_F2S 0x2
+
+#define CLKMGR_PLLM_MDIV(x) ((x) & 0x000003FF)
+#define CLKMGR_PLLGLOB_PD_SET_MSK 0x00000001
+#define CLKMGR_PLLGLOB_RST_SET_MSK 0x00000002
+
+#define CLKMGR_PLLGLOB_REFCLKDIV(x) (((x) & 0x00003F00) >> 8)
+#define CLKMGR_PLLGLOB_AREFCLKDIV(x) (((x) & 0x00000F00) >> 8)
+#define CLKMGR_PLLGLOB_DREFCLKDIV(x) (((x) & 0x00003000) >> 12)
-#define CLKMGR_PLLGLOB_PSRC_EOSC1 0x0
-#define CLKMGR_PLLGLOB_PSRC_INTOSC 0x1
-#define CLKMGR_PLLGLOB_PSRC_F2S 0x2
+#define CLKMGR_VCOCALIB_HSCNT_SET(x) (((x) << 0) & 0x000003FF)
+#define CLKMGR_VCOCALIB_MSCNT_SET(x) (((x) << 16) & 0x00FF0000)
-#define CLKMGR_PLLM_MDIV(x) ((x) & 0x000003ff)
-#define CLKMGR_PLLGLOB_PD_SET_MSK 0x00000001
-#define CLKMGR_PLLGLOB_RST_SET_MSK 0x00000002
+#define CLKMGR_CLR_LOSTLOCK_BYPASS 0x20000000
-#define CLKMGR_PLLGLOB_REFCLKDIV(x) (((x) & 0x00003f00) >> 8)
-#define CLKMGR_PLLGLOB_AREFCLKDIV(x) (((x) & 0x00000f00) >> 8)
-#define CLKMGR_PLLGLOB_DREFCLKDIV(x) (((x) & 0x00003000) >> 12)
+#define CLKMGR_CLKSRC_MASK GENMASK(18, 16)
+#define CLKMGR_CLKSRC_OFFSET 16
+#define CLKMGR_CLKSRC_MAIN 0
+#define CLKMGR_CLKSRC_PER 1
+#define CLKMGR_CLKSRC_OSC1 2
+#define CLKMGR_CLKSRC_INTOSC 3
+#define CLKMGR_CLKSRC_FPGA 4
+#define CLKMGR_PLLCX_DIV_MSK GENMASK(10, 0)
-#define CLKMGR_VCOCALIB_HSCNT_SET(x) (((x) << 0) & 0x000003ff)
-#define CLKMGR_VCOCALIB_MSCNT_SET(x) (((x) << 16) & 0x00ff0000)
+#define GET_CLKMGR_CLKSRC(x) (((x) & CLKMGR_CLKSRC_MASK) >> \
+ CLKMGR_CLKSRC_OFFSET)
-#define CLKMGR_CLR_LOSTLOCK_BYPASS 0x20000000
+#define CLKMGR_MAINPLL_NOCDIV_L4MP_MASK GENMASK(5, 4)
+#define CLKMGR_MAINPLL_NOCDIV_L4MP_OFFSET 4
+#define GET_CLKMGR_MAINPLL_NOCDIV_L4MP(x) (((x) & CLKMGR_MAINPLL_NOCDIV_L4MP_MASK) >> \
+ CLKMGR_MAINPLL_NOCDIV_L4MP_OFFSET)
-typedef struct {
- uint32_t clk_freq_of_eosc1;
- uint32_t clk_freq_of_f2h_free;
- uint32_t clk_freq_of_cb_intosc_ls;
-} CLOCK_SOURCE_CONFIG;
+#define CLKMGR_MAINPLL_NOCDIV_L4SP_MASK GENMASK(7, 6)
+#define CLKMGR_MAINPLL_NOCDIV_L4SP_OFFSET 6
+#define GET_CLKMGR_MAINPLL_NOCDIV_L4SP(x) (((x) & CLKMGR_MAINPLL_NOCDIV_L4SP_MASK) >> \
+ CLKMGR_MAINPLL_NOCDIV_L4SP_OFFSET)
+
+#define CLKMGR_MAINPLL_NOCDIV_SPHY_MASK GENMASK(17, 16)
+#define CLKMGR_MAINPLL_NOCDIV_SPHY_OFFSET 16
+#define GET_CLKMGR_MAINPLL_NOCDIV_SPHY(x) (((x) & CLKMGR_MAINPLL_NOCDIV_SPHY_MASK) >> \
+ CLKMGR_MAINPLL_NOCDIV_SPHY_OFFSET)
+
+
+#define CLKMGR_MAINPLL_NOCDIV_L4SYSFREE_MASK GENMASK(3, 2)
+#define CLKMGR_MAINPLL_NOCDIV_L4SYSFREE_OFFSET 2
+#define GET_CLKMGR_MAINPLL_NOCDIV_L4SYSFREE(x) (((x) & CLKMGR_MAINPLL_NOCDIV_L4SYSFREE_MASK) >> \
+ CLKMGR_MAINPLL_NOCDIV_L4SYSFREE_OFFSET)
+
+#define CLKMGR_PERPLL_EMAC0_CLK_SRC_MASK BIT(26)
+#define CLKMGR_PERPLL_EMAC0_CLK_SRC_OFFSET 26
+#define GET_CLKMGR_PERPLL_EMAC0_CLK_SRC(x) (((x) & CLKMGR_PERPLL_EMAC0_CLK_SRC_MASK) >> \
+ CLKMGR_PERPLL_EMAC0_CLK_SRC_OFFSET)
+
+#define CLKMGR_ALTERA_EMACACTR_CLK_SRC_MASK GENMASK(18, 16)
+#define CLKMGR_ALTERA_EMACACTR_CLK_SRC_OFFSET 16
+#define GET_CLKMGR_EMACACTR_CLK_SRC(x) (((x) & CLKMGR_ALTERA_EMACACTR_CLK_SRC_MASK) >> \
+ CLKMGR_ALTERA_EMACACTR_CLK_SRC_OFFSET)
+
+#define CLKMGR_MPU_CLK_ID 0
+#define CLKMGR_MPU_PERIPH_CLK_ID 1
+#define CLKMGR_L4_MAIN_CLK_ID 2
+#define CLKMGR_L4_MP_CLK_ID 3
+#define CLKMGR_L4_SP_CLK_ID 4
+#define CLKMGR_WDT_CLK_ID 5
+#define CLKMGR_UART_CLK_ID 6
+#define CLKMGR_EMAC0_CLK_ID 7
+#define CLKMGR_EMAC1_CLK_ID 8
+#define CLKMGR_EMAC2_CLK_ID 9
+#define CLKMGR_EMAC_PTP_CLK_ID 10
+#define CLKMGR_SDMMC_CLK_ID 11
+
+#define CLKMGR_MAINPLL_BYPASS_ALL (0xF6)
+#define CLKMGR_PERPLL_BYPASS_ALL (0xEF)
+#define CLKMGR_PLLCX_STAT BIT(29)
+#define GET_PLLCX_STAT(x) ((x) & CLKMGR_PLLCX_STAT)
+
+#define CLKMGR_MAINPLL_TYPE (0)
+#define CLKMGR_PERPLL_TYPE (1)
+
+#define CLKMGR_MAX_RETRY_COUNT 1000
+
+#define CLKMGR_PLLM_MDIV_MASK GENMASK(9, 0)
+#define CLKMGR_PLLGLOB_PD_MASK BIT(0)
+#define CLKMGR_PLLGLOB_RST_MASK BIT(1)
+#define CLKMGR_PLLGLOB_AREFCLKDIV_MASK GENMASK(11, 8)
+#define CLKMGR_PLLGLOB_DREFCLKDIV_MASK GENMASK(13, 12)
+#define CLKMGR_PLLGLOB_REFCLKDIV_MASK GENMASK(13, 8)
+#define CLKMGR_PLLGLOB_MODCLKDIV_MASK GENMASK(24, 27)
+#define CLKMGR_PLLGLOB_AREFCLKDIV_OFFSET 8
+#define CLKMGR_PLLGLOB_DREFCLKDIV_OFFSET 12
+#define CLKMGR_PLLGLOB_REFCLKDIV_OFFSET 8
+#define CLKMGR_PLLGLOB_MODCLKDIV_OFFSET 24
+#define CLKMGR_PLLGLOB_VCO_PSRC_MASK GENMASK(17, 16)
+#define CLKMGR_PLLGLOB_VCO_PSRC_OFFSET 16
+#define CLKMGR_PLLGLOB_CLR_LOSTLOCK_BYPASS_MASK BIT(29)
+
+#define CLKMGR_VCOCALIB_MSCNT_MASK GENMASK(23, 16)
+#define CLKMGR_VCOCALIB_MSCNT_OFFSET 16
+#define CLKMGR_VCOCALIB_HSCNT_MASK GENMASK(9, 0)
+#define CLKMGR_VCOCALIB_MSCNT_CONST 100
+#define CLKMGR_VCOCALIB_HSCNT_CONST 4
+
+int config_clkmgr_handoff(handoff *hoff_ptr);
+uint32_t clkmgr_get_rate(uint32_t clk_id);
-void config_clkmgr_handoff(handoff *hoff_ptr);
-uint32_t get_wdt_clk(void);
-uint32_t get_uart_clk(void);
-uint32_t get_mmc_clk(void);
+/* PLL configuration data structure in power-down state */
+typedef struct pll_cfg {
+ uint32_t addr;
+ uint32_t data;
+ uint32_t mask;
+} pll_cfg_t;
#endif
diff --git a/plat/intel/soc/agilex5/include/agilex5_ddr.h b/plat/intel/soc/agilex5/include/agilex5_ddr.h
new file mode 100644
index 0000000..631e006
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_ddr.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AGILEX5_DDR_H
+#define AGILEX5_DDR_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <lib/utils_def.h>
+
+#include "socfpga_handoff.h"
+
+#define CONFIG_NR_DRAM_BANKS 1
+
+typedef unsigned long long phys_addr_t;
+typedef unsigned long long phys_size_t;
+typedef phys_addr_t fdt_addr_t;
+
+/* DDR/RAM configuration */
+struct ddr_info {
+ phys_addr_t start;
+ phys_size_t size;
+};
+
+int agilex5_ddr_init(handoff *hoff_ptr);
+
+#endif /* AGILEX5_DDR_H */
diff --git a/plat/intel/soc/agilex5/include/agilex5_iossm_mailbox.h b/plat/intel/soc/agilex5/include/agilex5_iossm_mailbox.h
new file mode 100644
index 0000000..1fd8ef6
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_iossm_mailbox.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AGILEX5_IOSSM_MAILBOX_H
+#define AGILEX5_IOSSM_MAILBOX_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "lib/mmio.h"
+#include "agilex5_ddr.h"
+
+#define TIMEOUT_5000MS 5000
+#define TIMEOUT TIMEOUT_5000MS
+#define IOSSM_STATUS_CAL_SUCCESS BIT(0)
+#define IOSSM_STATUS_CAL_FAIL BIT(1)
+#define IOSSM_STATUS_CAL_BUSY BIT(2)
+#define IOSSM_STATUS_COMMAND_RESPONSE_READY 1
+#define IOSSM_CMD_RESPONSE_STATUS_OFFSET 0x45C
+#define IOSSM_CMD_RESPONSE_DATA_0_OFFSET 0x458
+#define IOSSM_CMD_RESPONSE_DATA_1_OFFSET 0x454
+#define IOSSM_CMD_RESPONSE_DATA_2_OFFSET 0x450
+#define IOSSM_CMD_REQ_OFFSET 0x43C
+#define IOSSM_CMD_PARAM_0_OFFSET 0x438
+#define IOSSM_CMD_PARAM_1_OFFSET 0x434
+#define IOSSM_CMD_PARAM_2_OFFSET 0x430
+#define IOSSM_CMD_PARAM_3_OFFSET 0x42C
+#define IOSSM_CMD_PARAM_4_OFFSET 0x428
+#define IOSSM_CMD_PARAM_5_OFFSET 0x424
+#define IOSSM_CMD_PARAM_6_OFFSET 0x420
+#define IOSSM_STATUS_OFFSET 0x400
+#define IOSSM_CMD_RESPONSE_DATA_SHORT_MASK GENMASK(31, 16)
+#define IOSSM_CMD_RESPONSE_DATA_SHORT(data) (((data) & \
+ IOSSM_CMD_RESPONSE_DATA_SHORT_MASK) >> 16)
+#define MAX_IO96B_SUPPORTED 2
+#define MAX_MEM_INTERFACES_SUPPORTED 2
+
+/* supported mailbox command type */
+enum iossm_mailbox_cmd_type {
+ CMD_NOP,
+ CMD_GET_SYS_INFO,
+ CMD_GET_MEM_INFO,
+ CMD_GET_MEM_CAL_INFO,
+ CMD_TRIG_CONTROLLER_OP,
+ CMD_TRIG_MEM_CAL_OP
+};
+
+/* supported mailbox command opcode */
+enum iossm_mailbox_cmd_opcode {
+ GET_MEM_INTF_INFO = 0x0001,
+ GET_MEM_TECHNOLOGY,
+ GET_MEMCLK_FREQ_KHZ,
+ GET_MEM_WIDTH_INFO,
+ ECC_ENABLE_SET = 0x0101,
+ ECC_ENABLE_STATUS,
+ ECC_INTERRUPT_STATUS,
+ ECC_INTERRUPT_ACK,
+ ECC_INTERRUPT_MASK,
+ ECC_WRITEBACK_ENABLE,
+ ECC_SCRUB_IN_PROGRESS_STATUS = 0x0201,
+ ECC_SCRUB_MODE_0_START,
+ ECC_SCRUB_MODE_1_START,
+ BIST_STANDARD_MODE_START = 0x0301,
+ BIST_RESULTS_STATUS,
+ BIST_MEM_INIT_START,
+ BIST_MEM_INIT_STATUS,
+ BIST_SET_DATA_PATTERN_UPPER,
+ BIST_SET_DATA_PATTERN_LOWER,
+ TRIG_MEM_CAL = 0x000a,
+ GET_MEM_CAL_STATUS
+};
+
+/*
+ * IOSSM mailbox required information
+ *
+ * @num_mem_interface: Number of memory interfaces instantiated
+ * @ip_type: IP type implemented on the IO96B
+ * @ip_instance_id: IP identifier for every IP instance implemented on the IO96B
+ */
+struct io96b_mb_ctrl {
+ uint32_t num_mem_interface;
+ uint32_t ip_type[2];
+ uint32_t ip_instance_id[2];
+};
+
+/*
+ * IOSSM mailbox response outputs
+ *
+ * @cmd_resp_status: Command Interface status
+ * @cmd_resp_data_*: More spaces for command response
+ */
+struct io96b_mb_resp {
+ uint32_t cmd_resp_status;
+ uint32_t cmd_resp_data_0;
+ uint32_t cmd_resp_data_1;
+ uint32_t cmd_resp_data_2;
+};
+
+/*
+ * IO96B instance specific information
+ *
+ * @size: Memory size
+ * @io96b_csr_addr: IO96B instance CSR address
+ * @cal_status: IO96B instance calibration status
+ * @mb_ctrl: IOSSM mailbox required information
+ */
+struct io96b_instance {
+ uint16_t size;
+ phys_addr_t io96b_csr_addr;
+ bool cal_status;
+ struct io96b_mb_ctrl mb_ctrl;
+};
+
+/*
+ * Overall IO96B instance(s) information
+ *
+ * @num_instance: Number of instance(s) assigned to HPS
+ * @overall_cal_status: Overall calibration status for all IO96B instance(s)
+ * @ddr_type: DDR memory type
+ * @ecc_status: ECC enable status (false = disabled, true = enabled)
+ * @overall_size: Total DDR memory size
+ * @io96b_0: IO96B 0 instance specific information
+ * @io96b_1: IO96B 1 instance specific information
+ */
+struct io96b_info {
+ uint8_t num_instance;
+ bool overall_cal_status;
+ const char *ddr_type;
+ bool ecc_status;
+ uint16_t overall_size;
+ struct io96b_instance io96b_0;
+ struct io96b_instance io96b_1;
+};
+
+int io96b_mb_req(phys_addr_t io96b_csr_addr, uint32_t ip_type, uint32_t instance_id,
+ uint32_t usr_cmd_type, uint32_t usr_cmd_opcode, uint32_t cmd_param_0,
+ uint32_t cmd_param_1, uint32_t cmd_param_2, uint32_t cmd_param_3,
+ uint32_t cmd_param_4, uint32_t cmd_param_5, uint32_t cmd_param_6,
+ uint32_t resp_data_len, struct io96b_mb_resp *resp);
+
+/* Supported IOSSM mailbox function */
+void io96b_mb_init(struct io96b_info *io96b_ctrl);
+int io96b_cal_status(phys_addr_t addr);
+void init_mem_cal(struct io96b_info *io96b_ctrl);
+int trig_mem_cal(struct io96b_info *io96b_ctrl);
+int get_mem_technology(struct io96b_info *io96b_ctrl);
+int get_mem_width_info(struct io96b_info *io96b_ctrl);
+int ecc_enable_status(struct io96b_info *io96b_ctrl);
+int bist_mem_init_start(struct io96b_info *io96b_ctrl);
+
+#endif /* AGILEX5_IOSSM_MAILBOX_H */
diff --git a/plat/intel/soc/agilex5/include/agilex5_pinmux.h b/plat/intel/soc/agilex5/include/agilex5_pinmux.h
index 8a8e8c7..78d19af 100644
--- a/plat/intel/soc/agilex5/include/agilex5_pinmux.h
+++ b/plat/intel/soc/agilex5/include/agilex5_pinmux.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,19 +8,13 @@
#ifndef AGX5_PINMUX_H
#define AGX5_PINMUX_H
-/* PINMUX REGISTER ADDRESS */
-#define AGX5_PINMUX_PIN0SEL 0x10d13000
-#define AGX5_PINMUX_IO0CTRL 0x10d13130
-#define AGX5_PINMUX_EMAC0_USEFPGA 0x10d13300
-#define AGX5_PINMUX_IO0_DELAY 0x10d13400
-#define AGX5_PERIPHERAL 0x10d14044
-
#include "socfpga_handoff.h"
-/* PINMUX DEFINE */
-#define PINMUX_HANDOFF_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-#define PINMUX_HANDOFF_CONFIG_ADDR 0xbeec
-#define PINMUX_HANDOFF_CONFIG_VAL 0x7e000
+/* PINMUX REGISTER ADDRESS */
+#define AGX5_PINMUX_PIN0SEL 0x10D13000
+#define AGX5_PINMUX_IO0CTRL 0x10D13130
+#define AGX5_PINMUX_EMAC0_USEFPGA 0x10D13300
+#define AGX5_PINMUX_IO0_DELAY 0x10D13400
/* Macros */
#define SOCFPGA_PINMUX_SEL_NAND (0x03)
@@ -142,6 +137,9 @@
#define SOCFPGA_PINMUX_JTAG_USEFPGA (0x50)
#define SOCFPGA_PINMUX_SDMMC_USEFPGA (0x54)
+#define SOCFPGA_PINUMX_USEFPGA(_reg) (AGX5_PINMUX_EMAC0_USEFPGA \
+ + SOCFPGA_PINMUX_##_reg)
+
#define SOCFPGA_PINMUX_IO0DELAY (0x00)
#define SOCFPGA_PINMUX_IO1DELAY (0x04)
#define SOCFPGA_PINMUX_IO2DELAY (0x08)
@@ -198,5 +196,4 @@
+ (SOCFPGA_PINMUX_##_reg))
void config_pinmux(handoff *handoff);
-void config_peripheral(handoff *handoff);
#endif
diff --git a/plat/intel/soc/agilex5/include/agilex5_power_manager.h b/plat/intel/soc/agilex5/include/agilex5_power_manager.h
index 1bba74b..178fd5b 100644
--- a/plat/intel/soc/agilex5/include/agilex5_power_manager.h
+++ b/plat/intel/soc/agilex5/include/agilex5_power_manager.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -77,7 +78,5 @@
#define AGX5_PWRMGR_PSS_STAT_BUSY_E_BUSY 0x0
#define AGX5_PWRMGR_PSS_STAT_BUSY(x) (((x) & 0x000000FF) >> 0)
-int pss_sram_power_off(handoff *hoff_ptr);
-int wait_verify_fsm(uint16_t timeout, uint32_t peripheral_handoff);
-
+void config_pwrmgr_handoff(handoff *hoff_ptr);
#endif
diff --git a/plat/intel/soc/agilex5/include/agilex5_system_manager.h b/plat/intel/soc/agilex5/include/agilex5_system_manager.h
index 53dcd13..ac4bf12 100644
--- a/plat/intel/soc/agilex5/include/agilex5_system_manager.h
+++ b/plat/intel/soc/agilex5/include/agilex5_system_manager.h
@@ -25,6 +25,7 @@
#define SOCFPGA_SYSMGR_TSN_0_ACE 0x50
#define SOCFPGA_SYSMGR_TSN_1_ACE 0x54
#define SOCFPGA_SYSMGR_TSN_2_ACE 0x58
+#define SOCFPGA_SYSMGR_FPGA_BRIDGE_CTRL 0x5C
#define SOCFPGA_SYSMGR_FPGAINTF_EN_1 0x68
#define SOCFPGA_SYSMGR_FPGAINTF_EN_2 0x6C
#define SOCFPGA_SYSMGR_FPGAINTF_EN_3 0x70
@@ -122,7 +123,7 @@
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_8 0x220
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_9 0x224
#define SOCFPGA_SYSMGR_MPFE_CONFIG 0x228
-#define SOCFPGA_SYSMGR_MPFE_status 0x22C
+#define SOCFPGA_SYSMGR_MPFE_STATUS 0x22C
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_0 0x230
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_1 0x234
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_2 0x238
@@ -184,11 +185,28 @@
#define SDM 0x000A000A
#define CORE_SIGHT_DEBUG 0x000B000B
+/* JTAG ID value for Agilex5 */
+#define A590_JTAG_ID 0x9000
+#define A594_JTAG_ID 0x40009000
+#define A5C0_JTAG_ID 0xC000
+#define A5C4_JTAG_ID 0x4000C000
+#define A5D0_JTAG_ID 0xD000
+#define A5D4_JTAG_ID 0x4000D000
+#define A5F0_JTAG_ID 0xC000
+#define A5F4_JTAG_ID 0x4000F000
+#define A510_JTAG_ID 0x1000
+#define A514_JTAG_ID 0x40001000
+#define A530_JTAG_ID 0x3000
+#define A534_JTAG_ID 0x40003000
+#define JTAG_ID_MASK 0xC000F000
+
/* Field Masking */
#define SYSMGR_SDMMC_DRVSEL(x) (((x) & 0x7) << 0)
#define SYSMGR_SDMMC_SMPLSEL(x) (((x) & 0x7) << 4)
#define SYSMGR_F2S_BRIDGE_CTRL_EN BIT(0)
+#define SYSMGR_SOC_BRIDGE_CTRL_EN BIT(0)
+#define SYSMGR_LWSOC_BRIDGE_CTRL_EN BIT(1)
#define IDLE_DATA_LWSOC2FPGA BIT(4)
#define IDLE_DATA_SOC2FPGA BIT(0)
#define IDLE_DATA_MASK (IDLE_DATA_LWSOC2FPGA \
diff --git a/plat/intel/soc/agilex5/include/socfpga_plat_def.h b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
index 9bfc304..c1f3cc5 100644
--- a/plat/intel/soc/agilex5/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
@@ -11,11 +11,15 @@
#include "agilex5_memory_controller.h"
#include "agilex5_system_manager.h"
+
#include <platform_def.h>
/* Platform Setting */
#define PLATFORM_MODEL PLAT_SOCFPGA_AGILEX5
-#define BOOT_SOURCE BOOT_SOURCE_SDMMC
+/* 1 = Flush cache, 0 = No cache flush.
+ * Default for Agilex5 is Cache flush.
+ */
+#define CACHE_FLUSH 1
#define MMC_DEVICE_TYPE 1 /* MMC = 0, SD = 1 */
#define XLAT_TABLES_V2 U(1)
#define PLAT_PRIMARY_CPU_A55 0x000
@@ -23,22 +27,43 @@
#define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT MPIDR_AFF2_SHIFT
#define PLAT_CPU_ID_MPIDR_AFF_SHIFT MPIDR_AFF1_SHIFT
#define PLAT_L2_RESET_REQ 0xB007C0DE
+#define PLAT_HANDOFF_OFFSET 0x0007F000
+#define PLAT_TIMER_BASE_ADDR 0x10D01000
/* System Counter */
/* TODO: Update back to 400MHz.
* This shall be updated to read from L4 clock instead of hardcoded.
*/
-#define PLAT_SYS_COUNTER_FREQ_IN_TICKS (400000000)
-#define PLAT_SYS_COUNTER_FREQ_IN_MHZ (400)
+#define PLAT_SYS_COUNTER_FREQ_IN_TICKS U(400000000)
+#define PLAT_SYS_COUNTER_FREQ_IN_MHZ U(400)
/* FPGA config helpers */
#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x80400000
-#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 0x2000000
+#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 0x82000000
/* QSPI Setting */
#define CAD_QSPIDATA_OFST 0x10900000
#define CAD_QSPI_OFFSET 0x108d2000
+/* FIP Setting */
+#define PLAT_FIP_BASE (0)
+#if ARM_LINUX_KERNEL_AS_BL33
+#define PLAT_FIP_MAX_SIZE (0x8000000)
+#else
+#define PLAT_FIP_MAX_SIZE (0x1000000)
+#endif
+
+/* SDMMC Setting */
+#if ARM_LINUX_KERNEL_AS_BL33
+#define PLAT_MMC_DATA_BASE (0x90000000)
+#define PLAT_MMC_DATA_SIZE (0x100000)
+#define SOCFPGA_MMC_BLOCK_SIZE U(32768)
+#else
+#define PLAT_MMC_DATA_BASE (0x0007D000)
+#define PLAT_MMC_DATA_SIZE (0x2000)
+#define SOCFPGA_MMC_BLOCK_SIZE U(8192)
+#endif
+
/* Register Mapping */
#define SOCFPGA_CCU_NOC_REG_BASE 0x1c000000
#define SOCFPGA_F2SDRAMMGR_REG_BASE 0x18001000
@@ -55,10 +80,22 @@
#define SOCFPGA_L4_SYS_SCR_REG_BASE 0x10d21100
#define SOCFPGA_SOC2FPGA_SCR_REG_BASE 0x10d21200
#define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE 0x10d21300
+#define SOCFPGA_SDMMC_SECU_BIT 0x40
+#define SOCFPGA_LWSOC2FPGA_ENABLE 0xffe0301
+#define SOCFPGA_SDMMC_SECU_BIT_ENABLE 0x1010001
+
/* Define maximum page size for NAND flash devices */
#define PLATFORM_MTD_MAX_PAGE_SIZE U(0x2000)
+/* OCRAM Register*/
+
+#define OCRAM_REG_BASE 0x108CC400
+#define OCRAM_REGION_0_OFFSET 0x18
+#define OCRAM_REGION_0_REG_BASE (OCRAM_REG_BASE + \
+ OCRAM_REGION_0_OFFSET)
+#define OCRAM_NON_SECURE_ENABLE 0x0
+
/*******************************************************************************
* Platform memory map related constants
******************************************************************************/
@@ -88,11 +125,10 @@
#define GIC_SIZE (0x00100000)
#define BL2_BASE (0x00000000)
-#define BL2_LIMIT (0x0002b000)
+#define BL2_LIMIT (0x0007E000)
#define BL31_BASE (0x80000000)
#define BL31_LIMIT (0x82000000)
-
/*******************************************************************************
* UART related constants
******************************************************************************/
diff --git a/plat/intel/soc/agilex5/platform.mk b/plat/intel/soc/agilex5/platform.mk
index 90678e1..a831c39 100644
--- a/plat/intel/soc/agilex5/platform.mk
+++ b/plat/intel/soc/agilex5/platform.mk
@@ -58,14 +58,16 @@
lib/cpus/aarch64/cortex_a76.S \
plat/intel/soc/agilex5/soc/agilex5_clock_manager.c \
plat/intel/soc/agilex5/soc/agilex5_memory_controller.c \
- plat/intel/soc/agilex5/soc/agilex5_mmc.c \
+ plat/intel/soc/agilex5/soc/agilex5_mmc.c \
plat/intel/soc/agilex5/soc/agilex5_pinmux.c \
plat/intel/soc/agilex5/soc/agilex5_power_manager.c \
+ plat/intel/soc/agilex5/soc/agilex5_ddr.c \
+ plat/intel/soc/agilex5/soc/agilex5_iossm_mailbox.c \
plat/intel/soc/common/bl2_plat_mem_params_desc.c \
plat/intel/soc/common/socfpga_image_load.c \
plat/intel/soc/common/socfpga_ros.c \
plat/intel/soc/common/socfpga_storage.c \
- plat/intel/soc/common/socfpga_vab.c \
+ plat/intel/soc/common/socfpga_vab.c \
plat/intel/soc/common/soc/socfpga_emac.c \
plat/intel/soc/common/soc/socfpga_firewall.c \
plat/intel/soc/common/soc/socfpga_handoff.c \
@@ -97,6 +99,7 @@
plat/intel/soc/common/sip/socfpga_sip_ecc.c \
plat/intel/soc/common/sip/socfpga_sip_fcs.c \
plat/intel/soc/common/soc/socfpga_mailbox.c \
+ plat/intel/soc/common/soc/socfpga_system_manager.c \
plat/intel/soc/common/soc/socfpga_reset_manager.c
# Configs for A76 and A55
@@ -111,6 +114,24 @@
$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
+# Configs for Boot Source
+SOCFPGA_BOOT_SOURCE_SDMMC ?= 0
+SOCFPGA_BOOT_SOURCE_QSPI ?= 0
+SOCFPGA_BOOT_SOURCE_NAND ?= 0
+
+$(eval $(call assert_booleans,\
+ $(sort \
+ SOCFPGA_BOOT_SOURCE_SDMMC \
+ SOCFPGA_BOOT_SOURCE_QSPI \
+ SOCFPGA_BOOT_SOURCE_NAND \
+)))
+$(eval $(call add_defines,\
+ $(sort \
+ SOCFPGA_BOOT_SOURCE_SDMMC \
+ SOCFPGA_BOOT_SOURCE_QSPI \
+ SOCFPGA_BOOT_SOURCE_NAND \
+)))
+
# Configs for VAB Authentication
SOCFPGA_SECURE_VAB_AUTH := 0
$(eval $(call assert_boolean,SOCFPGA_SECURE_VAB_AUTH))
diff --git a/plat/intel/soc/agilex5/soc/agilex5_cache.S b/plat/intel/soc/agilex5/soc/agilex5_cache.S
index a174386..52ed5d3 100644
--- a/plat/intel/soc/agilex5/soc/agilex5_cache.S
+++ b/plat/intel/soc/agilex5/soc/agilex5_cache.S
@@ -9,6 +9,21 @@
#include <plat_macros.S>
.globl invalidate_dcache_all
+ .globl invalidate_cache_low_el
+ /* --------------------------------------------------------
+ * Invalidate for NS EL2 and EL1
+ * --------------------------------------------------------
+ */
+func invalidate_cache_low_el
+ mrs x0,SCR_EL3
+ orr x1,x0,#SCR_NS_BIT
+ msr SCR_EL3, x1
+ isb
+ tlbi ALLE2
+ dsb sy
+ tlbi ALLE1
+ dsb sy
+endfunc invalidate_cache_low_el
.pushsection .text.asm_dcache_level, "ax"
func asm_dcache_level
diff --git a/plat/intel/soc/agilex5/soc/agilex5_clock_manager.c b/plat/intel/soc/agilex5/soc/agilex5_clock_manager.c
index fdf1a82..603aaf8 100644
--- a/plat/intel/soc/agilex5/soc/agilex5_clock_manager.c
+++ b/plat/intel/soc/agilex5/soc/agilex5_clock_manager.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,244 +14,639 @@
#include "agilex5_clock_manager.h"
#include "agilex5_system_manager.h"
-#include "socfpga_handoff.h"
#include "socfpga_system_manager.h"
-uint32_t wait_pll_lock(void)
+/* Main and Peripheral PLL configurations in Power Down(PD) state. */
+static const pll_cfg_t pll_cfg_set[] = {
+ {
+ /* Enable source synchronous mode */
+ CLKMGR_PLLCFG_SRC_SYNC_MODE,
+ BIT(7),
+ BIT(7)
+ },
+ {
+ /* Limit the PLL overshoot frequency during lock */
+ CLKMGR_PLLCFG_OVRSHOOT_FREQ_LOCK,
+ BIT(0),
+ BIT(0)
+ },
+ {
+ /* To give the PLL more time to settle before lock is asserted */
+ CLKMGR_PLLCFG_LOCK_SETTLE_TIME,
+ BIT(0),
+ BIT(0)
+ },
+ {
+ /* To set the PLL centering duty cycle for clock slice 0 */
+ CLKMGR_PLLCFG_DUTYCYCLE_CLKSLICE0,
+ 0x4A,
+ GENMASK(6, 0)
+ },
+ {
+ /* To set the PLL centering duty cycle for clock slice 1 */
+ CLKMGR_PLLCFG_DUTYCYCLE_CLKSLICE1,
+ 0x4A,
+ GENMASK(6, 0)
+ },
+};
+
+static int wait_pll_lock(uint32_t mask)
{
uint32_t data;
uint32_t count = 0;
+ uint32_t retry = 0U;
do {
- data = mmio_read_32(CLKMGR_OFFSET + CLKMGR_STAT);
- count++;
- if (count >= 1000)
+ /* return time out */
+ if (count >= CLKMGR_MAX_RETRY_COUNT) {
+ ERROR("CLKMGR: Timed out to satisfy the PLL mask\n");
return -ETIMEDOUT;
+ }
+
+ data = mmio_read_32(CLKMGR(STAT)) & mask;
+ /* wait for stable lock, make sure it is stable for these counts */
+ if (data == mask) {
+ retry++;
+ } else {
+ retry = 0U;
+ }
+
+ /* we are good now, break */
+ if (retry >= 5U) {
+ break;
+ }
+
+ count++;
+ } while (1);
- } while ((CLKMGR_STAT_MAINPLLLOCKED(data) == 0) ||
- (CLKMGR_STAT_PERPLLLOCKED(data) == 0));
return 0;
}
-uint32_t wait_fsm(void)
+static int wait_fsm(void)
{
uint32_t data;
uint32_t count = 0;
do {
- data = mmio_read_32(CLKMGR_OFFSET + CLKMGR_STAT);
+ data = mmio_read_32(CLKMGR(STAT));
count++;
- if (count >= 1000)
+ if (count >= CLKMGR_MAX_RETRY_COUNT) {
+ ERROR("CLKMGR: Timed out on fsm state\n");
return -ETIMEDOUT;
-
+ }
} while (CLKMGR_STAT_BUSY(data) == CLKMGR_STAT_BUSY_E_BUSY);
return 0;
}
-uint32_t pll_source_sync_config(uint32_t pll_mem_offset, uint32_t data)
+static uint32_t calc_pll_vcocalibration(uint32_t pllm, uint32_t pllglob)
{
- uint32_t val = 0;
- uint32_t count = 0;
- uint32_t req_status = 0;
+ uint32_t mdiv, refclkdiv, drefclkdiv, mscnt, hscnt, vcocalib;
- val = (CLKMGR_MEM_WR | CLKMGR_MEM_REQ |
- (data << CLKMGR_MEM_WDAT_OFFSET) | CLKMGR_MEM_ADDR);
- mmio_write_32(pll_mem_offset, val);
+ mdiv = pllm & CLKMGR_PLLM_MDIV_MASK;
+ drefclkdiv = ((pllglob & CLKMGR_PLLGLOB_DREFCLKDIV_MASK) >>
+ CLKMGR_PLLGLOB_DREFCLKDIV_OFFSET);
+ refclkdiv = ((pllglob & CLKMGR_PLLGLOB_REFCLKDIV_MASK) >>
+ CLKMGR_PLLGLOB_REFCLKDIV_OFFSET);
+ mscnt = CLKMGR_VCOCALIB_MSCNT_CONST / (mdiv * BIT(drefclkdiv));
+ if (mscnt == 0) {
+ mscnt = 1;
+ }
- do {
- req_status = mmio_read_32(pll_mem_offset);
+ hscnt = (mdiv * mscnt * BIT(drefclkdiv) / refclkdiv) -
+ CLKMGR_VCOCALIB_HSCNT_CONST;
+
+ vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) |
+ ((mscnt << CLKMGR_VCOCALIB_MSCNT_OFFSET) &
+ CLKMGR_VCOCALIB_MSCNT_MASK);
+
+ return vcocalib;
+}
+
+static int pll_source_sync_wait(uint32_t pll_type, int retry_count)
+{
+ int count = 0;
+ uint32_t req_status;
+
+ if ((pll_type == CLKMGR_MAINPLL_TYPE) != 0) {
+ req_status = mmio_read_32(CLKMGR_MAINPLL(MEM));
+ } else {
+ req_status = mmio_read_32(CLKMGR_PERPLL(MEM));
+ }
+
+ /* Check for error bit set */
+ if ((req_status & CLKMGR_MEM_ERR) != 0) {
+ INFO("CLKMGR: %s: Memory Error Status Signal Assert\n", __func__);
+ }
+
+ while ((count < retry_count) && (req_status & CLKMGR_MEM_REQ)) {
+ if (pll_type == CLKMGR_MAINPLL_TYPE)
+ req_status = mmio_read_32(CLKMGR_MAINPLL(MEM));
+ else
+ req_status = mmio_read_32(CLKMGR_PERPLL(MEM));
count++;
- } while ((req_status & CLKMGR_MEM_REQ) && (count < 10));
+ }
- if (count >= 10)
+ if (count >= retry_count) {
+ ERROR("CLKMGR: %s: timeout with pll_type %d\n", __func__, pll_type);
return -ETIMEDOUT;
+ }
return 0;
}
-uint32_t pll_source_sync_read(uint32_t pll_mem_offset)
+static int pll_source_sync_config(uint32_t pll_type, uint32_t addr_offset,
+ uint32_t wdat, int retry_count)
{
- uint32_t val = 0;
- uint32_t rdata = 0;
- uint32_t count = 0;
- uint32_t req_status = 0;
+ uint32_t addr;
+ uint32_t val;
- val = (CLKMGR_MEM_REQ | CLKMGR_MEM_ADDR);
- mmio_write_32(pll_mem_offset, val);
+ addr = ((addr_offset | CLKMGR_MEM_ADDR_START) & CLKMGR_MEM_ADDR_MASK);
+ val = (CLKMGR_MEM_REQ | CLKMGR_MEM_WR |
+ (wdat << CLKMGR_MEM_WDAT_OFFSET) | addr);
- do {
- req_status = mmio_read_32(pll_mem_offset);
- count++;
- } while ((req_status & CLKMGR_MEM_REQ) && (count < 10));
+ if ((pll_type == CLKMGR_MAINPLL_TYPE) != 0) {
+ mmio_write_32(CLKMGR_MAINPLL(MEM), val);
+ } else {
+ mmio_write_32(CLKMGR_PERPLL(MEM), val);
+ }
+
+ return pll_source_sync_wait(pll_type, retry_count);
+}
- if (count >= 10)
+static int pll_source_sync_read(uint32_t pll_type, uint32_t addr_offset,
+ uint32_t *rdata, int retry_count)
+{
+ uint32_t addr;
+ uint32_t val;
+
+ addr = ((addr_offset | CLKMGR_MEM_ADDR_START) & CLKMGR_MEM_ADDR_MASK);
+ val = ((CLKMGR_MEM_REQ & ~CLKMGR_MEM_WR) | addr);
+
+ if ((pll_type == CLKMGR_MAINPLL_TYPE) != 0) {
+ mmio_write_32(CLKMGR_MAINPLL(MEM), val);
+ } else {
+ mmio_write_32(CLKMGR_PERPLL(MEM), val);
+ }
+
+ *rdata = 0;
+
+ if ((pll_source_sync_wait(pll_type, retry_count)) != 0) {
return -ETIMEDOUT;
+ }
- rdata = mmio_read_32(pll_mem_offset + 0x4);
- INFO("rdata (%x) = %x\n", pll_mem_offset + 0x4, rdata);
+ if ((pll_type == CLKMGR_MAINPLL_TYPE) != 0) {
+ *rdata = mmio_read_32(CLKMGR_MAINPLL(MEMSTAT));
+ } else {
+ *rdata = mmio_read_32(CLKMGR_PERPLL(MEMSTAT));
+ }
- return rdata;
+ return 0;
}
-void config_clkmgr_handoff(handoff *hoff_ptr)
+static void config_pll_pd_state(uint32_t pll_type)
{
- /* Take both PLL out of reset and power up */
+ uint32_t rdata;
- mmio_setbits_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB,
- CLKMGR_PLLGLOB_PD_SET_MSK |
- CLKMGR_PLLGLOB_RST_SET_MSK);
- mmio_setbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB,
- CLKMGR_PLLGLOB_PD_SET_MSK |
- CLKMGR_PLLGLOB_RST_SET_MSK);
+ for (uint32_t i = 0; i < ARRAY_SIZE(pll_cfg_set); i++) {
+ (void)pll_source_sync_read(pll_type, pll_cfg_set[i].addr, &rdata,
+ CLKMGR_MAX_RETRY_COUNT);
- /* PLL lock */
- wait_pll_lock();
+ (void)pll_source_sync_config(pll_type, pll_cfg_set[i].addr,
+ ((rdata & ~pll_cfg_set[i].mask) | pll_cfg_set[i].data),
+ CLKMGR_MAX_RETRY_COUNT);
+ }
+}
+
+int config_clkmgr_handoff(handoff *hoff_ptr)
+{
+ int ret = 0;
+ uint32_t mainpll_vcocalib;
+ uint32_t perpll_vcocalib;
+
+ /* Enter boot mode before any configuration */
+ mmio_setbits_32(CLKMGR(CTRL), CLKMGR_CTRL_BOOTMODE);
/* Bypass all mainpllgrp's clocks to input clock ref */
- mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_BYPASSS, 0xff);
+ mmio_setbits_32(CLKMGR_MAINPLL(BYPASS), CLKMGR_MAINPLL_BYPASS_ALL);
+ ret = wait_fsm();
+ if (ret != 0)
+ return ret;
+
/* Bypass all perpllgrp's clocks to input clock ref */
- mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_BYPASS, 0xff);
+ mmio_setbits_32(CLKMGR_PERPLL(BYPASS), CLKMGR_PERPLL_BYPASS_ALL);
+ ret = wait_fsm();
+ if (ret != 0)
+ return ret;
+
+ /* Take both PLL out of reset and power down */
+ mmio_clrbits_32(CLKMGR_MAINPLL(PLLGLOB),
+ CLKMGR_MAINPLL_PLLGLOB_PD_N | CLKMGR_MAINPLL_PLLGLOB_RST_N);
+ mmio_clrbits_32(CLKMGR_PERPLL(PLLGLOB),
+ CLKMGR_PERPLL_PLLGLOB_PD_N | CLKMGR_PERPLL_PLLGLOB_RST_N);
+
+ /* Setup main PLL dividers */
+ mainpll_vcocalib = calc_pll_vcocalibration(hoff_ptr->main_pll_pllm,
+ hoff_ptr->main_pll_pllglob);
+ mmio_write_32(CLKMGR_MAINPLL(PLLGLOB),
+ hoff_ptr->main_pll_pllglob & ~CLKMGR_MAINPLL_PLLGLOB_RST_N);
+ mmio_write_32(CLKMGR_MAINPLL(FDBCK), hoff_ptr->main_pll_fdbck);
+ mmio_write_32(CLKMGR_MAINPLL(VCOCALIB), mainpll_vcocalib);
+ mmio_write_32(CLKMGR_MAINPLL(PLLC0), hoff_ptr->main_pll_pllc0);
+ mmio_write_32(CLKMGR_MAINPLL(PLLC1), hoff_ptr->main_pll_pllc1);
+ mmio_write_32(CLKMGR_MAINPLL(PLLC2), hoff_ptr->main_pll_pllc2);
+ mmio_write_32(CLKMGR_MAINPLL(PLLC3), hoff_ptr->main_pll_pllc3);
+ mmio_write_32(CLKMGR_MAINPLL(PLLM), hoff_ptr->main_pll_pllm);
+ mmio_write_32(CLKMGR_MAINPLL(NOCCLK), hoff_ptr->main_pll_nocclk);
+ mmio_write_32(CLKMGR_MAINPLL(NOCDIV), hoff_ptr->main_pll_nocdiv);
+
+ /* Setup peripheral PLL dividers */
+ perpll_vcocalib = calc_pll_vcocalibration(hoff_ptr->per_pll_pllm,
+ hoff_ptr->per_pll_pllglob);
+ mmio_write_32(CLKMGR_PERPLL(PLLGLOB),
+ hoff_ptr->per_pll_pllglob & ~CLKMGR_PERPLL_PLLGLOB_RST_N);
+ mmio_write_32(CLKMGR_PERPLL(FDBCK), hoff_ptr->per_pll_fdbck);
+ mmio_write_32(CLKMGR_PERPLL(VCOCALIB), perpll_vcocalib);
+ mmio_write_32(CLKMGR_PERPLL(PLLC0), hoff_ptr->per_pll_pllc0);
+ mmio_write_32(CLKMGR_PERPLL(PLLC1), hoff_ptr->per_pll_pllc1);
+ mmio_write_32(CLKMGR_PERPLL(PLLC2), hoff_ptr->per_pll_pllc2);
+ mmio_write_32(CLKMGR_PERPLL(PLLC3), hoff_ptr->per_pll_pllc3);
+ mmio_write_32(CLKMGR_PERPLL(PLLM), hoff_ptr->per_pll_pllm);
+ mmio_write_32(CLKMGR_PERPLL(EMACCTL), hoff_ptr->per_pll_emacctl);
+ mmio_write_32(CLKMGR_PERPLL(GPIODIV), hoff_ptr->per_pll_gpiodiv);
+
+ /* Configure ping pong counters */
+ mmio_write_32(CLKMGR_ALTERA(EMACACTR), hoff_ptr->alt_emacactr);
+ mmio_write_32(CLKMGR_ALTERA(EMACBCTR), hoff_ptr->alt_emacbctr);
+ mmio_write_32(CLKMGR_ALTERA(EMACPTPCTR), hoff_ptr->alt_emacptpctr);
+ mmio_write_32(CLKMGR_ALTERA(GPIODBCTR), hoff_ptr->alt_gpiodbctr);
+ mmio_write_32(CLKMGR_ALTERA(S2FUSER0CTR), hoff_ptr->alt_s2fuser0ctr);
+ mmio_write_32(CLKMGR_ALTERA(S2FUSER1CTR), hoff_ptr->alt_s2fuser1ctr);
+ mmio_write_32(CLKMGR_ALTERA(PSIREFCTR), hoff_ptr->alt_psirefctr);
+ mmio_write_32(CLKMGR_ALTERA(USB31CTR), hoff_ptr->alt_usb31ctr);
+ mmio_write_32(CLKMGR_ALTERA(DSUCTR), hoff_ptr->alt_dsuctr);
+ mmio_write_32(CLKMGR_ALTERA(CORE01CTR), hoff_ptr->alt_core01ctr);
+ mmio_write_32(CLKMGR_ALTERA(CORE23CTR), hoff_ptr->alt_core23ctr);
+ mmio_write_32(CLKMGR_ALTERA(CORE2CTR), hoff_ptr->alt_core2ctr);
+ mmio_write_32(CLKMGR_ALTERA(CORE3CTR), hoff_ptr->alt_core3ctr);
+
+ /* Take both PLL out of reset and power up */
+ mmio_setbits_32(CLKMGR_MAINPLL(PLLGLOB),
+ CLKMGR_MAINPLL_PLLGLOB_PD_N | CLKMGR_MAINPLL_PLLGLOB_RST_N);
+ mmio_setbits_32(CLKMGR_PERPLL(PLLGLOB),
+ CLKMGR_PERPLL_PLLGLOB_PD_N | CLKMGR_PERPLL_PLLGLOB_RST_N);
+
+ /* Main PLL configuration in Powed down state */
+ config_pll_pd_state(CLKMGR_MAINPLL_TYPE);
+
+ /* Peripheral PLL configuration in Powed down state */
+ config_pll_pd_state(CLKMGR_PERPLL_TYPE);
+
+ /* Enable main PLL clkslices */
+ mmio_setbits_32(CLKMGR_MAINPLL(PLLC0), CLKMGR_MAINPLL_PLLCX_EN);
+ mmio_setbits_32(CLKMGR_MAINPLL(PLLC1), CLKMGR_MAINPLL_PLLCX_EN);
+ mmio_setbits_32(CLKMGR_MAINPLL(PLLC2), CLKMGR_MAINPLL_PLLCX_EN);
+ mmio_setbits_32(CLKMGR_MAINPLL(PLLC3), CLKMGR_MAINPLL_PLLCX_EN);
+
+ /* Enable periheral PLL clkslices */
+ mmio_setbits_32(CLKMGR_PERPLL(PLLC0), CLKMGR_PERPLL_PLLCX_EN);
+ mmio_setbits_32(CLKMGR_PERPLL(PLLC1), CLKMGR_PERPLL_PLLCX_EN);
+ mmio_setbits_32(CLKMGR_PERPLL(PLLC2), CLKMGR_PERPLL_PLLCX_EN);
+ mmio_setbits_32(CLKMGR_PERPLL(PLLC3), CLKMGR_PERPLL_PLLCX_EN);
+
+ /* Wait for main and peri PLL lock state */
+ ret = wait_pll_lock(CLKMGR_STAT_ALLPLLLOCKED);
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* Main PLL and per PLL lost lock */
+ mmio_setbits_32(CLKMGR_MAINPLL(LOSTLOCK), CLKMGR_XPLL_LOSTLOCK_BYPASSCLEAR);
+ mmio_setbits_32(CLKMGR_PERPLL(LOSTLOCK), CLKMGR_XPLL_LOSTLOCK_BYPASSCLEAR);
+
+ /* Main PLL and per PLL clear lostlock bypass */
+ mmio_setbits_32(CLKMGR_MAINPLL(PLLGLOB), CLKMGR_XPLLGLOB_CLR_LOSTLOCK_BYPASS);
+ mmio_setbits_32(CLKMGR_PERPLL(PLLGLOB), CLKMGR_XPLLGLOB_CLR_LOSTLOCK_BYPASS);
- /* Pass clock source frequency into scratch register */
- mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1),
- hoff_ptr->hps_osc_clk_hz);
- mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2),
- hoff_ptr->fpga_clk_hz);
+ /* Pass clock source frequency into boot scratch register */
+ mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1), hoff_ptr->hps_osc_clk_hz);
+ mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2), hoff_ptr->fpga_clk_hz);
/* Take all PLLs out of bypass */
- mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_BYPASS, 0);
- wait_fsm();
- mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_BYPASS, 0);
- wait_fsm();
+ mmio_clrbits_32(CLKMGR_MAINPLL(BYPASS), CLKMGR_MAINPLL_BYPASS_ALL);
+ ret = wait_fsm();
+ if (ret != 0) {
+ return ret;
+ }
+
+ mmio_clrbits_32(CLKMGR_PERPLL(BYPASS), CLKMGR_PERPLL_BYPASS_ALL);
+ ret = wait_fsm();
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* Clear the loss of lock bits (write 1 to clear) */
+ mmio_write_32(CLKMGR(INTRCLR),
+ CLKMGR_INTRCLR_MAINLOCKLOST | CLKMGR_INTRCLR_PERLOCKLOST);
+
+ /* Take all ping pong counters out of reset */
+ mmio_clrbits_32(CLKMGR_ALTERA(EXTCNTRST), CLKMGR_ALTERA_EXTCNTRST_ALLCNTRST);
+
+ /* Exit boot mode */
+ mmio_clrbits_32(CLKMGR(CTRL), CLKMGR_CTRL_BOOTMODE);
- /* Enable mainpllgrp's software-managed clock */
- mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_EN,
- CLKMGR_MAINPLL_EN_RESET);
- mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EN,
- CLKMGR_PERPLL_EN_RESET);
+ return 0;
}
/* Extract reference clock from platform clock source */
-uint32_t get_ref_clk(uint32_t pllglob)
+uint32_t get_ref_clk(uint32_t pllglob_reg, uint32_t pllm_reg)
{
- uint32_t arefclkdiv, ref_clk;
- uint32_t scr_reg;
+ uint32_t arefclkdiv, ref_clk, mdiv;
+ uint32_t pllglob_val, pllm_val;
- switch (CLKMGR_PSRC(pllglob)) {
+ /* Read pllglob and pllm registers */
+ pllglob_val = mmio_read_32(pllglob_reg);
+ pllm_val = mmio_read_32(pllm_reg);
+
+ switch (CLKMGR_PLLGLOB_PSRC(pllglob_val)) {
case CLKMGR_PLLGLOB_PSRC_EOSC1:
- scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1);
- ref_clk = mmio_read_32(scr_reg);
+ ref_clk = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1));
break;
+
case CLKMGR_PLLGLOB_PSRC_INTOSC:
ref_clk = CLKMGR_INTOSC_HZ;
break;
+
case CLKMGR_PLLGLOB_PSRC_F2S:
- scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2);
- ref_clk = mmio_read_32(scr_reg);
+ ref_clk = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2));
break;
+
default:
ref_clk = 0;
assert(0);
break;
}
- arefclkdiv = CLKMGR_PLLGLOB_AREFCLKDIV(pllglob);
+ /* Get reference clock divider */
+ arefclkdiv = CLKMGR_PLLGLOB_AREFCLKDIV(pllglob_val);
ref_clk /= arefclkdiv;
+ /* Feedback clock divider */
+ mdiv = CLKMGR_PLLM_MDIV(pllm_val);
+ ref_clk *= mdiv;
+
+ VERBOSE("CLKMGR: %s: ref_clk %u\n", __func__, ref_clk);
return ref_clk;
}
/* Calculate clock frequency based on parameter */
-uint32_t get_clk_freq(uint32_t psrc_reg, uint32_t main_pllc, uint32_t per_pllc)
+uint32_t get_clk_freq(uint32_t psrc_reg, uint32_t mainpllc_reg,
+ uint32_t perpllc_reg)
{
- uint32_t ref_clk = 0;
+ uint32_t clock = 0;
+ uint32_t clk_psrc;
- uint32_t clk_psrc, mdiv;
- uint32_t pllm_reg, pllc_reg, pllc_div, pllglob_reg;
+ /*
+ * Select source for the active 5:1 clock selection when the PLL
+ * is not bypassed
+ */
+ clk_psrc = mmio_read_32(psrc_reg);
+ switch (GET_CLKMGR_CLKSRC(clk_psrc)) {
+ case CLKMGR_CLKSRC_MAIN:
+ clock = get_ref_clk(CLKMGR_MAINPLL(PLLGLOB), CLKMGR_MAINPLL(PLLM));
+ clock /= (mmio_read_32(mainpllc_reg) & CLKMGR_PLLCX_DIV_MSK);
+ break;
+ case CLKMGR_CLKSRC_PER:
+ clock = get_ref_clk(CLKMGR_PERPLL(PLLGLOB), CLKMGR_PERPLL(PLLM));
+ clock /= (mmio_read_32(perpllc_reg) & CLKMGR_PLLCX_DIV_MSK);
+ break;
- clk_psrc = mmio_read_32(CLKMGR_MAINPLL + psrc_reg);
- clk_psrc = 0;
+ case CLKMGR_CLKSRC_OSC1:
+ clock = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1));
+ break;
+
+ case CLKMGR_CLKSRC_INTOSC:
+ clock = CLKMGR_INTOSC_HZ;
+ break;
- switch (clk_psrc) {
- case 0:
- pllm_reg = CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLM;
- pllc_reg = CLKMGR_MAINPLL + main_pllc;
- pllglob_reg = CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB;
+ case CLKMGR_CLKSRC_FPGA:
+ clock = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2));
+ break;
+
+ default:
+ ERROR("CLKMGR: Invalid clock source select\n");
+ assert(0);
break;
}
- ref_clk = get_ref_clk(mmio_read_32(pllglob_reg));
- mdiv = CLKMGR_PLLM_MDIV(mmio_read_32(pllm_reg));
- ref_clk *= mdiv;
+ VERBOSE("CLKMGR: %s: clock type %lu and its value %u\n",
+ __func__, GET_CLKMGR_CLKSRC(clk_psrc), clock);
- pllc_div = mmio_read_32(pllc_reg) & 0x7ff;
- NOTICE("return = %d Hz\n", (ref_clk / pllc_div));
+ return clock;
+}
- ref_clk = 200000000;
- return (uint32_t) ref_clk;
+/* Get L3 free clock */
+static uint32_t get_l3_main_free_clk(void)
+{
+ return get_clk_freq(CLKMGR_MAINPLL(NOCCLK),
+ CLKMGR_MAINPLL(PLLC3),
+ CLKMGR_PERPLL(PLLC1));
+}
+/* Get L4 main clock */
+static uint32_t get_l4_main_clk(void)
+{
+ return get_l3_main_free_clk();
}
-/* Return L3 interconnect clock */
-uint32_t get_l3_clk(void)
+/* Get L4 mp clock */
+static uint32_t get_l4_mp_clk(void)
{
- uint32_t l3_clk;
+ uint32_t l3_main_free_clk = get_l3_main_free_clk();
+ uint32_t mainpll_nocdiv_l4mp = BIT(GET_CLKMGR_MAINPLL_NOCDIV_L4MP(
+ mmio_read_32(CLKMGR_MAINPLL(NOCDIV))));
- l3_clk = get_clk_freq(CLKMGR_MAINPLL_NOCCLK, CLKMGR_MAINPLL_PLLC1,
- CLKMGR_PERPLL_PLLC1);
- return l3_clk;
+ uint32_t l4_mp_clk = (l3_main_free_clk / mainpll_nocdiv_l4mp);
+
+ return l4_mp_clk;
}
-/* Calculate clock frequency to be used for watchdog timer */
-uint32_t get_wdt_clk(void)
+/* Get L4 sp clock */
+static uint32_t get_l4_sp_clk(void)
{
- uint32_t l3_clk, l4_sys_clk;
+ uint32_t l3_main_free_clk = get_l3_main_free_clk();
+ uint32_t mainpll_nocdiv_l4sp = BIT(GET_CLKMGR_MAINPLL_NOCDIV_L4SP(
+ mmio_read_32(CLKMGR_MAINPLL(NOCDIV))));
+
+ uint32_t l4_sp_clk = (l3_main_free_clk / mainpll_nocdiv_l4sp);
+
+ return l4_sp_clk;
+}
- l3_clk = get_l3_clk();
- l4_sys_clk = l3_clk / 4;
+/* Calculate clock frequency to be used for SDMMC driver */
+uint32_t get_sdmmc_clk(void)
+{
+ uint32_t l4_mp_clk = get_l4_mp_clk();
+ uint32_t mainpll_nocdiv = mmio_read_32(CLKMGR_MAINPLL(NOCDIV));
+ uint32_t sdmmc_clk = l4_mp_clk / BIT(GET_CLKMGR_MAINPLL_NOCDIV_SPHY(mainpll_nocdiv));
- return l4_sys_clk;
+ return sdmmc_clk;
}
-/* Calculate clock frequency to be used for UART driver */
-uint32_t get_uart_clk(void)
+/* Get clock for ethernet mac0 */
+static uint32_t get_emaca_clk(void)
{
- uint32_t data32, l3_clk, l4_sp_clk;
+ uint32_t emaca_ctr = mmio_read_32(CLKMGR_ALTERA(EMACACTR));
+ uint32_t perpll_emacctl = mmio_read_32(CLKMGR_PERPLL(EMACCTL));
+ uint32_t perpll_emac_src = GET_CLKMGR_PERPLL_EMAC0_CLK_SRC(perpll_emacctl);
+ uint32_t emac_ctr_reg;
+ uint32_t emac_clock;
- l3_clk = get_l3_clk();
+ if (perpll_emac_src != 0) {
+ emac_ctr_reg = CLKMGR_ALTERA(EMACBCTR);
+ } else {
+ emac_ctr_reg = CLKMGR_ALTERA(EMACACTR);
+ }
- data32 = mmio_read_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCDIV);
- data32 = (data32 >> 16) & 0x3;
+ /* Get EMACA clock source */
+ uint32_t emacactr_src = GET_CLKMGR_EMACACTR_CLK_SRC(emaca_ctr);
- l4_sp_clk = l3_clk >> data32;
+ /* Read the desired EMAC register again */
+ emaca_ctr = mmio_read_32(emac_ctr_reg);
- return l4_sp_clk;
+ /* Get the divider now */
+ uint32_t emaca_ctr_div = emaca_ctr & GENMASK(10, 0);
+
+ switch (emacactr_src) {
+ case CLKMGR_CLKSRC_MAIN:
+ emac_clock = get_ref_clk(CLKMGR_MAINPLL(PLLGLOB), CLKMGR_MAINPLL(PLLM));
+ emac_clock /= (mmio_read_32(CLKMGR_MAINPLL(PLLC1)) & GENMASK(10, 0));
+ break;
+
+ case CLKMGR_CLKSRC_PER:
+ emac_clock = get_ref_clk(CLKMGR_PERPLL(PLLGLOB), CLKMGR_PERPLL(PLLM));
+ emac_clock /= (mmio_read_32(CLKMGR_PERPLL(PLLC3)) & GENMASK(10, 0));
+ break;
+
+ default:
+ ERROR("CLKMGR: %s invalid clock source\n", __func__);
+ emac_clock = 0;
+ return emac_clock;
+ }
+
+ emac_clock /= 1 + emaca_ctr_div;
+
+ return emac_clock;
}
-/* Calculate clock frequency to be used for SDMMC driver */
-uint32_t get_mmc_clk(void)
+/* Get MPU clock */
+static uint32_t get_mpu_clk(void)
+{
+ uint32_t cpu_id = MPIDR_AFFLVL1_VAL(read_mpidr());
+ uint32_t ctr_reg = 0U;
+ uint32_t clock;
+
+ if (cpu_id > CLKMGR_ALTERA_CORE1) {
+ clock = get_clk_freq(CLKMGR_ALTERA(CORE23CTR),
+ CLKMGR_MAINPLL(PLLC0),
+ CLKMGR_PERPLL(PLLC0));
+ } else {
+ clock = get_clk_freq(CLKMGR_ALTERA(CORE01CTR),
+ CLKMGR_MAINPLL(PLLC1),
+ CLKMGR_PERPLL(PLLC0));
+ }
+
+ switch (cpu_id) {
+ case CLKMGR_ALTERA_CORE0:
+ case CLKMGR_ALTERA_CORE1:
+ ctr_reg = CLKMGR_ALTERA(CORE01CTR);
+ break;
+
+ case CLKMGR_ALTERA_CORE2:
+ ctr_reg = CLKMGR_ALTERA(CORE2CTR);
+ break;
+
+ case CLKMGR_ALTERA_CORE3:
+ ctr_reg = CLKMGR_ALTERA(CORE3CTR);
+ break;
+
+ default:
+ break;
+ }
+
+ /* Division setting for ping pong counter in clock slice */
+ clock /= 1 + (mmio_read_32(ctr_reg) & CLKMGR_PLLCX_DIV_MSK);
+
+ return clock;
+}
+
+/* Calculate clock frequency to be used for watchdog timer */
+static uint32_t get_wdt_clk(void)
+{
+ uint32_t l3_main_free_clk = get_l3_main_free_clk();
+ uint32_t mainpll_nocdiv_l4sysfreeclk = BIT(GET_CLKMGR_MAINPLL_NOCDIV_L4SYSFREE(
+ mmio_read_32(CLKMGR_MAINPLL(NOCDIV))));
+ uint32_t l4_sys_free_clk = (l3_main_free_clk / mainpll_nocdiv_l4sysfreeclk);
+
+ return l4_sys_free_clk;
+}
+
+/*
+ * Calculate clock frequency to be used for UART driver.
+ * 'l4_sp_clk' (100MHz) will be used for slow peripherals like UART, I2C
+ * and Timers.
+ */
+static uint32_t get_uart_clk(void)
{
- uint32_t mmc_clk;
+ return get_l4_sp_clk();
+}
+
+/* Return the clock value of a given system component */
+uint32_t clkmgr_get_rate(uint32_t clk_id)
+{
+ uint32_t clk_rate;
+
+ switch (clk_id) {
+ case CLKMGR_MPU_CLK_ID:
+ clk_rate = get_mpu_clk();
+ break;
+
+ case CLKMGR_L4_MAIN_CLK_ID:
+ clk_rate = get_l4_main_clk();
+ break;
+
+ case CLKMGR_L4_MP_CLK_ID:
+ clk_rate = get_l4_mp_clk();
+ break;
- //TODO: To update when handoff data is ready
- //uint32_t data32;
+ case CLKMGR_L4_SP_CLK_ID:
+ clk_rate = get_l4_sp_clk();
+ break;
- //mmc_clk = get_clk_freq(CLKMGR_ALTERA_SDMMCCTR, CLKMGR_MAINPLL_PLLC3, CLKMGR_PERPLL_PLLC3);
+ case CLKMGR_EMAC0_CLK_ID:
+ clk_rate = get_emaca_clk();
+ break;
- //data32 = mmio_read_32(CLKMGR_ALTERA + CLKMGR_ALTERA_SDMMCCTR);
- //data32 = (data32 & 0x7ff) + 1;
- //mmc_clk = (mmc_clk / data32) / 4;
+ case CLKMGR_SDMMC_CLK_ID:
+ clk_rate = get_sdmmc_clk();
+ break;
+ case CLKMGR_UART_CLK_ID:
+ clk_rate = get_uart_clk();
+ break;
- mmc_clk = get_clk_freq(CLKMGR_MAINPLL_NOCCLK, CLKMGR_MAINPLL_PLLC3,
- CLKMGR_PERPLL_PLLC3);
+ case CLKMGR_WDT_CLK_ID:
+ clk_rate = get_wdt_clk();
+ break;
- // TODO: To update when handoff data is ready
- NOTICE("mmc_clk = %d Hz\n", mmc_clk);
+ default:
+ ERROR("CLKMGR: %s: Invalid clock ID\n", __func__);
+ clk_rate = 0;
+ break;
+ }
- return mmc_clk;
+ return clk_rate;
}
/* Return mpu_periph_clk tick */
diff --git a/plat/intel/soc/agilex5/soc/agilex5_ddr.c b/plat/intel/soc/agilex5/soc/agilex5_ddr.c
new file mode 100644
index 0000000..ef2ae57
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_ddr.c
@@ -0,0 +1,434 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include "lib/mmio.h"
+
+#include "agilex5_ddr.h"
+#include "agilex5_iossm_mailbox.h"
+
+/*
+ * TODO: We need to leverage the legacy products DDR drivers and consider
+ * the upcoming products like KM and then come up with common source code/driver
+ * architecture to address all the products in one view.
+ */
+
+#define SYSMGR_BS_COLD3_DDR_RESET_TYPE_MASK GENMASK(31, 29)
+#define SYSMGR_BS_COLD3_DDR_RESET_TYPE_SHIFT 29
+#define SYSMGR_BS_COLD3_DDR_DBE_MASK (1 << 1)
+#define SYSMGR_BS_COLD3_OCRAM_DBE_MASK (1)
+#define SYSMGR_BS_POR0_DDR_PROGRESS_MASK (1)
+
+/* MPFE NOC registers */
+#define F2SDRAM_SIDEBAND_FLAGOUTSET0 0x50
+#define F2SDRAM_SIDEBAND_FLAGOUTCLR0 0x54
+#define F2SDRAM_SIDEBAND_FLAGOUTSTATUS0 0x58
+
+#define SOCFPGA_F2SDRAM_MGR_ADDRESS 0x18001000
+#define SOCFPGA_MPFE_SCR_IO96B0 0x18000D00
+#define SOCFPGA_MPFE_SCR_IO96B1 0x18000D04
+#define SOCFPGA_MPFE_NOC_SCHED_CSR 0x18000D08
+
+#define SIDEBANDMGR_FLAGOUTSET0_REG (SOCFPGA_F2SDRAM_MGR_ADDRESS \
+ + F2SDRAM_SIDEBAND_FLAGOUTSET0)
+#define SIDEBANDMGR_FLAGOUTSTATUS0_REG (SOCFPGA_F2SDRAM_MGR_ADDRESS \
+ +F2SDRAM_SIDEBAND_FLAGOUTSTATUS0)
+#define SIDEBANDMGR_FLAGOUTCLR0_REG (SOCFPGA_F2SDRAM_MGR_ADDRESS \
+ + F2SDRAM_SIDEBAND_FLAGOUTCLR0)
+#define SZ_8 0x00000008
+
+
+/* Firewall MPU DDR SCR registers */
+#define FW_MPU_DDR_SCR_EN 0x00
+#define FW_MPU_DDR_SCR_EN_SET 0x04
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_BASE 0x10
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_BASEEXT 0x14
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMIT 0x18
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMITEXT 0x1c
+
+#define SOCFPGA_FW_DDR_CCU_DMI0_ADDRESS 0x18000800
+#define SOCFPGA_FW_DDR_CCU_DMI1_ADDRESS 0x18000A00
+#define SOCFPGA_FW_TBU2NOC_ADDRESS 0x18000C00
+
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASE 0x90
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASEEXT 0x94
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMIT 0x98
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT 0x9c
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT_FIELD 0xff
+
+/* Firewall F2SDRAM DDR SCR registers */
+#define FW_F2SDRAM_DDR_SCR_EN 0x00
+#define FW_F2SDRAM_DDR_SCR_EN_SET 0x04
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASE 0x10
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASEEXT 0x14
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMIT 0x18
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMITEXT 0x1c
+
+#define FW_MPU_DDR_SCR_WRITEL(data, reg) \
+ do { \
+ mmio_write_32(SOCFPGA_FW_DDR_CCU_DMI0_ADDRESS + (reg), data); \
+ mmio_write_32(SOCFPGA_FW_DDR_CCU_DMI1_ADDRESS + (reg), data); \
+ } while (0)
+
+#define FW_F2SDRAM_DDR_SCR_WRITEL(data, reg) \
+ mmio_write_32(SOCFPGA_FW_TBU2NOC_ADDRESS + (reg), data)
+
+/* DDR banks info set */
+static struct ddr_info ddr_info_set[CONFIG_NR_DRAM_BANKS];
+
+/* Reset type */
+enum reset_type {
+ POR_RESET,
+ WARM_RESET,
+ COLD_RESET,
+ NCONFIG,
+ JTAG_CONFIG,
+ RSU_RECONFIG
+};
+
+/* Get reset type by reading boot scratch register cold3 */
+static inline enum reset_type get_reset_type(uint32_t sys_reg)
+{
+ return ((sys_reg & SYSMGR_BS_COLD3_DDR_RESET_TYPE_MASK) >>
+ SYSMGR_BS_COLD3_DDR_RESET_TYPE_SHIFT);
+}
+
+/* DDR hang check before the reset */
+static inline bool is_ddr_init_hang(void)
+{
+ uint32_t sys_reg = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0));
+
+ if ((sys_reg & SYSMGR_BS_POR0_DDR_PROGRESS_MASK) != 0) {
+ INFO("DDR: Hang before this reset\n");
+ return true;
+ }
+
+ return false;
+}
+
+/* Set the DDR init progress bit */
+static inline void ddr_init_inprogress(bool start)
+{
+ if (start) {
+ mmio_setbits_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0),
+ SYSMGR_BS_POR0_DDR_PROGRESS_MASK);
+ } else {
+ mmio_clrbits_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0),
+ SYSMGR_BS_POR0_DDR_PROGRESS_MASK);
+ }
+}
+
+/* Configure the IO96B CSRs address based on the handoff data */
+static void config_io96b_csr_addr(bool is_dualemif, struct io96b_info *io96b_ctrl)
+{
+ if (is_dualemif)
+ io96b_ctrl->num_instance = 2;
+ else
+ io96b_ctrl->num_instance = 1;
+
+ /* Assign IO96B CSR base address if it is valid */
+ for (int i = 0; i < io96b_ctrl->num_instance; i++) {
+ switch (i) {
+ case 0:
+ io96b_ctrl->io96b_0.io96b_csr_addr = 0x18400000;
+ INFO("DDR: IO96B0 0x%llx CSR enabled\n",
+ io96b_ctrl->io96b_0.io96b_csr_addr);
+ break;
+
+ case 1:
+ io96b_ctrl->io96b_1.io96b_csr_addr = 0x18800000;
+ INFO("DDR: IO96B1 0x%llx CSR enabled\n",
+ io96b_ctrl->io96b_1.io96b_csr_addr);
+ break;
+
+ default:
+ ERROR("%s: Invalid IO96B CSR\n", __func__);
+ } /* switch */
+ } /* for */
+}
+
+static inline bool hps_ocram_dbe_status(void)
+{
+ uint32_t sys_reg = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_3));
+
+ if ((sys_reg & SYSMGR_BS_COLD3_OCRAM_DBE_MASK) != 0)
+ return true;
+
+ return false;
+}
+
+static inline bool ddr_ecc_dbe_status(void)
+{
+ uint32_t sys_reg = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_3));
+
+ if ((sys_reg & SYSMGR_BS_COLD3_DDR_DBE_MASK) != 0)
+ return true;
+
+ return false;
+}
+
+static void sdram_set_firewall_non_f2sdram(void)
+{
+ uint32_t i;
+ phys_size_t value;
+ uint32_t lower, upper;
+
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+ if (ddr_info_set[i].size == 0) {
+ continue;
+ }
+
+ value = ddr_info_set[i].start;
+
+ /*
+ * Keep first 1MB of SDRAM memory region as secure region when
+ * using ATF flow, where the ATF code is located.
+ */
+ value += SZ_1M;
+
+ /* Setting non-secure MPU region base and base extended */
+ lower = LO(value);
+ upper = HI(value);
+
+ FW_MPU_DDR_SCR_WRITEL(lower,
+ FW_MPU_DDR_SCR_MPUREGION0ADDR_BASE +
+ (i * 4 * sizeof(uint32_t)));
+ FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
+ FW_MPU_DDR_SCR_MPUREGION0ADDR_BASEEXT +
+ (i * 4 * sizeof(uint32_t)));
+
+ /* Setting non-secure Non-MPU region base and base extended */
+ FW_MPU_DDR_SCR_WRITEL(lower,
+ FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASE +
+ (i * 4 * sizeof(uint32_t)));
+ FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
+ FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASEEXT +
+ (i * 4 * sizeof(uint32_t)));
+
+ /* Setting non-secure MPU limit and limit extended */
+ value = ddr_info_set[i].start + ddr_info_set[i].size - 1;
+
+ lower = LO(value);
+ upper = HI(value);
+
+ FW_MPU_DDR_SCR_WRITEL(lower,
+ FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMIT +
+ (i * 4 * sizeof(uint32_t)));
+ FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
+ FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMITEXT +
+ (i * 4 * sizeof(uint32_t)));
+
+ /* Setting non-secure Non-MPU limit and limit extended */
+ FW_MPU_DDR_SCR_WRITEL(lower,
+ FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMIT +
+ (i * 4 * sizeof(uint32_t)));
+ FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
+ FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT +
+ (i * 4 * sizeof(uint32_t)));
+
+ FW_MPU_DDR_SCR_WRITEL(BIT(i) | BIT(i + 8),
+ FW_MPU_DDR_SCR_EN_SET);
+ }
+}
+
+static void sdram_set_firewall_f2sdram(void)
+{
+ uint32_t i;
+ phys_size_t value;
+ uint32_t lower, upper;
+
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+ if (ddr_info_set[i].size == 0) {
+ continue;
+ }
+
+ value = ddr_info_set[i].start;
+
+ /* Keep first 1MB of SDRAM memory region as secure region when
+ * using ATF flow, where the ATF code is located.
+ */
+ value += SZ_1M;
+
+ /* Setting base and base extended */
+ lower = LO(value);
+ upper = HI(value);
+ FW_F2SDRAM_DDR_SCR_WRITEL(lower,
+ FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASE +
+ (i * 4 * sizeof(uint32_t)));
+ FW_F2SDRAM_DDR_SCR_WRITEL(upper & 0xff,
+ FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASEEXT +
+ (i * 4 * sizeof(uint32_t)));
+
+ /* Setting limit and limit extended */
+ value = ddr_info_set[i].start + ddr_info_set[i].size - 1;
+
+ lower = LO(value);
+ upper = HI(value);
+
+ FW_F2SDRAM_DDR_SCR_WRITEL(lower,
+ FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMIT +
+ (i * 4 * sizeof(uint32_t)));
+ FW_F2SDRAM_DDR_SCR_WRITEL(upper & 0xff,
+ FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMITEXT +
+ (i * 4 * sizeof(uint32_t)));
+
+ FW_F2SDRAM_DDR_SCR_WRITEL(BIT(i), FW_F2SDRAM_DDR_SCR_EN_SET);
+ }
+}
+
+static void sdram_set_firewall(void)
+{
+ sdram_set_firewall_non_f2sdram();
+ sdram_set_firewall_f2sdram();
+}
+
+/*
+ * Agilex5 DDR/IOSSM controller initialization routine
+ */
+int agilex5_ddr_init(handoff *hoff_ptr)
+{
+ int ret;
+ bool full_mem_init = false;
+ phys_size_t hw_ddr_size;
+ phys_size_t config_ddr_size;
+ struct io96b_info io96b_ctrl;
+ enum reset_type reset_t = get_reset_type(mmio_read_32(SOCFPGA_SYSMGR(
+ BOOT_SCRATCH_COLD_3)));
+ bool is_dualport = hoff_ptr->ddr_config & BIT(0);
+ bool is_dualemif = hoff_ptr->ddr_config & BIT(1);
+
+ NOTICE("DDR: Reset type is '%s'\n",
+ (reset_t == POR_RESET ? "Power-On" : (reset_t == COLD_RESET ? "Cold" : "Warm")));
+
+ /* DDR initialization progress status tracking */
+ bool is_ddr_hang_bfr_rst = is_ddr_init_hang();
+
+ /* Set the DDR initialization progress */
+ ddr_init_inprogress(true);
+
+ /* Configure the IO96B CSR address based on the handoff data */
+ config_io96b_csr_addr(is_dualemif, &io96b_ctrl);
+
+ /* Configuring MPFE sideband manager registers */
+ /* Dual port setting */
+ if (is_dualport)
+ mmio_setbits_32(SIDEBANDMGR_FLAGOUTSET0_REG, BIT(4));
+
+ /* Dual EMIF setting */
+ if (is_dualemif) {
+ /* Set mpfe_lite_active in the system manager */
+ /* TODO: recheck on the bit value?? */
+ mmio_setbits_32(SOCFPGA_SYSMGR(MPFE_CONFIG), BIT(8));
+
+ mmio_setbits_32(SIDEBANDMGR_FLAGOUTSET0_REG, BIT(5));
+ }
+
+ if (is_dualport || is_dualemif)
+ INFO("DDR: SIDEBANDMGR_FLAGOUTSTATUS0: 0x%x\n",
+ mmio_read_32(SIDEBANDMGR_FLAGOUTSTATUS0_REG));
+
+ /* Ensure calibration status passing */
+ init_mem_cal(&io96b_ctrl);
+
+ /* Initiate IOSSM mailbox */
+ io96b_mb_init(&io96b_ctrl);
+
+ /* Need to trigger re-calibration for DDR DBE */
+ if (ddr_ecc_dbe_status()) {
+ io96b_ctrl.io96b_0.cal_status = false;
+ io96b_ctrl.io96b_1.cal_status = false;
+ io96b_ctrl.overall_cal_status = io96b_ctrl.io96b_0.cal_status ||
+ io96b_ctrl.io96b_1.cal_status;
+ }
+
+ /* Trigger re-calibration if calibration failed */
+ if (!(io96b_ctrl.overall_cal_status)) {
+ NOTICE("DDR: Re-calibration in progress...\n");
+ trig_mem_cal(&io96b_ctrl);
+ }
+ NOTICE("DDR: Calibration success\n");
+
+ /* DDR type, DDR size and ECC status) */
+ ret = get_mem_technology(&io96b_ctrl);
+ if (ret != 0) {
+ ERROR("DDR: Failed to get DDR type\n");
+ return ret;
+ }
+
+ ret = get_mem_width_info(&io96b_ctrl);
+ if (ret != 0) {
+ ERROR("DDR: Failed to get DDR size\n");
+ return ret;
+ }
+
+ /* DDR size queried from the IOSSM controller */
+ hw_ddr_size = (phys_size_t)io96b_ctrl.overall_size * SZ_1G / SZ_8;
+
+ /* TODO: Hard code 1GB as of now, and DDR start and end address */
+ config_ddr_size = 0x40000000;
+ ddr_info_set[0].start = 0x80000000;
+ ddr_info_set[0].size = 0x40000000;
+
+ if (config_ddr_size != hw_ddr_size) {
+ WARN("DDR: DDR size configured is (%lld MiB)\n", config_ddr_size >> 20);
+ WARN("DDR: Mismatch with hardware size (%lld MiB).\n", hw_ddr_size >> 20);
+ }
+
+ if (config_ddr_size > hw_ddr_size) {
+ ERROR("DDR: Confgured DDR size is greater than the hardware size - HANG!!!\n");
+ while (1)
+ ;
+ }
+
+ ret = ecc_enable_status(&io96b_ctrl);
+ if (ret != 0) {
+ ERROR("DDR: Failed to get DDR ECC status\n");
+ return ret;
+ }
+
+ /*
+ * HPS cold or warm reset? If yes, skip full memory initialization if
+ * ECC is enabled to preserve memory content.
+ */
+ if (io96b_ctrl.ecc_status != 0) {
+ full_mem_init = hps_ocram_dbe_status() | ddr_ecc_dbe_status() |
+ is_ddr_hang_bfr_rst;
+ if ((full_mem_init == true) || (reset_t == WARM_RESET ||
+ reset_t == COLD_RESET) == 0) {
+ ret = bist_mem_init_start(&io96b_ctrl);
+ if (ret != 0) {
+ ERROR("DDR: Failed to fully initialize DDR memory\n");
+ return ret;
+ }
+ }
+ INFO("DDR: ECC initialized successfully\n");
+ }
+
+ sdram_set_firewall();
+
+ /*
+ * Firewall setting for MPFE CSRs, allow both secure and non-secure
+ * transactions.
+ */
+ /* IO96B0_reg */
+ mmio_setbits_32(SOCFPGA_MPFE_SCR_IO96B0, BIT(0));
+ /* IO96B1_reg */
+ mmio_setbits_32(SOCFPGA_MPFE_SCR_IO96B1, BIT(0));
+ /* noc_scheduler_csr */
+ mmio_setbits_32(SOCFPGA_MPFE_NOC_SCHED_CSR, BIT(0));
+
+ INFO("DDR: firewall init done\n");
+
+ /* Ending DDR driver initialization success tracking */
+ ddr_init_inprogress(false);
+
+ NOTICE("###DDR:init success###\n");
+
+ return 0;
+}
diff --git a/plat/intel/soc/agilex5/soc/agilex5_iossm_mailbox.c b/plat/intel/soc/agilex5/soc/agilex5_iossm_mailbox.c
new file mode 100644
index 0000000..c2ab047
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_iossm_mailbox.c
@@ -0,0 +1,811 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+
+#include "agilex5_iossm_mailbox.h"
+
+/* supported DDR type list */
+static const char *ddr_type_list[7] = {
+ "DDR4", "DDR5", "DDR5_RDIMM", "LPDDR4", "LPDDR5", "QDRIV", "UNKNOWN"
+};
+
+static inline int wait_for_bit(const void *reg,
+ const uint32_t mask,
+ const bool set,
+ const unsigned int timeout_ms)
+{
+ uint32_t val;
+ uint32_t timeout_sec = (timeout_ms / 1000);
+
+ while (timeout_sec > 0) {
+ val = mmio_read_32((uintptr_t)reg);
+
+ INFO("IOSSM: timeout_sec %d, val %x\n", timeout_sec, val);
+
+ if (!set) {
+ val = ~val;
+ }
+
+ if ((val & mask) == mask) {
+ INFO("IOSSM: %s, success\n", __func__);
+ return 0;
+ }
+
+ /* one second delay */
+ mdelay(1000);
+
+ timeout_sec--;
+ }
+
+ ERROR("IOSSM: %s, failed, time out\n", __func__);
+ return -ETIMEDOUT;
+}
+
+int io96b_mb_req(phys_addr_t io96b_csr_addr, uint32_t ip_type, uint32_t instance_id,
+ uint32_t usr_cmd_type, uint32_t usr_cmd_opcode, uint32_t cmd_param_0,
+ uint32_t cmd_param_1, uint32_t cmd_param_2, uint32_t cmd_param_3,
+ uint32_t cmd_param_4, uint32_t cmd_param_5, uint32_t cmd_param_6,
+ uint32_t resp_data_len, struct io96b_mb_resp *resp)
+{
+ int i;
+ int ret;
+ uint32_t cmd_req, cmd_resp;
+
+ /* Initialized zeros for responses*/
+ resp->cmd_resp_status = 0;
+ resp->cmd_resp_data_0 = 0;
+ resp->cmd_resp_data_1 = 0;
+ resp->cmd_resp_data_2 = 0;
+
+ /* Ensure CMD_REQ is cleared before write any command request */
+ ret = wait_for_bit((const void *)(io96b_csr_addr + IOSSM_CMD_REQ_OFFSET),
+ GENMASK(31, 0), 0, 10000);
+
+ if (ret != 0) {
+ ERROR("%s: CMD_REQ not ready\n", __func__);
+ return -1;
+ }
+
+ /* Write CMD_PARAM_* */
+ for (i = 0; i < 6 ; i++) {
+ switch (i) {
+ case 0:
+ if (cmd_param_0 != 0) {
+ mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_0_OFFSET,
+ cmd_param_0);
+ }
+ break;
+ case 1:
+ if (cmd_param_1 != 0) {
+ mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_1_OFFSET,
+ cmd_param_1);
+ }
+ break;
+ case 2:
+ if (cmd_param_2 != 0) {
+ mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_2_OFFSET,
+ cmd_param_2);
+ }
+ break;
+ case 3:
+ if (cmd_param_3 != 0) {
+ mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_3_OFFSET,
+ cmd_param_3);
+ }
+ break;
+ case 4:
+ if (cmd_param_4 != 0) {
+ mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_4_OFFSET,
+ cmd_param_4);
+ }
+ break;
+ case 5:
+ if (cmd_param_5 != 0) {
+ mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_5_OFFSET,
+ cmd_param_5);
+ }
+ break;
+ case 6:
+ if (cmd_param_6 != 0) {
+ mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_6_OFFSET,
+ cmd_param_6);
+ }
+ break;
+ default:
+ ERROR("IOSSM: %s: Invalid command parameter\n", __func__);
+ }
+ }
+
+ /* Write CMD_REQ (IP_TYPE, IP_INSTANCE_ID, CMD_TYPE and CMD_OPCODE) */
+ cmd_req = (usr_cmd_opcode << 0) | (usr_cmd_type << 16) | (instance_id << 24) |
+ (ip_type << 29);
+ mmio_write_32(io96b_csr_addr + IOSSM_CMD_REQ_OFFSET, cmd_req);
+ INFO("IOSSM: %s: Write 0x%x to IOSSM_CMD_REQ_OFFSET 0x%llx\n",
+ __func__, cmd_req, io96b_csr_addr + IOSSM_CMD_REQ_OFFSET);
+
+ /* Read CMD_RESPONSE_READY in CMD_RESPONSE_STATUS*/
+ ret = wait_for_bit((const void *)(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET),
+ IOSSM_STATUS_COMMAND_RESPONSE_READY, 1, 10000);
+
+ if (ret != 0) {
+ ERROR("%s: CMD_RESPONSE ERROR:\n", __func__);
+ cmd_resp = (io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+ ERROR("%s: STATUS_GENERAL_ERROR: 0x%x\n", __func__, (cmd_resp >> 1) & 0xF);
+ ERROR("%s: STATUS_CMD_RESPONSE_ERROR: 0x%x\n", __func__, (cmd_resp >> 5) & 0x7);
+ }
+
+ /* read CMD_RESPONSE_STATUS*/
+ resp->cmd_resp_status = mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+ INFO("IOSSM: %s: CMD_RESPONSE_STATUS 0x%llx: 0x%x\n",
+ __func__, io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET, resp->cmd_resp_status);
+
+ /* read CMD_RESPONSE_DATA_* */
+ for (i = 0; i < resp_data_len; i++) {
+ switch (i) {
+ case 0:
+ resp->cmd_resp_data_0 =
+ mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_0_OFFSET);
+
+ break;
+ case 1:
+ resp->cmd_resp_data_1 =
+ mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_1_OFFSET);
+
+ break;
+ case 2:
+ resp->cmd_resp_data_2 =
+ mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_2_OFFSET);
+ break;
+ default:
+ ERROR("%s: Invalid response data\n", __func__);
+ }
+ }
+
+ resp->cmd_resp_status = mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+ INFO("IOSSM: %s: CMD_RESPONSE_STATUS 0x%llx: 0x%x\n",
+ __func__, io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET, resp->cmd_resp_status);
+
+ /* write CMD_RESPONSE_READY = 0 */
+ mmio_clrbits_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET,
+ IOSSM_STATUS_COMMAND_RESPONSE_READY);
+
+ resp->cmd_resp_status = mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+ INFO("IOSSM: %s: CMD_RESPONSE_READY 0x%llx: 0x%x\n",
+ __func__, io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET, resp->cmd_resp_status);
+
+ return 0;
+}
+
+/*
+ * Initial function to be called to set memory interface IP type and instance ID
+ * IP type and instance ID need to be determined before sending mailbox command
+ */
+void io96b_mb_init(struct io96b_info *io96b_ctrl)
+{
+ struct io96b_mb_resp usr_resp;
+ uint8_t ip_type_ret, instance_id_ret;
+ int i, j, k;
+
+ for (i = 0; i < io96b_ctrl->num_instance; i++) {
+ switch (i) {
+ case 0:
+ /* Get memory interface IP type & instance ID (IP identifier) */
+ io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+ CMD_GET_SYS_INFO, GET_MEM_INTF_INFO, 0, 0,
+ 0, 0, 0, 0, 0, 2, &usr_resp);
+ /* Retrieve number of memory interface(s) */
+ io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface =
+ IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status) & 0x3;
+
+ /* Retrieve memory interface IP type and instance ID (IP identifier) */
+ j = 0;
+ for (k = 0; k < MAX_MEM_INTERFACES_SUPPORTED; k++) {
+ switch (k) {
+ case 0:
+ ip_type_ret = (usr_resp.cmd_resp_data_0 >> 29) & 0x7;
+ instance_id_ret = (usr_resp.cmd_resp_data_0 >> 24) & 0x1F;
+ break;
+ case 1:
+ ip_type_ret = (usr_resp.cmd_resp_data_1 >> 29) & 0x7;
+ instance_id_ret = (usr_resp.cmd_resp_data_1 >> 24) & 0x1F;
+ break;
+ }
+
+ if (ip_type_ret != 0) {
+ io96b_ctrl->io96b_0.mb_ctrl.ip_type[j] = ip_type_ret;
+ io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j] =
+ instance_id_ret;
+ j++;
+ }
+ }
+ break;
+ case 1:
+ /* Get memory interface IP type and instance ID (IP identifier) */
+ io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0, CMD_GET_SYS_INFO,
+ GET_MEM_INTF_INFO, 0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+
+ /* Retrieve number of memory interface(s) */
+ io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface =
+ IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status) & 0x3;
+
+ /* Retrieve memory interface IP type and instance ID (IP identifier) */
+ j = 0;
+ for (k = 0; k < MAX_MEM_INTERFACES_SUPPORTED; k++) {
+ switch (k) {
+ case 0:
+ ip_type_ret = (usr_resp.cmd_resp_data_0 >> 29) & 0x7;
+ instance_id_ret = (usr_resp.cmd_resp_data_0 >> 24) & 0x1F;
+ break;
+ case 1:
+ ip_type_ret = (usr_resp.cmd_resp_data_1 >> 29) & 0x7;
+ instance_id_ret = (usr_resp.cmd_resp_data_1 >> 24) & 0x1F;
+ break;
+ }
+
+ if (ip_type_ret != 0) {
+ io96b_ctrl->io96b_1.mb_ctrl.ip_type[j] = ip_type_ret;
+ io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j] =
+ instance_id_ret;
+ j++;
+ }
+ }
+ break;
+ }
+
+ }
+}
+
+static inline void hang(void)
+{
+ ERROR("IOSSM: %s: system is going to die :(\n", __func__);
+ while (1)
+ ;
+}
+
+int io96b_cal_status(phys_addr_t addr)
+{
+ int cal_busy_status, cal_success_status;
+ phys_addr_t status_addr = addr + IOSSM_STATUS_OFFSET;
+
+ /* Ensure calibration busy status */
+ cal_busy_status = wait_for_bit((const void *)status_addr, IOSSM_STATUS_CAL_BUSY,
+ false, 15000);
+ if (cal_busy_status != 0) {
+ ERROR("IOSSM: One or more EMIF instances are busy with calibration\n");
+ return -EBUSY;
+ }
+
+ /* Calibration success status check */
+ NOTICE("IOSSM: Calibration success status check...\n");
+ cal_success_status = wait_for_bit((const void *)status_addr, IOSSM_STATUS_CAL_SUCCESS,
+ true, 15000);
+ if (cal_success_status != 0) {
+ ERROR("IOSSM: One/more EMIF instances either failed to calibrate/not completed\n");
+ return -EBUSY;
+ }
+
+ NOTICE("IOSSM: All EMIF instances within the IO96 have calibrated successfully!\n");
+ return 0;
+}
+
+void init_mem_cal(struct io96b_info *io96b_ctrl)
+{
+ int count, i, ret;
+
+ /* Initialize overall calibration status */
+ io96b_ctrl->overall_cal_status = false;
+
+ /* Check initial calibration status for the assigned IO96B */
+ count = 0;
+ for (i = 0; i < io96b_ctrl->num_instance; i++) {
+ switch (i) {
+ case 0:
+ ret = io96b_cal_status(io96b_ctrl->io96b_0.io96b_csr_addr);
+ if (ret != 0) {
+ io96b_ctrl->io96b_0.cal_status = false;
+ ERROR("%s: Initial DDR calibration IO96B_0 failed %d\n",
+ __func__, ret);
+ break;
+ }
+ io96b_ctrl->io96b_0.cal_status = true;
+ INFO("IOSSM: %s: Initial DDR calibration IO96B_0 succeed\n", __func__);
+ count++;
+ break;
+ case 1:
+ ret = io96b_cal_status(io96b_ctrl->io96b_1.io96b_csr_addr);
+ if (ret != 0) {
+ io96b_ctrl->io96b_1.cal_status = false;
+ ERROR("%s: Initial DDR calibration IO96B_1 failed %d\n",
+ __func__, ret);
+ break;
+ }
+ io96b_ctrl->io96b_1.cal_status = true;
+ INFO("IOSSM: %s: Initial DDR calibration IO96B_1 succeed\n", __func__);
+ count++;
+ break;
+ }
+ }
+
+ if (count == io96b_ctrl->num_instance)
+ io96b_ctrl->overall_cal_status = true;
+}
+
+/*
+ * Trying 3 times re-calibration if initial calibration failed
+ */
+int trig_mem_cal(struct io96b_info *io96b_ctrl)
+{
+ struct io96b_mb_resp usr_resp;
+ bool recal_success;
+ int i;
+ uint8_t cal_stat;
+
+ for (i = 0; i < io96b_ctrl->num_instance; i++) {
+ switch (i) {
+ case 0:
+ if (!(io96b_ctrl->io96b_0.cal_status)) {
+ /* Get the memory calibration status for first memory interface */
+ io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+ CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS, 0,
+ 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+
+ recal_success = false;
+
+ /* Re-calibration first memory interface with failed calibration */
+ for (i = 0; i < 3; i++) {
+ cal_stat = usr_resp.cmd_resp_data_0 & GENMASK(2, 0);
+ if (cal_stat < 0x2) {
+ recal_success = true;
+ break;
+ }
+ io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+ io96b_ctrl->io96b_0.mb_ctrl.ip_type[0],
+ io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[0],
+ CMD_TRIG_MEM_CAL_OP, TRIG_MEM_CAL, 0, 0, 0, 0,
+ 0, 0, 0, 2, &usr_resp);
+ mdelay(1000);
+ io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+ CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS,
+ 0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+ }
+
+ if (!recal_success) {
+ ERROR("%s: Error as SDRAM calibration failed\n", __func__);
+ hang();
+ }
+
+ /* Get the memory calibration status for second memory interface */
+ io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+ CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS, 0, 0, 0,
+ 0, 0, 0, 0, 2, &usr_resp);
+
+ recal_success = false;
+
+ /* Re-calibration second memory interface with failed calibration*/
+ for (i = 0; i < 3; i++) {
+ cal_stat = usr_resp.cmd_resp_data_1 & GENMASK(2, 0);
+ if (cal_stat < 0x2) {
+ recal_success = true;
+ break;
+ }
+ io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+ io96b_ctrl->io96b_0.mb_ctrl.ip_type[1],
+ io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[1],
+ CMD_TRIG_MEM_CAL_OP, TRIG_MEM_CAL, 0, 0, 0, 0,
+ 0, 0, 0, 2, &usr_resp);
+ mdelay(1000);
+ io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+ CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS,
+ 0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+ }
+
+ if (!recal_success) {
+ ERROR("IOSSMM: Error as SDRAM calibration failed\n");
+ hang();
+ }
+
+ io96b_ctrl->io96b_0.cal_status = true;
+ }
+ break;
+ case 1:
+ if (!(io96b_ctrl->io96b_1.cal_status)) {
+ /* Get the memory calibration status for first memory interface */
+ io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0,
+ CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS, 0,
+ 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+
+ recal_success = false;
+
+ /* Re-calibration first memory interface with failed calibration */
+ for (i = 0; i < 3; i++) {
+ cal_stat = usr_resp.cmd_resp_data_0 & GENMASK(2, 0);
+ if (cal_stat < 0x2) {
+ recal_success = true;
+ break;
+ }
+ io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+ io96b_ctrl->io96b_1.mb_ctrl.ip_type[0],
+ io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[0],
+ CMD_TRIG_MEM_CAL_OP, TRIG_MEM_CAL, 0, 0, 0, 0,
+ 0, 0, 0, 2, &usr_resp);
+ mdelay(1000);
+ io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0,
+ CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS,
+ 0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+ }
+
+ if (!recal_success) {
+ ERROR("IOSSM: Error as SDRAM calibration failed\n");
+ hang();
+ }
+
+ /* Get the memory calibration status for second memory interface */
+ io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0,
+ CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS, 0, 0, 0,
+ 0, 0, 0, 0, 2, &usr_resp);
+
+ recal_success = false;
+
+ /* Re-calibration second memory interface with failed calibration*/
+ for (i = 0; i < 3; i++) {
+ cal_stat = usr_resp.cmd_resp_data_0 & GENMASK(2, 0);
+ if (cal_stat < 0x2) {
+ recal_success = true;
+ break;
+ }
+ io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+ io96b_ctrl->io96b_1.mb_ctrl.ip_type[1],
+ io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[1],
+ CMD_TRIG_MEM_CAL_OP, TRIG_MEM_CAL, 0, 0, 0, 0,
+ 0, 0, 0, 2, &usr_resp);
+ mdelay(1000);
+ io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0,
+ CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS,
+ 0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+ }
+
+ if (!recal_success) {
+ ERROR("IOSSM: Error as SDRAM calibration failed\n");
+ hang();
+ }
+
+ io96b_ctrl->io96b_1.cal_status = true;
+ }
+ break;
+ }
+ }
+
+ if (io96b_ctrl->io96b_0.cal_status && io96b_ctrl->io96b_1.cal_status) {
+ INFO("IOSSM: %s: Overall SDRAM calibration success\n", __func__);
+ io96b_ctrl->overall_cal_status = true;
+ }
+
+ return 0;
+}
+
+int get_mem_technology(struct io96b_info *io96b_ctrl)
+{
+ struct io96b_mb_resp usr_resp;
+ int i, j;
+ uint8_t ddr_type_ret;
+
+ /* Initialize ddr type */
+ io96b_ctrl->ddr_type = ddr_type_list[6];
+
+ /* Get and ensure all memory interface(s) same DDR type */
+ for (i = 0; i < io96b_ctrl->num_instance; i++) {
+ switch (i) {
+ case 0:
+ for (j = 0; j < io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface; j++) {
+ io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+ io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+ io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+ CMD_GET_MEM_INFO, GET_MEM_TECHNOLOGY, 0, 0, 0, 0,
+ 0, 0, 0, 0, &usr_resp);
+
+ ddr_type_ret =
+ IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+ & GENMASK(2, 0);
+
+ if (strcmp(io96b_ctrl->ddr_type, "UNKNOWN") == 0)
+ io96b_ctrl->ddr_type = ddr_type_list[ddr_type_ret];
+
+ if (ddr_type_list[ddr_type_ret] != io96b_ctrl->ddr_type) {
+ ERROR("IOSSM: Mismatch DDR type on IO96B_0\n");
+ return -ENOEXEC;
+ }
+ }
+ break;
+ case 1:
+ for (j = 0; j < io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface; j++) {
+ io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+ io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+ io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+ CMD_GET_MEM_INFO, GET_MEM_TECHNOLOGY, 0, 0, 0,
+ 0, 0, 0, 0, 0, &usr_resp);
+
+ ddr_type_ret =
+ IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+ & GENMASK(2, 0);
+
+ if (strcmp(io96b_ctrl->ddr_type, "UNKNOWN") == 0)
+ io96b_ctrl->ddr_type = ddr_type_list[ddr_type_ret];
+
+ if (ddr_type_list[ddr_type_ret] != io96b_ctrl->ddr_type) {
+ ERROR("IOSSM: Mismatch DDR type on IO96B_1\n");
+ return -ENOEXEC;
+ }
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int get_mem_width_info(struct io96b_info *io96b_ctrl)
+{
+ struct io96b_mb_resp usr_resp;
+ int i, j;
+ uint16_t memory_size = 0U;
+ uint16_t total_memory_size = 0U;
+
+ /* Get all memory interface(s) total memory size on all instance(s) */
+ for (i = 0; i < io96b_ctrl->num_instance; i++) {
+ switch (i) {
+ case 0:
+ memory_size = 0;
+ for (j = 0; j < io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface; j++) {
+ io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+ io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+ io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+ CMD_GET_MEM_INFO, GET_MEM_WIDTH_INFO, 0, 0, 0,
+ 0, 0, 0, 0, 2, &usr_resp);
+
+ memory_size = memory_size +
+ (usr_resp.cmd_resp_data_1 & GENMASK(7, 0));
+ }
+
+ if (memory_size == 0U) {
+ ERROR("IOSSM: %s: Failed to get valid memory size\n", __func__);
+ return -ENOEXEC;
+ }
+
+ io96b_ctrl->io96b_0.size = memory_size;
+
+ break;
+ case 1:
+ memory_size = 0;
+ for (j = 0; j < io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface; j++) {
+ io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+ io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+ io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+ CMD_GET_MEM_INFO, GET_MEM_WIDTH_INFO, 0, 0, 0,
+ 0, 0, 0, 0, 2, &usr_resp);
+
+ memory_size = memory_size +
+ (usr_resp.cmd_resp_data_1 & GENMASK(7, 0));
+ }
+
+ if (memory_size == 0U) {
+ ERROR("IOSSM: %s: Failed to get valid memory size\n", __func__);
+ return -ENOEXEC;
+ }
+
+ io96b_ctrl->io96b_1.size = memory_size;
+
+ break;
+ }
+
+ total_memory_size = total_memory_size + memory_size;
+ }
+
+ if (total_memory_size == 0U) {
+ ERROR("IOSSM: %s: Failed to get valid memory size\n", __func__);
+ return -ENOEXEC;
+ }
+
+ io96b_ctrl->overall_size = total_memory_size;
+
+ return 0;
+}
+
+int ecc_enable_status(struct io96b_info *io96b_ctrl)
+{
+ struct io96b_mb_resp usr_resp;
+ int i, j;
+ bool ecc_stat_set = false;
+ bool ecc_stat;
+
+ /* Initialize ECC status */
+ io96b_ctrl->ecc_status = false;
+
+ /* Get and ensure all memory interface(s) same ECC status */
+ for (i = 0; i < io96b_ctrl->num_instance; i++) {
+ switch (i) {
+ case 0:
+ for (j = 0; j < io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface; j++) {
+ io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+ io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+ io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+ CMD_TRIG_CONTROLLER_OP, ECC_ENABLE_STATUS, 0, 0,
+ 0, 0, 0, 0, 0, 0, &usr_resp);
+
+ ecc_stat = ((IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+ & GENMASK(1, 0)) == 0 ? false : true);
+
+ if (!ecc_stat_set) {
+ io96b_ctrl->ecc_status = ecc_stat;
+ ecc_stat_set = true;
+ }
+
+ if (ecc_stat != io96b_ctrl->ecc_status) {
+ ERROR("IOSSM: %s: Mismatch DDR ECC status on IO96B_0\n",
+ __func__);
+ return -ENOEXEC;
+ }
+ }
+ break;
+ case 1:
+ for (j = 0; j < io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface; j++) {
+ io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+ io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+ io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+ CMD_TRIG_CONTROLLER_OP, ECC_ENABLE_STATUS, 0, 0,
+ 0, 0, 0, 0, 0, 0, &usr_resp);
+
+ ecc_stat = ((IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+ & GENMASK(1, 0)) == 0 ? false : true);
+
+ if (!ecc_stat_set) {
+ io96b_ctrl->ecc_status = ecc_stat;
+ ecc_stat_set = true;
+ }
+
+ if (ecc_stat != io96b_ctrl->ecc_status) {
+ ERROR("%s: Mismatch DDR ECC status on IO96B_1\n"
+ , __func__);
+ return -ENOEXEC;
+ }
+ }
+ break;
+ }
+ }
+ return 0;
+}
+
+int bist_mem_init_start(struct io96b_info *io96b_ctrl)
+{
+ struct io96b_mb_resp usr_resp;
+ int i, j;
+ bool bist_start, bist_success;
+ uint32_t read_count;
+ uint32_t read_interval_ms;
+
+ /* Full memory initialization BIST performed on all memory interface(s) */
+ for (i = 0; i < io96b_ctrl->num_instance; i++) {
+ switch (i) {
+ case 0:
+ for (j = 0; j < io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface; j++) {
+ bist_start = false;
+ bist_success = false;
+ read_interval_ms = 500U;
+
+ /* Start memory initialization BIST on full memory address */
+ io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+ io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+ io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+ CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_START, 0x40,
+ 0, 0, 0, 0, 0, 0, 0, &usr_resp);
+
+ bist_start =
+ (IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+ & 1);
+
+ if (!bist_start) {
+ ERROR("IOSSM: %s: Failed to initialized memory on IO96B_0\n"
+ , __func__);
+ ERROR("IOSSM: %s: BIST_MEM_INIT_START Error code 0x%x\n",
+ __func__,
+ (IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+ & GENMASK(2, 1)) > 0x1);
+ return -ENOEXEC;
+ }
+
+ /* Polling for the initiated memory initialization BIST status */
+ read_count = read_interval_ms / TIMEOUT;
+ while (!bist_success) {
+ io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+ io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+ io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+ CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_STATUS,
+ 0, 0, 0, 0, 0, 0, 0, 0, &usr_resp);
+
+ bist_success = (IOSSM_CMD_RESPONSE_DATA_SHORT
+ (usr_resp.cmd_resp_status) & 1);
+
+ if ((!bist_success) && (read_count == 0U)) {
+ ERROR("IOSSM: %s: Timeout init memory on IO96B_0\n"
+ , __func__);
+ ERROR("IOSSM: %s: BIST_MEM_INIT_STATUS Err code%x\n"
+ , __func__, (IOSSM_CMD_RESPONSE_DATA_SHORT
+ (usr_resp.cmd_resp_status)
+ & GENMASK(2, 1)) > 0x1);
+ return -ETIMEDOUT;
+ }
+ read_count--;
+ mdelay(read_interval_ms);
+ }
+ }
+
+ NOTICE("IOSSM: %s: Memory initialized successfully on IO96B_0\n", __func__);
+ break;
+
+ case 1:
+ for (j = 0; j < io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface; j++) {
+ bist_start = false;
+ bist_success = false;
+ read_interval_ms = 500U;
+
+ /* Start memory initialization BIST on full memory address */
+ io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+ io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+ io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+ CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_START, 0x40,
+ 0, 0, 0, 0, 0, 0, 0, &usr_resp);
+
+ bist_start =
+ (IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+ & 1);
+
+ if (!bist_start) {
+ ERROR("IOSSM: %s: Failed to initialized memory on IO96B_1\n"
+ , __func__);
+ ERROR("IOSSM: %s: BIST_MEM_INIT_START Error code 0x%x\n",
+ __func__,
+ (IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+ & GENMASK(2, 1)) > 0x1);
+ return -ENOEXEC;
+ }
+
+ /* Polling for the initiated memory initialization BIST status */
+ read_count = read_interval_ms / TIMEOUT;
+ while (!bist_success) {
+ io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+ io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+ io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+ CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_STATUS,
+ 0, 0, 0, 0, 0, 0, 0, 0, &usr_resp);
+
+ bist_success = (IOSSM_CMD_RESPONSE_DATA_SHORT
+ (usr_resp.cmd_resp_status) & 1);
+
+ if ((!bist_success) && (read_count == 0U)) {
+ ERROR("IOSSM: %s: Timeout init memory on IO96B_1\n"
+ , __func__);
+ ERROR("IOSSM: %s: BIST_MEM_INIT_STATUS ErrCode %x\n"
+ , __func__, (IOSSM_CMD_RESPONSE_DATA_SHORT
+ (usr_resp.cmd_resp_status)
+ & GENMASK(2, 1)) > 0x1);
+ return -ETIMEDOUT;
+ }
+ read_count--;
+ mdelay(read_interval_ms);
+ }
+ }
+
+ NOTICE("IOSSM: %s: Memory initialized successfully on IO96B_1\n", __func__);
+ break;
+ }
+ }
+ return 0;
+}
diff --git a/plat/intel/soc/agilex5/soc/agilex5_pinmux.c b/plat/intel/soc/agilex5/soc/agilex5_pinmux.c
index 50d9e36..317b4d8 100644
--- a/plat/intel/soc/agilex5/soc/agilex5_pinmux.c
+++ b/plat/intel/soc/agilex5/soc/agilex5_pinmux.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -186,40 +187,72 @@
0x0000011c, 0x00000000
};
-void config_fpgaintf_mod(void)
+static void config_fpgaintf_mod(void)
{
- mmio_write_32(SOCFPGA_SYSMGR(FPGAINTF_EN_2), 1<<8);
+ uint32_t fpgaintf_en_val;
+
+ /*
+ * System manager FPGA interface enable2 register, disable individual
+ * interfaces between the FPGA and HPS.
+ */
+ fpgaintf_en_val = 0U;
+ if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(NAND_USEFPGA)) & 0x01) != 0)
+ fpgaintf_en_val |= BIT(4);
+ if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(SDMMC_USEFPGA)) & 0x01) != 0)
+ fpgaintf_en_val |= BIT(8);
+ if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(SPIM0_USEFPGA)) & 0x01) != 0)
+ fpgaintf_en_val |= BIT(16);
+ if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(SPIM1_USEFPGA)) & 0x01) != 0)
+ fpgaintf_en_val |= BIT(24);
+ mmio_write_32(SOCFPGA_SYSMGR(FPGAINTF_EN_2), fpgaintf_en_val);
+
+ /*
+ * System manager FPGA interface enable3 register, disable individual
+ * interfaces between the FPGA and HPS.
+ */
+ fpgaintf_en_val = 0U;
+ if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(EMAC0_USEFPGA)) & 0x01) != 0)
+ fpgaintf_en_val |= BIT(0);
+ if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(EMAC1_USEFPGA)) & 0x01) != 0)
+ fpgaintf_en_val |= BIT(8);
+ if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(EMAC2_USEFPGA)) & 0x01) != 0)
+ fpgaintf_en_val |= BIT(16);
+ mmio_write_32(SOCFPGA_SYSMGR(FPGAINTF_EN_3), fpgaintf_en_val);
}
void config_pinmux(handoff *hoff_ptr)
{
- unsigned int i;
+ uint32_t i;
- mmio_write_32(PINMUX_HANDOFF_CONFIG_ADDR, PINMUX_HANDOFF_CONFIG_VAL);
- for (i = 0; i < PINMUX_HANDOFF_ARRAY_SIZE(hoff_ptr->pinmux_sel_array); i += 2) {
- mmio_write_32(AGX5_PINMUX_PIN0SEL +
- hoff_ptr->pinmux_sel_array[i],
- hoff_ptr->pinmux_sel_array[i + 1]);
+ /* Configure the pin selection */
+ for (i = 0; i < ARRAY_SIZE(hoff_ptr->pinmux_sel_array); i += 2) {
+ mmio_write_32(AGX5_PINMUX_PIN0SEL + hoff_ptr->pinmux_sel_array[i],
+ hoff_ptr->pinmux_sel_array[i+1]);
}
- config_fpgaintf_mod();
-}
-
-void config_peripheral(handoff *hoff_ptr)
-{
-
- // TODO: This need to be update due to peripheral_pwr_gate_array handoff change
- // Pending SDM to pass over handoff data
- // unsigned int i;
+ /* Configure the pin control */
+ for (i = 0; i < ARRAY_SIZE(hoff_ptr->pinmux_io_array); i += 2) {
+ mmio_write_32(AGX5_PINMUX_IO0CTRL + hoff_ptr->pinmux_io_array[i],
+ hoff_ptr->pinmux_io_array[i+1]);
+ }
- // for (i = 0; i < 4; i += 2) {
- // mmio_write_32(AGX_EDGE_PERIPHERAL +
- // hoff_ptr->peripheral_pwr_gate_array[i],
- // hoff_ptr->peripheral_pwr_gate_array[i+1]);
- // }
+ /*
+ * Configure the FPGA use.
+ * The actual generic handoff contains extra 4 elements, and these 4 elements
+ * are not applicable to the Agilex5 platform. Writing these extra 4 elements
+ * will cause the system to crash, so let's avoid writing them here.
+ */
+ for (i = 0; i < (ARRAY_SIZE(hoff_ptr->pinmux_fpga_array) - 4); i += 2) {
+ mmio_write_32(AGX5_PINMUX_EMAC0_USEFPGA + hoff_ptr->pinmux_fpga_array[i],
+ hoff_ptr->pinmux_fpga_array[i+1]);
+ }
+ /* Configure the IO delay */
+ for (i = 0; i < ARRAY_SIZE(hoff_ptr->pinmux_iodelay_array); i += 2) {
+ mmio_write_32(AGX5_PINMUX_IO0_DELAY + hoff_ptr->pinmux_iodelay_array[i],
+ hoff_ptr->pinmux_iodelay_array[i+1]);
+ }
- // TODO: This need to be update due to peripheral_pwr_gate_array handoff change
- mmio_write_32(AGX5_PERIPHERAL,
- hoff_ptr->peripheral_pwr_gate_array);
+ /* Enable/Disable individual interfaces between the FPGA and HPS */
+ config_fpgaintf_mod();
}
diff --git a/plat/intel/soc/agilex5/soc/agilex5_power_manager.c b/plat/intel/soc/agilex5/soc/agilex5_power_manager.c
index 0d81970..ef3acf9 100644
--- a/plat/intel/soc/agilex5/soc/agilex5_power_manager.c
+++ b/plat/intel/soc/agilex5/soc/agilex5_power_manager.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,7 +14,7 @@
#include "agilex5_power_manager.h"
#include "socfpga_reset_manager.h"
-int wait_verify_fsm(uint16_t timeout, uint32_t peripheral_handoff)
+static int wait_verify_fsm(uint16_t timeout, uint32_t peripheral_handoff)
{
uint32_t data = 0;
uint32_t count = 0;
@@ -38,7 +39,7 @@
return 0;
}
-int pss_sram_power_off(handoff *hoff_ptr)
+static int pss_sram_power_off(handoff *hoff_ptr)
{
int ret = 0;
uint32_t peripheral_handoff = 0;
@@ -66,7 +67,7 @@
{
int ret = 0;
- switch (hoff_ptr->header_magic) {
+ switch (hoff_ptr->peripheral_pwr_gate_magic) {
case HANDOFF_MAGIC_PERIPHERAL:
ret = pss_sram_power_off(hoff_ptr);
break;
diff --git a/plat/intel/soc/common/aarch64/plat_helpers.S b/plat/intel/soc/common/aarch64/plat_helpers.S
index cbd0121..b3d5665 100644
--- a/plat/intel/soc/common/aarch64/plat_helpers.S
+++ b/plat/intel/soc/common/aarch64/plat_helpers.S
@@ -1,5 +1,7 @@
/*
* Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -96,18 +98,6 @@
endfunc plat_my_core_pos
func warm_reset_req
-#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
- bl plat_is_my_cpu_primary
- cbnz x0, warm_reset
-warm_reset:
- mov_imm x1, PLAT_SEC_ENTRY
- str xzr, [x1]
- mrs x1, rmr_el3
- orr x1, x1, #0x02
- msr rmr_el3, x1
- isb
- dsb sy
-#else
str xzr, [x4]
bl plat_is_my_cpu_primary
cbz x0, cpu_in_wfi
@@ -121,22 +111,35 @@
cpu_in_wfi:
wfi
b cpu_in_wfi
-#endif
endfunc warm_reset_req
-/* TODO: Zephyr warm reset test */
#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
func plat_get_my_entrypoint
ldr x4, =L2_RESET_DONE_REG
ldr x5, [x4]
- ldr x1, =PLAT_L2_RESET_REQ
+
+ /* Check for warm reset request */
+ ldr x1, =L2_RESET_DONE_STATUS
cmp x1, x5
- b.eq zephyr_reset_req
+ b.eq warm_reset_req
+
+ /* Check for SMP secondary cores boot request */
+ ldr x1, =SMP_SEC_CORE_BOOT_REQ
+ cmp x1, x5
+ b.eq smp_request
+
+ /* Otherwise it is cold reset */
+ mov x0, #0
+ ret
+smp_request:
+ /*
+ * Return the address 'bl31_warm_entrypoint', which is passed to
+ * 'psci_setup' routine as part of BL31 initialization.
+ */
mov_imm x1, PLAT_SEC_ENTRY
ldr x0, [x1]
- ret
-zephyr_reset_req:
- ldr x0, =0x00
+ /* Clear the mark up before return */
+ str xzr, [x4]
ret
endfunc plat_get_my_entrypoint
#else
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
index ca76b6a..931ffcf 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
@@ -1,10 +1,12 @@
/*
* Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <common/debug.h>
+#include <drivers/delay_timer.h>
#include <errno.h>
#include <lib/mmio.h>
#include <platform_def.h>
@@ -16,7 +18,24 @@
uint32_t poll_active_bit(uint32_t dir);
-#define SMMU_DMI 1
+#define SMMU_DMI 1
+#define CCU_DMI0_DMIUSMCMCR SOCFPGA_CCU_NOC_REG_BASE + 0x7340
+#define CCU_DMI0_DMIUSMCMAR SOCFPGA_CCU_NOC_REG_BASE + 0x7344
+#define CCU_DMI0_DMIUSMCMCR_MNTOP GENMASK(3, 0)
+#define MAX_DISTRIBUTED_MEM_INTERFACE 2
+#define FLUSH_ALL_ENTRIES 0x4
+#define CCU_DMI0_DMIUSMCMCR_ARRAY_ID GENMASK(21, 16)
+#define ARRAY_ID_TAG 0x0
+#define ARRAY_ID_DATA 0x1
+#define CACHE_OPERATION_DONE BIT(0)
+#define TIMEOUT_200MS 200
+
+#define __bf_shf(x) (__builtin_ffsll(x) - 1)
+
+#define FIELD_PREP(_mask, _val) \
+ ({ \
+ ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \
+ })
#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
ncore_ccu_reg_t ncore_ccu_modules[] = {
@@ -632,3 +651,61 @@
mmio_write_32(SOCFPGA_SYSMGR(TSN_TBU_STREAM_CTRL_REG_3_TSN1), ENABLE_STREAMID);
mmio_write_32(SOCFPGA_SYSMGR(TSN_TBU_STREAM_CTRL_REG_3_TSN2), ENABLE_STREAMID);
}
+
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+/* TODO: Temp added this here*/
+static int poll_idle_status(uint32_t addr, uint32_t mask, uint32_t match, uint32_t delay_ms)
+{
+ int time_out = delay_ms;
+
+ while (time_out-- > 0) {
+
+ if ((mmio_read_32(addr) & mask) == match) {
+ return 0;
+ }
+ udelay(1000);
+ }
+
+ return -ETIMEDOUT;
+}
+
+int flush_l3_dcache(void)
+{
+ int i;
+ int ret = 0;
+
+ /* Flushing all entries in CCU system memory cache */
+ for (i = 0; i < MAX_DISTRIBUTED_MEM_INTERFACE; i++) {
+ mmio_write_32(FIELD_PREP(CCU_DMI0_DMIUSMCMCR_MNTOP, FLUSH_ALL_ENTRIES) |
+ FIELD_PREP(CCU_DMI0_DMIUSMCMCR_ARRAY_ID, ARRAY_ID_TAG),
+ (uintptr_t)(CCU_DMI0_DMIUSMCMCR + (i * 0x1000)));
+
+ /* Wait for cache maintenance operation done */
+ ret = poll_idle_status((CCU_DMI0_DMIUSMCMAR +
+ (i * 0x1000)), CACHE_OPERATION_DONE,
+ CACHE_OPERATION_DONE, TIMEOUT_200MS);
+
+ if (ret != 0) {
+ VERBOSE("%s: Timeout while waiting for flushing tag in DMI%d done\n",
+ __func__, i);
+ return ret;
+ }
+
+ mmio_write_32(FIELD_PREP(CCU_DMI0_DMIUSMCMCR_MNTOP, FLUSH_ALL_ENTRIES) |
+ FIELD_PREP(CCU_DMI0_DMIUSMCMCR_ARRAY_ID, ARRAY_ID_DATA),
+ (uintptr_t)(CCU_DMI0_DMIUSMCMCR + (i * 0x1000)));
+
+ /* Wait for cache maintenance operation done */
+ ret = poll_idle_status((CCU_DMI0_DMIUSMCMAR +
+ (i * 0x1000)), CACHE_OPERATION_DONE,
+ CACHE_OPERATION_DONE, TIMEOUT_200MS);
+
+ if (ret != 0) {
+ VERBOSE("%s: Timeout while waiting for flushing data in DMI%d done\n",
+ __func__, i);
+ }
+ }
+
+ return ret;
+}
+#endif
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.h b/plat/intel/soc/common/drivers/ccu/ncore_ccu.h
index e00c4b7..a89c098 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.h
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -452,5 +453,6 @@
uint32_t init_ncore_ccu(void);
void ncore_enable_ocram_firewall(void);
void setup_smmu_stream_id(void);
+int flush_l3_dcache(void);
#endif
diff --git a/plat/intel/soc/common/drivers/sdmmc/sdmmc.c b/plat/intel/soc/common/drivers/sdmmc/sdmmc.c
index 48f91eb..62698a9 100644
--- a/plat/intel/soc/common/drivers/sdmmc/sdmmc.c
+++ b/plat/intel/soc/common/drivers/sdmmc/sdmmc.c
@@ -18,53 +18,26 @@
#include <lib/mmio.h>
#include <lib/utils.h>
-#include "agilex5_pinmux.h"
#include "sdmmc.h"
#include "socfpga_mailbox.h"
+#include "wdt/watchdog.h"
static const struct mmc_ops *ops;
static unsigned int mmc_ocr_value;
-static struct mmc_csd_emmc mmc_csd;
-static struct sd_switch_status sd_switch_func_status;
-static unsigned char mmc_ext_csd[512] __aligned(16);
static unsigned int mmc_flags;
-static struct mmc_device_info *mmc_dev_info;
static unsigned int rca;
-static unsigned int scr[2]__aligned(16) = { 0 };
extern const struct mmc_ops cdns_sdmmc_ops;
extern struct cdns_sdmmc_params cdns_params;
extern struct cdns_sdmmc_combo_phy sdmmc_combo_phy_reg;
extern struct cdns_sdmmc_sdhc sdmmc_sdhc_reg;
-static bool is_cmd23_enabled(void)
+bool is_cmd23_enabled(void)
{
return ((mmc_flags & MMC_FLAG_CMD23) != 0U);
}
-static bool is_sd_cmd6_enabled(void)
-{
- return ((mmc_flags & MMC_FLAG_SD_CMD6) != 0U);
-}
-
-/* TODO: Will romove once ATF driver is developed */
-void sdmmc_pin_config(void)
-{
- /* temp use base + addr. Official must change to common method */
- mmio_write_32(AGX5_PINMUX_PIN0SEL+0x00, 0x0);
- mmio_write_32(AGX5_PINMUX_PIN0SEL+0x04, 0x0);
- mmio_write_32(AGX5_PINMUX_PIN0SEL+0x08, 0x0);
- mmio_write_32(AGX5_PINMUX_PIN0SEL+0x0C, 0x0);
- mmio_write_32(AGX5_PINMUX_PIN0SEL+0x10, 0x0);
- mmio_write_32(AGX5_PINMUX_PIN0SEL+0x14, 0x0);
- mmio_write_32(AGX5_PINMUX_PIN0SEL+0x18, 0x0);
- mmio_write_32(AGX5_PINMUX_PIN0SEL+0x1C, 0x0);
- mmio_write_32(AGX5_PINMUX_PIN0SEL+0x20, 0x0);
- mmio_write_32(AGX5_PINMUX_PIN0SEL+0x24, 0x0);
- mmio_write_32(AGX5_PINMUX_PIN0SEL+0x28, 0x0);
-}
-
-static int sdmmc_send_cmd(unsigned int idx, unsigned int arg,
+int sdmmc_send_cmd(unsigned int idx, unsigned int arg,
unsigned int r_type, unsigned int *r_data)
{
struct mmc_cmd cmd;
@@ -94,7 +67,7 @@
return ret;
}
-static int sdmmc_device_state(void)
+int sdmmc_device_state(void)
{
int retries = DEFAULT_SDMMC_MAX_RETRIES;
unsigned int resp_data[4];
@@ -125,521 +98,12 @@
return MMC_GET_STATE(resp_data[0]);
}
-static int sdmmc_set_ext_csd(unsigned int ext_cmd, unsigned int value)
-{
- int ret;
-
- ret = sdmmc_send_cmd(MMC_CMD(6),
- EXTCSD_WRITE_BYTES | EXTCSD_CMD(ext_cmd) |
- EXTCSD_VALUE(value) | EXTCSD_CMD_SET_NORMAL,
- MMC_RESPONSE_R1B, NULL);
- if (ret != 0) {
- return ret;
- }
-
- do {
- ret = sdmmc_device_state();
- if (ret < 0) {
- return ret;
- }
- } while (ret == MMC_STATE_PRG);
-
- return 0;
-}
-
-static int sdmmc_mmc_sd_switch(unsigned int bus_width)
-{
- int ret;
- int retries = DEFAULT_SDMMC_MAX_RETRIES;
- unsigned int bus_width_arg = 0;
-
- /* CMD55: Application Specific Command */
- ret = sdmmc_send_cmd(MMC_CMD(55), rca << RCA_SHIFT_OFFSET,
- MMC_RESPONSE_R5, NULL);
- if (ret != 0) {
- return ret;
- }
-
- ret = ops->prepare(0, (uintptr_t)&scr, sizeof(scr));
- if (ret != 0) {
- return ret;
- }
-
- /* ACMD51: SEND_SCR */
- do {
- ret = sdmmc_send_cmd(MMC_ACMD(51), 0, MMC_RESPONSE_R1, NULL);
- if ((ret != 0) && (retries == 0)) {
- ERROR("ACMD51 failed after %d retries (ret=%d)\n",
- DEFAULT_SDMMC_MAX_RETRIES, ret);
- return ret;
- }
-
- retries--;
- } while (ret != 0);
-
- ret = ops->read(0, (uintptr_t)&scr, sizeof(scr));
- if (ret != 0) {
- return ret;
- }
-
- if (((scr[0] & SD_SCR_BUS_WIDTH_4) != 0U) &&
- (bus_width == MMC_BUS_WIDTH_4)) {
- bus_width_arg = 2;
- }
-
- /* CMD55: Application Specific Command */
- ret = sdmmc_send_cmd(MMC_CMD(55), rca << RCA_SHIFT_OFFSET,
- MMC_RESPONSE_R5, NULL);
- if (ret != 0) {
- return ret;
- }
-
- /* ACMD6: SET_BUS_WIDTH */
- ret = sdmmc_send_cmd(MMC_ACMD(6), bus_width_arg, MMC_RESPONSE_R1, NULL);
- if (ret != 0) {
- return ret;
- }
-
- do {
- ret = sdmmc_device_state();
- if (ret < 0) {
- return ret;
- }
- } while (ret == MMC_STATE_PRG);
-
- return 0;
-}
-
-static int sdmmc_set_ios(unsigned int clk, unsigned int bus_width)
-{
- int ret;
- unsigned int width = bus_width;
-
- if (mmc_dev_info->mmc_dev_type != MMC_IS_EMMC) {
- if (width == MMC_BUS_WIDTH_8) {
- WARN("Wrong bus config for SD-card, force to 4\n");
- width = MMC_BUS_WIDTH_4;
- }
- ret = sdmmc_mmc_sd_switch(width);
- if (ret != 0) {
- return ret;
- }
- } else if (mmc_csd.spec_vers == 4U) {
- ret = sdmmc_set_ext_csd(CMD_EXTCSD_BUS_WIDTH,
- (unsigned int)width);
- if (ret != 0) {
- return ret;
- }
- } else {
- VERBOSE("Wrong MMC type or spec version\n");
- }
-
- return ops->set_ios(clk, width);
-}
-
-static int sdmmc_fill_device_info(void)
-{
- unsigned long long c_size;
- unsigned int speed_idx;
- unsigned int nb_blocks;
- unsigned int freq_unit;
- int ret = 0;
- struct mmc_csd_sd_v2 *csd_sd_v2;
-
- switch (mmc_dev_info->mmc_dev_type) {
- case MMC_IS_EMMC:
- mmc_dev_info->block_size = MMC_BLOCK_SIZE;
-
- ret = ops->prepare(0, (uintptr_t)&mmc_ext_csd,
- sizeof(mmc_ext_csd));
- if (ret != 0) {
- return ret;
- }
-
- /* MMC CMD8: SEND_EXT_CSD */
- ret = sdmmc_send_cmd(MMC_CMD(8), 0, MMC_RESPONSE_R1, NULL);
- if (ret != 0) {
- return ret;
- }
-
- ret = ops->read(0, (uintptr_t)&mmc_ext_csd,
- sizeof(mmc_ext_csd));
- if (ret != 0) {
- return ret;
- }
-
- do {
- ret = sdmmc_device_state();
- if (ret < 0) {
- return ret;
- }
- } while (ret != MMC_STATE_TRAN);
-
- nb_blocks = (mmc_ext_csd[CMD_EXTCSD_SEC_CNT] << 0) |
- (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 1] << 8) |
- (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 2] << 16) |
- (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 3] << 24);
-
- mmc_dev_info->device_size = (unsigned long long)nb_blocks *
- mmc_dev_info->block_size;
-
- break;
-
- case MMC_IS_SD:
- /*
- * Use the same mmc_csd struct, as required fields here
- * (READ_BL_LEN, C_SIZE, CSIZE_MULT) are common with eMMC.
- */
- mmc_dev_info->block_size = BIT_32(mmc_csd.read_bl_len);
-
- c_size = ((unsigned long long)mmc_csd.c_size_high << 2U) |
- (unsigned long long)mmc_csd.c_size_low;
- assert(c_size != 0xFFFU);
-
- mmc_dev_info->device_size = (c_size + 1U) *
- BIT_64(mmc_csd.c_size_mult + 2U) *
- mmc_dev_info->block_size;
-
- break;
-
- case MMC_IS_SD_HC:
- assert(mmc_csd.csd_structure == 1U);
-
- mmc_dev_info->block_size = MMC_BLOCK_SIZE;
-
- /* Need to use mmc_csd_sd_v2 struct */
- csd_sd_v2 = (struct mmc_csd_sd_v2 *)&mmc_csd;
- c_size = ((unsigned long long)csd_sd_v2->c_size_high << 16) |
- (unsigned long long)csd_sd_v2->c_size_low;
-
- mmc_dev_info->device_size = (c_size + 1U) << SDMMC_MULT_BY_512K_SHIFT;
-
- break;
-
- default:
- ret = -EINVAL;
- break;
- }
-
- if (ret < 0) {
- return ret;
- }
-
- speed_idx = (mmc_csd.tran_speed & CSD_TRAN_SPEED_MULT_MASK) >>
- CSD_TRAN_SPEED_MULT_SHIFT;
-
- assert(speed_idx > 0U);
-
- if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
- mmc_dev_info->max_bus_freq = tran_speed_base[speed_idx];
- } else {
- mmc_dev_info->max_bus_freq = sd_tran_speed_base[speed_idx];
- }
-
- freq_unit = mmc_csd.tran_speed & CSD_TRAN_SPEED_UNIT_MASK;
- while (freq_unit != 0U) {
- mmc_dev_info->max_bus_freq *= 10U;
- --freq_unit;
- }
-
- mmc_dev_info->max_bus_freq *= 10000U;
-
- return 0;
-}
-
-static int sdmmc_sd_switch(unsigned int mode, unsigned char group,
- unsigned char func)
-{
- unsigned int group_shift = (group - 1U) * 4U;
- unsigned int group_mask = GENMASK(group_shift + 3U, group_shift);
- unsigned int arg;
- int ret;
-
- ret = ops->prepare(0, (uintptr_t)&sd_switch_func_status,
- sizeof(sd_switch_func_status));
- if (ret != 0) {
- return ret;
- }
-
- /* MMC CMD6: SWITCH_FUNC */
- arg = mode | SD_SWITCH_ALL_GROUPS_MASK;
- arg &= ~group_mask;
- arg |= func << group_shift;
- ret = sdmmc_send_cmd(MMC_CMD(6), arg, MMC_RESPONSE_R1, NULL);
- if (ret != 0) {
- return ret;
- }
-
- return ops->read(0, (uintptr_t)&sd_switch_func_status,
- sizeof(sd_switch_func_status));
-}
-
-static int sdmmc_sd_send_op_cond(void)
-{
- int n;
- unsigned int resp_data[4];
-
- for (n = 0; n < SEND_SDMMC_OP_COND_MAX_RETRIES; n++) {
- int ret;
-
- /* CMD55: Application Specific Command */
- ret = sdmmc_send_cmd(MMC_CMD(55), 0, MMC_RESPONSE_R1, NULL);
- if (ret != 0) {
- return ret;
- }
-
- /* ACMD41: SD_SEND_OP_COND */
- ret = sdmmc_send_cmd(MMC_ACMD(41), OCR_HCS |
- mmc_dev_info->ocr_voltage, MMC_RESPONSE_R3,
- &resp_data[0]);
- if (ret != 0) {
- return ret;
- }
-
- if ((resp_data[0] & OCR_POWERUP) != 0U) {
- mmc_ocr_value = resp_data[0];
-
- if ((mmc_ocr_value & OCR_HCS) != 0U) {
- mmc_dev_info->mmc_dev_type = MMC_IS_SD_HC;
- } else {
- mmc_dev_info->mmc_dev_type = MMC_IS_SD;
- }
-
- return 0;
- }
-
- mdelay(10);
- }
-
- ERROR("ACMD41 failed after %d retries\n", SEND_SDMMC_OP_COND_MAX_RETRIES);
-
- return -EIO;
-}
-
-static int sdmmc_reset_to_idle(void)
-{
- int ret;
-
- /* CMD0: reset to IDLE */
- ret = sdmmc_send_cmd(MMC_CMD(0), 0, 0, NULL);
- if (ret != 0) {
- return ret;
- }
-
- mdelay(2);
-
- return 0;
-}
-
-static int sdmmc_send_op_cond(void)
-{
- int ret, n;
- unsigned int resp_data[4];
-
- ret = sdmmc_reset_to_idle();
- if (ret != 0) {
- return ret;
- }
-
- for (n = 0; n < SEND_SDMMC_OP_COND_MAX_RETRIES; n++) {
- ret = sdmmc_send_cmd(MMC_CMD(1), OCR_SECTOR_MODE |
- OCR_VDD_MIN_2V7 | OCR_VDD_MIN_1V7,
- MMC_RESPONSE_R3, &resp_data[0]);
- if (ret != 0) {
- return ret;
- }
-
- if ((resp_data[0] & OCR_POWERUP) != 0U) {
- mmc_ocr_value = resp_data[0];
- return 0;
- }
-
- mdelay(10);
- }
-
- ERROR("CMD1 failed after %d retries\n", SEND_SDMMC_OP_COND_MAX_RETRIES);
-
- return -EIO;
-}
-
-static int sdmmc_enumerate(unsigned int clk, unsigned int bus_width)
-{
- int ret;
- unsigned int resp_data[4];
-
- ops->init();
-
- ret = sdmmc_reset_to_idle();
- if (ret != 0) {
- return ret;
- }
-
- if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
- ret = sdmmc_send_op_cond();
- } else {
- /* CMD8: Send Interface Condition Command */
- ret = sdmmc_send_cmd(MMC_CMD(8), VHS_2_7_3_6_V | CMD8_CHECK_PATTERN,
- MMC_RESPONSE_R5, &resp_data[0]);
-
- if ((ret == 0) && ((resp_data[0] & 0xffU) == CMD8_CHECK_PATTERN)) {
- ret = sdmmc_sd_send_op_cond();
- }
- }
- if (ret != 0) {
- return ret;
- }
-
- /* CMD2: Card Identification */
- ret = sdmmc_send_cmd(MMC_CMD(2), 0, MMC_RESPONSE_R2, NULL);
- if (ret != 0) {
- return ret;
- }
-
- /* CMD3: Set Relative Address */
- if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
- rca = MMC_FIX_RCA;
- ret = sdmmc_send_cmd(MMC_CMD(3), rca << RCA_SHIFT_OFFSET,
- MMC_RESPONSE_R1, NULL);
- if (ret != 0) {
- return ret;
- }
- } else {
- ret = sdmmc_send_cmd(MMC_CMD(3), 0,
- MMC_RESPONSE_R6, &resp_data[0]);
- if (ret != 0) {
- return ret;
- }
-
- rca = (resp_data[0] & 0xFFFF0000U) >> 16;
- }
-
- /* CMD9: CSD Register */
- ret = sdmmc_send_cmd(MMC_CMD(9), rca << RCA_SHIFT_OFFSET,
- MMC_RESPONSE_R2, &resp_data[0]);
- if (ret != 0) {
- return ret;
- }
-
- memcpy_s(&mmc_csd, sizeof(mmc_csd) / MBOX_WORD_BYTE,
- &resp_data, sizeof(resp_data) / MBOX_WORD_BYTE);
-
- /* CMD7: Select Card */
- ret = sdmmc_send_cmd(MMC_CMD(7), rca << RCA_SHIFT_OFFSET,
- MMC_RESPONSE_R1, NULL);
- if (ret != 0) {
- return ret;
- }
-
- do {
- ret = sdmmc_device_state();
- if (ret < 0) {
- return ret;
- }
- } while (ret != MMC_STATE_TRAN);
-
- ret = sdmmc_set_ios(clk, bus_width);
- if (ret != 0) {
- return ret;
- }
-
- ret = sdmmc_fill_device_info();
- if (ret != 0) {
- return ret;
- }
-
- if (is_sd_cmd6_enabled() &&
- (mmc_dev_info->mmc_dev_type == MMC_IS_SD_HC)) {
- /* Try to switch to High Speed Mode */
- ret = sdmmc_sd_switch(SD_SWITCH_FUNC_CHECK, 1U, 1U);
- if (ret != 0) {
- return ret;
- }
-
- if ((sd_switch_func_status.support_g1 & BIT(9)) == 0U) {
- /* High speed not supported, keep default speed */
- return 0;
- }
-
- ret = sdmmc_sd_switch(SD_SWITCH_FUNC_SWITCH, 1U, 1U);
- if (ret != 0) {
- return ret;
- }
-
- if ((sd_switch_func_status.sel_g2_g1 & 0x1U) == 0U) {
- /* Cannot switch to high speed, keep default speed */
- return 0;
- }
-
- mmc_dev_info->max_bus_freq = 50000000U;
- ret = ops->set_ios(clk, bus_width);
- }
-
- return ret;
-}
-
size_t sdmmc_read_blocks(int lba, uintptr_t buf, size_t size)
{
- int ret;
- unsigned int cmd_idx, cmd_arg;
-
- assert((ops != NULL) &&
- (ops->read != NULL) &&
- (size != 0U) &&
- ((size & MMC_BLOCK_MASK) == 0U));
-
- ret = ops->prepare(lba, buf, size);
- if (ret != 0) {
- return 0;
- }
-
- if (is_cmd23_enabled()) {
- /* Set block count */
- ret = sdmmc_send_cmd(MMC_CMD(23), size / MMC_BLOCK_SIZE,
- MMC_RESPONSE_R1, NULL);
- if (ret != 0) {
- return 0;
- }
-
- cmd_idx = MMC_CMD(18);
- } else {
- if (size > MMC_BLOCK_SIZE) {
- cmd_idx = MMC_CMD(18);
- } else {
- cmd_idx = MMC_CMD(17);
- }
- }
-
- if (((mmc_ocr_value & OCR_ACCESS_MODE_MASK) == OCR_BYTE_MODE) &&
- (mmc_dev_info->mmc_dev_type != MMC_IS_SD_HC)) {
- cmd_arg = lba * MMC_BLOCK_SIZE;
- } else {
- cmd_arg = lba;
- }
+ mmc_read_blocks(lba, buf, size);
- ret = sdmmc_send_cmd(cmd_idx, cmd_arg, MMC_RESPONSE_R1, NULL);
- if (ret != 0) {
- return 0;
- }
-
- ret = ops->read(lba, buf, size);
- if (ret != 0) {
- return 0;
- }
-
- /* Wait buffer empty */
- do {
- ret = sdmmc_device_state();
- if (ret < 0) {
- return 0;
- }
- } while ((ret != MMC_STATE_TRAN) && (ret != MMC_STATE_DATA));
-
- if (!is_cmd23_enabled() && (size > MMC_BLOCK_SIZE)) {
- ret = sdmmc_send_cmd(MMC_CMD(12), 0, MMC_RESPONSE_R1B, NULL);
- if (ret != 0) {
- return 0;
- }
- }
+ /* Restart watchdog for reading each chunk byte */
+ watchdog_sw_rst();
return size;
}
@@ -710,64 +174,3 @@
return size;
}
-
-int sd_or_mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
- unsigned int width, unsigned int flags,
- struct mmc_device_info *device_info)
-{
- assert((ops_ptr != NULL) &&
- (ops_ptr->init != NULL) &&
- (ops_ptr->send_cmd != NULL) &&
- (ops_ptr->set_ios != NULL) &&
- (ops_ptr->prepare != NULL) &&
- (ops_ptr->read != NULL) &&
- (ops_ptr->write != NULL) &&
- (device_info != NULL) &&
- (clk != 0) &&
- ((width == MMC_BUS_WIDTH_1) ||
- (width == MMC_BUS_WIDTH_4) ||
- (width == MMC_BUS_WIDTH_8) ||
- (width == MMC_BUS_WIDTH_DDR_4) ||
- (width == MMC_BUS_WIDTH_DDR_8)));
-
- ops = ops_ptr;
- mmc_flags = flags;
- mmc_dev_info = device_info;
-
- return sdmmc_enumerate(clk, width);
-}
-
-int sdmmc_init(handoff *hoff_ptr, struct cdns_sdmmc_params *params, struct mmc_device_info *info)
-{
- int result = 0;
-
- /* SDMMC pin mux configuration */
- sdmmc_pin_config();
- cdns_set_sdmmc_var(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
- result = cdns_sd_host_init(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
- if (result < 0) {
- return result;
- }
-
- assert((params != NULL) &&
- ((params->reg_base & MMC_BLOCK_MASK) == 0) &&
- ((params->desc_base & MMC_BLOCK_MASK) == 0) &&
- ((params->desc_size & MMC_BLOCK_MASK) == 0) &&
- ((params->reg_pinmux & MMC_BLOCK_MASK) == 0) &&
- ((params->reg_phy & MMC_BLOCK_MASK) == 0) &&
- (params->desc_size > 0) &&
- (params->clk_rate > 0) &&
- ((params->bus_width == MMC_BUS_WIDTH_1) ||
- (params->bus_width == MMC_BUS_WIDTH_4) ||
- (params->bus_width == MMC_BUS_WIDTH_8)));
-
- memcpy_s(&cdns_params, sizeof(struct cdns_sdmmc_params) / MBOX_WORD_BYTE,
- params, sizeof(struct cdns_sdmmc_params) / MBOX_WORD_BYTE);
- cdns_params.cdn_sdmmc_dev_type = info->mmc_dev_type;
- cdns_params.cdn_sdmmc_dev_mode = SD_DS;
-
- result = sd_or_mmc_init(&cdns_sdmmc_ops, params->clk_rate, params->bus_width,
- params->flags, info);
-
- return result;
-}
diff --git a/plat/intel/soc/common/drivers/sdmmc/sdmmc.h b/plat/intel/soc/common/drivers/sdmmc/sdmmc.h
index 16c6b04..3f6119c 100644
--- a/plat/intel/soc/common/drivers/sdmmc/sdmmc.h
+++ b/plat/intel/soc/common/drivers/sdmmc/sdmmc.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -33,10 +34,12 @@
* @hoff_ptr: Pointer to the hand-off data
* Return: 0 on success, a negative errno on failure
*/
-int sdmmc_init(handoff *hoff_ptr, struct cdns_sdmmc_params *params,
- struct mmc_device_info *info);
-int sd_or_mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
- unsigned int width, unsigned int flags,
- struct mmc_device_info *device_info);
void sdmmc_pin_config(void);
+size_t sdmmc_read_blocks(int lba, uintptr_t buf, size_t size);
+size_t sdmmc_write_blocks(int lba, const uintptr_t buf, size_t size);
+int sdmmc_device_state(void);
+bool is_cmd23_enabled(void);
+int sdmmc_send_cmd(unsigned int idx, unsigned int arg,
+ unsigned int r_type, unsigned int *r_data);
+
#endif
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index 1946898..a820e41 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -21,6 +22,18 @@
#define PLAT_SOCFPGA_AGILEX5 4
#define SIMICS_RUN 1
#define MAX_IO_MTD_DEVICES U(1)
+/* Boot Source configuration
+ * TODO: Shall consider "assert_numeric" in the future
+ */
+#if SOCFPGA_BOOT_SOURCE_NAND
+#define BOOT_SOURCE BOOT_SOURCE_NAND
+#elif SOCFPGA_BOOT_SOURCE_SDMMC
+#define BOOT_SOURCE BOOT_SOURCE_SDMMC
+#elif SOCFPGA_BOOT_SOURCE_QSPI
+#define BOOT_SOURCE BOOT_SOURCE_QSPI
+#else
+#define BOOT_SOURCE BOOT_SOURCE_SDMMC
+#endif
/* sysmgr.boot_scratch_cold4 & 5 used for CPU release address for SPL */
#define PLAT_CPU_RELEASE_ADDR 0xffd12210
@@ -28,26 +41,26 @@
/* Magic word to indicate L2 reset is completed */
#define L2_RESET_DONE_STATUS 0x1228E5E7
+/* Magic word to differentiate for SMP secondary core boot request */
+#define SMP_SEC_CORE_BOOT_REQ 0x1228E5E8
+
/* Define next boot image name and offset */
/* Get non-secure image entrypoint for BL33. Zephyr and Linux */
-#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
-
-#ifndef PRELOADED_BL33_BASE
-#define PLAT_NS_IMAGE_OFFSET 0x80200000
-#else
+#ifdef PRELOADED_BL33_BASE
#define PLAT_NS_IMAGE_OFFSET PRELOADED_BL33_BASE
-#endif
-#define PLAT_HANDOFF_OFFSET 0x0003F000
-
+#else
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+#define PLAT_NS_IMAGE_OFFSET 0x80200000
#else
#define PLAT_NS_IMAGE_OFFSET 0x10000000
-#define PLAT_HANDOFF_OFFSET 0xFFE3F000
#endif
+#endif /* #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 */
#define PLAT_QSPI_DATA_BASE (0x3C00000)
#define PLAT_NAND_DATA_BASE (0x0200000)
#define PLAT_SDMMC_DATA_BASE (0x0)
+
/*******************************************************************************
* Platform binary types for linking
******************************************************************************/
diff --git a/plat/intel/soc/common/include/socfpga_handoff.h b/plat/intel/soc/common/include/socfpga_handoff.h
index b2913c7..7e1d0c0 100644
--- a/plat/intel/soc/common/include/socfpga_handoff.h
+++ b/plat/intel/soc/common/include/socfpga_handoff.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,12 +11,12 @@
#define HANDOFF_MAGIC_HEADER 0x424f4f54 /* BOOT */
#define HANDOFF_MAGIC_PINMUX_SEL 0x504d5558 /* PMUX */
#define HANDOFF_MAGIC_IOCTLR 0x494f4354 /* IOCT */
-#define HANDOFF_MAGIC_FPGA 0x46504741 /* FPGA */
+#define HANDOFF_MAGIC_FPGA 0x46504741 /* FPGA */
#define HANDOFF_MAGIC_IODELAY 0x444c4159 /* DLAY */
-#define HANDOFF_MAGIC_CLOCK 0x434c4b53 /* CLKS */
-#define HANDOFF_MAGIC_MISC 0x4d495343 /* MISC */
+#define HANDOFF_MAGIC_CLOCK 0x434c4b53 /* CLKS */
+#define HANDOFF_MAGIC_MISC 0x4d495343 /* MISC */
#define HANDOFF_MAGIC_PERIPHERAL 0x50455249 /* PERIPHERAL */
-#define HANDOFF_MAGIC_DDR 0x5344524d /* DDR */
+#define HANDOFF_MAGIC_DDR 0x5344524d /* DDR */
#include <socfpga_plat_def.h>
@@ -126,6 +127,8 @@
uint32_t clock_magic;
uint32_t clock_length;
uint32_t _pad_0x588_0x590[2];
+
+ /* main group PLL */
uint32_t main_pll_nocclk;
uint32_t main_pll_nocdiv;
uint32_t main_pll_pllglob;
@@ -135,6 +138,8 @@
uint32_t main_pll_pllc2;
uint32_t main_pll_pllc3;
uint32_t main_pll_pllm;
+
+ /* peripheral group PLL */
uint32_t per_pll_emacctl;
uint32_t per_pll_gpiodiv;
uint32_t per_pll_pllglob;
@@ -144,29 +149,25 @@
uint32_t per_pll_pllc2;
uint32_t per_pll_pllc3;
uint32_t per_pll_pllm;
+
+ /* control group */
uint32_t alt_emacactr;
uint32_t alt_emacbctr;
uint32_t alt_emacptpctr;
uint32_t alt_gpiodbctr;
- uint32_t alt_sdmmcctr;
uint32_t alt_s2fuser0ctr;
uint32_t alt_s2fuser1ctr;
uint32_t alt_psirefctr;
- /* TODO: Temp added for clk manager. */
- uint32_t qspi_clk_khz;
+ uint32_t alt_usb31ctr;
+ uint32_t alt_dsuctr;
+ uint32_t alt_core01ctr;
+ uint32_t alt_core23ctr;
+ uint32_t alt_core2ctr;
+ uint32_t alt_core3ctr;
uint32_t hps_osc_clk_hz;
uint32_t fpga_clk_hz;
- /* TODO: Temp added for clk manager. */
- uint32_t ddr_reset_type;
- /* TODO: Temp added for clk manager. */
- uint32_t hps_status_coldreset;
- /* TODO: Temp remove due to add in extra handoff data */
- //uint32_t _pad_0x604_0x610[3];
+ uint32_t _pad_0x604_0x610[3];
#endif
- /* misc configuration */
- uint32_t misc_magic;
- uint32_t misc_length;
- uint32_t _pad_0x618_0x620[2];
#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
/* peripheral configuration - select */
@@ -179,7 +180,7 @@
uint32_t ddr_magic;
uint32_t ddr_length;
uint32_t _pad_0x1C_0x20[2];
- uint32_t ddr_array[4]; /* offset, value */
+ uint32_t ddr_config; /* BIT[0]-Dual Port. BIT[1]-Dual EMIF */
#endif
} handoff;
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index fcee101..82f9fd3 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -247,6 +247,7 @@
#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
void intel_smmu_hps_remapper_init(uint64_t *mem);
+int intel_smmu_hps_remapper_config(uint32_t remapper_bypass);
#endif
int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len);
diff --git a/plat/intel/soc/common/include/socfpga_private.h b/plat/intel/soc/common/include/socfpga_private.h
index 041c282..fbe18c3 100644
--- a/plat/intel/soc/common/include/socfpga_private.h
+++ b/plat/intel/soc/common/include/socfpga_private.h
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -23,8 +24,8 @@
BOOT_SOURCE_FPGA = 0,
BOOT_SOURCE_SDMMC,
BOOT_SOURCE_NAND,
- BOOT_SOURCE_RSVD,
- BOOT_SOURCE_QSPI
+ BOOT_SOURCE_QSPI,
+ BOOT_SOURCE_RSVD
} boot_source_type;
/*******************************************************************************
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index d2eceb9..31474c4 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -140,6 +140,7 @@
#define INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_FINALIZE 0xC200008B
#define INTEL_SIP_SMC_FCS_ECDH_REQUEST_INIT 0xC200008C
#define INTEL_SIP_SMC_FCS_ECDH_REQUEST_FINALIZE 0xC200008E
+#define INTEL_SIP_SMC_FCS_SDM_REMAPPER_CONFIG 0xC2000201
/* SEU ERR */
#define INTEL_SIP_SMC_SEU_ERR_STATUS 0xC2000099
diff --git a/plat/intel/soc/common/include/socfpga_system_manager.h b/plat/intel/soc/common/include/socfpga_system_manager.h
index 1327b81..346cfe1 100644
--- a/plat/intel/soc/common/include/socfpga_system_manager.h
+++ b/plat/intel/soc/common/include/socfpga_system_manager.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -32,4 +33,8 @@
#define SOCFPGA_SYSMGR(_reg) (SOCFPGA_SYSMGR_REG_BASE \
+ (SOCFPGA_SYSMGR_##_reg))
+/* Function Prototype */
+uint32_t intel_hps_get_jtag_id(void);
+bool is_agilex5_A5F0(void);
+
#endif /* SOCFPGA_SYSTEMMANAGER_H */
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index 74ecc95..5d31e99 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -168,7 +168,7 @@
}
if (MBOX_RESP_ERR(resp_data) > 0U) {
- INFO("Error in response: %x\n", resp_data);
+ INFO("SDM response: Return Code: 0x%x\n", MBOX_RESP_ERR(resp_data));
return -MBOX_RESP_ERR(resp_data);
}
@@ -337,7 +337,7 @@
}
if (MBOX_RESP_ERR(resp_data) > 0U) {
- INFO("Error in response: %x\n", resp_data);
+ INFO("SDM response: Return Code: 0x%x\n", MBOX_RESP_ERR(resp_data));
return -MBOX_RESP_ERR(resp_data);
}
@@ -652,7 +652,7 @@
res = response[RECONFIG_STATUS_SOFTFUNC_STATUS];
if ((res & SOFTFUNC_STATUS_SEU_ERROR) != 0U) {
- ERROR("SoftFunction Status SEU ERROR\n");
+ return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
}
if ((res & SOFTFUNC_STATUS_CONF_DONE) == 0U) {
diff --git a/plat/intel/soc/common/soc/socfpga_reset_manager.c b/plat/intel/soc/common/soc/socfpga_reset_manager.c
index cb4a210..c7d7076 100644
--- a/plat/intel/soc/common/soc/socfpga_reset_manager.c
+++ b/plat/intel/soc/common/soc/socfpga_reset_manager.c
@@ -76,7 +76,7 @@
RSTMGR_FIELD(PER0, DMAIF6) |
RSTMGR_FIELD(PER0, DMAIF7));
-#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX
+#if (PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX) || (PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5)
mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST),
RSTMGR_FIELD(BRG, MPFE));
#endif
@@ -484,6 +484,11 @@
(~brg_lst & (RSTMGR_BRGMODRST_SOC2FPGA
| RSTMGR_BRGMODRST_LWHPS2FPGA))
| RSTMGR_BRGMODRST_SOC2FPGA);
+
+ /* Set System Manager soc bridge control register[soc2fpga_ready_latency_enable] = 1 */
+ VERBOSE("Set SOC soc2fpga_ready_latency_enable ...\n");
+ mmio_setbits_32(SOCFPGA_SYSMGR(FPGA_BRIDGE_CTRL),
+ SYSMGR_SOC_BRIDGE_CTRL_EN);
}
/**************** LWSOCFPGA ****************/
@@ -567,6 +572,11 @@
((~brg_lst & (RSTMGR_BRGMODRST_SOC2FPGA
| RSTMGR_BRGMODRST_LWHPS2FPGA)))
| RSTMGR_BRGMODRST_LWHPS2FPGA);
+
+ /* Set System Manager lwsoc bridge control register[lwsoc2fpga_ready_latency_enable] = 1 */
+ VERBOSE("Set LWSOC lwsoc2fpga_ready_latency_enable ...\n");
+ mmio_setbits_32(SOCFPGA_SYSMGR(FPGA_BRIDGE_CTRL),
+ SYSMGR_LWSOC_BRIDGE_CTRL_EN);
}
#else
if (brg_mask != 0U) {
@@ -580,9 +590,6 @@
/* Wait until idle ack becomes 0 */
ret_hps = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLEACK),
noc_mask, 0, 1000);
- if (ret_hps < 0) {
- ERROR("S2F bridge enable: Timeout idle ack\n");
- }
}
#endif
@@ -958,6 +965,11 @@
mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
RSTMGR_BRGMODRST_SOC2FPGA);
+ /* Clear System Manager soc bridge control register[soc2fpga_ready_latency_enable] = 1 */
+ VERBOSE("Clear SOC soc2fpga_ready_latency_enable ...\n");
+ mmio_clrbits_32(SOCFPGA_SYSMGR(FPGA_BRIDGE_CTRL),
+ SYSMGR_SOC_BRIDGE_CTRL_EN);
+
udelay(1000);
}
@@ -991,6 +1003,11 @@
mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
RSTMGR_BRGMODRST_LWHPS2FPGA);
+ /* Clear System Manager lwsoc bridge control register[lwsoc2fpga_ready_latency_enable] = 1 */
+ VERBOSE("Clear LWSOC lwsoc2fpga_ready_latency_enable ...\n");
+ mmio_clrbits_32(SOCFPGA_SYSMGR(FPGA_BRIDGE_CTRL),
+ SYSMGR_LWSOC_BRIDGE_CTRL_EN);
+
udelay(1000);
}
#else
@@ -1266,4 +1283,4 @@
} while (timeout-- > 0);
return RSTMGR_RET_ERROR;
-}
+}
\ No newline at end of file
diff --git a/plat/intel/soc/common/soc/socfpga_system_manager.c b/plat/intel/soc/common/soc/socfpga_system_manager.c
new file mode 100644
index 0000000..4223b2b
--- /dev/null
+++ b/plat/intel/soc/common/soc/socfpga_system_manager.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include "socfpga_system_manager.h"
+
+uint32_t intel_hps_get_jtag_id(void)
+{
+ uint32_t jtag_id = 0x00;
+
+ jtag_id = (mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_4)));
+
+ INFO("%s: JTAG ID: 0x%x\n", __func__, jtag_id);
+
+ return jtag_id;
+}
+
+/* Check for Agilex5 SM4 */
+bool is_agilex5_A5F0(void)
+{
+ return ((intel_hps_get_jtag_id() & JTAG_ID_MASK) == A5F0_JTAG_ID);
+}
diff --git a/plat/intel/soc/common/socfpga_delay_timer.c b/plat/intel/soc/common/socfpga_delay_timer.c
index db173a4..3759009 100644
--- a/plat/intel/soc/common/socfpga_delay_timer.c
+++ b/plat/intel/soc/common/socfpga_delay_timer.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,7 +11,6 @@
#include <lib/mmio.h>
#include "socfpga_plat_def.h"
-
#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX
#include "agilex_clock_manager.h"
#elif PLATFORM_MODEL == PLAT_SOCFPGA_N5X
@@ -19,7 +19,7 @@
#include "s10_clock_manager.h"
#endif
-#define SOCFPGA_GLOBAL_TIMER 0xffd01000
+#define SOCFPGA_GLOBAL_TIMER PLAT_TIMER_BASE_ADDR
#define SOCFPGA_GLOBAL_TIMER_EN 0x3
static timer_ops_t plat_timer_ops;
@@ -44,7 +44,6 @@
plat_timer_ops.clk_div = PLAT_SYS_COUNTER_FREQ_IN_MHZ;
timer_init(&plat_timer_ops);
-
}
void socfpga_delay_timer_init(void)
@@ -54,5 +53,4 @@
asm volatile("msr cntp_ctl_el0, %0" : : "r" (SOCFPGA_GLOBAL_TIMER_EN));
asm volatile("msr cntp_tval_el0, %0" : : "r" (~0));
-
}
diff --git a/plat/intel/soc/common/socfpga_image_load.c b/plat/intel/soc/common/socfpga_image_load.c
index a5c3279..ee79158 100644
--- a/plat/intel/soc/common/socfpga_image_load.c
+++ b/plat/intel/soc/common/socfpga_image_load.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,7 +13,13 @@
******************************************************************************/
void plat_flush_next_bl_params(void)
{
+ /*
+ * We cannot flush these descriptors on the Agilex5 platform,
+ * since the BL2 runs on the OCRAM and this OCRAM is not cache coherent.
+ */
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
flush_bl_params_desc();
+#endif
}
/*******************************************************************************
diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c
index 623843e..50d4820 100644
--- a/plat/intel/soc/common/socfpga_psci.c
+++ b/plat/intel/soc/common/socfpga_psci.c
@@ -17,8 +17,13 @@
#include <lib/mmio.h>
#include <lib/psci/psci.h>
#include <plat/common/platform.h>
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+#include "agilex5_cache.h"
+#endif
+#include "ccu/ncore_ccu.h"
#include "socfpga_mailbox.h"
#include "socfpga_plat_def.h"
+#include "socfpga_private.h"
#include "socfpga_reset_manager.h"
#include "socfpga_sip_svc.h"
#include "socfpga_system_manager.h"
@@ -190,6 +195,14 @@
if (intel_rsu_update_address) {
mailbox_rsu_update(addr_buf);
} else {
+#if CACHE_FLUSH
+ /* ATF Flush and Invalidate Cache */
+ dcsw_op_all(DCCISW);
+ invalidate_cache_low_el();
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+ flush_l3_dcache();
+#endif
+#endif
mailbox_reset_cold();
}
@@ -200,6 +213,16 @@
static int socfpga_system_reset2(int is_vendor, int reset_type,
u_register_t cookie)
{
+
+#if CACHE_FLUSH
+ /*
+ * ATF Flush and Invalidate Cache due to hardware limitation
+ * of auto Flush and Invalidate Cache.
+ */
+ dcsw_op_all(DCCISW);
+ invalidate_cache_low_el();
+#endif
+
#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
mailbox_reset_warm(reset_type);
#else
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index 5dfbc14..3c223c1 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -28,6 +28,9 @@
static uint32_t send_id, rcv_id;
static uint32_t bytes_per_block, blocks_submitted;
static bool bridge_disable;
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+static uint32_t g_remapper_bypass;
+#endif
/* RSU static variables */
static uint32_t rsu_dcmf_ver[4] = {0};
@@ -758,7 +761,7 @@
/* Read out Bit 1 value */
uint32_t remap = (mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_1)) & 0x02);
- if (remap == 0x00) {
+ if ((remap == 0x00) && (g_remapper_bypass == 0x00)) {
/* Update DRAM Base address for SDM SMMU */
mmio_write_32(SOCFPGA_SYSMGR(SDM_BE_ARADDR_REMAP), DRAM_BASE);
mmio_write_32(SOCFPGA_SYSMGR(SDM_BE_AWADDR_REMAP), DRAM_BASE);
@@ -766,6 +769,19 @@
} else {
*mem = *mem - DRAM_BASE;
}
+}
+
+int intel_smmu_hps_remapper_config(uint32_t remapper_bypass)
+{
+ /* Read out the JTAG-ID from boot scratch register */
+ if (is_agilex5_A5F0() != 0) {
+ if (remapper_bypass == 0x01) {
+ g_remapper_bypass = remapper_bypass;
+ mmio_write_32(SOCFPGA_SYSMGR(SDM_BE_ARADDR_REMAP), 0);
+ mmio_write_32(SOCFPGA_SYSMGR(SDM_BE_AWADDR_REMAP), 0);
+ }
+ }
+ return INTEL_SIP_SMC_STATUS_OK;
}
#endif
@@ -1291,6 +1307,12 @@
status = intel_fcs_aes_crypt_update_finalize(x1, x2, x3, x4,
x5, x6, true, &send_id);
SMC_RET1(handle, status);
+
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+ case INTEL_SIP_SMC_FCS_SDM_REMAPPER_CONFIG:
+ status = intel_smmu_hps_remapper_config(x1);
+ SMC_RET1(handle, status);
+#endif
case INTEL_SIP_SMC_GET_ROM_PATCH_SHA384:
status = intel_fcs_get_rom_patch_sha384(x1, &retval64,
diff --git a/plat/intel/soc/common/socfpga_storage.c b/plat/intel/soc/common/socfpga_storage.c
index d250d9e..66b5216 100644
--- a/plat/intel/soc/common/socfpga_storage.c
+++ b/plat/intel/soc/common/socfpga_storage.c
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,11 +28,6 @@
#include "socfpga_ros.h"
-#define PLAT_FIP_BASE (0)
-#define PLAT_FIP_MAX_SIZE (0x1000000)
-#define PLAT_MMC_DATA_BASE (0xffe3c000)
-#define PLAT_MMC_DATA_SIZE (0x2000)
-
static const io_dev_connector_t *fip_dev_con;
static const io_dev_connector_t *boot_dev_con;
diff --git a/plat/intel/soc/n5x/include/n5x_clock_manager.h b/plat/intel/soc/n5x/include/n5x_clock_manager.h
index 54477da..95a3d5c 100644
--- a/plat/intel/soc/n5x/include/n5x_clock_manager.h
+++ b/plat/intel/soc/n5x/include/n5x_clock_manager.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,7 +10,6 @@
/* MACRO DEFINITION */
-#define SOCFPGA_GLOBAL_TIMER 0xffd01000
#define SOCFPGA_GLOBAL_TIMER_EN 0x3
#define CLKMGR_PLLGLOB_VCO_PSRC_MASK GENMASK(17, 16)
diff --git a/plat/intel/soc/n5x/include/n5x_system_manager.h b/plat/intel/soc/n5x/include/n5x_system_manager.h
index 3610a6e..fd789a2 100644
--- a/plat/intel/soc/n5x/include/n5x_system_manager.h
+++ b/plat/intel/soc/n5x/include/n5x_system_manager.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -121,7 +122,7 @@
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_8 0x220
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_9 0x224
#define SOCFPGA_SYSMGR_MPFE_CONFIG 0x228
-#define SOCFPGA_SYSMGR_MPFE_status 0x22C
+#define SOCFPGA_SYSMGR_MPFE_STATUS 0x22C
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_0 0x230
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_1 0x234
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_2 0x238
diff --git a/plat/intel/soc/n5x/include/socfpga_plat_def.h b/plat/intel/soc/n5x/include/socfpga_plat_def.h
index 1eafeef..6f0a40b 100644
--- a/plat/intel/soc/n5x/include/socfpga_plat_def.h
+++ b/plat/intel/soc/n5x/include/socfpga_plat_def.h
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,10 +15,11 @@
/* Platform Setting */
#define PLATFORM_MODEL PLAT_SOCFPGA_N5X
-#define BOOT_SOURCE BOOT_SOURCE_SDMMC
#define PLAT_PRIMARY_CPU 0
#define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT MPIDR_AFF1_SHIFT
#define PLAT_CPU_ID_MPIDR_AFF_SHIFT MPIDR_AFF0_SHIFT
+#define PLAT_HANDOFF_OFFSET 0xFFE3F000
+#define PLAT_TIMER_BASE_ADDR 0xFFD01000
/* FPGA config helpers */
#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x400000
@@ -27,6 +29,15 @@
#define CAD_QSPIDATA_OFST 0xff900000
#define CAD_QSPI_OFFSET 0xff8d2000
+/* FIP Setting */
+#define PLAT_FIP_BASE (0)
+#define PLAT_FIP_MAX_SIZE (0x1000000)
+
+/* SDMMC Setting */
+#define PLAT_MMC_DATA_BASE (0xffe3c000)
+#define PLAT_MMC_DATA_SIZE (0x2000)
+#define SOCFPGA_MMC_BLOCK_SIZE U(8192)
+
/* Register Mapping */
#define SOCFPGA_CCU_NOC_REG_BASE U(0xf7000000)
#define SOCFPGA_F2SDRAMMGR_REG_BASE U(0xf8024000)
diff --git a/plat/intel/soc/n5x/platform.mk b/plat/intel/soc/n5x/platform.mk
index 29fd0eb..4770f8d 100644
--- a/plat/intel/soc/n5x/platform.mk
+++ b/plat/intel/soc/n5x/platform.mk
@@ -1,5 +1,6 @@
#
-# Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
+# Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+# Copyright (c) 2024, Altera Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -46,8 +47,30 @@
plat/intel/soc/common/soc/socfpga_mailbox.c \
plat/intel/soc/common/soc/socfpga_reset_manager.c
+# Don't have the Linux kernel as a BL33 image by default
+ARM_LINUX_KERNEL_AS_BL33 := 0
+$(eval $(call assert_boolean,ARM_LINUX_KERNEL_AS_BL33))
+$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
+# Configs for Boot Source
+SOCFPGA_BOOT_SOURCE_SDMMC ?= 0
+SOCFPGA_BOOT_SOURCE_QSPI ?= 0
+SOCFPGA_BOOT_SOURCE_NAND ?= 0
+
+$(eval $(call assert_booleans,\
+ $(sort \
+ SOCFPGA_BOOT_SOURCE_SDMMC \
+ SOCFPGA_BOOT_SOURCE_QSPI \
+ SOCFPGA_BOOT_SOURCE_NAND \
+)))
+$(eval $(call add_defines,\
+ $(sort \
+ SOCFPGA_BOOT_SOURCE_SDMMC \
+ SOCFPGA_BOOT_SOURCE_QSPI \
+ SOCFPGA_BOOT_SOURCE_NAND \
+)))
+
PROGRAMMABLE_RESET_ADDRESS := 0
RESET_TO_BL2 := 1
BL2_INV_DCACHE := 0
diff --git a/plat/intel/soc/stratix10/include/s10_memory_controller.h b/plat/intel/soc/stratix10/include/s10_memory_controller.h
index 155b279..056f6cf 100644
--- a/plat/intel/soc/stratix10/include/s10_memory_controller.h
+++ b/plat/intel/soc/stratix10/include/s10_memory_controller.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -26,7 +27,7 @@
#define S10_MPFE_HMC_ADP_ECCCTRL1 0xf8011100
#define S10_MPFE_HMC_ADP_ECCCTRL2 0xf8011104
#define S10_MPFE_HMC_ADP_RSTHANDSHAKESTAT 0xf8011218
-#define S10_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE 0x000000ff
+#define S10_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE 0x0000000f
#define S10_MPFE_HMC_ADP_RSTHANDSHAKECTRL 0xf8011214
diff --git a/plat/intel/soc/stratix10/include/s10_system_manager.h b/plat/intel/soc/stratix10/include/s10_system_manager.h
index e7bf730..dcc1517 100644
--- a/plat/intel/soc/stratix10/include/s10_system_manager.h
+++ b/plat/intel/soc/stratix10/include/s10_system_manager.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -120,7 +121,7 @@
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_8 0x220
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_9 0x224
#define SOCFPGA_SYSMGR_MPFE_CONFIG 0x228
-#define SOCFPGA_SYSMGR_MPFE_status 0x22C
+#define SOCFPGA_SYSMGR_MPFE_STATUS 0x22C
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_0 0x230
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_1 0x234
#define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_2 0x238
diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
index 7f452bd..90345c3 100644
--- a/plat/intel/soc/stratix10/include/socfpga_plat_def.h
+++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,10 +14,11 @@
/* Platform Setting */
#define PLATFORM_MODEL PLAT_SOCFPGA_STRATIX10
-#define BOOT_SOURCE BOOT_SOURCE_SDMMC
#define PLAT_PRIMARY_CPU 0
#define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT MPIDR_AFF1_SHIFT
#define PLAT_CPU_ID_MPIDR_AFF_SHIFT MPIDR_AFF0_SHIFT
+#define PLAT_HANDOFF_OFFSET 0xFFE3F000
+#define PLAT_TIMER_BASE_ADDR 0xFFD01000
/* FPGA config helpers */
#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x400000
@@ -26,6 +28,15 @@
#define CAD_QSPIDATA_OFST 0xff900000
#define CAD_QSPI_OFFSET 0xff8d2000
+/* FIP Setting */
+#define PLAT_FIP_BASE (0)
+#define PLAT_FIP_MAX_SIZE (0x1000000)
+
+/* SDMMC Setting */
+#define PLAT_MMC_DATA_BASE (0xffe3c000)
+#define PLAT_MMC_DATA_SIZE (0x2000)
+#define SOCFPGA_MMC_BLOCK_SIZE U(8192)
+
/* Register Mapping */
#define SOCFPGA_CCU_NOC_REG_BASE 0xf7000000
#define SOCFPGA_F2SDRAMMGR_REG_BASE U(0xf8024000)
diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk
index afcf514..4cd7032 100644
--- a/plat/intel/soc/stratix10/platform.mk
+++ b/plat/intel/soc/stratix10/platform.mk
@@ -1,6 +1,7 @@
#
# Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
-# Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+# Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+# Copyright (c) 2024, Altera Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -26,6 +27,7 @@
lib/xlat_tables/xlat_tables_common.c \
plat/intel/soc/common/aarch64/platform_common.c \
plat/intel/soc/common/aarch64/plat_helpers.S \
+ plat/intel/soc/common/drivers/ccu/ncore_ccu.c \
plat/intel/soc/common/socfpga_delay_timer.c \
plat/intel/soc/common/soc/socfpga_firewall.c
@@ -76,8 +78,30 @@
plat/intel/soc/common/soc/socfpga_mailbox.c \
plat/intel/soc/common/soc/socfpga_reset_manager.c
+# Don't have the Linux kernel as a BL33 image by default
+ARM_LINUX_KERNEL_AS_BL33 := 0
+$(eval $(call assert_boolean,ARM_LINUX_KERNEL_AS_BL33))
+$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
+# Configs for Boot Source
+SOCFPGA_BOOT_SOURCE_SDMMC ?= 0
+SOCFPGA_BOOT_SOURCE_QSPI ?= 0
+SOCFPGA_BOOT_SOURCE_NAND ?= 0
+
+$(eval $(call assert_booleans,\
+ $(sort \
+ SOCFPGA_BOOT_SOURCE_SDMMC \
+ SOCFPGA_BOOT_SOURCE_QSPI \
+ SOCFPGA_BOOT_SOURCE_NAND \
+)))
+$(eval $(call add_defines,\
+ $(sort \
+ SOCFPGA_BOOT_SOURCE_SDMMC \
+ SOCFPGA_BOOT_SOURCE_QSPI \
+ SOCFPGA_BOOT_SOURCE_NAND \
+)))
+
PROGRAMMABLE_RESET_ADDRESS := 0
RESET_TO_BL2 := 1
USE_COHERENT_MEM := 1
diff --git a/plat/mediatek/drivers/rng/mt8186/rng_plat.c b/plat/mediatek/drivers/rng/mt8186/rng_plat.c
new file mode 100644
index 0000000..691b923
--- /dev/null
+++ b/plat/mediatek/drivers/rng/mt8186/rng_plat.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/smccc.h>
+#include <lib/spinlock.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <services/trng_svc.h>
+#include <smccc_helpers.h>
+
+#include <mtk_mmap_pool.h>
+#include <mtk_sip_svc.h>
+#include "rng_plat.h"
+
+static spinlock_t rng_lock;
+
+static int trng_wait(uint32_t reg, uint32_t expected_value)
+{
+ uint64_t timeout = timeout_init_us(TRNG_TIME_OUT);
+ uint32_t value = 0;
+
+ do {
+ value = mmio_read_32(reg);
+ if ((value & expected_value) == expected_value)
+ return 0;
+
+ udelay(10);
+ } while (!timeout_elapsed(timeout));
+
+ return -ETIMEDOUT;
+}
+
+static int trng_write(uint32_t reg, uint32_t value,
+ uint32_t read_reg, uint32_t expected_value)
+{
+ int retry = MTK_TRNG_MAX_ROUND;
+ uint32_t read_value = 0;
+
+ do {
+ mmio_write_32(reg, value);
+
+ read_value = mmio_read_32(read_reg);
+ if ((read_value & value) == expected_value)
+ return 0;
+
+ udelay(10);
+ } while (--retry > 0);
+
+ return -ETIMEDOUT;
+}
+
+static uint32_t trng_prng(uint32_t *rand)
+{
+ int32_t ret = 0;
+ uint32_t seed[4] = {0};
+
+ if (rand == NULL)
+ return MTK_SIP_E_INVALID_PARAM;
+
+ /* ungate */
+ ret = trng_write(TRNG_PDN_CLR, TRNG_PDN_VALUE, TRNG_PDN_STATUS, 0);
+ if (ret) {
+ ERROR("%s: ungate fail\n", __func__);
+ return MTK_SIP_E_NOT_SUPPORTED;
+ }
+
+ /* read random data once and drop it */
+ seed[0] = mmio_read_32(TRNG_DATA);
+
+ /* enable von-neumann extractor */
+ mmio_setbits_32(TRNG_CONF, TRNG_CONF_VON_EN);
+
+ /* start */
+ mmio_setbits_32(TRNG_CTRL, TRNG_CTRL_START);
+
+ /* get seeds from trng */
+ for (int i = 0; i < ARRAY_SIZE(seed); i++) {
+ ret = trng_wait(TRNG_CTRL, TRNG_CTRL_RDY);
+ if (ret) {
+ ERROR("%s: trng NOT ready\n", __func__);
+ return MTK_SIP_E_NOT_SUPPORTED;
+ }
+
+ seed[i] = mmio_read_32(TRNG_DATA);
+ }
+
+ /* stop */
+ mmio_clrbits_32(TRNG_CTRL, TRNG_CTRL_START);
+
+ /* gate */
+ ret = trng_write(TRNG_PDN_SET, TRNG_PDN_VALUE, TRNG_PDN_STATUS, TRNG_PDN_VALUE);
+ if (ret) {
+ ERROR("%s: gate fail\n", __func__);
+ return MTK_SIP_E_NOT_SUPPORTED;
+ }
+
+ for (int i = 0; i < ARRAY_SIZE(seed); i++)
+ rand[i] = seed[i];
+
+ return 0;
+}
+
+static uint32_t get_true_rnd(uint32_t *val, uint32_t num)
+{
+ uint32_t rand[4] = {0};
+ uint32_t ret;
+
+ if (val == NULL || num > ARRAY_SIZE(rand))
+ return MTK_SIP_E_INVALID_PARAM;
+
+ spin_lock(&rng_lock);
+ ret = trng_prng(rand);
+ spin_unlock(&rng_lock);
+
+ for (int i = 0; i < num; i++)
+ val[i] = rand[i];
+
+ return ret;
+}
+
+/*
+ * plat_get_entropy - get 64-bit random number data which is used form
+ * atf early stage
+ * output - out: output 64-bit entropy combine with 2 32-bit random number
+ */
+bool plat_get_entropy(uint64_t *out)
+{
+ uint32_t entropy_pool[2] = {0};
+ uint32_t ret;
+
+ assert(out);
+ assert(!check_uptr_overflow((uintptr_t)out, sizeof(*out)));
+
+ /* Get 2 32-bits entropy */
+ ret = get_true_rnd(entropy_pool, ARRAY_SIZE(entropy_pool));
+ if (ret)
+ return false;
+
+ /* Output 8 bytes entropy combine with 2 32-bit random number. */
+ *out = ((uint64_t)entropy_pool[0] << 32) | entropy_pool[1];
+
+ return true;
+}
diff --git a/plat/mediatek/drivers/rng/mt8186/rng_plat.h b/plat/mediatek/drivers/rng/mt8186/rng_plat.h
new file mode 100644
index 0000000..ab22c45
--- /dev/null
+++ b/plat/mediatek/drivers/rng/mt8186/rng_plat.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RNG_PLAT_H
+#define RNG_PLAT_H
+
+#define TRNG_TIME_OUT 1000
+#define MTK_TRNG_MAX_ROUND 4
+
+/*******************************************************************************
+ * TRNG related constants
+ ******************************************************************************/
+#define TRNG_BASE_SIZE 0x1000
+#define TRNG_CTRL (TRNG_BASE + 0x0000)
+#define TRNG_TIME (TRNG_BASE + 0x0004)
+#define TRNG_DATA (TRNG_BASE + 0x0008)
+#define TRNG_CONF (TRNG_BASE + 0x000C)
+#define TRNG_CTRL_RDY 0x80000000
+#define TRNG_CTRL_START 0x00000001
+#define TRNG_CONF_VON_EN 0x00000020
+#define TRNG_PDN_BASE_SIZE 0x1000
+#define TRNG_PDN_SET (INFRACFG_AO_BASE + 0x0088)
+#define TRNG_PDN_CLR (INFRACFG_AO_BASE + 0x008C)
+#define TRNG_PDN_STATUS (INFRACFG_AO_BASE + 0x0094)
+#define TRNG_PDN_VALUE 0x200
+
+#endif /* RNG_PLAT_H */
diff --git a/plat/mediatek/drivers/rng/rng.c b/plat/mediatek/drivers/rng/rng.c
new file mode 100644
index 0000000..d611168
--- /dev/null
+++ b/plat/mediatek/drivers/rng/rng.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <lib/smccc.h>
+#include <plat/common/plat_trng.h>
+
+#include <mtk_sip_svc.h>
+
+DEFINE_SVC_UUID2(_plat_trng_uuid,
+ 0xf6b2c8d9, 0x1abb, 0x4d83, 0xb2, 0x3f,
+ 0x5c, 0x51, 0xb6, 0xef, 0xfc, 0xaf
+);
+uuid_t plat_trng_uuid;
+
+void plat_entropy_setup(void)
+{
+ uint64_t placeholder;
+
+ plat_trng_uuid = _plat_trng_uuid;
+
+ /* Initialise the entropy source and trigger RNG generation */
+ plat_get_entropy(&placeholder);
+}
diff --git a/plat/mediatek/drivers/rng/rules.mk b/plat/mediatek/drivers/rng/rules.mk
new file mode 100644
index 0000000..5bcd2cd
--- /dev/null
+++ b/plat/mediatek/drivers/rng/rules.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := rng
+
+PLAT_INCLUDES += -I${LOCAL_DIR}/${MTK_SOC}
+PLAT_INCLUDES += -I${LOCAL_DIR}
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/rng.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/${MTK_SOC}/rng_plat.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/mt8186/include/platform_def.h b/plat/mediatek/mt8186/include/platform_def.h
index 98b88bd..707f4a5 100644
--- a/plat/mediatek/mt8186/include/platform_def.h
+++ b/plat/mediatek/mt8186/include/platform_def.h
@@ -77,6 +77,11 @@
#define MSDC0_BASE (IO_PHYS + 0x01230000)
/*******************************************************************************
+ * TRNG related constants
+ ******************************************************************************/
+#define TRNG_BASE (IO_PHYS + 0x0020F000)
+
+/*******************************************************************************
* GIC-600 & interrupt handling related constants
******************************************************************************/
/* Base MTK_platform compatible GIC memory map */
diff --git a/plat/mediatek/mt8186/platform.mk b/plat/mediatek/mt8186/platform.mk
index 2bd2fb4..9c03340 100644
--- a/plat/mediatek/mt8186/platform.mk
+++ b/plat/mediatek/mt8186/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2021-2023, MediaTek Inc. All rights reserved.
+# Copyright (c) 2021-2024, MediaTek Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -7,6 +7,9 @@
MTK_PLAT := plat/mediatek
MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
+# True Random Number Generator firmware Interface
+TRNG_SUPPORT := 1
+
PLAT_INCLUDES := -I${MTK_PLAT}/common/ \
-I${MTK_PLAT}/drivers/cirq/ \
-I${MTK_PLAT}/drivers/gic600/ \
@@ -79,6 +82,11 @@
${MTK_PLAT_SOC}/plat_sip_calls.c \
${MTK_PLAT_SOC}/plat_topology.c
+ifeq (${TRNG_SUPPORT},1)
+BL31_SOURCES += ${MTK_PLAT}/drivers/rng/rng.c \
+ ${MTK_PLAT}/drivers/rng/${PLAT}/rng_plat.c
+endif
+
# Build SPM drivers
include ${MTK_PLAT_SOC}/drivers/spm/build.mk
diff --git a/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c b/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c
index 26bed29..7b867d8 100644
--- a/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c
+++ b/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c
@@ -97,7 +97,7 @@
/* PCI-e protect address(64MB) */
region_info.start = 0xC0000000ULL;
- region_info.end = 0xC3FF0000ULL;
+ region_info.end = 0xC3FFFFFFULL;
region_info.region = 1;
SET_ACCESS_PERMISSION(region_info.apc, 1,
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
@@ -108,7 +108,7 @@
/* SCP protect address */
region_info.start = 0x50000000ULL;
- region_info.end = 0x513F0000ULL;
+ region_info.end = 0x513FFFFFULL;
region_info.region = 2;
SET_ACCESS_PERMISSION(region_info.apc, 1,
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
@@ -117,21 +117,10 @@
NO_PROT, FORBIDDEN, FORBIDDEN, NO_PROT);
emi_mpu_set_protection(®ion_info);
- /* DSP protect address */
- region_info.start = 0x40000000ULL; /* dram base addr */
- region_info.end = 0x1FFFF0000ULL;
- region_info.region = 3;
- SET_ACCESS_PERMISSION(region_info.apc, 1,
- FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
- FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
- FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
- FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROT);
- emi_mpu_set_protection(®ion_info);
-
/* Forbidden All */
region_info.start = 0x40000000ULL; /* dram base addr */
- region_info.end = 0x1FFFF0000ULL;
- region_info.region = 4;
+ region_info.end = 0x1FFFFFFFFULL;
+ region_info.region = 3;
SET_ACCESS_PERMISSION(region_info.apc, 1,
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
diff --git a/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c b/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c
index b6e5a2d..8e4a675 100644
--- a/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c
+++ b/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c
@@ -118,7 +118,7 @@
/* SCP DRAM */
region_info.start = 0x50000000ULL;
- region_info.end = 0x51400000ULL;
+ region_info.end = 0x513FFFFFULL;
region_info.region = 2;
SET_ACCESS_PERMISSION(region_info.apc, 1,
FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
diff --git a/plat/rockchip/common/include/plat_macros.S b/plat/rockchip/common/include/plat_macros.S
index 691beeb..548e3d9 100644
--- a/plat/rockchip/common/include/plat_macros.S
+++ b/plat/rockchip/common/include/plat_macros.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -23,8 +23,8 @@
/* Registers common to both GICv2 and GICv3 */
gicd_pend_reg:
- .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n" \
- " Offset:\t\t\tvalue\n"
+ .ascii "gicd_ispendr regs (Offsets 0x200 - 0x278)\n" \
+ " Offset:\t\t\tvalue\n\0"
newline:
.asciz "\n"
spacer:
diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c
index 1aecece..644275e 100644
--- a/plat/st/common/stm32mp_fconf_io.c
+++ b/plat/st/common/stm32mp_fconf_io.c
@@ -77,7 +77,7 @@
#define DEFAULT_UUID_NUMBER U(7)
#ifdef __aarch64__
-#define BL31_UUID_NUMBER U(1)
+#define BL31_UUID_NUMBER U(2)
#else
#define BL31_UUID_NUMBER U(0)
#endif
@@ -115,6 +115,7 @@
{FW_CONFIG_ID, "fw_cfg_uuid"},
#ifdef __aarch64__
{BL31_IMAGE_ID, "bl31_uuid"},
+ {SOC_FW_CONFIG_ID, "soc_fw_cfg_uuid"},
#endif
{BL32_IMAGE_ID, "bl32_uuid"},
{BL32_EXTRA1_IMAGE_ID, "bl32_extra1_uuid"},
diff --git a/plat/st/stm32mp2/bl2_plat_setup.c b/plat/st/stm32mp2/bl2_plat_setup.c
index 345850b..2fabc41 100644
--- a/plat/st/stm32mp2/bl2_plat_setup.c
+++ b/plat/st/stm32mp2/bl2_plat_setup.c
@@ -280,6 +280,7 @@
unsigned int i;
const unsigned int image_ids[] = {
BL31_IMAGE_ID,
+ SOC_FW_CONFIG_ID,
BL32_IMAGE_ID,
BL33_IMAGE_ID,
HW_CONFIG_ID,
@@ -345,6 +346,7 @@
break;
case HW_CONFIG_ID:
+ case SOC_FW_CONFIG_ID:
break;
default:
diff --git a/plat/st/stm32mp2/bl31_plat_setup.c b/plat/st/stm32mp2/bl31_plat_setup.c
index dbf1371..586bfe8 100644
--- a/plat/st/stm32mp2/bl31_plat_setup.c
+++ b/plat/st/stm32mp2/bl31_plat_setup.c
@@ -8,12 +8,16 @@
#include <stdint.h>
#include <common/bl_common.h>
+#include <drivers/generic_delay_timer.h>
#include <drivers/st/stm32_console.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
#include <platform_def.h>
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
@@ -31,6 +35,12 @@
BL_CODE_END - BL_CODE_BASE,
MT_CODE | MT_SECURE);
+ /*
+ * Map soc_fw_config device tree with secure property, i.e. default region.
+ * DDR region definitions will be finalized at BL32 level.
+ */
+ mmap_add_region(arg1, arg1, STM32MP_SOC_FW_CONFIG_MAX_SIZE, MT_RO_DATA | MT_SECURE);
+
#if USE_COHERENT_MEM
/* Map coherent memory */
mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
@@ -40,6 +50,20 @@
configure_mmu();
+ ret = dt_open_and_check(arg1);
+ if (ret < 0) {
+ EARLY_ERROR("%s: failed to open DT (%d)\n", __func__, ret);
+ panic();
+ }
+
+ ret = stm32mp2_clk_init();
+ if (ret < 0) {
+ EARLY_ERROR("%s: failed init clocks (%d)\n", __func__, ret);
+ panic();
+ }
+
+ (void)stm32mp_uart_console_setup();
+
/*
* Map upper SYSRAM where bl_params_t are stored in BL2
*/
@@ -60,6 +84,31 @@
bl_params_node_t *bl_params = params_from_bl2->head;
while (bl_params != NULL) {
+ /*
+ * Copy BL33 entry point information.
+ * They are stored in Secure RAM, in BL2's address space.
+ */
+ if (bl_params->image_id == BL33_IMAGE_ID) {
+ bl33_image_ep_info = *bl_params->ep_info;
+ /*
+ * Check if hw_configuration is given to BL32 and
+ * share it to BL33
+ */
+ if (arg2 != 0U) {
+ bl33_image_ep_info.args.arg0 = 0U;
+ bl33_image_ep_info.args.arg1 = 0U;
+ bl33_image_ep_info.args.arg2 = arg2;
+ }
+ }
+
+ if (bl_params->image_id == BL32_IMAGE_ID) {
+ bl32_image_ep_info = *bl_params->ep_info;
+
+ if (arg2 != 0U) {
+ bl32_image_ep_info.args.arg3 = arg2;
+ }
+ }
+
bl_params = bl_params->next_params_info;
}
@@ -73,6 +122,9 @@
void bl31_plat_arch_setup(void)
{
+ generic_delay_timer_init();
+
+ stm32mp_gic_init();
}
void bl31_platform_setup(void)
@@ -81,5 +133,27 @@
entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
{
- return NULL;
+ entry_point_info_t *next_image_info = NULL;
+
+ assert(sec_state_is_valid(type));
+
+ switch (type) {
+ case NON_SECURE:
+ next_image_info = &bl33_image_ep_info;
+ break;
+
+ case SECURE:
+ next_image_info = &bl32_image_ep_info;
+ break;
+
+ default:
+ break;
+ }
+
+ /* None of the next images on ST platforms can have 0x0 as the entrypoint */
+ if ((next_image_info == NULL) || (next_image_info->pc == 0UL)) {
+ return NULL;
+ }
+
+ return next_image_info;
}
diff --git a/plat/st/stm32mp2/plat_bl2_mem_params_desc.c b/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
index ecad0b4..2513180 100644
--- a/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
+++ b/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
@@ -70,6 +70,21 @@
.next_handoff_image_id = BL32_IMAGE_ID,
},
+ /* Fill SoC FW config related information */
+ {
+ .image_id = SOC_FW_CONFIG_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t,
+ SECURE | NON_EXECUTABLE),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_SKIP_LOADING),
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+
/* Fill BL32 related information */
{
.image_id = BL32_IMAGE_ID,
diff --git a/plat/st/stm32mp2/platform.mk b/plat/st/stm32mp2/platform.mk
index c12e512..df1cacd 100644
--- a/plat/st/stm32mp2/platform.mk
+++ b/plat/st/stm32mp2/platform.mk
@@ -48,6 +48,8 @@
# Device tree
BL2_DTSI := stm32mp25-bl2.dtsi
FDT_SOURCES := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME)))
+BL31_DTSI := stm32mp25-bl31.dtsi
+FDT_SOURCES += $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl31.dts,$(DTB_FILE_NAME)))
# Macros and rules to build TF binary
STM32_TF_STM32 := $(addprefix ${BUILD_PLAT}/tf-a-, $(patsubst %.dtb,%.stm32,$(DTB_FILE_NAME)))
@@ -56,6 +58,7 @@
STM32MP_FW_CONFIG_NAME := $(patsubst %.dtb,%-fw-config.dtb,$(DTB_FILE_NAME))
STM32MP_FW_CONFIG := ${BUILD_PLAT}/fdts/$(STM32MP_FW_CONFIG_NAME)
+STM32MP_SOC_FW_CONFIG := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl31.dtb,$(DTB_FILE_NAME)))
ifeq (${STM32MP_DDR_FIP_IO_STORAGE},1)
STM32MP_DDR_FW_PATH ?= drivers/st/ddr/phy/firmware/bin/stm32mp2
STM32MP_DDR_FW_NAME := ${DDR_TYPE}_pmu_train.bin
@@ -64,6 +67,8 @@
FDT_SOURCES += $(addprefix fdts/, $(patsubst %.dtb,%.dts,$(STM32MP_FW_CONFIG_NAME)))
# Add the FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_FW_CONFIG},--fw-config))
+# Add the SOC_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_IMG,STM32MP_SOC_FW_CONFIG,--soc-fw-config))
ifeq (${STM32MP_DDR_FIP_IO_STORAGE},1)
# Add the FW_DDR to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_IMG,STM32MP_DDR_FW,--ddr-fw))
@@ -198,4 +203,11 @@
false; \
fi
+# Create DTB file for BL31
+${BUILD_PLAT}/fdts/%-bl31.dts: fdts/%.dts fdts/${BL31_DTSI} | $$(@D)/
+ @echo '#include "$(patsubst fdts/%,%,$<)"' > $@
+ @echo '#include "${BL31_DTSI}"' >> $@
+
+${BUILD_PLAT}/fdts/%-bl31.dtb: ${BUILD_PLAT}/fdts/%-bl31.dts
+
include plat/st/common/common_rules.mk
diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h
index 73116db..b441502 100644
--- a/plat/st/stm32mp2/stm32mp2_def.h
+++ b/plat/st/stm32mp2/stm32mp2_def.h
@@ -138,7 +138,11 @@
* MAX_MMAP_REGIONS is usually:
* BL stm32mp2_mmap size + mmap regions in *_plat_arch_setup
*/
+#if defined(IMAGE_BL31)
+#define MAX_MMAP_REGIONS 7
+#else
#define MAX_MMAP_REGIONS 6
+#endif
/* DTB initialization value */
#define STM32MP_BL2_DTB_SIZE U(0x00006000) /* 24 KB for DTB */
@@ -166,6 +170,7 @@
#define STM32MP_HW_CONFIG_BASE (STM32MP_BL33_BASE + \
STM32MP_BL33_MAX_SIZE)
#define STM32MP_HW_CONFIG_MAX_SIZE U(0x40000)
+#define STM32MP_SOC_FW_CONFIG_MAX_SIZE U(0x10000) /* 64kB for BL31 DT */
/*******************************************************************************
* STM32MP2 device/io map related constants (used for MMU)
diff --git a/plat/st/stm32mp2/stm32mp2_private.c b/plat/st/stm32mp2/stm32mp2_private.c
index 7ad974f..5be4c5a 100644
--- a/plat/st/stm32mp2/stm32mp2_private.c
+++ b/plat/st/stm32mp2/stm32mp2_private.c
@@ -117,6 +117,33 @@
return CK_BUS_GPIOA + (bank - GPIO_BANK_A);
}
+#if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
+/*
+ * UART Management
+ */
+static const uintptr_t stm32mp2_uart_addresses[STM32MP_NB_OF_UART] = {
+ USART1_BASE,
+ USART2_BASE,
+ USART3_BASE,
+ UART4_BASE,
+ UART5_BASE,
+ USART6_BASE,
+ UART7_BASE,
+ UART8_BASE,
+ UART9_BASE,
+};
+
+uintptr_t get_uart_address(uint32_t instance_nb)
+{
+ if ((instance_nb == 0U) ||
+ (instance_nb > STM32MP_NB_OF_UART)) {
+ return 0U;
+ }
+
+ return stm32mp2_uart_addresses[instance_nb - 1U];
+}
+#endif
+
uint32_t stm32mp_get_chip_version(void)
{
static uint32_t rev;
diff --git a/plat/xilinx/common/include/plat_console.h b/plat/xilinx/common/include/plat_console.h
index 0f8320e..fa6021d 100644
--- a/plat/xilinx/common/include/plat_console.h
+++ b/plat/xilinx/common/include/plat_console.h
@@ -8,18 +8,30 @@
#define PLAT_DT_UART_H
#define DT_UART_DCC_COMPAT "arm,dcc"
+#define DT_UART_CAD_COMPAT "xlnx,zynqmp-uart"
+#define DT_UART_PL011_COMPAT "arm,pl011"
-#if defined(PLAT_zynqmp)
-#define DT_UART_COMPAT "xlnx,zynqmp-uart"
-#else
-#define DT_UART_COMPAT "arm,pl011"
-#endif
+/* Default console type is either CADENCE0 or CADENCE1 or PL011_0 or PL011_1
+ * Debug console type is DCC
+ */
+#define CONSOLE_NONE 0
+#define CONSOLE_CDNS 1
+#define CONSOLE_PL011 2
+#define CONSOLE_DCC 3
+
+typedef struct console_hd {
+ uint32_t clk;
+ uint32_t baud_rate;
+ uintptr_t base;
+ uint32_t console_scope;
+ uint8_t console_type;
+} console_holder;
typedef struct dt_uart_info_s {
char compatible[30];
uintptr_t base;
uint32_t baud_rate;
- int32_t status;
+ uint8_t console_type;
} dt_uart_info_t;
void setup_console(void);
diff --git a/plat/xilinx/common/include/plat_xfer_list.h b/plat/xilinx/common/include/plat_xfer_list.h
new file mode 100644
index 0000000..cc79a2c
--- /dev/null
+++ b/plat/xilinx/common/include/plat_xfer_list.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_XFER_LIST_H
+#define PLAT_XFER_LIST_H
+
+#include <lib/transfer_list.h>
+
+int32_t transfer_list_populate_ep_info(entry_point_info_t *bl32,
+ entry_point_info_t *bl33);
+
+#endif /* PLAT_XFER_LIST_H */
diff --git a/plat/xilinx/common/ipi.c b/plat/xilinx/common/ipi.c
index 399d283..f69cc82 100644
--- a/plat/xilinx/common/ipi.c
+++ b/plat/xilinx/common/ipi.c
@@ -70,7 +70,7 @@
{
int ret = 1;
- if (remote >= ipi_total || local >= ipi_total) {
+ if ((remote >= ipi_total) || (local >= ipi_total)) {
ret = 0;
}
diff --git a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
index 6265928..0ea51f0 100644
--- a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
+++ b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
@@ -106,11 +106,11 @@
SMC_RET1(handle, 0);
case IPI_MAILBOX_STATUS_ENQUIRY:
{
- int32_t disable_irq;
+ int32_t disable_interrupt;
- disable_irq = (x3 & IPI_SMC_ENQUIRY_DIRQ_MASK) ? 1 : 0;
+ disable_interrupt = (x3 & IPI_SMC_ENQUIRY_DIRQ_MASK) ? 1 : 0;
ret = ipi_mb_enquire_status(ipi_local_id, ipi_remote_id);
- if ((ret & IPI_MB_STATUS_RECV_PENDING) && disable_irq)
+ if ((ret & IPI_MB_STATUS_RECV_PENDING) && disable_interrupt)
ipi_mb_disable_irq(ipi_local_id, ipi_remote_id);
SMC_RET1(handle, ret);
}
@@ -124,11 +124,11 @@
}
case IPI_MAILBOX_ACK:
{
- int32_t enable_irq;
+ int32_t enable_interrupt;
- enable_irq = (x3 & IPI_SMC_ACK_EIRQ_MASK) ? 1 : 0;
+ enable_interrupt = (x3 & IPI_SMC_ACK_EIRQ_MASK) ? 1 : 0;
ipi_mb_ack(ipi_local_id, ipi_remote_id);
- if (enable_irq)
+ if (enable_interrupt)
ipi_mb_enable_irq(ipi_local_id, ipi_remote_id);
SMC_RET1(handle, 0);
}
diff --git a/plat/xilinx/common/plat_console.c b/plat/xilinx/common/plat_console.c
index b84912a..681226f 100644
--- a/plat/xilinx/common/plat_console.c
+++ b/plat/xilinx/common/plat_console.c
@@ -23,9 +23,64 @@
#include <platform_def.h>
#include <plat_private.h>
-static console_t console;
+#if !(CONSOLE_IS(none))
+static console_t boot_console;
+static console_holder boot_hd_console;
+#if defined(CONSOLE_RUNTIME)
+static console_t runtime_console;
+static console_holder rt_hd_console;
+#endif
+
+#if ((CONSOLE_IS(dtb) || RT_CONSOLE_IS(dtb)) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+ (!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+ !IS_TFA_IN_OCM(BL31_BASE)))
+static dt_uart_info_t dt_uart_info;
+#endif
+
+/**
+ * register_console() - Registers the uart with console list.
+ * @consoleh: Console holder structure with UART base address,
+ * UART clock, UART buad rate, flags & console type
+ * @console: Pointer to the console information structure.
+ */
+static void register_console(const console_holder *consoleh, console_t *console)
+{
+ int32_t rc = 0;
+
+ switch (consoleh->console_type) {
+#if defined(PLAT_zynqmp)
+ case CONSOLE_CDNS:
+ rc = console_cdns_register(consoleh->base,
+ consoleh->clk,
+ consoleh->baud_rate,
+ console);
+ break;
+#else
+ case CONSOLE_PL011:
+ rc = console_pl011_register(consoleh->base,
+ consoleh->clk,
+ consoleh->baud_rate,
+ console);
+ break;
+#endif
+ case CONSOLE_DCC:
+ rc = console_dcc_register(console);
+ break;
+ default:
+ INFO("Invalid console type\n");
+ break;
+ }
-#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
+ if (rc == 0) {
+ panic();
+ }
+
+ console_set_scope(console, consoleh->console_scope);
+}
+
+#if ((CONSOLE_IS(dtb) || RT_CONSOLE_IS(dtb)) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+ (!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+ !IS_TFA_IN_OCM(BL31_BASE)))
/**
* get_baudrate() - Get the baudrate form DTB.
* @dtb: Address of the Device Tree Blob (DTB).
@@ -103,34 +158,56 @@
* @node: Node address in the device tree.
* @dtb: Address of the Device Tree Blob(DTB).
*
- * Return: On success, it returns 1; on failure, it returns an 0.
+ * Return: On success, it returns 0; on failure, it returns -1 or -FDT_ERR_NOTFOUND.
*/
-static uint32_t fdt_add_uart_info(dt_uart_info_t *info, int node, void *dtb)
+static int32_t fdt_add_uart_info(dt_uart_info_t *info, int node, void *dtb)
{
uintptr_t base_addr;
const char *com;
int32_t ret = 0;
+ uint32_t status;
com = fdt_getprop(dtb, node, "compatible", NULL);
if (com != NULL) {
strlcpy(info->compatible, com, sizeof(info->compatible));
} else {
ERROR("Compatible property not found in DTB node\n");
- ret = -FDT_ERR_NOTFOUND;
+ ret = -FDT_ERR_NOTFOUND;
goto error;
}
- ret = fdt_get_reg_props_by_index(dtb, node, 0, &base_addr, NULL);
- if (ret >= 0) {
- info->base = base_addr;
- } else {
- ERROR("Failed to retrieve base address. Error code: %d\n", ret);
- ret = -FDT_ERR_NOTFOUND;
+ status = get_node_status(dtb, node);
+ if (status == 0) {
+ ERROR("Uart node is disabled in DTB\n");
+ ret = -FDT_ERR_NOTFOUND;
goto error;
}
+ if (strncmp(info->compatible, DT_UART_DCC_COMPAT, strlen(DT_UART_DCC_COMPAT)) != 0) {
+ ret = fdt_get_reg_props_by_index(dtb, node, 0, &base_addr, NULL);
+ if (ret >= 0) {
+ info->base = base_addr;
+ } else {
+ ERROR("Failed to retrieve base address. Error code: %d\n", ret);
+ ret = -FDT_ERR_NOTFOUND;
+ goto error;
+ }
+
- info->status = get_node_status(dtb, node);
- info->baud_rate = get_baudrate(dtb);
+ info->baud_rate = get_baudrate(dtb);
+
+ if (strncmp(info->compatible, DT_UART_CAD_COMPAT,
+ strlen(DT_UART_CAD_COMPAT)) == 0) {
+ info->console_type = CONSOLE_CDNS;
+ } else if (strncmp(info->compatible, DT_UART_PL011_COMPAT,
+ strlen(DT_UART_PL011_COMPAT)) == 0) {
+ info->console_type = CONSOLE_PL011;
+ } else {
+ ERROR("Incompatible uart node in DTB\n");
+ ret = -FDT_ERR_NOTFOUND;
+ }
+ } else {
+ info->console_type = CONSOLE_DCC;
+ }
error:
return ret;
@@ -150,194 +227,87 @@
ret = is_valid_dtb(dtb);
if (ret < 0) {
ERROR("Invalid Device Tree at %p: error %d\n", dtb, ret);
- ret = -FDT_ERR_NOTFOUND;
goto error;
}
node = fdt_get_stdout_node_offset(dtb);
if (node < 0) {
ERROR("DT get stdout node failed : %d\n", node);
- ret = -FDT_ERR_NOTFOUND;
goto error;
}
ret = fdt_add_uart_info(info, node, dtb);
if (ret < 0) {
ERROR("Failed to add DT UART info: %d\n", ret);
- ret = -FDT_ERR_NOTFOUND;
- goto error;
- }
-
-error:
- return ret;
-}
-
-/**
- * check_fdt_uart_info() - Check early uart info with DTB uart info.
- * @info: Pointer to the UART information structure.
- *
- * Return: On success, it returns 0; on failure, it returns an error+reason.
- */
-static int32_t check_fdt_uart_info(dt_uart_info_t *info)
-{
- int32_t ret = 0;
-
- if (info->status == 0) {
- ret = -ENODEV;
- goto error;
- }
-
- if ((info->base == console.base) &&
- (info->baud_rate == UART_BAUDRATE) && !CONSOLE_IS(dcc)) {
- ret = -ENODEV;
goto error;
}
error:
return ret;
}
-
-/**
- * console_boot_end() - Unregister the console_t instance form the console list.
- * @boot_console: Pointer to the console information structure.
- */
-static void console_boot_end(console_t *boot_console)
-{
- if (CONSOLE_IS(dcc)) {
- console_dcc_unregister();
- } else {
- console_flush();
- (void)console_unregister(boot_console);
- }
-}
-
-/**
- * setup_runtime_console() - Registers the runtime uart with console list.
- * @clock: UART clock.
- * @info: Pointer to the UART information structure.
- */
-static void setup_runtime_console(uint32_t clock, dt_uart_info_t *info)
-{
- static console_t bl31_runtime_console;
- int32_t rc;
-
-#if defined(PLAT_zynqmp)
- rc = console_cdns_register(info->base,
- clock,
- info->baud_rate,
- &bl31_runtime_console);
-#else
- rc = console_pl011_register(info->base,
- clock,
- info->baud_rate,
- &bl31_runtime_console);
#endif
- if (rc == 0) {
- panic();
- }
-
- console_set_scope(&bl31_runtime_console,
- CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME |
- CONSOLE_FLAG_CRASH);
-}
-
-/**
- * runtime_console_init() - Initializes the run time console information.
- * @uart_info: Pointer to the UART information structure.
- * @bl31_boot_console: Pointer to the console information structure.
- * @clock: UART clock.
- *
- * Return: On success, it returns 0; on failure, it returns an error+reason;
- */
-static int32_t runtime_console_init(dt_uart_info_t *uart_info,
- console_t *bl31_boot_console,
- uint32_t clock)
+void setup_console(void)
{
- int32_t rc = 0;
+ /* This is hardcoded console setup just in case that DTB console fails */
+ boot_hd_console.base = (uintptr_t)UART_BASE;
+ boot_hd_console.baud_rate = (uint32_t)UART_BAUDRATE;
+ boot_hd_console.clk = get_uart_clk();
+ boot_hd_console.console_scope = CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH;
+ boot_hd_console.console_type = UART_TYPE;
- /* Parse UART information from Device Tree Blob (DTB) */
- rc = fdt_get_uart_info(uart_info);
- if (rc < 0) {
- rc = -FDT_ERR_NOTFOUND;
- goto error;
- }
+ /* For DT code decoding uncomment console registration below */
+ /* register_console(&boot_hd_console, &boot_console); */
- if (strncmp(uart_info->compatible, DT_UART_COMPAT,
- strlen(DT_UART_COMPAT)) == 0) {
-
- if (check_fdt_uart_info(uart_info) == 0) {
- setup_runtime_console(clock, uart_info);
- console_boot_end(bl31_boot_console);
- INFO("Runtime console setup\n");
- } else {
- INFO("Early console and DTB console are same\n");
+#if ((CONSOLE_IS(dtb) || RT_CONSOLE_IS(dtb)) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+ (!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+ !IS_TFA_IN_OCM(BL31_BASE)))
+ /* Parse DTB console for UART information */
+ if (fdt_get_uart_info(&dt_uart_info) == 0) {
+ if (CONSOLE_IS(dtb)) {
+ boot_hd_console.base = dt_uart_info.base;
+ boot_hd_console.baud_rate = dt_uart_info.baud_rate;
+ boot_hd_console.console_type = dt_uart_info.console_type;
}
- } else if (strncmp(uart_info->compatible, DT_UART_DCC_COMPAT,
- strlen(DT_UART_DCC_COMPAT)) == 0) {
- rc = console_dcc_register();
- if (rc == 0) {
- panic();
- }
- console_boot_end(bl31_boot_console);
} else {
- WARN("BL31: No console device found in DT.\n");
+ ERROR("Failed to initialize DT console or console node is disabled\n");
}
-
-error:
- return rc;
-}
#endif
-void setup_console(void)
-{
- int32_t rc;
- uint32_t uart_clk = get_uart_clk();
+ /* Initialize the boot console */
+ register_console(&boot_hd_console, &boot_console);
-#if defined(PLAT_zynqmp)
- if (CONSOLE_IS(cadence) || (CONSOLE_IS(cadence1))) {
- rc = console_cdns_register(UART_BASE,
- uart_clk,
- UART_BAUDRATE,
- &console);
- if (rc == 0) {
- panic();
- }
+ INFO("BL31: Early console setup\n");
- console_set_scope(&console, CONSOLE_FLAG_BOOT |
- CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
- }
+#ifdef CONSOLE_RUNTIME
+#if (RT_CONSOLE_IS(dtb) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+ (!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+ !IS_TFA_IN_OCM(BL31_BASE)))
+ rt_hd_console.base = dt_uart_info.base;
+ rt_hd_console.baud_rate = dt_uart_info.baud_rate;
+ rt_hd_console.console_type = dt_uart_info.console_type;
#else
- if (CONSOLE_IS(pl011) || (CONSOLE_IS(pl011_1))) {
- /* Initialize the console to provide early debug support */
- rc = console_pl011_register((uint32_t)UART_BASE,
- uart_clk,
- (uint32_t)UART_BAUDRATE,
- &console);
- if (rc == 0) {
- panic();
- }
-
- console_set_scope(&console, CONSOLE_FLAG_BOOT |
- CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
- }
+ rt_hd_console.base = (uintptr_t)RT_UART_BASE;
+ rt_hd_console.baud_rate = (uint32_t)UART_BAUDRATE;
+ rt_hd_console.console_type = RT_UART_TYPE;
#endif
- if (CONSOLE_IS(dcc)) {
- /* Initialize the dcc console for debug */
- rc = console_dcc_register();
- if (rc == 0) {
- panic();
- }
- }
- INFO("BL31: Early console setup\n");
-#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
- static dt_uart_info_t uart_info = {0};
+ if ((rt_hd_console.console_type == boot_hd_console.console_type) &&
+ (rt_hd_console.base == boot_hd_console.base)) {
+ console_set_scope(&boot_console,
+ CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH | CONSOLE_FLAG_RUNTIME);
+ INFO("Successfully initialized runtime console\n");
+ } else {
+ rt_hd_console.clk = get_uart_clk();
+ rt_hd_console.console_scope = CONSOLE_FLAG_RUNTIME;
- /* Initialize the runtime console using UART information from the DTB */
- rc = runtime_console_init(&uart_info, &console, uart_clk);
- if (rc < 0) {
- ERROR("Failed to initialize runtime console: %d\n", rc);
+ register_console(&rt_hd_console, &runtime_console);
+ INFO("Successfully initialized new runtime console\n");
}
#endif
}
+#else
+void setup_console(void)
+{
+}
+#endif
diff --git a/plat/xilinx/common/plat_startup.c b/plat/xilinx/common/plat_startup.c
index 5beb765..149ba2d 100644
--- a/plat/xilinx/common/plat_startup.c
+++ b/plat/xilinx/common/plat_startup.c
@@ -237,8 +237,8 @@
}
target_secure = get_xbl_ss(&HandoffParams->partition[i]);
- if (target_secure == XBL_FLAGS_SECURE &&
- target_el == XBL_FLAGS_EL2) {
+ if ((target_secure == XBL_FLAGS_SECURE) &&
+ (target_el == XBL_FLAGS_EL2)) {
WARN("BL31: invalid security state (%i) for exception level (%i)\n",
target_secure, target_el);
continue;
@@ -284,7 +284,7 @@
}
VERBOSE("Setting up %s entry point to:%" PRIx64 ", el:%x\n",
- target_secure == XBL_FLAGS_SECURE ? "BL32" : "BL33",
+ (target_secure == XBL_FLAGS_SECURE) ? "BL32" : "BL33",
HandoffParams->partition[i].entry_point,
target_el);
image->pc = HandoffParams->partition[i].entry_point;
diff --git a/plat/xilinx/common/plat_xfer_list.c b/plat/xilinx/common/plat_xfer_list.c
new file mode 100644
index 0000000..eae7ce4
--- /dev/null
+++ b/plat/xilinx/common/plat_xfer_list.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <stddef.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/transfer_list.h>
+
+/*
+ * FIXME: This address should come from firmware before TF-A runs
+ * Having this to make sure the transfer list functionality works
+ */
+#define FW_HANDOFF_BASE U(0x1200000)
+#define FW_HANDOFF_SIZE U(0x600000)
+
+static struct transfer_list_header *tl_hdr;
+
+int32_t transfer_list_populate_ep_info(entry_point_info_t *bl32,
+ entry_point_info_t *bl33)
+{
+ struct transfer_list_entry *te = NULL;
+ struct entry_point_info *ep;
+ int32_t ret;
+
+ tl_hdr = (struct transfer_list_header *)FW_HANDOFF_BASE;
+ ret = transfer_list_check_header(tl_hdr);
+ if ((ret == TL_OPS_ALL) || (ret == TL_OPS_RO)) {
+ transfer_list_dump(tl_hdr);
+ while ((te = transfer_list_next(tl_hdr, te)) != NULL) {
+ ep = transfer_list_entry_data(te);
+ if (te->tag_id == TL_TAG_EXEC_EP_INFO64) {
+ switch (GET_SECURITY_STATE(ep->h.attr)) {
+ case NON_SECURE:
+ *bl33 = *ep;
+ continue;
+ case SECURE:
+ *bl32 = *ep;
+ continue;
+ default:
+ ERROR("Unrecognized Image Security State %lu\n",
+ GET_SECURITY_STATE(ep->h.attr));
+ ret = TL_OPS_NON;
+ }
+ }
+ }
+ }
+ return ret;
+}
diff --git a/plat/xilinx/common/pm_service/pm_svc_main.c b/plat/xilinx/common/pm_service/pm_svc_main.c
index 861c5b3..afb9a96 100644
--- a/plat/xilinx/common/pm_service/pm_svc_main.c
+++ b/plat/xilinx/common/pm_service/pm_svc_main.c
@@ -478,9 +478,9 @@
* than other eemi calls.
*/
if (api_id == (uint32_t)PM_QUERY_DATA) {
- if ((pm_arg[0] == XPM_QID_CLOCK_GET_NAME ||
- pm_arg[0] == XPM_QID_PINCTRL_GET_FUNCTION_NAME) &&
- ret == PM_RET_SUCCESS) {
+ if (((pm_arg[0] == XPM_QID_CLOCK_GET_NAME) ||
+ (pm_arg[0] == XPM_QID_PINCTRL_GET_FUNCTION_NAME)) &&
+ (ret == PM_RET_SUCCESS)) {
SMC_RET2(handle, (uint64_t)buf[0] | ((uint64_t)buf[1] << 32U),
(uint64_t)buf[2] | ((uint64_t)buf[3] << 32U));
}
@@ -559,7 +559,7 @@
uint32_t security_flag = NON_SECURE_FLAG;
uint32_t api_id;
bool status = false, status_tmp = false;
- uint64_t x[4] = {x1, x2, x3, x4};
+ const uint64_t x[4] = {x1, x2, x3, x4};
/* Handle case where PM wasn't initialized properly */
if (pm_up == false) {
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index 58589ad..819a55b 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -76,7 +76,7 @@
uint64_t tfa_handoff_addr;
uint32_t payload[PAYLOAD_ARG_CNT], max_size = HANDOFF_PARAMS_MAX_SIZE;
enum pm_ret_status ret_status;
- uint64_t addr[HANDOFF_PARAMS_MAX_SIZE];
+ const uint64_t addr[HANDOFF_PARAMS_MAX_SIZE];
/*
* Do initial security configuration to allow DRAM/device access. On
@@ -131,7 +131,7 @@
enum xbl_handoff ret = xbl_handover(&bl32_image_ep_info,
&bl33_image_ep_info,
tfa_handoff_addr);
- if (ret == XBL_HANDOFF_NO_STRUCT || ret == XBL_HANDOFF_INVAL_STRUCT) {
+ if ((ret == XBL_HANDOFF_NO_STRUCT) || (ret == XBL_HANDOFF_INVAL_STRUCT)) {
bl31_set_default_config();
} else if (ret == XBL_HANDOFF_TOO_MANY_PARTS) {
ERROR("BL31: Error too many partitions %u\n", ret);
@@ -153,7 +153,7 @@
uint32_t i;
/* Validate 'handler' and 'id' parameters */
- if (handler == NULL || index >= MAX_INTR_EL3) {
+ if ((handler == NULL) || (index >= MAX_INTR_EL3)) {
return -EINVAL;
}
diff --git a/plat/xilinx/versal/include/versal_def.h b/plat/xilinx/versal/include/versal_def.h
index c50df7e..3a1c127 100644
--- a/plat/xilinx/versal/include/versal_def.h
+++ b/plat/xilinx/versal/include/versal_def.h
@@ -18,13 +18,24 @@
/* number of interrupt handlers. increase as required */
#define MAX_INTR_EL3 2
/* List all consoles */
+#define VERSAL_CONSOLE_ID_none 0
#define VERSAL_CONSOLE_ID_pl011 1
#define VERSAL_CONSOLE_ID_pl011_0 1
#define VERSAL_CONSOLE_ID_pl011_1 2
#define VERSAL_CONSOLE_ID_dcc 3
+#define VERSAL_CONSOLE_ID_dtb 4
#define CONSOLE_IS(con) (VERSAL_CONSOLE_ID_ ## con == VERSAL_CONSOLE)
+/* Runtime console */
+#define RT_CONSOLE_ID_pl011 1
+#define RT_CONSOLE_ID_pl011_0 1
+#define RT_CONSOLE_ID_pl011_1 2
+#define RT_CONSOLE_ID_dcc 3
+#define RT_CONSOLE_ID_dtb 4
+
+#define RT_CONSOLE_IS(con) (RT_CONSOLE_ID_ ## con == CONSOLE_RUNTIME)
+
/* List of platforms */
#define VERSAL_SILICON U(0)
#define VERSAL_SPP U(1)
@@ -63,14 +74,37 @@
#define VERSAL_UART0_BASE 0xFF000000
#define VERSAL_UART1_BASE 0xFF010000
-#if CONSOLE_IS(pl011) || CONSOLE_IS(dcc)
+#if CONSOLE_IS(pl011) || CONSOLE_IS(dtb)
# define UART_BASE VERSAL_UART0_BASE
+# define UART_TYPE CONSOLE_PL011
#elif CONSOLE_IS(pl011_1)
# define UART_BASE VERSAL_UART1_BASE
+# define UART_TYPE CONSOLE_PL011
+#elif CONSOLE_IS(dcc)
+# define UART_BASE 0x0
+# define UART_TYPE CONSOLE_DCC
+#elif CONSOLE_IS(none)
+# define UART_TYPE CONSOLE_NONE
#else
# error "invalid VERSAL_CONSOLE"
#endif
+/* Runtime console */
+#if defined(CONSOLE_RUNTIME)
+#if RT_CONSOLE_IS(pl011) || RT_CONSOLE_IS(dtb)
+# define RT_UART_BASE VERSAL_UART0_BASE
+# define RT_UART_TYPE CONSOLE_PL011
+#elif RT_CONSOLE_IS(pl011_1)
+# define RT_UART_BASE VERSAL_UART1_BASE
+# define RT_UART_TYPE CONSOLE_PL011
+#elif RT_CONSOLE_IS(dcc)
+# define RT_UART_BASE 0x0
+# define RT_UART_TYPE CONSOLE_DCC
+#else
+# error "invalid CONSOLE_RUNTIME"
+#endif
+#endif
+
/*******************************************************************************
* Platform related constants
******************************************************************************/
diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c
index 74c5bf3..d6d4e39 100644
--- a/plat/xilinx/versal/plat_psci.c
+++ b/plat/xilinx/versal/plat_psci.c
@@ -77,7 +77,7 @@
plat_versal_gic_save();
}
- state = target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE ?
+ state = (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) ?
PM_STATE_SUSPEND_TO_RAM : PM_STATE_CPU_IDLE;
/* Send request to PMC to suspend this core */
@@ -250,7 +250,7 @@
uint32_t pstate = psci_get_pstate_type(power_state);
- assert(req_state);
+ assert(req_state != NULL);
/* Sanity check the requested state */
if (pstate == PSTATE_TYPE_STANDBY) {
diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk
index e65800e..7c15be0 100644
--- a/plat/xilinx/versal/platform.mk
+++ b/plat/xilinx/versal/platform.mk
@@ -85,13 +85,27 @@
${XLAT_TABLES_LIB_SRCS}
VERSAL_CONSOLE ?= pl011
-ifeq (${VERSAL_CONSOLE}, $(filter ${VERSAL_CONSOLE},pl011 pl011_0 pl011_1 dcc))
+ifeq (${VERSAL_CONSOLE}, $(filter ${VERSAL_CONSOLE},pl011 pl011_0 pl011_1 dcc dtb none))
else
$(error "Please define VERSAL_CONSOLE")
endif
$(eval $(call add_define_val,VERSAL_CONSOLE,VERSAL_CONSOLE_ID_${VERSAL_CONSOLE}))
+# Runtime console in default console in DEBUG build
+ifeq ($(DEBUG), 1)
+CONSOLE_RUNTIME ?= pl011
+endif
+
+# Runtime console
+ifdef CONSOLE_RUNTIME
+ifeq (${CONSOLE_RUNTIME}, $(filter ${CONSOLE_RUNTIME},pl011 pl011_0 pl011_1 dcc dtb))
+$(eval $(call add_define_val,CONSOLE_RUNTIME,RT_CONSOLE_ID_${CONSOLE_RUNTIME}))
+else
+$(error "Please define CONSOLE_RUNTIME")
+endif
+endif
+
BL31_SOURCES += drivers/arm/cci/cci.c \
lib/cpus/aarch64/cortex_a72.S \
common/fdt_wrappers.c \
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index ebde49f..12d3e3b 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -179,7 +179,7 @@
uint32_t i;
/* Validate 'handler' and 'id' parameters */
- if (handler == NULL || index >= MAX_INTR_EL3) {
+ if ((handler == NULL) || (index >= MAX_INTR_EL3)) {
return -EINVAL;
}
diff --git a/plat/xilinx/versal_net/include/versal_net_def.h b/plat/xilinx/versal_net/include/versal_net_def.h
index e7d234b..5caf376 100644
--- a/plat/xilinx/versal_net/include/versal_net_def.h
+++ b/plat/xilinx/versal_net/include/versal_net_def.h
@@ -15,13 +15,24 @@
#define MAX_INTR_EL3 2
/* List all consoles */
+#define VERSAL_NET_CONSOLE_ID_none U(0)
#define VERSAL_NET_CONSOLE_ID_pl011 U(1)
#define VERSAL_NET_CONSOLE_ID_pl011_0 U(1)
#define VERSAL_NET_CONSOLE_ID_pl011_1 U(2)
#define VERSAL_NET_CONSOLE_ID_dcc U(3)
+#define VERSAL_NET_CONSOLE_ID_dtb U(4)
#define CONSOLE_IS(con) (VERSAL_NET_CONSOLE_ID_ ## con == VERSAL_NET_CONSOLE)
+/* Runtime console */
+#define RT_CONSOLE_ID_pl011 1
+#define RT_CONSOLE_ID_pl011_0 1
+#define RT_CONSOLE_ID_pl011_1 2
+#define RT_CONSOLE_ID_dcc 3
+#define RT_CONSOLE_ID_dtb 4
+
+#define RT_CONSOLE_IS(con) (RT_CONSOLE_ID_ ## con == CONSOLE_RUNTIME)
+
/* List all platforms */
#define VERSAL_NET_SILICON U(0)
#define VERSAL_NET_SPP U(1)
@@ -138,11 +149,35 @@
#define UART_BAUDRATE 115200
-#if CONSOLE_IS(pl011_1)
-#define UART_BASE VERSAL_NET_UART1_BASE
+#if CONSOLE_IS(pl011) || CONSOLE_IS(dtb)
+#define UART_BASE VERSAL_NET_UART0_BASE
+# define UART_TYPE CONSOLE_PL011
+#elif CONSOLE_IS(pl011_1)
+#define UART_BASE VERSAL_NET_UART1_BASE
+# define UART_TYPE CONSOLE_PL011
+#elif CONSOLE_IS(dcc)
+# define UART_BASE 0x0
+# define UART_TYPE CONSOLE_DCC
+#elif CONSOLE_IS(none)
+# define UART_TYPE CONSOLE_NONE
+#else
+# error "invalid VERSAL_NET_CONSOLE"
+#endif
+
+/* Runtime console */
+#if defined(CONSOLE_RUNTIME)
+#if RT_CONSOLE_IS(pl011) || RT_CONSOLE_IS(dtb)
+# define RT_UART_BASE VERSAL_NET_UART0_BASE
+# define RT_UART_TYPE CONSOLE_PL011
+#elif RT_CONSOLE_IS(pl011_1)
+# define RT_UART_BASE VERSAL_NET_UART1_BASE
+# define RT_UART_TYPE CONSOLE_PL011
+#elif RT_CONSOLE_IS(dcc)
+# define RT_UART_BASE 0x0
+# define RT_UART_TYPE CONSOLE_DCC
#else
-/* Default console is UART0 */
-#define UART_BASE VERSAL_NET_UART0_BASE
+# error "invalid CONSOLE_RUNTIME"
+#endif
#endif
/* Processor core device IDs */
diff --git a/plat/xilinx/versal_net/plat_psci_pm.c b/plat/xilinx/versal_net/plat_psci_pm.c
index fb2005d..e89af71 100644
--- a/plat/xilinx/versal_net/plat_psci_pm.c
+++ b/plat/xilinx/versal_net/plat_psci_pm.c
@@ -162,7 +162,7 @@
plat_arm_gic_save();
}
- state = target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE ?
+ state = (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) ?
PM_STATE_SUSPEND_TO_RAM : PM_STATE_CPU_IDLE;
/* Send request to PMC to suspend this core */
@@ -247,7 +247,7 @@
int32_t pstate = psci_get_pstate_type(power_state);
- assert(req_state);
+ assert(req_state != NULL);
/* Sanity check the requested state */
if (pstate == PSTATE_TYPE_STANDBY) {
diff --git a/plat/xilinx/versal_net/platform.mk b/plat/xilinx/versal_net/platform.mk
index 40e9206..9534118 100644
--- a/plat/xilinx/versal_net/platform.mk
+++ b/plat/xilinx/versal_net/platform.mk
@@ -60,7 +60,7 @@
HW_ASSISTED_COHERENCY := 1
VERSAL_NET_CONSOLE ?= pl011
-ifeq (${VERSAL_NET_CONSOLE}, $(filter ${VERSAL_NET_CONSOLE},pl011 pl011_0 pl011_1 dcc))
+ifeq (${VERSAL_NET_CONSOLE}, $(filter ${VERSAL_NET_CONSOLE},pl011 pl011_0 pl011_1 dcc dtb none))
else
$(error Please define VERSAL_NET_CONSOLE)
endif
@@ -71,6 +71,20 @@
$(eval $(call add_define,XILINX_OF_BOARD_DTB_ADDR))
endif
+# Runtime console in default console in DEBUG build
+ifeq ($(DEBUG), 1)
+CONSOLE_RUNTIME ?= pl011
+endif
+
+# Runtime console
+ifdef CONSOLE_RUNTIME
+ifeq (${CONSOLE_RUNTIME}, $(filter ${CONSOLE_RUNTIME},pl011 pl011_0 pl011_1 dcc dtb))
+$(eval $(call add_define_val,CONSOLE_RUNTIME,RT_CONSOLE_ID_${CONSOLE_RUNTIME}))
+else
+$(error "Please define CONSOLE_RUNTIME")
+endif
+endif
+
# enable assert() for release/debug builds
ENABLE_ASSERTIONS := 1
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index b0bd8a1..8b902c8 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -244,8 +244,8 @@
ver = chipid[1] >> ZYNQMP_EFUSE_IPDISABLE_SHIFT;
for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
- if (zynqmp_devices[i].id == id &&
- zynqmp_devices[i].ver == (ver & ZYNQMP_CSU_VERSION_MASK)) {
+ if ((zynqmp_devices[i].id == id) &&
+ (zynqmp_devices[i].ver == (ver & ZYNQMP_CSU_VERSION_MASK))) {
break;
}
}
@@ -299,8 +299,8 @@
tmp = id;
tmp &= ZYNQMP_CSU_IDCODE_XILINX_ID_MASK |
ZYNQMP_CSU_IDCODE_FAMILY_MASK;
- maskid = ZYNQMP_CSU_IDCODE_XILINX_ID << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT |
- ZYNQMP_CSU_IDCODE_FAMILY << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT;
+ maskid = (ZYNQMP_CSU_IDCODE_XILINX_ID << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT) |
+ (ZYNQMP_CSU_IDCODE_FAMILY << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT);
if (tmp != maskid) {
ERROR("Incorrect IDCODE 0x%x, maskid 0x%x\n", id, maskid);
return "UNKN";
@@ -348,7 +348,7 @@
{
uint32_t ver = zynqmp_get_silicon_ver();
uint32_t rtl = zynqmp_get_rtl_ver();
- char *label = "Unknown";
+ const char *label = "Unknown";
switch (ver) {
case ZYNQMP_CSU_VERSION_QEMU:
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index d715ce2..68485cf 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -10,13 +10,24 @@
#include <plat/arm/common/smccc_def.h>
#include <plat/common/common_def.h>
+#define ZYNQMP_CONSOLE_ID_none 0
#define ZYNQMP_CONSOLE_ID_cadence 1
#define ZYNQMP_CONSOLE_ID_cadence0 1
#define ZYNQMP_CONSOLE_ID_cadence1 2
#define ZYNQMP_CONSOLE_ID_dcc 3
+#define ZYNQMP_CONSOLE_ID_dtb 4
#define CONSOLE_IS(con) (ZYNQMP_CONSOLE_ID_ ## con == ZYNQMP_CONSOLE)
+/* Runtime console */
+#define RT_CONSOLE_ID_cadence 1
+#define RT_CONSOLE_ID_cadence0 1
+#define RT_CONSOLE_ID_cadence1 2
+#define RT_CONSOLE_ID_dcc 3
+#define RT_CONSOLE_ID_dtb 4
+
+#define RT_CONSOLE_IS(con) (RT_CONSOLE_ID_ ## con == CONSOLE_RUNTIME)
+
/* Default counter frequency */
#define ZYNQMP_DEFAULT_COUNTER_FREQ 0U
@@ -144,14 +155,38 @@
#define ZYNQMP_UART0_BASE U(0xFF000000)
#define ZYNQMP_UART1_BASE U(0xFF010000)
-#if CONSOLE_IS(cadence) || CONSOLE_IS(dcc)
+/* Boot console */
+#if CONSOLE_IS(cadence) || CONSOLE_IS(dtb)
# define UART_BASE ZYNQMP_UART0_BASE
+# define UART_TYPE CONSOLE_CDNS
#elif CONSOLE_IS(cadence1)
# define UART_BASE ZYNQMP_UART1_BASE
+# define UART_TYPE CONSOLE_CDNS
+#elif CONSOLE_IS(dcc)
+# define UART_BASE 0x0
+# define UART_TYPE CONSOLE_DCC
+#elif CONSOLE_IS(none)
+# define UART_TYPE CONSOLE_NONE
#else
# error "invalid ZYNQMP_CONSOLE"
#endif
+/* Runtime console */
+#if defined(CONSOLE_RUNTIME)
+#if RT_CONSOLE_IS(cadence) || RT_CONSOLE_IS(dtb)
+# define RT_UART_BASE ZYNQMP_UART0_BASE
+# define RT_UART_TYPE CONSOLE_CDNS
+#elif RT_CONSOLE_IS(cadence1)
+# define RT_UART_BASE ZYNQMP_UART1_BASE
+# define RT_UART_TYPE CONSOLE_CDNS
+#elif RT_CONSOLE_IS(dcc)
+# define RT_UART_BASE 0x0
+# define RT_UART_TYPE CONSOLE_DCC
+#else
+# error "invalid CONSOLE_RUNTIME"
+#endif
+#endif
+
/* Must be non zero */
#define UART_BAUDRATE 115200
diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c
index 1e7df05..526e215 100644
--- a/plat/xilinx/zynqmp/plat_psci.c
+++ b/plat/xilinx/zynqmp/plat_psci.c
@@ -105,7 +105,7 @@
VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
__func__, i, target_state->pwr_domain_state[i]);
- state = target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE ?
+ state = (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) ?
PM_STATE_SUSPEND_TO_RAM : PM_STATE_CPU_IDLE;
/* Send request to PMU to suspend this core */
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 9fdc649..5a86658 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -111,12 +111,26 @@
${XLAT_TABLES_LIB_SRCS}
ZYNQMP_CONSOLE ?= cadence
-ifeq (${ZYNQMP_CONSOLE}, $(filter ${ZYNQMP_CONSOLE},cadence cadence0 cadence1 dcc))
+ifeq (${ZYNQMP_CONSOLE}, $(filter ${ZYNQMP_CONSOLE},cadence cadence0 cadence1 dcc dtb none))
else
$(error "Please define ZYNQMP_CONSOLE")
endif
$(eval $(call add_define_val,ZYNQMP_CONSOLE,ZYNQMP_CONSOLE_ID_${ZYNQMP_CONSOLE}))
+# Runtime console in default console in DEBUG build
+ifeq ($(DEBUG), 1)
+CONSOLE_RUNTIME ?= cadence
+endif
+
+# Runtime console
+ifdef CONSOLE_RUNTIME
+ifeq (${CONSOLE_RUNTIME}, $(filter ${CONSOLE_RUNTIME},cadence cadence0 cadence1 dcc dtb))
+$(eval $(call add_define_val,CONSOLE_RUNTIME,RT_CONSOLE_ID_${CONSOLE_RUNTIME}))
+else
+$(error "Please define CONSOLE_RUNTIME")
+endif
+endif
+
# Build PM code as a Library
include plat/xilinx/zynqmp/libpm.mk
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index 9682e59..ee4f07d 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -1226,7 +1226,7 @@
.control_reg = CRF_APB_ACPU_CTRL,
.status_reg = 0,
.parents = &((int32_t []) {
- CLK_ACPU | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+ (CLK_ACPU | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
CLK_NA_PARENT
}),
.nodes = &acpu_full_nodes,
@@ -2117,7 +2117,7 @@
.control_reg = CRF_APB_ACPU_CTRL,
.status_reg = 0,
.parents = &((int32_t []) {
- CLK_ACPU | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+ (CLK_ACPU | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
CLK_NA_PARENT
}),
.nodes = &acpu_half_nodes,
@@ -2140,7 +2140,7 @@
.control_reg = CRF_APB_GPU_REF_CTRL,
.status_reg = 0,
.parents = &((int32_t []) {
- CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+ (CLK_GPU_REF | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
CLK_NA_PARENT
}),
.nodes = &gpu_pp0_nodes,
@@ -2151,7 +2151,7 @@
.control_reg = CRF_APB_GPU_REF_CTRL,
.status_reg = 0,
.parents = &((int32_t []) {
- CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+ (CLK_GPU_REF | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
CLK_NA_PARENT
}),
.nodes = &gpu_pp1_nodes,
@@ -2176,7 +2176,7 @@
.control_reg = CRL_APB_CPU_R5_CTRL,
.status_reg = 0,
.parents = &((int32_t []) {
- CLK_CPU_R5 | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+ (CLK_CPU_R5 | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
CLK_DUMMY_PARENT,
CLK_NA_PARENT
}),
@@ -2456,8 +2456,8 @@
void pm_api_clock_get_name(uint32_t clock_id, char *name)
{
if (clock_id == CLK_MAX) {
- memcpy(name, END_OF_CLK, sizeof(END_OF_CLK) > CLK_NAME_LEN ?
- CLK_NAME_LEN : sizeof(END_OF_CLK));
+ memcpy(name, END_OF_CLK, ((sizeof(END_OF_CLK) > CLK_NAME_LEN) ?
+ CLK_NAME_LEN : sizeof(END_OF_CLK)));
} else if ((clock_id > CLK_MAX) || (!pm_clock_valid(clock_id))) {
memset(name, 0, CLK_NAME_LEN);
} else if (clock_id < CLK_MAX_OUTPUT_CLK) {
@@ -2486,7 +2486,7 @@
uint32_t index,
uint32_t *topology)
{
- struct pm_clock_node *clock_nodes;
+ const struct pm_clock_node *clock_nodes;
uint8_t num_nodes;
uint32_t i;
uint16_t typeflags;
@@ -2543,7 +2543,7 @@
uint32_t *mul,
uint32_t *div)
{
- struct pm_clock_node *clock_nodes;
+ const struct pm_clock_node *clock_nodes;
uint8_t num_nodes;
uint32_t type, i;
@@ -2598,7 +2598,7 @@
uint32_t *parents)
{
uint32_t i;
- int32_t *clk_parents;
+ const int32_t *clk_parents;
if (!pm_clock_valid(clock_id)) {
return PM_RET_ERROR_ARGS;
@@ -2675,7 +2675,7 @@
uint32_t *max_div)
{
uint32_t i;
- struct pm_clock_node *nodes;
+ const struct pm_clock_node *nodes;
if (clock_id >= CLK_MAX_OUTPUT_CLK) {
return PM_RET_ERROR_ARGS;
@@ -2789,9 +2789,9 @@
enum pm_ret_status pm_clock_get_pll_node_id(enum clock_id clock_id,
enum pm_node_id *node_id)
{
- struct pm_pll *pll = pm_clock_get_pll(clock_id);
+ const struct pm_pll *pll = pm_clock_get_pll(clock_id);
- if (pll) {
+ if (pll != NULL) {
*node_id = pll->nid;
return PM_RET_SUCCESS;
}
@@ -2812,10 +2812,10 @@
uint32_t i;
for (i = 0; i < ARRAY_SIZE(pm_plls); i++) {
- if (pm_plls[i].pre_src == clock_id ||
- pm_plls[i].post_src == clock_id ||
- pm_plls[i].div2 == clock_id ||
- pm_plls[i].bypass == clock_id) {
+ if ((pm_plls[i].pre_src == clock_id) ||
+ (pm_plls[i].post_src == clock_id) ||
+ (pm_plls[i].div2 == clock_id) ||
+ (pm_plls[i].bypass == clock_id)) {
return &pm_plls[i];
}
}
@@ -2883,7 +2883,7 @@
enum pm_ret_status status;
enum pm_pll_mode mode;
- if ((pll == NULL) || !state) {
+ if ((pll == NULL) || (state == NULL)) {
return PM_RET_ERROR_ARGS;
}
@@ -2990,7 +2990,7 @@
{
struct pm_pll *pll = pm_clock_get_pll(clock_id);
- if ((pll == NULL) || (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE)) {
+ if ((pll == NULL) || ((mode != PLL_FRAC_MODE) && (mode != PLL_INT_MODE))) {
return PM_RET_ERROR_ARGS;
}
pll->mode = mode;
@@ -3011,9 +3011,9 @@
enum pm_ret_status pm_clock_get_pll_mode(enum clock_id clock_id,
uint32_t *mode)
{
- struct pm_pll *pll = pm_clock_get_pll(clock_id);
+ const struct pm_pll *pll = pm_clock_get_pll(clock_id);
- if ((pll == NULL) || !mode) {
+ if ((pll == NULL) || (mode == NULL)) {
return PM_RET_ERROR_ARGS;
}
*mode = pll->mode;
@@ -3052,7 +3052,7 @@
uint8_t pm_clock_has_div(uint32_t clock_id, enum pm_clock_div_id div_id)
{
uint32_t i;
- struct pm_clock_node *nodes;
+ const struct pm_clock_node *nodes;
if (clock_id >= CLK_MAX_OUTPUT_CLK) {
return 0;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index dd21499..aea607c 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -165,8 +165,8 @@
static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(uint32_t type,
uint32_t value)
{
- if ((value != PM_TAPDELAY_BYPASS_ENABLE &&
- value != PM_TAPDELAY_BYPASS_DISABLE) || type >= PM_TAPDELAY_MAX) {
+ if ((((value != PM_TAPDELAY_BYPASS_ENABLE) &&
+ (value != PM_TAPDELAY_BYPASS_DISABLE)) || (type >= PM_TAPDELAY_MAX))) {
return PM_RET_ERROR_ARGS;
}
@@ -481,7 +481,7 @@
uint32_t value)
{
uint32_t mask;
- uint32_t regarr[] = {0xFD360000U,
+ const uint32_t regarr[] = {0xFD360000U,
0xFD360014U,
0xFD370000U,
0xFD370014U,
@@ -682,7 +682,7 @@
*/
enum pm_ret_status tfa_ioctl_bitmask(uint32_t *bit_mask)
{
- uint8_t supported_ids[] = {
+ const uint8_t supported_ids[] = {
IOCTL_GET_RPU_OPER_MODE,
IOCTL_SET_RPU_OPER_MODE,
IOCTL_RPU_BOOT_ADDR_CONFIG,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
index 2d8c23b..b34369b 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
@@ -2088,7 +2088,7 @@
uint16_t *groups)
{
uint32_t i;
- uint16_t *grps;
+ const uint16_t *grps;
if (pin >= MAX_PIN) {
return PM_RET_ERROR_ARGS;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c
index 9d0e2c4..716ebb6 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_client.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_client.c
@@ -218,7 +218,7 @@
node = irq_to_pm_node(irq);
reg &= ~lowest_set;
- if (node > NODE_UNKNOWN && node < NODE_MAX) {
+ if ((node > NODE_UNKNOWN) && (node < NODE_MAX)) {
if (pm_wakeup_nodes_set[node] == 0U) {
ret = pm_set_wakeup_source(NODE_APU, node, 1U);
pm_wakeup_nodes_set[node] = (ret == PM_RET_SUCCESS) ? 1U : 0U;
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
index daf3e61..5456689 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
@@ -1150,7 +1150,7 @@
/* First try to handle it as a PLL */
pll = pm_clock_get_pll(clock_id);
- if (pll) {
+ if (pll != NULL) {
return pm_clock_pll_enable(pll);
}
@@ -1175,7 +1175,7 @@
/* First try to handle it as a PLL */
pll = pm_clock_get_pll(clock_id);
- if (pll) {
+ if (pll != NULL) {
return pm_clock_pll_disable(pll);
}
@@ -1203,9 +1203,9 @@
/* First try to handle it as a PLL */
pll = pm_clock_get_pll(clock_id);
- if (pll)
+ if (pll != NULL) {
return pm_clock_pll_get_state(pll, state);
-
+ }
/* Check if clock ID is a valid on-chip clock */
status = pm_clock_id_is_valid(clock_id);
if (status != PM_RET_SUCCESS) {
@@ -1341,7 +1341,7 @@
/* First try to handle it as a PLL */
pll = pm_clock_get_pll_by_related_clk(clock_id);
- if (pll) {
+ if (pll != NULL) {
return pm_clock_pll_set_parent(pll, clock_id, parent_index);
}
@@ -1376,7 +1376,7 @@
/* First try to handle it as a PLL */
pll = pm_clock_get_pll_by_related_clk(clock_id);
- if (pll) {
+ if (pll != NULL) {
return pm_clock_pll_get_parent(pll, clock_id, parent_index);
}
@@ -1657,7 +1657,7 @@
uint32_t payload[PAYLOAD_ARG_CNT];
/* Check if given node ID is a PLL node */
- if (nid < NODE_APLL || nid > NODE_IOPLL) {
+ if ((nid < NODE_APLL) || (nid > NODE_IOPLL)) {
return PM_RET_ERROR_ARGS;
}
@@ -1688,7 +1688,7 @@
uint32_t payload[PAYLOAD_ARG_CNT];
/* Check if given node ID is a PLL node */
- if (nid < NODE_APLL || nid > NODE_IOPLL) {
+ if ((nid < NODE_APLL) || (nid > NODE_IOPLL)) {
return PM_RET_ERROR_ARGS;
}
@@ -1721,7 +1721,7 @@
uint32_t payload[PAYLOAD_ARG_CNT];
/* Check if given node ID is a PLL node */
- if (nid < NODE_APLL || nid > NODE_IOPLL) {
+ if ((nid < NODE_APLL) || (nid > NODE_IOPLL)) {
return PM_RET_ERROR_ARGS;
}
@@ -1749,7 +1749,7 @@
uint32_t payload[PAYLOAD_ARG_CNT];
/* Check if given node ID is a PLL node */
- if (nid < NODE_APLL || nid > NODE_IOPLL) {
+ if ((nid < NODE_APLL) || (nid > NODE_IOPLL)) {
return PM_RET_ERROR_ARGS;
}
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
index 65b2426..b3215f8 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
@@ -374,7 +374,7 @@
uint32_t value = 0U;
ret = pm_fpga_get_status(&value);
- SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+ SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32)));
}
case PM_SECURE_RSA_AES:
@@ -389,15 +389,15 @@
}
SMC_RET2(handle,
- (uint64_t)result[0] | ((uint64_t)result[1] << 32),
- (uint64_t)result[2] | ((uint64_t)result[3] << 32));
+ ((uint64_t)result[0] | ((uint64_t)result[1] << 32)),
+ ((uint64_t)result[2] | ((uint64_t)result[3] << 32)));
case PM_IOCTL:
{
uint32_t value = 0U;
ret = pm_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
pm_arg[3], &value);
- SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+ SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32)));
}
case PM_QUERY_DATA:
@@ -406,8 +406,8 @@
pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
pm_arg[3], data);
- SMC_RET2(handle, (uint64_t)data[0] | ((uint64_t)data[1] << 32),
- (uint64_t)data[2] | ((uint64_t)data[3] << 32));
+ SMC_RET2(handle, ((uint64_t)data[0] | ((uint64_t)data[1] << 32)),
+ ((uint64_t)data[2] | ((uint64_t)data[3] << 32)));
}
case PM_CLOCK_ENABLE:
@@ -423,7 +423,7 @@
uint32_t value = 0U;
ret = pm_clock_getstate(pm_arg[0], &value);
- SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+ SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32)));
}
case PM_CLOCK_SETDIVIDER:
@@ -435,7 +435,7 @@
uint32_t value = 0U;
ret = pm_clock_getdivider(pm_arg[0], &value);
- SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+ SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32)));
}
case PM_CLOCK_SETPARENT:
@@ -447,7 +447,7 @@
uint32_t value = 0U;
ret = pm_clock_getparent(pm_arg[0], &value);
- SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
+ SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32U)));
}
case PM_GET_TRUSTZONE_VERSION:
@@ -472,7 +472,7 @@
{
ret = pm_secure_image(pm_arg[0], pm_arg[1], pm_arg[2],
pm_arg[3], &result[0]);
- SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U),
+ SMC_RET2(handle, ((uint64_t)ret | ((uint64_t)result[0] << 32U)),
result[1]);
}
@@ -482,7 +482,7 @@
ret = pm_fpga_read(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3],
&value);
- SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
+ SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32U)));
}
case PM_SECURE_AES:
@@ -490,7 +490,7 @@
uint32_t value = 0U;
ret = pm_aes_engine(pm_arg[0], pm_arg[1], &value);
- SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
+ SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32U)));
}
case PM_PLL_SET_PARAMETER:
@@ -502,7 +502,7 @@
uint32_t value = 0U;
ret = pm_pll_get_parameter(pm_arg[0], pm_arg[1], &value);
- SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value << 32U));
+ SMC_RET1(handle, ((uint64_t)ret | ((uint64_t)value << 32U)));
}
case PM_PLL_SET_MODE:
@@ -514,7 +514,7 @@
uint32_t mode = 0U;
ret = pm_pll_get_mode(pm_arg[0], &mode);
- SMC_RET1(handle, (uint64_t)ret | ((uint64_t)mode << 32U));
+ SMC_RET1(handle, ((uint64_t)ret | ((uint64_t)mode << 32U)));
}
case PM_REGISTER_ACCESS:
@@ -523,7 +523,7 @@
ret = pm_register_access(pm_arg[0], pm_arg[1], pm_arg[2],
pm_arg[3], &value);
- SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
+ SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32U)));
}
case PM_EFUSE_ACCESS:
@@ -538,7 +538,7 @@
}
#endif
ret = pm_efuse_access(pm_arg[0], pm_arg[1], &value);
- SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
+ SMC_RET1(handle, (uint64_t)ret | (((uint64_t)value) << 32U));
}
case PM_FPGA_GET_VERSION:
@@ -549,8 +549,8 @@
PM_PACK_PAYLOAD5(payload, smc_fid & FUNCID_NUM_MASK,
pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]);
ret = pm_ipi_send_sync(primary_proc, payload, ret_payload, 3U);
- SMC_RET2(handle, (uint64_t)ret | (uint64_t)ret_payload[0] << 32U,
- (uint64_t)ret_payload[1] | (uint64_t)ret_payload[2] << 32U);
+ SMC_RET2(handle, ((uint64_t)ret | ((uint64_t)ret_payload[0] << 32U)),
+ ((uint64_t)ret_payload[1] | ((uint64_t)ret_payload[2] << 32U)));
}
case PM_FEATURE_CHECK:
@@ -560,8 +560,8 @@
ret = pm_feature_check(pm_arg[0], &version, bit_mask,
ARRAY_SIZE(bit_mask));
- SMC_RET2(handle, (uint64_t)ret | ((uint64_t)version << 32U),
- (uint64_t)bit_mask[0] | ((uint64_t)bit_mask[1] << 32U));
+ SMC_RET2(handle, ((uint64_t)ret | ((uint64_t)version << 32U)),
+ ((uint64_t)bit_mask[0] | ((uint64_t)bit_mask[1] << 32U)));
}
default:
@@ -570,7 +570,7 @@
pm_arg[2], pm_arg[3], pm_arg[4]);
ret = pm_ipi_send_sync(primary_proc, payload, result,
RET_PAYLOAD_ARG_CNT);
- SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U),
- (uint64_t)result[1] | ((uint64_t)result[2] << 32U));
+ SMC_RET2(handle, ((uint64_t)ret | ((uint64_t)result[0] << 32U)),
+ ((uint64_t)result[1] | ((uint64_t)result[2] << 32U)));
}
}
diff --git a/services/spd/tlkd/tlkd.mk b/services/spd/tlkd/tlkd.mk
index 56de0a6..fc8840d 100644
--- a/services/spd/tlkd/tlkd.mk
+++ b/services/spd/tlkd/tlkd.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -8,7 +8,9 @@
SPD_INCLUDES := -Iinclude/bl32/payloads
endif
+ifeq (${ENABLE_FEAT_D128}, 0)
SPD_SOURCES := services/spd/tlkd/tlkd_common.c \
services/spd/tlkd/tlkd_helpers.S \
services/spd/tlkd/tlkd_main.c \
services/spd/tlkd/tlkd_pm.c
+endif
\ No newline at end of file
diff --git a/services/std_svc/rmmd/rmmd_attest.c b/services/std_svc/rmmd/rmmd_attest.c
index f73236c..7d4ea70 100644
--- a/services/std_svc/rmmd/rmmd_attest.c
+++ b/services/std_svc/rmmd/rmmd_attest.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2024, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,7 +13,8 @@
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
#include "rmmd_private.h"
-#include <services/rmmd_svc.h>
+#include <services/rmm_el3_token_sign.h>
+#include <smccc_helpers.h>
static spinlock_t lock;
@@ -156,10 +158,110 @@
(unsigned int)ecc_curve);
if (err != 0) {
ERROR("Failed to get attestation key: %d.\n", err);
- err = E_RMM_UNK;
+ err = E_RMM_UNK;
}
spin_unlock(&lock);
return err;
}
+
+static int rmmd_el3_token_sign_push_req(uint64_t buf_pa, uint64_t buf_size)
+{
+ int err;
+
+ err = validate_buffer_params(buf_pa, buf_size);
+ if (err != 0) {
+ return err;
+ }
+
+ if (buf_size < sizeof(struct el3_token_sign_request)) {
+ return E_RMM_INVAL;
+ }
+
+ spin_lock(&lock);
+
+ /* Call platform port to handle attestation toekn signing request. */
+ err = plat_rmmd_el3_token_sign_push_req((struct el3_token_sign_request *)buf_pa);
+
+ spin_unlock(&lock);
+
+ return err;
+}
+
+static int rmmd_el3_token_sign_pull_resp(uint64_t buf_pa, uint64_t buf_size)
+{
+ int err;
+
+ err = validate_buffer_params(buf_pa, buf_size);
+ if (err != 0) {
+ return err;
+ }
+
+
+ if (buf_size < sizeof(struct el3_token_sign_response)) {
+ return E_RMM_INVAL;
+ }
+
+ spin_lock(&lock);
+
+ /* Pull attestation signing response from HES. */
+ err = plat_rmmd_el3_token_sign_pull_resp(
+ (struct el3_token_sign_response *)buf_pa);
+
+ spin_unlock(&lock);
+
+ return err;
+}
+
+static int rmmd_attest_get_attest_pub_key(uint64_t buf_pa, uint64_t *buf_size,
+ uint64_t ecc_curve)
+{
+ int err;
+
+ err = validate_buffer_params(buf_pa, *buf_size);
+ if (err != 0) {
+ return err;
+ }
+
+ if (ecc_curve != ATTEST_KEY_CURVE_ECC_SECP384R1) {
+ ERROR("Invalid ECC curve specified\n");
+ return E_RMM_INVAL;
+ }
+
+ spin_lock(&lock);
+
+ /* Get the Realm attestation public key from platform port. */
+ err = plat_rmmd_el3_token_sign_get_rak_pub(
+ (uintptr_t)buf_pa, buf_size, (unsigned int)ecc_curve);
+
+ spin_unlock(&lock);
+ if (err != 0) {
+ ERROR("Failed to get attestation public key from HES: %d.\n",
+ err);
+ err = E_RMM_UNK;
+ }
+
+
+ return err;
+}
+
+uint64_t rmmd_el3_token_sign(void *handle, uint64_t opcode, uint64_t x2,
+ uint64_t x3, uint64_t x4)
+{
+ int ret;
+
+ switch (opcode) {
+ case RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP:
+ ret = rmmd_el3_token_sign_push_req(x2, x3);
+ SMC_RET1(handle, ret);
+ case RMM_EL3_TOKEN_SIGN_PULL_RESP_OP:
+ ret = rmmd_el3_token_sign_pull_resp(x2, x3);
+ SMC_RET1(handle, ret);
+ case RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP:
+ ret = rmmd_attest_get_attest_pub_key(x2, &x3, x4);
+ SMC_RET2(handle, ret, x3);
+ default:
+ SMC_RET1(handle, SMC_UNK);
+ }
+}
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index 153bb01..d063ea3 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -441,6 +441,21 @@
return ret;
}
+static int rmm_el3_ifc_get_feat_register(uint64_t feat_reg_idx,
+ uint64_t *feat_reg)
+{
+ if (feat_reg_idx != RMM_EL3_FEAT_REG_0_IDX) {
+ ERROR("RMMD: Failed to get feature register %ld\n", feat_reg_idx);
+ return E_RMM_INVAL;
+ }
+
+ *feat_reg = 0UL;
+#if RMMD_ENABLE_EL3_TOKEN_SIGN
+ *feat_reg |= RMM_EL3_FEAT_REG_0_EL3_TOKEN_SIGN_MASK;
+#endif
+ return E_RMM_OK;
+}
+
/*******************************************************************************
* This function handles RMM-EL3 interface SMCs
******************************************************************************/
@@ -448,7 +463,7 @@
uint64_t x3, uint64_t x4, void *cookie,
void *handle, uint64_t flags)
{
- uint64_t remaining_len = 0;
+ uint64_t remaining_len = 0UL;
uint32_t src_sec_state;
int ret;
@@ -479,7 +494,13 @@
case RMM_ATTEST_GET_REALM_KEY:
ret = rmmd_attest_get_signing_key(x1, &x2, x3);
SMC_RET2(handle, ret, x2);
-
+ case RMM_EL3_FEATURES:
+ ret = rmm_el3_ifc_get_feat_register(x1, &x2);
+ SMC_RET2(handle, ret, x2);
+#if RMMD_ENABLE_EL3_TOKEN_SIGN
+ case RMM_EL3_TOKEN_SIGN:
+ return rmmd_el3_token_sign(handle, x1, x2, x3, x4);
+#endif
case RMM_BOOT_COMPLETE:
VERBOSE("RMMD: running rmmd_rmm_sync_exit\n");
rmmd_rmm_sync_exit(x1);
diff --git a/services/std_svc/rmmd/rmmd_private.h b/services/std_svc/rmmd/rmmd_private.h
index 6d3b5ec..0ce104d 100644
--- a/services/std_svc/rmmd/rmmd_private.h
+++ b/services/std_svc/rmmd/rmmd_private.h
@@ -51,6 +51,8 @@
uint64_t *remaining_len);
int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_size,
uint64_t ecc_curve);
+uint64_t rmmd_el3_token_sign(void *handle, uint64_t x1, uint64_t x2,
+ uint64_t x3, uint64_t x4);
/* Assembly helpers */
uint64_t rmmd_rmm_enter(uint64_t *c_rt_ctx);