Merge changes from topic "fix-imx8m-uart-domain-permission" into integration
* changes:
fix(imx8m): ensure domain permissions for the console
refactor(imx8m): replace UART base magic numbers with macros
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..4f3f261 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)
@@ -1177,6 +1169,7 @@
HW_ASSISTED_COHERENCY \
MEASURED_BOOT \
DICE_PROTECTION_ENVIRONMENT \
+ RMMD_ENABLE_EL3_TOKEN_SIGN \
DRTM_SUPPORT \
NS_TIMER_SWITCH \
OVERRIDE_LIBC \
@@ -1263,11 +1256,13 @@
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_GCS \
ENABLE_FEAT_VHE \
ENABLE_FEAT_MPAM \
@@ -1331,6 +1326,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 +1415,12 @@
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_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..e63eec4 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -257,6 +257,18 @@
}
+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);
+}
+
/***********************************************************************************
* 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 +377,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(),
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..7776f5b 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -455,6 +455,22 @@
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_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/docs/plat/index.rst b/docs/plat/index.rst
index 85c97e5..a8e0c8d 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -72,8 +72,8 @@
+----------------+----------------+--------------------+--------------------+
| Platform | Vendor | Deprecated version | Deleted version |
+================+================+====================+====================+
-| None at this | | | |
-| time. | | | |
+| TC2 | Arm | 2.12 | TBD |
+| | | | |
+----------------+----------------+--------------------+--------------------+
--------------
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/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/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_c_initphyconfig.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_c_initphyconfig.c
index 38b8a07..a0712b5 100644
--- a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_c_initphyconfig.c
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_c_initphyconfig.c
@@ -71,7 +71,7 @@
uint32_t anib;
uint32_t atxpren; /* Default to 0xf (max). Optimal setting is technology specific */
uint32_t atxprep; /* Default to 0xf (max). Optimal setting is technology specific */
- uint32_t ck_anib_inst[2];
+ uint32_t ck_anib_inst[2] = {0};
atxprep = config->uia.txslewriseac;
atxpren = config->uia.txslewfallac;
@@ -1012,7 +1012,6 @@
} else if (anib == 7U) {
aforcetricont = 0xFU;
}
-#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
/*
* If all the lanes can be disabled, and Anib is not the first or last disable
@@ -1022,6 +1021,8 @@
(anib != (config->uib.numanib - 1U))) {
acx4anibdis = acx4anibdis | (0x1U << anib);
}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TANIB | c_addr |
CSR_AFORCETRICONT_ADDR))),
aforcetricont);
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-ddr.dtsi b/fdts/stm32mp25-ddr.dtsi
new file mode 100644
index 0000000..1fcd13d
--- /dev/null
+++ b/fdts/stm32mp25-ddr.dtsi
@@ -0,0 +1,253 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ */
+
+&ddr{
+ st,mem-name = DDR_MEM_NAME;
+ st,mem-speed = <DDR_MEM_SPEED>;
+ st,mem-size = <(DDR_MEM_SIZE >> 32) (DDR_MEM_SIZE & 0xFFFFFFFF)>;
+
+ st,ctl-reg = <
+ DDR_MSTR
+ DDR_MRCTRL0
+ DDR_MRCTRL1
+ DDR_MRCTRL2
+ DDR_DERATEEN
+ DDR_DERATEINT
+ DDR_DERATECTL
+ DDR_PWRCTL
+ DDR_PWRTMG
+ DDR_HWLPCTL
+ DDR_RFSHCTL0
+ DDR_RFSHCTL1
+ DDR_RFSHCTL3
+ DDR_CRCPARCTL0
+ DDR_CRCPARCTL1
+ DDR_INIT0
+ DDR_INIT1
+ DDR_INIT2
+ DDR_INIT3
+ DDR_INIT4
+ DDR_INIT5
+ DDR_INIT6
+ DDR_INIT7
+ DDR_DIMMCTL
+ DDR_RANKCTL
+ DDR_RANKCTL1
+ DDR_ZQCTL0
+ DDR_ZQCTL1
+ DDR_ZQCTL2
+ DDR_DFITMG0
+ DDR_DFITMG1
+ DDR_DFILPCFG0
+ DDR_DFILPCFG1
+ DDR_DFIUPD0
+ DDR_DFIUPD1
+ DDR_DFIUPD2
+ DDR_DFIMISC
+ DDR_DFITMG2
+ DDR_DFITMG3
+ DDR_DBICTL
+ DDR_DFIPHYMSTR
+ DDR_DBG0
+ DDR_DBG1
+ DDR_DBGCMD
+ DDR_SWCTL
+ DDR_SWCTLSTATIC
+ DDR_POISONCFG
+ DDR_PCCFG
+ >;
+
+ st,ctl-timing = <
+ DDR_RFSHTMG
+ DDR_RFSHTMG1
+ DDR_DRAMTMG0
+ DDR_DRAMTMG1
+ DDR_DRAMTMG2
+ DDR_DRAMTMG3
+ DDR_DRAMTMG4
+ DDR_DRAMTMG5
+ DDR_DRAMTMG6
+ DDR_DRAMTMG7
+ DDR_DRAMTMG8
+ DDR_DRAMTMG9
+ DDR_DRAMTMG10
+ DDR_DRAMTMG11
+ DDR_DRAMTMG12
+ DDR_DRAMTMG13
+ DDR_DRAMTMG14
+ DDR_DRAMTMG15
+ DDR_ODTCFG
+ DDR_ODTMAP
+ >;
+
+ st,ctl-map = <
+ DDR_ADDRMAP0
+ DDR_ADDRMAP1
+ DDR_ADDRMAP2
+ DDR_ADDRMAP3
+ DDR_ADDRMAP4
+ DDR_ADDRMAP5
+ DDR_ADDRMAP6
+ DDR_ADDRMAP7
+ DDR_ADDRMAP8
+ DDR_ADDRMAP9
+ DDR_ADDRMAP10
+ DDR_ADDRMAP11
+ >;
+
+ st,ctl-perf = <
+ DDR_SCHED
+ DDR_SCHED1
+ DDR_PERFHPR1
+ DDR_PERFLPR1
+ DDR_PERFWR1
+ DDR_SCHED3
+ DDR_SCHED4
+ DDR_PCFGR_0
+ DDR_PCFGW_0
+ DDR_PCTRL_0
+ DDR_PCFGQOS0_0
+ DDR_PCFGQOS1_0
+ DDR_PCFGWQOS0_0
+ DDR_PCFGWQOS1_0
+ DDR_PCFGR_1
+ DDR_PCFGW_1
+ DDR_PCTRL_1
+ DDR_PCFGQOS0_1
+ DDR_PCFGQOS1_1
+ DDR_PCFGWQOS0_1
+ DDR_PCFGWQOS1_1
+ >;
+
+ st,phy-basic = <
+ DDR_UIB_DRAMTYPE
+ DDR_UIB_DIMMTYPE
+ DDR_UIB_LP4XMODE
+ DDR_UIB_NUMDBYTE
+ DDR_UIB_NUMACTIVEDBYTEDFI0
+ DDR_UIB_NUMACTIVEDBYTEDFI1
+ DDR_UIB_NUMANIB
+ DDR_UIB_NUMRANK_DFI0
+ DDR_UIB_NUMRANK_DFI1
+ DDR_UIB_DRAMDATAWIDTH
+ DDR_UIB_NUMPSTATES
+ DDR_UIB_FREQUENCY_0
+ DDR_UIB_PLLBYPASS_0
+ DDR_UIB_DFIFREQRATIO_0
+ DDR_UIB_DFI1EXISTS
+ DDR_UIB_TRAIN2D
+ DDR_UIB_HARDMACROVER
+ DDR_UIB_READDBIENABLE_0
+ DDR_UIB_DFIMODE
+ >;
+
+ st,phy-advanced = <
+ DDR_UIA_LP4RXPREAMBLEMODE_0
+ DDR_UIA_LP4POSTAMBLEEXT_0
+ DDR_UIA_D4RXPREAMBLELENGTH_0
+ DDR_UIA_D4TXPREAMBLELENGTH_0
+ DDR_UIA_EXTCALRESVAL
+ DDR_UIA_IS2TTIMING_0
+ DDR_UIA_ODTIMPEDANCE_0
+ DDR_UIA_TXIMPEDANCE_0
+ DDR_UIA_ATXIMPEDANCE
+ DDR_UIA_MEMALERTEN
+ DDR_UIA_MEMALERTPUIMP
+ DDR_UIA_MEMALERTVREFLEVEL
+ DDR_UIA_MEMALERTSYNCBYPASS
+ DDR_UIA_DISDYNADRTRI_0
+ DDR_UIA_PHYMSTRTRAININTERVAL_0
+ DDR_UIA_PHYMSTRMAXREQTOACK_0
+ DDR_UIA_WDQSEXT
+ DDR_UIA_CALINTERVAL
+ DDR_UIA_CALONCE
+ DDR_UIA_LP4RL_0
+ DDR_UIA_LP4WL_0
+ DDR_UIA_LP4WLS_0
+ DDR_UIA_LP4DBIRD_0
+ DDR_UIA_LP4DBIWR_0
+ DDR_UIA_LP4NWR_0
+ DDR_UIA_LP4LOWPOWERDRV
+ DDR_UIA_DRAMBYTESWAP
+ DDR_UIA_RXENBACKOFF
+ DDR_UIA_TRAINSEQUENCECTRL
+ DDR_UIA_SNPSUMCTLOPT
+ DDR_UIA_SNPSUMCTLF0RC5X_0
+ DDR_UIA_TXSLEWRISEDQ_0
+ DDR_UIA_TXSLEWFALLDQ_0
+ DDR_UIA_TXSLEWRISEAC
+ DDR_UIA_TXSLEWFALLAC
+ DDR_UIA_DISABLERETRAINING
+ DDR_UIA_DISABLEPHYUPDATE
+ DDR_UIA_ENABLEHIGHCLKSKEWFIX
+ DDR_UIA_DISABLEUNUSEDADDRLNS
+ DDR_UIA_PHYINITSEQUENCENUM
+ DDR_UIA_ENABLEDFICSPOLARITYFIX
+ DDR_UIA_PHYVREF
+ DDR_UIA_SEQUENCECTRL_0
+ >;
+
+ st,phy-mr = <
+ DDR_UIM_MR0_0
+ DDR_UIM_MR1_0
+ DDR_UIM_MR2_0
+ DDR_UIM_MR3_0
+ DDR_UIM_MR4_0
+ DDR_UIM_MR5_0
+ DDR_UIM_MR6_0
+ DDR_UIM_MR11_0
+ DDR_UIM_MR12_0
+ DDR_UIM_MR13_0
+ DDR_UIM_MR14_0
+ DDR_UIM_MR22_0
+ >;
+
+ st,phy-swizzle = <
+ DDR_UIS_SWIZZLE_0
+ DDR_UIS_SWIZZLE_1
+ DDR_UIS_SWIZZLE_2
+ DDR_UIS_SWIZZLE_3
+ DDR_UIS_SWIZZLE_4
+ DDR_UIS_SWIZZLE_5
+ DDR_UIS_SWIZZLE_6
+ DDR_UIS_SWIZZLE_7
+ DDR_UIS_SWIZZLE_8
+ DDR_UIS_SWIZZLE_9
+ DDR_UIS_SWIZZLE_10
+ DDR_UIS_SWIZZLE_11
+ DDR_UIS_SWIZZLE_12
+ DDR_UIS_SWIZZLE_13
+ DDR_UIS_SWIZZLE_14
+ DDR_UIS_SWIZZLE_15
+ DDR_UIS_SWIZZLE_16
+ DDR_UIS_SWIZZLE_17
+ DDR_UIS_SWIZZLE_18
+ DDR_UIS_SWIZZLE_19
+ DDR_UIS_SWIZZLE_20
+ DDR_UIS_SWIZZLE_21
+ DDR_UIS_SWIZZLE_22
+ DDR_UIS_SWIZZLE_23
+ DDR_UIS_SWIZZLE_24
+ DDR_UIS_SWIZZLE_25
+ DDR_UIS_SWIZZLE_26
+ DDR_UIS_SWIZZLE_27
+ DDR_UIS_SWIZZLE_28
+ DDR_UIS_SWIZZLE_29
+ DDR_UIS_SWIZZLE_30
+ DDR_UIS_SWIZZLE_31
+ DDR_UIS_SWIZZLE_32
+ DDR_UIS_SWIZZLE_33
+ DDR_UIS_SWIZZLE_34
+ DDR_UIS_SWIZZLE_35
+ DDR_UIS_SWIZZLE_36
+ DDR_UIS_SWIZZLE_37
+ DDR_UIS_SWIZZLE_38
+ DDR_UIS_SWIZZLE_39
+ DDR_UIS_SWIZZLE_40
+ DDR_UIS_SWIZZLE_41
+ DDR_UIS_SWIZZLE_42
+ DDR_UIS_SWIZZLE_43
+ >;
+};
diff --git a/fdts/stm32mp25-ddr4-2x16Gbits-2x16bits-1200MHz.dtsi b/fdts/stm32mp25-ddr4-2x16Gbits-2x16bits-1200MHz.dtsi
new file mode 100644
index 0000000..3d69448
--- /dev/null
+++ b/fdts/stm32mp25-ddr4-2x16Gbits-2x16bits-1200MHz.dtsi
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
+ */
+
+/*
+ * STM32MP25 DDR4 board configuration
+ * DDR4 2x16Gbits 2x16bits 1200MHz
+ *
+ * version 2
+ * package 1 Package selection (14x14 and 18x18)
+ * memclk 1200MHz (2x DFI clock) + range check
+ * Speed_Bin Worse from JEDEC
+ * device_width 16 x16 by default
+ * width 32 32: full width / 16: half width
+ * density 16Gbits (per 16bit device)
+ * Addressing RBC row/bank interleaving
+ * RDBI No Read DBI
+ */
+
+#define DDR_MEM_NAME "DDR4 2x16Gbits 2x16bits 1200MHz"
+#define DDR_MEM_SPEED 1200000
+#define DDR_MEM_SIZE 0x100000000
+
+#define DDR_MSTR 0x01040010
+#define DDR_MRCTRL0 0x00000030
+#define DDR_MRCTRL1 0x00000000
+#define DDR_MRCTRL2 0x00000000
+#define DDR_DERATEEN 0x00000000
+#define DDR_DERATEINT 0x00000000
+#define DDR_DERATECTL 0x00000000
+#define DDR_PWRCTL 0x00000000
+#define DDR_PWRTMG 0x00130001
+#define DDR_HWLPCTL 0x00000002
+#define DDR_RFSHCTL0 0x00210010
+#define DDR_RFSHCTL1 0x00000000
+#define DDR_RFSHCTL3 0x00000000
+#define DDR_RFSHTMG 0x0092014A
+#define DDR_RFSHTMG1 0x008C0000
+#define DDR_CRCPARCTL0 0x00000000
+#define DDR_CRCPARCTL1 0x00001000
+#define DDR_INIT0 0xC0020002
+#define DDR_INIT1 0x00010002
+#define DDR_INIT2 0x00000D00
+#define DDR_INIT3 0x09400103
+#define DDR_INIT4 0x00180000
+#define DDR_INIT5 0x00100004
+#define DDR_INIT6 0x00080460
+#define DDR_INIT7 0x00000C16
+#define DDR_DIMMCTL 0x00000000
+#define DDR_RANKCTL 0x0000066F
+#define DDR_RANKCTL1 0x0000000D
+#define DDR_DRAMTMG0 0x11152815
+#define DDR_DRAMTMG1 0x0004051E
+#define DDR_DRAMTMG2 0x0609060D
+#define DDR_DRAMTMG3 0x0050400C
+#define DDR_DRAMTMG4 0x0904050A
+#define DDR_DRAMTMG5 0x06060403
+#define DDR_DRAMTMG6 0x02020005
+#define DDR_DRAMTMG7 0x00000202
+#define DDR_DRAMTMG8 0x0606100B
+#define DDR_DRAMTMG9 0x0002040A
+#define DDR_DRAMTMG10 0x001C180A
+#define DDR_DRAMTMG11 0x4408021C
+#define DDR_DRAMTMG12 0x0C020010
+#define DDR_DRAMTMG13 0x1C200004
+#define DDR_DRAMTMG14 0x000000A0
+#define DDR_DRAMTMG15 0x00000000
+#define DDR_ZQCTL0 0x01000040
+#define DDR_ZQCTL1 0x2000493E
+#define DDR_ZQCTL2 0x00000000
+#define DDR_DFITMG0 0x038F8209
+#define DDR_DFITMG1 0x00080303
+#define DDR_DFILPCFG0 0x07004111
+#define DDR_DFILPCFG1 0x00000000
+#define DDR_DFIUPD0 0xC0300018
+#define DDR_DFIUPD1 0x005700B4
+#define DDR_DFIUPD2 0x80000000
+#define DDR_DFIMISC 0x00000041
+#define DDR_DFITMG2 0x00000F09
+#define DDR_DFITMG3 0x00000000
+#define DDR_DBICTL 0x00000001
+#define DDR_DFIPHYMSTR 0x80000000
+#define DDR_ADDRMAP0 0x0000001F
+#define DDR_ADDRMAP1 0x003F0909
+#define DDR_ADDRMAP2 0x00000700
+#define DDR_ADDRMAP3 0x00000000
+#define DDR_ADDRMAP4 0x00001F1F
+#define DDR_ADDRMAP5 0x070F0707
+#define DDR_ADDRMAP6 0x07070707
+#define DDR_ADDRMAP7 0x00000F07
+#define DDR_ADDRMAP8 0x00003F01
+#define DDR_ADDRMAP9 0x07070707
+#define DDR_ADDRMAP10 0x07070707
+#define DDR_ADDRMAP11 0x00000007
+#define DDR_ODTCFG 0x06000618
+#define DDR_ODTMAP 0x00000001
+#define DDR_SCHED 0x80001B00
+#define DDR_SCHED1 0x00000000
+#define DDR_PERFHPR1 0x04000200
+#define DDR_PERFLPR1 0x08000080
+#define DDR_PERFWR1 0x08000400
+#define DDR_SCHED3 0x04040208
+#define DDR_SCHED4 0x08400810
+#define DDR_DBG0 0x00000000
+#define DDR_DBG1 0x00000000
+#define DDR_DBGCMD 0x00000000
+#define DDR_SWCTL 0x00000000
+#define DDR_SWCTLSTATIC 0x00000000
+#define DDR_POISONCFG 0x00000000
+#define DDR_PCCFG 0x00000000
+#define DDR_PCFGR_0 0x00704100
+#define DDR_PCFGW_0 0x00004100
+#define DDR_PCTRL_0 0x00000000
+#define DDR_PCFGQOS0_0 0x0021000C
+#define DDR_PCFGQOS1_0 0x01000080
+#define DDR_PCFGWQOS0_0 0x01100C07
+#define DDR_PCFGWQOS1_0 0x04000200
+#define DDR_PCFGR_1 0x00704100
+#define DDR_PCFGW_1 0x00004100
+#define DDR_PCTRL_1 0x00000000
+#define DDR_PCFGQOS0_1 0x00100007
+#define DDR_PCFGQOS1_1 0x01000080
+#define DDR_PCFGWQOS0_1 0x01100C07
+#define DDR_PCFGWQOS1_1 0x04000200
+
+#define DDR_UIB_DRAMTYPE 0x00000000
+#define DDR_UIB_DIMMTYPE 0x00000004
+#define DDR_UIB_LP4XMODE 0x00000000
+#define DDR_UIB_NUMDBYTE 0x00000004
+#define DDR_UIB_NUMACTIVEDBYTEDFI0 0x00000004
+#define DDR_UIB_NUMACTIVEDBYTEDFI1 0x00000000
+#define DDR_UIB_NUMANIB 0x00000008
+#define DDR_UIB_NUMRANK_DFI0 0x00000001
+#define DDR_UIB_NUMRANK_DFI1 0x00000001
+#define DDR_UIB_DRAMDATAWIDTH 0x00000010
+#define DDR_UIB_NUMPSTATES 0x00000001
+#define DDR_UIB_FREQUENCY_0 0x000004B0
+#define DDR_UIB_PLLBYPASS_0 0x00000000
+#define DDR_UIB_DFIFREQRATIO_0 0x00000001
+#define DDR_UIB_DFI1EXISTS 0x00000001
+#define DDR_UIB_TRAIN2D 0x00000000
+#define DDR_UIB_HARDMACROVER 0x00000003
+#define DDR_UIB_READDBIENABLE_0 0x00000000
+#define DDR_UIB_DFIMODE 0x00000000
+
+#define DDR_UIA_LP4RXPREAMBLEMODE_0 0x00000000
+#define DDR_UIA_LP4POSTAMBLEEXT_0 0x00000000
+#define DDR_UIA_D4RXPREAMBLELENGTH_0 0x00000000
+#define DDR_UIA_D4TXPREAMBLELENGTH_0 0x00000000
+#define DDR_UIA_EXTCALRESVAL 0x00000000
+#define DDR_UIA_IS2TTIMING_0 0x00000000
+#define DDR_UIA_ODTIMPEDANCE_0 0x00000035
+#define DDR_UIA_TXIMPEDANCE_0 0x00000028
+#define DDR_UIA_ATXIMPEDANCE 0x00000028
+#define DDR_UIA_MEMALERTEN 0x00000000
+#define DDR_UIA_MEMALERTPUIMP 0x00000000
+#define DDR_UIA_MEMALERTVREFLEVEL 0x00000000
+#define DDR_UIA_MEMALERTSYNCBYPASS 0x00000000
+#define DDR_UIA_DISDYNADRTRI_0 0x00000001
+#define DDR_UIA_PHYMSTRTRAININTERVAL_0 0x00000000
+#define DDR_UIA_PHYMSTRMAXREQTOACK_0 0x00000000
+#define DDR_UIA_WDQSEXT 0x00000000
+#define DDR_UIA_CALINTERVAL 0x00000009
+#define DDR_UIA_CALONCE 0x00000000
+#define DDR_UIA_LP4RL_0 0x00000000
+#define DDR_UIA_LP4WL_0 0x00000000
+#define DDR_UIA_LP4WLS_0 0x00000000
+#define DDR_UIA_LP4DBIRD_0 0x00000000
+#define DDR_UIA_LP4DBIWR_0 0x00000000
+#define DDR_UIA_LP4NWR_0 0x00000000
+#define DDR_UIA_LP4LOWPOWERDRV 0x00000000
+#define DDR_UIA_DRAMBYTESWAP 0x00000000
+#define DDR_UIA_RXENBACKOFF 0x00000000
+#define DDR_UIA_TRAINSEQUENCECTRL 0x00000000
+#define DDR_UIA_SNPSUMCTLOPT 0x00000000
+#define DDR_UIA_SNPSUMCTLF0RC5X_0 0x00000000
+#define DDR_UIA_TXSLEWRISEDQ_0 0x0000000F
+#define DDR_UIA_TXSLEWFALLDQ_0 0x0000000F
+#define DDR_UIA_TXSLEWRISEAC 0x0000000F
+#define DDR_UIA_TXSLEWFALLAC 0x0000000F
+#define DDR_UIA_DISABLERETRAINING 0x00000001
+#define DDR_UIA_DISABLEPHYUPDATE 0x00000000
+#define DDR_UIA_ENABLEHIGHCLKSKEWFIX 0x00000000
+#define DDR_UIA_DISABLEUNUSEDADDRLNS 0x00000001
+#define DDR_UIA_PHYINITSEQUENCENUM 0x00000000
+#define DDR_UIA_ENABLEDFICSPOLARITYFIX 0x00000000
+#define DDR_UIA_PHYVREF 0x0000005E
+#define DDR_UIA_SEQUENCECTRL_0 0x0000031F
+
+#define DDR_UIM_MR0_0 0x00000940
+#define DDR_UIM_MR1_0 0x00000103
+#define DDR_UIM_MR2_0 0x00000018
+#define DDR_UIM_MR3_0 0x00000000
+#define DDR_UIM_MR4_0 0x00000008
+#define DDR_UIM_MR5_0 0x00000460
+#define DDR_UIM_MR6_0 0x00000C16
+#define DDR_UIM_MR11_0 0x00000000
+#define DDR_UIM_MR12_0 0x00000000
+#define DDR_UIM_MR13_0 0x00000000
+#define DDR_UIM_MR14_0 0x00000000
+#define DDR_UIM_MR22_0 0x00000000
+
+#define DDR_UIS_SWIZZLE_0 0x0000000C
+#define DDR_UIS_SWIZZLE_1 0x00000005
+#define DDR_UIS_SWIZZLE_2 0x00000013
+#define DDR_UIS_SWIZZLE_3 0x0000001A
+#define DDR_UIS_SWIZZLE_4 0x00000009
+#define DDR_UIS_SWIZZLE_5 0x00000003
+#define DDR_UIS_SWIZZLE_6 0x00000001
+#define DDR_UIS_SWIZZLE_7 0x00000019
+#define DDR_UIS_SWIZZLE_8 0x00000007
+#define DDR_UIS_SWIZZLE_9 0x00000004
+#define DDR_UIS_SWIZZLE_10 0x0000000A
+#define DDR_UIS_SWIZZLE_11 0x0000000D
+#define DDR_UIS_SWIZZLE_12 0x00000014
+#define DDR_UIS_SWIZZLE_13 0x00000000
+#define DDR_UIS_SWIZZLE_14 0x00000000
+#define DDR_UIS_SWIZZLE_15 0x00000000
+#define DDR_UIS_SWIZZLE_16 0x00000000
+#define DDR_UIS_SWIZZLE_17 0x00000000
+#define DDR_UIS_SWIZZLE_18 0x00000006
+#define DDR_UIS_SWIZZLE_19 0x0000000B
+#define DDR_UIS_SWIZZLE_20 0x00000000
+#define DDR_UIS_SWIZZLE_21 0x00000000
+#define DDR_UIS_SWIZZLE_22 0x00000000
+#define DDR_UIS_SWIZZLE_23 0x00000008
+#define DDR_UIS_SWIZZLE_24 0x00000002
+#define DDR_UIS_SWIZZLE_25 0x00000018
+#define DDR_UIS_SWIZZLE_26 0x1A13050C
+#define DDR_UIS_SWIZZLE_27 0x19010309
+#define DDR_UIS_SWIZZLE_28 0x0D0A0407
+#define DDR_UIS_SWIZZLE_29 0x00000014
+#define DDR_UIS_SWIZZLE_30 0x000B0600
+#define DDR_UIS_SWIZZLE_31 0x02080000
+#define DDR_UIS_SWIZZLE_32 0x00000018
+#define DDR_UIS_SWIZZLE_33 0x00000000
+#define DDR_UIS_SWIZZLE_34 0x00000000
+#define DDR_UIS_SWIZZLE_35 0x00000000
+#define DDR_UIS_SWIZZLE_36 0x00000000
+#define DDR_UIS_SWIZZLE_37 0x00000000
+#define DDR_UIS_SWIZZLE_38 0x00000000
+#define DDR_UIS_SWIZZLE_39 0x00000000
+#define DDR_UIS_SWIZZLE_40 0x00000000
+#define DDR_UIS_SWIZZLE_41 0x00000000
+#define DDR_UIS_SWIZZLE_42 0x00000000
+#define DDR_UIS_SWIZZLE_43 0x00000000
+
+#include "stm32mp25-ddr.dtsi"
diff --git a/fdts/stm32mp25-ddr4-2x8Gbits-2x16bits-1200MHz.dtsi b/fdts/stm32mp25-ddr4-2x8Gbits-2x16bits-1200MHz.dtsi
new file mode 100644
index 0000000..674cb3d
--- /dev/null
+++ b/fdts/stm32mp25-ddr4-2x8Gbits-2x16bits-1200MHz.dtsi
@@ -0,0 +1,245 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
+ */
+
+/*
+ * STM32MP25 DDR4 board configuration
+ * DDR4 2x8Gbits 2x16bits 1200MHz
+ *
+ * version 1
+ * package 1 Package selection (14x14 and 18x18)
+ * memclk 1200MHz (2x DFI clock) + range check
+ * Speed_Bin Worse from JEDEC
+ * width 32 32: full width / 16: half width
+ * ranks 1 Single or Dual rank
+ * density 8Gbits (per 16bit device)
+ * Addressing RBC row/bank interleaving
+ * RDBI No Read DBI
+ */
+
+#define DDR_MEM_NAME "DDR4 2x8Gbits 2x16bits 1200MHz"
+#define DDR_MEM_SPEED 1200000
+#define DDR_MEM_SIZE 0x80000000
+
+#define DDR_MSTR 0x01040010
+#define DDR_MRCTRL0 0x00000030
+#define DDR_MRCTRL1 0x00000000
+#define DDR_MRCTRL2 0x00000000
+#define DDR_DERATEEN 0x00000000
+#define DDR_DERATEINT 0x00000000
+#define DDR_DERATECTL 0x00000000
+#define DDR_PWRCTL 0x00000000
+#define DDR_PWRTMG 0x00130001
+#define DDR_HWLPCTL 0x00000002
+#define DDR_RFSHCTL0 0x00210010
+#define DDR_RFSHCTL1 0x00000000
+#define DDR_RFSHCTL3 0x00000000
+#define DDR_RFSHTMG 0x009200D2
+#define DDR_RFSHTMG1 0x008C0000
+#define DDR_CRCPARCTL0 0x00000000
+#define DDR_CRCPARCTL1 0x00001000
+#define DDR_INIT0 0xC0020002
+#define DDR_INIT1 0x00010002
+#define DDR_INIT2 0x00000D00
+#define DDR_INIT3 0x09400103
+#define DDR_INIT4 0x00180000
+#define DDR_INIT5 0x00100004
+#define DDR_INIT6 0x00080460
+#define DDR_INIT7 0x00000C16
+#define DDR_DIMMCTL 0x00000000
+#define DDR_RANKCTL 0x0000066F
+#define DDR_DRAMTMG0 0x11152815
+#define DDR_DRAMTMG1 0x0004051E
+#define DDR_DRAMTMG2 0x0609060D
+#define DDR_DRAMTMG3 0x0050400C
+#define DDR_DRAMTMG4 0x0904050A
+#define DDR_DRAMTMG5 0x06060403
+#define DDR_DRAMTMG6 0x02020005
+#define DDR_DRAMTMG7 0x00000202
+#define DDR_DRAMTMG8 0x04041007
+#define DDR_DRAMTMG9 0x0002040A
+#define DDR_DRAMTMG10 0x001C180A
+#define DDR_DRAMTMG11 0x4408021C
+#define DDR_DRAMTMG12 0x0C020010
+#define DDR_DRAMTMG13 0x1C200004
+#define DDR_DRAMTMG14 0x000000A0
+#define DDR_DRAMTMG15 0x00000000
+#define DDR_ZQCTL0 0x01000040
+#define DDR_ZQCTL1 0x2000493E
+#define DDR_ZQCTL2 0x00000000
+#define DDR_DFITMG0 0x038F8209
+#define DDR_DFITMG1 0x00080303
+#define DDR_DFILPCFG0 0x07004111
+#define DDR_DFILPCFG1 0x00000000
+#define DDR_DFIUPD0 0xC0300018
+#define DDR_DFIUPD1 0x005700B4
+#define DDR_DFIUPD2 0x80000000
+#define DDR_DFIMISC 0x00000041
+#define DDR_DFITMG2 0x00000F09
+#define DDR_DFITMG3 0x00000000
+#define DDR_DBICTL 0x00000001
+#define DDR_DFIPHYMSTR 0x80000000
+#define DDR_ADDRMAP0 0x0000001F
+#define DDR_ADDRMAP1 0x003F0909
+#define DDR_ADDRMAP2 0x00000700
+#define DDR_ADDRMAP3 0x00000000
+#define DDR_ADDRMAP4 0x00001F1F
+#define DDR_ADDRMAP5 0x070F0707
+#define DDR_ADDRMAP6 0x07070707
+#define DDR_ADDRMAP7 0x00000F0F
+#define DDR_ADDRMAP8 0x00003F01
+#define DDR_ADDRMAP9 0x07070707
+#define DDR_ADDRMAP10 0x07070707
+#define DDR_ADDRMAP11 0x00000007
+#define DDR_ODTCFG 0x06000618
+#define DDR_ODTMAP 0x00000001
+#define DDR_SCHED 0x00000F00
+#define DDR_SCHED1 0x00000000
+#define DDR_PERFHPR1 0x0F000001
+#define DDR_PERFLPR1 0x0F000080
+#define DDR_PERFWR1 0x01000200
+#define DDR_DBG0 0x00000000
+#define DDR_DBG1 0x00000000
+#define DDR_DBGCMD 0x00000000
+#define DDR_SWCTL 0x00000000
+#define DDR_POISONCFG 0x00000000
+#define DDR_PCCFG 0x00000000
+#define DDR_PCFGR_0 0x00004100
+#define DDR_PCFGW_0 0x00004100
+#define DDR_PCTRL_0 0x00000000
+#define DDR_PCFGQOS0_0 0x00200007
+#define DDR_PCFGQOS1_0 0x01000100
+#define DDR_PCFGWQOS0_0 0x00000C07
+#define DDR_PCFGWQOS1_0 0x02000200
+#define DDR_PCFGR_1 0x00004100
+#define DDR_PCFGW_1 0x00004100
+#define DDR_PCTRL_1 0x00000000
+#define DDR_PCFGQOS0_1 0x00200007
+#define DDR_PCFGQOS1_1 0x01000180
+#define DDR_PCFGWQOS0_1 0x00000C07
+#define DDR_PCFGWQOS1_1 0x04000400
+
+#define DDR_UIB_DRAMTYPE 0x00000000
+#define DDR_UIB_DIMMTYPE 0x00000004
+#define DDR_UIB_LP4XMODE 0x00000000
+#define DDR_UIB_NUMDBYTE 0x00000004
+#define DDR_UIB_NUMACTIVEDBYTEDFI0 0x00000004
+#define DDR_UIB_NUMACTIVEDBYTEDFI1 0x00000000
+#define DDR_UIB_NUMANIB 0x00000008
+#define DDR_UIB_NUMRANK_DFI0 0x00000001
+#define DDR_UIB_NUMRANK_DFI1 0x00000001
+#define DDR_UIB_DRAMDATAWIDTH 0x00000010
+#define DDR_UIB_NUMPSTATES 0x00000001
+#define DDR_UIB_FREQUENCY_0 0x000004B0
+#define DDR_UIB_PLLBYPASS_0 0x00000000
+#define DDR_UIB_DFIFREQRATIO_0 0x00000001
+#define DDR_UIB_DFI1EXISTS 0x00000001
+#define DDR_UIB_TRAIN2D 0x00000000
+#define DDR_UIB_HARDMACROVER 0x00000003
+#define DDR_UIB_READDBIENABLE_0 0x00000000
+#define DDR_UIB_DFIMODE 0x00000000
+
+#define DDR_UIA_LP4RXPREAMBLEMODE_0 0x00000000
+#define DDR_UIA_LP4POSTAMBLEEXT_0 0x00000000
+#define DDR_UIA_D4RXPREAMBLELENGTH_0 0x00000000
+#define DDR_UIA_D4TXPREAMBLELENGTH_0 0x00000000
+#define DDR_UIA_EXTCALRESVAL 0x00000000
+#define DDR_UIA_IS2TTIMING_0 0x00000000
+#define DDR_UIA_ODTIMPEDANCE_0 0x00000035
+#define DDR_UIA_TXIMPEDANCE_0 0x00000028
+#define DDR_UIA_ATXIMPEDANCE 0x00000028
+#define DDR_UIA_MEMALERTEN 0x00000000
+#define DDR_UIA_MEMALERTPUIMP 0x00000000
+#define DDR_UIA_MEMALERTVREFLEVEL 0x00000000
+#define DDR_UIA_MEMALERTSYNCBYPASS 0x00000000
+#define DDR_UIA_DISDYNADRTRI_0 0x00000001
+#define DDR_UIA_PHYMSTRTRAININTERVAL_0 0x00000000
+#define DDR_UIA_PHYMSTRMAXREQTOACK_0 0x00000000
+#define DDR_UIA_WDQSEXT 0x00000000
+#define DDR_UIA_CALINTERVAL 0x00000009
+#define DDR_UIA_CALONCE 0x00000000
+#define DDR_UIA_LP4RL_0 0x00000000
+#define DDR_UIA_LP4WL_0 0x00000000
+#define DDR_UIA_LP4WLS_0 0x00000000
+#define DDR_UIA_LP4DBIRD_0 0x00000000
+#define DDR_UIA_LP4DBIWR_0 0x00000000
+#define DDR_UIA_LP4NWR_0 0x00000000
+#define DDR_UIA_LP4LOWPOWERDRV 0x00000000
+#define DDR_UIA_DRAMBYTESWAP 0x00000000
+#define DDR_UIA_RXENBACKOFF 0x00000000
+#define DDR_UIA_TRAINSEQUENCECTRL 0x00000000
+#define DDR_UIA_SNPSUMCTLOPT 0x00000000
+#define DDR_UIA_SNPSUMCTLF0RC5X_0 0x00000000
+#define DDR_UIA_TXSLEWRISEDQ_0 0x0000000F
+#define DDR_UIA_TXSLEWFALLDQ_0 0x0000000F
+#define DDR_UIA_TXSLEWRISEAC 0x0000000F
+#define DDR_UIA_TXSLEWFALLAC 0x0000000F
+#define DDR_UIA_DISABLERETRAINING 0x00000001
+#define DDR_UIA_DISABLEPHYUPDATE 0x00000000
+#define DDR_UIA_ENABLEHIGHCLKSKEWFIX 0x00000000
+#define DDR_UIA_DISABLEUNUSEDADDRLNS 0x00000001
+#define DDR_UIA_PHYINITSEQUENCENUM 0x00000000
+#define DDR_UIA_ENABLEDFICSPOLARITYFIX 0x00000000
+#define DDR_UIA_PHYVREF 0x0000005E
+#define DDR_UIA_SEQUENCECTRL_0 0x0000031F
+
+#define DDR_UIM_MR0_0 0x00000940
+#define DDR_UIM_MR1_0 0x00000103
+#define DDR_UIM_MR2_0 0x00000018
+#define DDR_UIM_MR3_0 0x00000000
+#define DDR_UIM_MR4_0 0x00000008
+#define DDR_UIM_MR5_0 0x00000460
+#define DDR_UIM_MR6_0 0x00000C16
+#define DDR_UIM_MR11_0 0x00000000
+#define DDR_UIM_MR12_0 0x00000000
+#define DDR_UIM_MR13_0 0x00000000
+#define DDR_UIM_MR14_0 0x00000000
+#define DDR_UIM_MR22_0 0x00000000
+
+#define DDR_UIS_SWIZZLE_0 0x0000000C
+#define DDR_UIS_SWIZZLE_1 0x00000005
+#define DDR_UIS_SWIZZLE_2 0x00000013
+#define DDR_UIS_SWIZZLE_3 0x0000001A
+#define DDR_UIS_SWIZZLE_4 0x00000009
+#define DDR_UIS_SWIZZLE_5 0x00000003
+#define DDR_UIS_SWIZZLE_6 0x00000001
+#define DDR_UIS_SWIZZLE_7 0x00000019
+#define DDR_UIS_SWIZZLE_8 0x00000007
+#define DDR_UIS_SWIZZLE_9 0x00000004
+#define DDR_UIS_SWIZZLE_10 0x0000000A
+#define DDR_UIS_SWIZZLE_11 0x0000000D
+#define DDR_UIS_SWIZZLE_12 0x00000014
+#define DDR_UIS_SWIZZLE_13 0x00000000
+#define DDR_UIS_SWIZZLE_14 0x00000000
+#define DDR_UIS_SWIZZLE_15 0x00000000
+#define DDR_UIS_SWIZZLE_16 0x00000000
+#define DDR_UIS_SWIZZLE_17 0x00000000
+#define DDR_UIS_SWIZZLE_18 0x00000006
+#define DDR_UIS_SWIZZLE_19 0x0000000B
+#define DDR_UIS_SWIZZLE_20 0x00000000
+#define DDR_UIS_SWIZZLE_21 0x00000000
+#define DDR_UIS_SWIZZLE_22 0x00000000
+#define DDR_UIS_SWIZZLE_23 0x00000008
+#define DDR_UIS_SWIZZLE_24 0x00000002
+#define DDR_UIS_SWIZZLE_25 0x00000018
+#define DDR_UIS_SWIZZLE_26 0x1A13050C
+#define DDR_UIS_SWIZZLE_27 0x19010309
+#define DDR_UIS_SWIZZLE_28 0x0D0A0407
+#define DDR_UIS_SWIZZLE_29 0x00000014
+#define DDR_UIS_SWIZZLE_30 0x000B0600
+#define DDR_UIS_SWIZZLE_31 0x02080000
+#define DDR_UIS_SWIZZLE_32 0x00000018
+#define DDR_UIS_SWIZZLE_33 0x00000000
+#define DDR_UIS_SWIZZLE_34 0x00000000
+#define DDR_UIS_SWIZZLE_35 0x00000000
+#define DDR_UIS_SWIZZLE_36 0x00000000
+#define DDR_UIS_SWIZZLE_37 0x00000000
+#define DDR_UIS_SWIZZLE_38 0x00000000
+#define DDR_UIS_SWIZZLE_39 0x00000000
+#define DDR_UIS_SWIZZLE_40 0x00000000
+#define DDR_UIS_SWIZZLE_41 0x00000000
+#define DDR_UIS_SWIZZLE_42 0x00000000
+#define DDR_UIS_SWIZZLE_43 0x00000000
+
+#include "stm32mp25-ddr.dtsi"
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/stm32mp251.dtsi b/fdts/stm32mp251.dtsi
index 9e89813..c2c2764 100644
--- a/fdts/stm32mp251.dtsi
+++ b/fdts/stm32mp251.dtsi
@@ -328,6 +328,13 @@
reg = <0x44230000 0x10000>;
};
+ ddr: ddr@48040000 {
+ compatible = "st,stm32mp2-ddr";
+ reg = <0x48040000 0x10000>,
+ <0x48c00000 0x400000>;
+ status = "okay";
+ };
+
pinctrl: pinctrl@44240000 {
#address-cells = <1>;
#size-cells = <1>;
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/fdts/stm32mp257f-ev1.dts b/fdts/stm32mp257f-ev1.dts
index d2b5e55..5d5e35d 100644
--- a/fdts/stm32mp257f-ev1.dts
+++ b/fdts/stm32mp257f-ev1.dts
@@ -10,6 +10,7 @@
#include "stm32mp257.dtsi"
#include "stm32mp25xf.dtsi"
#include "stm32mp257f-ev1-ca35tdcid-rcc.dtsi"
+#include "stm32mp25-ddr4-2x16Gbits-2x16bits-1200MHz.dtsi"
#include "stm32mp25-pinctrl.dtsi"
#include "stm32mp25xxai-pinctrl.dtsi"
@@ -37,6 +38,13 @@
};
};
+&ddr {
+ vdd-supply = <&vdd_ddr>;
+ vtt-supply = <&vtt_ddr>;
+ vpp-supply = <&vpp_ddr>;
+ vref-supply = <&vref_ddr>;
+};
+
&i2c7 {
pinctrl-names = "default";
pinctrl-0 = <&i2c7_pins_a>;
diff --git a/fdts/tc-base.dtsi b/fdts/tc-base.dtsi
index be0a9f6..735d429 100644
--- a/fdts/tc-base.dtsi
+++ b/fdts/tc-base.dtsi
@@ -247,10 +247,6 @@
reg = <0x0 TC_NS_OPTEE_BASE 0x0 TC_NS_OPTEE_SIZE>;
};
- fwu_mm {
- reg = <0x0 TC_NS_FWU_BASE 0x0 TC_NS_FWU_SIZE>;
- no-map;
- };
};
memory {
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index d8ad881..6a19822 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -406,6 +406,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 +437,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 */
@@ -589,7 +597,9 @@
#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 +633,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)
@@ -1473,6 +1485,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..de21fea 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -134,6 +134,10 @@
* +----------------------------+
* | FEAT_FGT2 |
* +----------------------------+
+ * | FEAT_THE |
+ * +----------------------------+
+ * | FEAT_SCTLR2 |
+ * +----------------------------+
*/
__attribute__((always_inline))
@@ -262,6 +266,15 @@
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)
+
__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..acaa1b8 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -670,6 +670,14 @@
DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el1, GCSPR_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el0, GCSPR_EL0)
+/* FEAT_THE Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(rcwmask_el1, RCWMASK_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(rcwsmask_el1, RCWSMASK_EL1)
+
+/* 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/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..4be7414 100644
--- a/include/drivers/cadence/cdns_sdmmc.h
+++ b/include/drivers/cadence/cdns_sdmmc.h
@@ -281,7 +281,6 @@
(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 MMC_RESPONSE_NONE 0
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..94af210 100644
--- a/include/lib/el3_runtime/context_el1.h
+++ b/include/lib/el3_runtime/context_el1.h
@@ -107,6 +107,15 @@
uint64_t gcspr_el0;
} el1_gcs_regs_t;
+typedef struct el1_the_regs {
+ uint64_t rcwmask_el1;
+ uint64_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 +164,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 +283,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..ad0b68f 100644
--- a/include/lib/el3_runtime/context_el2.h
+++ b/include/lib/el3_runtime/context_el2.h
@@ -135,6 +135,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 +207,10 @@
el2_mpam_regs_t mpam;
#endif
+#if ENABLE_FEAT_SCTLR2
+ el2_sctlr2_regs_t sctlr2;
+#endif
+
} el2_sysregs_t;
/*
@@ -358,6 +366,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/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..003cb25 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -260,6 +260,21 @@
*/
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;
+ }
+
write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
/* Initialize EL2 context registers */
@@ -760,13 +775,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 +800,10 @@
debugv8p9_extended_bp_wp_enable(ctx);
}
+ if (is_feat_brbe_supported()) {
+ brbe_enable(ctx);
+ }
+
pmuv3_enable(ctx);
#endif /* IMAGE_BL31 */
}
@@ -1437,6 +1449,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 +1540,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 +1732,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 +1837,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/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/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index 675779f..6c893f4 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
#----
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..64c356a 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();
@@ -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..59aff08 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),
@@ -649,6 +649,11 @@
/* Keep i2c on 100MHz to calculate rates properly */
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..7cb3982 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -71,11 +71,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 +196,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 +212,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 +268,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/fdts/tc_spmc_manifest.dtsi b/plat/arm/board/tc/fdts/tc_spmc_manifest.dtsi
index a6b63a1..737997d 100644
--- a/plat/arm/board/tc/fdts/tc_spmc_manifest.dtsi
+++ b/plat/arm/board/tc/fdts/tc_spmc_manifest.dtsi
@@ -99,11 +99,7 @@
memory@1 {
device_type = "ns-memory";
- reg =
-#ifdef TS_SP_FW_CONFIG
- <0x0 0x08000000 0x0 0x4000000>,
-#endif /* TS_SP_FW_CONFIG */
- <0x0 TC_NS_DRAM1_BASE 0x0 TC_NS_DRAM1_SIZE>,
+ reg = <0x0 TC_NS_DRAM1_BASE 0x0 TC_NS_DRAM1_SIZE>,
<HI(PLAT_ARM_DRAM2_BASE) LO(PLAT_ARM_DRAM2_BASE)
HI(TC_NS_DRAM2_SIZE) LO(TC_NS_DRAM2_SIZE)>;
};
@@ -117,4 +113,11 @@
device_type = "device-memory";
reg = <0x0 PLAT_ARM_BOOT_UART_BASE 0x0 0x01000>;
};
+
+#ifdef TS_SP_FW_CONFIG
+ ns_flash {
+ device_type = "ns-device-memory";
+ reg = <0x0 V2M_FLASH0_BASE 0x0 V2M_FLASH0_SIZE>;
+ };
+#endif
};
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index 0652148..86fce0e 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -51,9 +51,6 @@
* | (4KB) |
* 0x8000_9000 ------------------
* | ... |
- * 0xf8a0_0000 ------------------ TC_NS_FWU_BASE
- * | FWU shmem |
- * | (4MB) |
* 0xf8e0_0000 ------------------ TC_NS_OPTEE_BASE
* | OP-TEE shmem |
* | (2MB) |
@@ -85,8 +82,6 @@
#define TC_NS_OPTEE_SIZE (2 * SZ_1M)
#define TC_NS_OPTEE_BASE (TC_NS_DRAM1_BASE + TC_NS_DRAM1_SIZE - TC_NS_OPTEE_SIZE)
-#define TC_NS_FWU_SIZE (4 * SZ_1M)
-#define TC_NS_FWU_BASE (TC_NS_OPTEE_BASE - TC_NS_FWU_SIZE)
/*
* Mappings for TC DRAM1 (non-secure) and TC TZC DRAM1 (secure)
@@ -192,7 +187,7 @@
# if SPM_MM
# define PLATFORM_STACK_SIZE 0x500
# else
-# define PLATFORM_STACK_SIZE 0xa00
+# define PLATFORM_STACK_SIZE 0xb00
# endif
#elif defined(IMAGE_BL32)
# define PLATFORM_STACK_SIZE 0x440
@@ -227,8 +222,11 @@
#define TC_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\
V2M_FLASH0_SIZE, \
MT_DEVICE | MT_RO | MT_SECURE)
-
-#define PLAT_ARM_NSTIMER_FRAME_ID 0
+#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/board/tc/platform_test.mk b/plat/arm/board/tc/platform_test.mk
index 8d39325..2ce6648 100644
--- a/plat/arm/board/tc/platform_test.mk
+++ b/plat/arm/board/tc/platform_test.mk
@@ -33,6 +33,7 @@
$(eval $(call add_define,PLATFORM_TEST_ROTPK))
else ifeq (${PLATFORM_TEST},tfm-testsuite)
include drivers/arm/rse/rse_comms.mk
+ include drivers/measured_boot/rse/qcbor.mk
# The variables need to be set to compile the platform test:
ifeq (${TF_M_TESTS_PATH},)
@@ -80,7 +81,8 @@
$(DELEGATED_ATTEST_TESTS_PATH)/delegated_attest_test.c \
drivers/auth/mbedtls/mbedtls_common.c \
lib/psa/measured_boot.c \
- lib/psa/delegated_attestation.c
+ lib/psa/delegated_attestation.c \
+ ${QCBOR_SOURCES}
PLAT_INCLUDES += -I$(TF_M_EXTRAS_PATH)/partitions/measured_boot/interface/include \
-I$(TF_M_EXTRAS_PATH)/partitions/delegated_attestation/interface/include \
@@ -93,7 +95,8 @@
-Iplat/arm/board/tc \
-Iinclude/drivers/auth/mbedtls \
-Iinclude/drivers/arm \
- -Iinclude/lib/psa
+ -Iinclude/lib/psa \
+ -I${QCBOR_INCLUDES}
# Some of the PSA functions are declared in multiple header files, that
# triggers this warning.
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..94fed3a 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
*/
@@ -15,9 +16,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 +35,13 @@
#define CAD_QSPIDATA_OFST 0xff900000
#define CAD_QSPI_OFFSET 0xff8d2000
+/* SDMMC Setting */
+# if ARM_LINUX_KERNEL_AS_BL33
+#define SOCFPGA_MMC_BLOCK_SIZE U(32768)
+# else
+#define SOCFPGA_MMC_BLOCK_SIZE U(8192)
+# endif
+
/* Register Mapping */
#define SOCFPGA_CCU_NOC_REG_BASE 0xf7000000
#define SOCFPGA_F2SDRAMMGR_REG_BASE U(0xf8024000)
diff --git a/plat/intel/soc/agilex5/bl2_plat_setup.c b/plat/intel/soc/agilex5/bl2_plat_setup.c
index 265ee57..78a4889 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,75 @@
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);
- /* 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 +145,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;
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..f61c479 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
@@ -189,6 +190,8 @@
#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..3a0aea1 100644
--- a/plat/intel/soc/agilex5/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
@@ -11,11 +11,16 @@
#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 +28,31 @@
#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
+/* SDMMC Setting */
+# if ARM_LINUX_KERNEL_AS_BL33
+#define SOCFPGA_MMC_BLOCK_SIZE U(32768)
+# else
+#define SOCFPGA_MMC_BLOCK_SIZE U(8192)
+# endif
+
/* Register Mapping */
#define SOCFPGA_CCU_NOC_REG_BASE 0x1c000000
#define SOCFPGA_F2SDRAMMGR_REG_BASE 0x18001000
@@ -88,11 +102,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..4bb90d5 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 \
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/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index 1946898..08ab5df 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
*/
@@ -28,26 +29,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_private.h b/plat/intel/soc/common/include/socfpga_private.h
index 041c282..a0d4180 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
*/
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/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_storage.c b/plat/intel/soc/common/socfpga_storage.c
index d250d9e..7679f59 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
*/
@@ -21,16 +22,21 @@
#include <drivers/partition/partition.h>
#include <lib/mmio.h>
#include <tools_share/firmware_image_package.h>
-
#include "drivers/sdmmc/sdmmc.h"
#include "socfpga_private.h"
#include "socfpga_ros.h"
#define PLAT_FIP_BASE (0)
+# if ARM_LINUX_KERNEL_AS_BL33
+#define PLAT_FIP_MAX_SIZE (0x8000000)
+#define PLAT_MMC_DATA_BASE (0x10000000)
+#define PLAT_MMC_DATA_SIZE (0x100000)
+# else
#define PLAT_FIP_MAX_SIZE (0x1000000)
#define PLAT_MMC_DATA_BASE (0xffe3c000)
#define PLAT_MMC_DATA_SIZE (0x2000)
+# endif
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..c477787 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
*/
@@ -18,6 +19,8 @@
#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 +30,13 @@
#define CAD_QSPIDATA_OFST 0xff900000
#define CAD_QSPI_OFFSET 0xff8d2000
+/* SDMMC Setting */
+# if ARM_LINUX_KERNEL_AS_BL33
+#define SOCFPGA_MMC_BLOCK_SIZE U(32768)
+# else
+#define SOCFPGA_MMC_BLOCK_SIZE U(8192)
+# endif
+
/* Register Mapping */
#define SOCFPGA_CCU_NOC_REG_BASE U(0xf7000000)
#define SOCFPGA_F2SDRAMMGR_REG_BASE U(0xf8024000)
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..cd5b076 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
*/
@@ -17,6 +18,8 @@
#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 +29,13 @@
#define CAD_QSPIDATA_OFST 0xff900000
#define CAD_QSPI_OFFSET 0xff8d2000
+/* SDMMC Setting */
+# if ARM_LINUX_KERNEL_AS_BL33
+#define SOCFPGA_MMC_BLOCK_SIZE U(32768)
+# else
+#define SOCFPGA_MMC_BLOCK_SIZE U(8192)
+# endif
+
/* 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..0a33c3d 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
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/nxp/s32/s32g274ardb2/include/s32cc-ncore.h b/plat/nxp/s32/s32g274ardb2/include/s32cc-ncore.h
new file mode 100644
index 0000000..0c0870f
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/include/s32cc-ncore.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2019-2021, 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef S32G2_NCORE_H
+#define S32G2_NCORE_H
+
+#include <stdbool.h>
+
+#define NCORE_BASE_ADDR UL(0x50400000)
+
+#define A53_CLUSTER0_CAIU U(0)
+#define A53_CLUSTER1_CAIU U(1)
+
+/**
+ * Directory Unit Registers
+ *
+ * The directory provides a point of serialization for establishing transaction
+ * ordering and sequences coherence operations and memory accesses.
+ */
+#define NCORE_DIRU(N) (NCORE_BASE_ADDR + UL(0x80000) + ((N) * UL(0x1000)))
+
+/* DIRU Snoop Filtering Enable */
+#define NCORE_DIRUSFE(N) (NCORE_DIRU(N) + UL(0x10))
+#define NCORE_DIRUSFE_SFEN(SF) BIT_32(SF)
+
+/* DIRU Caching Agent Snoop Enable */
+#define NCORE_DIRUCASE(N) (NCORE_DIRU(N) + UL(0x40))
+#define NCORE_DIRUCASE_CASNPEN(CAIU) BIT_32(CAIU)
+
+/* DIRU Snoop Filter Maintenance Control */
+#define NCORE_DIRUSFMC(N) (NCORE_DIRU(N) + UL(0x80))
+#define NCORE_DIRUSFMC_SFID(SF) ((SF) << 16U)
+#define NCORE_DIRUSFMC_SFMNTOP_ALL U(0x0)
+
+/* DIRU Snoop Filter Maintenance Activity */
+#define NCORE_DIRUSFMA(N) (NCORE_DIRU(N) + UL(0x84))
+#define NCORE_DIRUSFMA_MNTOPACTV BIT_32(0)
+
+/**
+ * Coherent Agent Interface Unit Registers
+ *
+ * CAI provides a means for a fully-coherent agent to be connected to the Ncore.
+ * The CAI behaves as a fully-coherent slave.
+ */
+#define NCORE_CAIU(N) (NCORE_BASE_ADDR + ((N) * UL(0x1000)))
+#define NCORE_CAIU0_BASE_ADDR NCORE_BASE_ADDR
+
+/* CAIU Transaction Control */
+#define NCORE_CAIUTC_OFF UL(0x0)
+#define NCORE_CAIUTC_ISOLEN_SHIFT U(1)
+#define NCORE_CAIUTC_ISOLEN_MASK BIT_32(NCORE_CAIUTC_ISOLEN_SHIFT)
+
+#define NCORE_CAIUTC(N) (NCORE_CAIU(N) + NCORE_CAIUTC_OFF)
+
+/* CAIU Identification */
+#define NCORE_CAIUID(n) (NCORE_CAIU(n) + UL(0xFFC))
+#define NCORE_CAIUID_TYPE GENMASK_32(U(19), U(16))
+#define NCORE_CAIUID_TYPE_ACE_DVM U(0x0)
+
+/**
+ * Coherent Subsystem Registers
+ */
+#define NCORE_CSR (NCORE_BASE_ADDR + UL(0xFF000))
+
+/* Coherent Subsystem ACE DVM Snoop Enable */
+#define NCORE_CSADSE (NCORE_CSR + UL(0x40))
+#define NCORE_CSADSE_DVMSNPEN(CAIU) BIT_32(CAIU)
+
+/* Coherent Subsystem Identification */
+#define NCORE_CSID (NCORE_CSR + UL(0xFFC))
+#define NCORE_CSID_NUMSFS_SHIFT U(18)
+#define NCORE_CSID_NUMSFS_MASK GENMASK_32(U(22), NCORE_CSID_NUMSFS_SHIFT)
+#define NCORE_CSID_NUMSFS(CSIDR) (((CSIDR) & NCORE_CSID_NUMSFS_MASK) \
+ >> NCORE_CSID_NUMSFS_SHIFT)
+
+/* Coherent Subsystem Unit Identification */
+#define NCORE_CSUID (NCORE_CSR + UL(0xFF8))
+#define NCORE_CSUID_NUMCMIUS_SHIFT U(24)
+#define NCORE_CSUID_NUMCMIUS_MASK GENMASK_32(U(29), NCORE_CSUID_NUMCMIUS_SHIFT)
+#define NCORE_CSUID_NUMCMIUS(CSUIDR) (((CSUIDR) & NCORE_CSUID_NUMCMIUS_MASK) \
+ >> NCORE_CSUID_NUMCMIUS_SHIFT)
+#define NCORE_CSUID_NUMDIRUS_SHIFT U(16)
+#define NCORE_CSUID_NUMDIRUS_MASK GENMASK_32(U(21), NCORE_CSUID_NUMDIRUS_SHIFT)
+#define NCORE_CSUID_NUMDIRUS(CSUIDR) (((CSUIDR) & NCORE_CSUID_NUMDIRUS_MASK) \
+ >> NCORE_CSUID_NUMDIRUS_SHIFT)
+#define NCORE_CSUID_NUMNCBUS_SHIFT U(8)
+#define NCORE_CSUID_NUMNCBUS_MASK GENMASK_32(U(13), NCORE_CSUID_NUMNCBUS_SHIFT)
+#define NCORE_CSUID_NUMNCBUS(CSUIDR) (((CSUIDR) & NCORE_CSUID_NUMNCBUS_MASK) \
+ >> NCORE_CSUID_NUMNCBUS_SHIFT)
+
+#ifndef __ASSEMBLER__
+void ncore_caiu_online(uint32_t caiu);
+void ncore_caiu_offline(uint32_t caiu);
+void ncore_init(void);
+bool ncore_is_caiu_online(uint32_t caiu);
+void ncore_disable_caiu_isolation(uint32_t caiu);
+#endif /* __ASSEMBLER__ */
+
+#endif /* S32G2_NCORE_H */
diff --git a/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c b/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
index 705832c..4645f01 100644
--- a/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
+++ b/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
@@ -11,6 +11,7 @@
#include <plat_console.h>
#include <s32cc-clk-drv.h>
#include <plat_io_storage.h>
+#include <s32cc-ncore.h>
#define SIUL2_PC09_MSCR UL(0x4009C2E4)
#define SIUL2_PC10_MSCR UL(0x4009C2E8)
@@ -62,6 +63,14 @@
linflex_config_pinctrl();
console_s32g2_register();
+ /* Restore (clear) the CAIUTC[IsolEn] bit for the primary cluster, which
+ * we have manually set during early BL2 boot.
+ */
+ ncore_disable_caiu_isolation(A53_CLUSTER0_CAIU);
+
+ ncore_init();
+ ncore_caiu_online(A53_CLUSTER0_CAIU);
+
plat_s32g2_io_setup();
}
diff --git a/plat/nxp/s32/s32g274ardb2/plat_helpers.S b/plat/nxp/s32/s32g274ardb2/plat_helpers.S
index 10c0035..7121900 100644
--- a/plat/nxp/s32/s32g274ardb2/plat_helpers.S
+++ b/plat/nxp/s32/s32g274ardb2/plat_helpers.S
@@ -6,10 +6,7 @@
#include <asm_macros.S>
#include <platform_def.h>
-
-#define S32G_NCORE_CAIU0_BASE_ADDR UL(0x50400000)
-#define S32G_NCORE_CAIUTC_OFF U(0x0)
-#define S32G_NCORE_CAIUTC_ISOLEN_SHIFT U(1)
+#include <s32cc-ncore.h>
.globl plat_crash_console_flush
.globl plat_crash_console_init
@@ -104,12 +101,12 @@
* Clobber list: x0, x1, x2
*/
func plat_reset_handler
- mov x0, #S32G_NCORE_CAIU0_BASE_ADDR
- ldr w1, [x0, #S32G_NCORE_CAIUTC_OFF]
+ mov x0, #NCORE_CAIU0_BASE_ADDR
+ ldr w1, [x0, #NCORE_CAIUTC_OFF]
movz w2, #1
- lsl w2, w2, #S32G_NCORE_CAIUTC_ISOLEN_SHIFT
+ lsl w2, w2, #NCORE_CAIUTC_ISOLEN_SHIFT
orr w1, w1, w2
- str w1, [x0, #S32G_NCORE_CAIUTC_OFF]
+ str w1, [x0, #NCORE_CAIUTC_OFF]
ret
endfunc plat_reset_handler
diff --git a/plat/nxp/s32/s32g274ardb2/platform.mk b/plat/nxp/s32/s32g274ardb2/platform.mk
index 7dc287d..7d6e960 100644
--- a/plat/nxp/s32/s32g274ardb2/platform.mk
+++ b/plat/nxp/s32/s32g274ardb2/platform.mk
@@ -53,6 +53,7 @@
${PLAT_S32G274ARDB2}/plat_bl2_el3_setup.c \
${PLAT_S32G274ARDB2}/plat_bl2_image_desc.c \
${PLAT_S32G274ARDB2}/plat_io_storage.c \
+ ${PLAT_S32G274ARDB2}/s32cc_ncore.c \
common/desc_image_load.c \
drivers/io/io_fip.c \
drivers/io/io_memmap.c \
diff --git a/plat/nxp/s32/s32g274ardb2/s32cc_ncore.c b/plat/nxp/s32/s32g274ardb2/s32cc_ncore.c
new file mode 100644
index 0000000..aa60ac4
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/s32cc_ncore.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2019-2021, 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <s32cc-ncore.h>
+
+static void ncore_diru_online(uint32_t diru)
+{
+ uint32_t numsfs, sf;
+
+ numsfs = NCORE_CSID_NUMSFS(mmio_read_32(NCORE_CSID)) + 1U;
+
+ /* Initialize all entries maintenance operation for each snoop filter */
+ for (sf = 0U; sf < numsfs; sf++) {
+ mmio_write_32(NCORE_DIRUSFMC(diru), NCORE_DIRUSFMC_SFID(sf) |
+ NCORE_DIRUSFMC_SFMNTOP_ALL);
+
+ while ((mmio_read_32(NCORE_DIRUSFMA(diru)) & NCORE_DIRUSFMA_MNTOPACTV) != 0U) {
+ }
+
+ mmio_setbits_32(NCORE_DIRUSFE(diru), NCORE_DIRUSFE_SFEN(sf));
+ }
+}
+
+void ncore_disable_caiu_isolation(uint32_t caiu)
+{
+ /* Exit from low-power state */
+ mmio_clrbits_32(NCORE_CAIUTC(caiu), NCORE_CAIUTC_ISOLEN_MASK);
+}
+
+static void set_caiu(uint32_t caiu, bool on)
+{
+ uint32_t dirucase, csadser, caiuidr;
+ uint32_t numdirus, diru;
+
+ /* Enable or disable snoop messages to the CAI for each DIRU */
+ numdirus = NCORE_CSUID_NUMDIRUS(mmio_read_32(NCORE_CSUID));
+ for (diru = 0; diru < numdirus; diru++) {
+ dirucase = mmio_read_32(NCORE_DIRUCASE(diru));
+
+ if (on) {
+ dirucase |= NCORE_DIRUCASE_CASNPEN(caiu);
+ } else {
+ dirucase &= ~NCORE_DIRUCASE_CASNPEN(caiu);
+ }
+
+ mmio_write_32(NCORE_DIRUCASE(diru), dirucase);
+ }
+
+ /* Enable or disable DVM messages to the CAI */
+ caiuidr = mmio_read_32(NCORE_CAIUID(caiu));
+ if ((caiuidr & NCORE_CAIUID_TYPE) == NCORE_CAIUID_TYPE_ACE_DVM) {
+ csadser = mmio_read_32(NCORE_CSADSE);
+
+ if (on) {
+ csadser |= NCORE_CSADSE_DVMSNPEN(caiu);
+ } else {
+ csadser &= ~NCORE_CSADSE_DVMSNPEN(caiu);
+ }
+
+ mmio_write_32(NCORE_CSADSE, csadser);
+ }
+}
+
+void ncore_caiu_online(uint32_t caiu)
+{
+ set_caiu(caiu, true);
+}
+
+void ncore_caiu_offline(uint32_t caiu)
+{
+ set_caiu(caiu, false);
+}
+
+bool ncore_is_caiu_online(uint32_t caiu)
+{
+ uint32_t stat = mmio_read_32(NCORE_CSADSE);
+
+ return ((stat & NCORE_CSADSE_DVMSNPEN(caiu)) != 0U);
+}
+
+void ncore_init(void)
+{
+ uint32_t csuidr = mmio_read_32(NCORE_CSUID);
+ uint32_t numdirus, diru;
+
+ numdirus = NCORE_CSUID_NUMDIRUS(csuidr);
+ for (diru = 0U; diru < numdirus; diru++) {
+ /**
+ * Transition the directory to an online state by ensuring that
+ * all DIRUs within the interface are operational.
+ */
+ ncore_diru_online(diru);
+ }
+}
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 20cbc6e..2fabc41 100644
--- a/plat/st/stm32mp2/bl2_plat_setup.c
+++ b/plat/st/stm32mp2/bl2_plat_setup.c
@@ -15,11 +15,13 @@
#include <drivers/mmc.h>
#include <drivers/st/regulator_fixed.h>
#include <drivers/st/stm32mp2_ddr_helpers.h>
+#include <drivers/st/stm32mp2_ram.h>
#include <drivers/st/stm32mp_pmic2.h>
#include <drivers/st/stm32mp_risab_regs.h>
#include <lib/fconf/fconf.h>
#include <lib/fconf/fconf_dyn_cfg_getter.h>
#include <lib/mmio.h>
+#include <lib/optee_utils.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
@@ -135,6 +137,21 @@
void bl2_platform_setup(void)
{
+ int ret;
+
+ ret = stm32mp2_ddr_probe();
+ if (ret != 0) {
+ ERROR("DDR probe: error %d\n", ret);
+ panic();
+ }
+
+ /* Map DDR for binary load, now with cacheable attribute */
+ ret = mmap_add_dynamic_region(STM32MP_DDR_BASE, STM32MP_DDR_BASE,
+ STM32MP_DDR_MAX_SIZE, MT_MEMORY | MT_RW | MT_SECURE);
+ if (ret < 0) {
+ ERROR("DDR mapping: error %d\n", ret);
+ panic();
+ }
}
static void reset_backup_domain(void)
@@ -258,10 +275,15 @@
{
int err = 0;
bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+ bl_mem_params_node_t *pager_mem_params;
const struct dyn_cfg_dtb_info_t *config_info;
unsigned int i;
const unsigned int image_ids[] = {
BL31_IMAGE_ID,
+ SOC_FW_CONFIG_ID,
+ BL32_IMAGE_ID,
+ BL33_IMAGE_ID,
+ HW_CONFIG_ID,
};
assert(bl_mem_params != NULL);
@@ -305,6 +327,28 @@
case BL31_IMAGE_ID:
bl_mem_params->ep_info.pc = config_info->config_addr;
break;
+
+ case BL32_IMAGE_ID:
+ bl_mem_params->ep_info.pc = config_info->config_addr;
+
+ /* In case of OPTEE, initialize address space with tos_fw addr */
+ pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+ if (pager_mem_params != NULL) {
+ pager_mem_params->image_info.image_base =
+ config_info->config_addr;
+ pager_mem_params->image_info.image_max_size =
+ config_info->config_max_size;
+ }
+ break;
+
+ case BL33_IMAGE_ID:
+ bl_mem_params->ep_info.pc = config_info->config_addr;
+ break;
+
+ case HW_CONFIG_ID:
+ case SOC_FW_CONFIG_ID:
+ break;
+
default:
return -EINVAL;
}
@@ -317,6 +361,30 @@
break;
+ case BL32_IMAGE_ID:
+ if ((bl_mem_params->image_info.image_base != 0UL) &&
+ (optee_header_is_valid(bl_mem_params->image_info.image_base))) {
+ /* BL32 is OP-TEE header */
+ bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
+ pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+ assert(pager_mem_params != NULL);
+
+ err = parse_optee_header(&bl_mem_params->ep_info,
+ &pager_mem_params->image_info,
+ NULL);
+ if (err != 0) {
+ ERROR("OPTEE header parse error.\n");
+ panic();
+ }
+
+ /* Set optee boot info from parsed header data */
+ bl_mem_params->ep_info.args.arg0 = 0U; /* Unused */
+ bl_mem_params->ep_info.args.arg1 = 0U; /* Unused */
+ bl_mem_params->ep_info.args.arg2 = 0U; /* No DT supported */
+ }
+ break;
+
+ case BL33_IMAGE_ID:
default:
/* Do nothing in default case */
break;
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 f845560..2513180 100644
--- a/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
+++ b/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
@@ -67,8 +67,85 @@
VERSION_2, image_info_t,
IMAGE_ATTRIB_SKIP_LOADING),
+ .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,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_SKIP_LOADING),
+
+ .next_handoff_image_id = BL33_IMAGE_ID,
+ },
+
+ /* Fill BL32 external 1 image related information */
+ {
+ .image_id = BL32_EXTRA1_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | NON_EXECUTABLE),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_SKIP_LOADING),
+
.next_handoff_image_id = INVALID_IMAGE_ID,
},
+
+ /* Fill HW_CONFIG related information if it exists */
+ {
+ .image_id = HW_CONFIG_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t,
+ NON_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 BL33 related information */
+ {
+ .image_id = BL33_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ NON_SECURE | EXECUTABLE),
+
+ .ep_info.spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_SKIP_LOADING),
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ }
};
REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
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_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_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/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..a299d14 100644
--- a/plat/xilinx/versal/plat_psci.c
+++ b/plat/xilinx/versal/plat_psci.c
@@ -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/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..7a653d4 100644
--- a/plat/xilinx/versal_net/plat_psci_pm.c
+++ b/plat/xilinx/versal_net/plat_psci_pm.c
@@ -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/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/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..5a1e218 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -2791,7 +2791,7 @@
{
struct pm_pll *pll = pm_clock_get_pll(clock_id);
- if (pll) {
+ if (pll != NULL) {
*node_id = pll->nid;
return PM_RET_SUCCESS;
}
@@ -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;
}
@@ -3013,7 +3013,7 @@
{
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;
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..d7c9f24 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);
}
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);