Merge "refactor(cpufeat): add FGT2 and Debugv8p9 to realm state" into integration
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index a871c59..67f29f0 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -1030,7 +1030,7 @@
 For Cortex-A720_AE, the following errata build flags are defined :
 
 -  ``ERRATA_A720_AE_3699562``: This applies errata 3699562 workaround
-   to Cortex-A715_AE CPU. This needs to be enabled for revisions r0p0.
+   to Cortex-A720_AE CPU. This needs to be enabled for revisions r0p0.
    It is still open.
 
 For Cortex-A725, the following errata build flags are defined :
diff --git a/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h b/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
index 665930b..79e5ed1 100644
--- a/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
+++ b/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
@@ -11,6 +11,7 @@
 #define ARMPLL_BASE_ADDR		(0x40038000UL)
 #define PERIPHPLL_BASE_ADDR		(0x4003C000UL)
 #define ARM_DFS_BASE_ADDR		(0x40054000UL)
+#define PERIPH_DFS_BASE_ADDR		(0x40058000UL)
 #define CGM0_BASE_ADDR			(0x40030000UL)
 #define CGM1_BASE_ADDR			(0x40034000UL)
 #define DDRPLL_BASE_ADDR		(0x40044000UL)
@@ -92,6 +93,25 @@
 #define MC_CGM_MUXn_CSS_SWTRG_SAFE_CLK_INACTIVE	0x5U
 #define MC_CGM_MUXn_CSS_SWIP		BIT_32(16U)
 #define MC_CGM_MUXn_CSS_SAFE_SW		BIT_32(3U)
+#define MC_CGM_MUXn_DCm(CGM_ADDR, MUX, DC) \
+					(((CGM_ADDR) + 0x308UL) + \
+					 ((MUX) * 0x40UL) + ((DC) * 0x4UL))
+#define MC_CGM_MUXn_DCm_DIV_OFFSET	(16U)
+#define MC_CGM_MUXn_DCm_DIV_MASK	GENMASK_32(23U, MC_CGM_MUXn_DCm_DIV_OFFSET)
+#define MC_CGM_MUXn_DCm_DIV_SET(VAL)	(MC_CGM_MUXn_DCm_DIV_MASK & ((VAL) \
+					 << MC_CGM_MUXn_DCm_DIV_OFFSET))
+#define MC_CGM_MUXn_DCm_DIV(VAL)	((MC_CGM_MUXn_DCm_DIV_MASK & (VAL)) \
+					 >> MC_CGM_MUXn_DCm_DIV_OFFSET)
+#define MC_CGM_MUXn_DCm_DE		BIT_32(31U)
+#define MC_CGM_MUXn_DIV_UPD_STAT(CGM_ADDR, MUX) \
+					(((CGM_ADDR) + 0x33CUL + ((MUX) * 0x40UL)))
+#define MC_CGM_MUXn_DIV_UPD_STAT_DIVSTAT_OFFSET	(0U)
+#define MC_CGM_MUXn_DIV_UPD_STAT_DIVSTAT(CSS) \
+					((MC_CGM_MUXn_DIV_UPD_STAT_DIVSTAT_MASK \
+					  & (CSS)) \
+					  >> MC_CGM_MUXn_DIV_UPD_STAT_DIVSTAT_OFFSET)
+#define MC_CGM_MUXn_DIV_UPD_STAT_DIVSTAT_MASK	BIT_32(0U)
+
 
 /* DFS */
 #define DFS_PORTSR(DFS_ADDR)		((DFS_ADDR) + 0xCUL)
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
index c235e04..0a71152 100644
--- a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
@@ -24,6 +24,7 @@
 	uintptr_t armpll_base;
 	uintptr_t periphpll_base;
 	uintptr_t armdfs_base;
+	uintptr_t periphdfs_base;
 	uintptr_t cgm0_base;
 	uintptr_t cgm1_base;
 	uintptr_t cgm5_base;
@@ -58,6 +59,7 @@
 		.armpll_base = ARMPLL_BASE_ADDR,
 		.periphpll_base = PERIPHPLL_BASE_ADDR,
 		.armdfs_base = ARM_DFS_BASE_ADDR,
+		.periphdfs_base = PERIPH_DFS_BASE_ADDR,
 		.cgm0_base = CGM0_BASE_ADDR,
 		.cgm1_base = CGM1_BASE_ADDR,
 		.cgm5_base = MC_CGM5_BASE_ADDR,
@@ -110,6 +112,9 @@
 	case S32CC_ARM_DFS:
 		*base = drv->armdfs_base;
 		break;
+	case S32CC_PERIPH_DFS:
+		*base = drv->periphdfs_base;
+		break;
 	case S32CC_CGM0:
 		*base = drv->cgm0_base;
 		break;
@@ -1085,6 +1090,232 @@
 	return get_module_rate(block->parent, drv, rate, ldepth);
 }
 
+static void cgm_mux_div_config(uintptr_t cgm_addr, uint32_t mux,
+			       uint32_t dc, uint32_t div_index)
+{
+	uint32_t updstat;
+	uint32_t dc_val = mmio_read_32(MC_CGM_MUXn_DCm(cgm_addr, mux, div_index));
+
+	dc_val &= (MC_CGM_MUXn_DCm_DIV_MASK | MC_CGM_MUXn_DCm_DE);
+
+	if (dc_val == (MC_CGM_MUXn_DCm_DE | MC_CGM_MUXn_DCm_DIV_SET(dc))) {
+		return;
+	}
+
+	/* Set the divider */
+	mmio_write_32(MC_CGM_MUXn_DCm(cgm_addr, mux, div_index),
+		      MC_CGM_MUXn_DCm_DE | MC_CGM_MUXn_DCm_DIV_SET(dc));
+
+	/* Wait for divider to get updated */
+	do {
+		updstat = mmio_read_32(MC_CGM_MUXn_DIV_UPD_STAT(cgm_addr, mux));
+	} while (MC_CGM_MUXn_DIV_UPD_STAT_DIVSTAT(updstat) != 0U);
+}
+
+static inline struct s32cc_clkmux *get_cgm_div_mux(const struct s32cc_cgm_div *cgm_div)
+{
+	const struct s32cc_clk_obj *parent = cgm_div->parent;
+	const struct s32cc_clk_obj *mux_obj;
+	const struct s32cc_clk *clk;
+
+	if (parent == NULL) {
+		ERROR("Failed to identify CGM DIV's parent\n");
+		return NULL;
+	}
+
+	if (parent->type != s32cc_clk_t) {
+		ERROR("The parent of the CGM DIV isn't a clock\n");
+		return NULL;
+	}
+
+	clk = s32cc_obj2clk(parent);
+
+	if (clk->module == NULL) {
+		ERROR("The clock isn't connected to a module\n");
+		return NULL;
+	}
+
+	mux_obj = clk->module;
+
+	if ((mux_obj->type != s32cc_clkmux_t) &&
+	    (mux_obj->type != s32cc_shared_clkmux_t)) {
+		ERROR("The parent of the CGM DIV isn't a MUX\n");
+		return NULL;
+	}
+
+	return s32cc_obj2clkmux(mux_obj);
+}
+
+static int enable_cgm_div(struct s32cc_clk_obj *module,
+			  const struct s32cc_clk_drv *drv, unsigned int depth)
+{
+	const struct s32cc_cgm_div *cgm_div = s32cc_obj2cgmdiv(module);
+	const struct s32cc_clkmux *mux;
+	unsigned int ldepth = depth;
+	uintptr_t cgm_addr = 0ULL;
+	uint64_t pfreq, dc64;
+	uint32_t dc;
+	int ret;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (cgm_div->parent == NULL) {
+		ERROR("Failed to identify CGM divider's parent\n");
+		return -EINVAL;
+	}
+
+	if (cgm_div->freq == 0U) {
+		ERROR("The frequency of the divider %" PRIu32 " is not set\n",
+		      cgm_div->index);
+		return -EINVAL;
+	}
+
+	mux = get_cgm_div_mux(cgm_div);
+	if (mux == NULL) {
+		return -EINVAL;
+	}
+
+	ret = get_base_addr(mux->module, drv, &cgm_addr);
+	if (ret != 0) {
+		ERROR("Failed to get CGM base address of the MUX module %d\n",
+		      mux->module);
+		return ret;
+	}
+
+	ret = get_module_rate(cgm_div->parent, drv, &pfreq, ldepth);
+	if (ret != 0) {
+		ERROR("Failed to enable the div due to unknown frequency of "
+		      "the CGM MUX %" PRIu8 "(CGM=%" PRIxPTR ")\n",
+		      mux->index, cgm_addr);
+		return -EINVAL;
+	}
+
+	dc64 = ((pfreq * FP_PRECISION) / cgm_div->freq) / FP_PRECISION;
+	dc = (uint32_t)dc64;
+
+	if ((pfreq / dc64) != cgm_div->freq) {
+		ERROR("Cannot set CGM divider (mux:%" PRIu8 ", div:%" PRIu32
+		      ") for input = %lu & output = %lu, Nearest freq = %lu\n",
+		mux->index, cgm_div->index, (unsigned long)pfreq,
+		cgm_div->freq, (unsigned long)(pfreq / dc));
+		return -EINVAL;
+	}
+
+	cgm_mux_div_config(cgm_addr, mux->index, dc - 1U, cgm_div->index);
+	return 0;
+}
+
+static int set_cgm_div_freq(const struct s32cc_clk_obj *module,
+			    unsigned long rate, unsigned long *orate,
+			    unsigned int *depth)
+{
+	struct s32cc_cgm_div *cgm_div = s32cc_obj2cgmdiv(module);
+	int ret;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (cgm_div->parent == NULL) {
+		ERROR("Failed to identify the CGM divider's parent\n");
+		return -EINVAL;
+	}
+
+	cgm_div->freq = rate;
+	*orate = rate;
+
+	return 0;
+}
+
+static inline bool is_cgm_div_enabled(uintptr_t cgm_addr, uint32_t mux,
+				      uint32_t div_index)
+{
+	uint32_t dc_val;
+
+	dc_val = mmio_read_32(MC_CGM_MUXn_DCm(cgm_addr, mux, div_index));
+
+	return ((dc_val & MC_CGM_MUXn_DCm_DE) != 0U);
+}
+
+static unsigned long calc_cgm_div_freq(uintptr_t cgm_addr, uint32_t mux,
+				       uint32_t div_index, unsigned long pfreq)
+{
+	uint32_t dc_val;
+	uint32_t dc_div;
+
+	dc_val = mmio_read_32(MC_CGM_MUXn_DCm(cgm_addr, mux, div_index));
+	dc_div = MC_CGM_MUXn_DCm_DIV(dc_val) + 1U;
+
+	return pfreq * FP_PRECISION / dc_div / FP_PRECISION;
+}
+
+static int get_cgm_div_freq(const struct s32cc_clk_obj *module,
+			    const struct s32cc_clk_drv *drv,
+			    unsigned long *rate, unsigned int depth)
+{
+	const struct s32cc_cgm_div *cgm_div = s32cc_obj2cgmdiv(module);
+	const struct s32cc_clkmux *mux;
+	unsigned int ldepth = depth;
+	uintptr_t cgm_addr = 0ULL;
+	unsigned long pfreq;
+	int ret;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (cgm_div->parent == NULL) {
+		ERROR("Failed to identify CGM divider's parent\n");
+		return -EINVAL;
+	}
+
+	mux = get_cgm_div_mux(cgm_div);
+	if (mux == NULL) {
+		return -EINVAL;
+	}
+
+	ret = get_base_addr(mux->module, drv, &cgm_addr);
+	if (ret != 0) {
+		ERROR("Failed to get CGM base address of the MUX module %d\n",
+		      mux->module);
+		return ret;
+	}
+
+	if (!is_cgm_div_enabled(cgm_addr, mux->index, cgm_div->index)) {
+		*rate = cgm_div->freq;
+		return 0;
+	}
+
+	ret = get_module_rate(cgm_div->parent, drv, &pfreq, ldepth);
+	if (ret != 0) {
+		ERROR("Failed to get the frequency of CGM MUX %" PRIu8 "(CGM=0x%" PRIxPTR ")\n",
+		      mux->index, cgm_addr);
+		return ret;
+	}
+
+	*rate = calc_cgm_div_freq(cgm_addr, mux->index, cgm_div->index, pfreq);
+
+	return 0;
+}
+
+static struct s32cc_clk_obj *
+get_cgm_div_parent(const struct s32cc_clk_obj *module)
+{
+	const struct s32cc_cgm_div *cgm_div = s32cc_obj2cgmdiv(module);
+
+	if (cgm_div->parent == NULL) {
+		ERROR("Failed to identify the CGM divider's parent\n");
+		return NULL;
+	}
+
+	return cgm_div->parent;
+}
+
 static int no_enable(struct s32cc_clk_obj *module,
 		     const struct s32cc_clk_drv *drv,
 		     unsigned int depth)
@@ -1131,7 +1362,7 @@
 			 unsigned int depth)
 {
 	struct s32cc_clk_obj *parent = get_module_parent(module);
-	static const enable_clk_t enable_clbs[12] = {
+	static const enable_clk_t enable_clbs[13] = {
 		[s32cc_clk_t] = no_enable,
 		[s32cc_osc_t] = enable_osc,
 		[s32cc_pll_t] = enable_pll,
@@ -1143,6 +1374,7 @@
 		[s32cc_part_t] = enable_part,
 		[s32cc_part_block_t] = enable_part_block,
 		[s32cc_part_block_link_t] = enable_part_block_link,
+		[s32cc_cgm_div_t] = enable_cgm_div,
 	};
 	unsigned int ldepth = depth;
 	uint32_t index;
@@ -1558,6 +1790,13 @@
 	return 0;
 }
 
+static inline struct s32cc_clk_obj *get_fixed_div_parent(const struct s32cc_clk_obj *module)
+{
+	const struct s32cc_fixed_div *fdiv = s32cc_obj2fixeddiv(module);
+
+	return fdiv->parent;
+}
+
 static int set_mux_freq(const struct s32cc_clk_obj *module, unsigned long rate,
 			unsigned long *orate, unsigned int *depth)
 {
@@ -1703,6 +1942,28 @@
 	return 0;
 }
 
+static int set_part_block_link_freq(const struct s32cc_clk_obj *module,
+				    unsigned long rate, unsigned long *orate,
+				    const unsigned int *depth)
+{
+	const struct s32cc_part_block_link *link = s32cc_obj2partblocklink(module);
+	const struct s32cc_clk_obj *parent = link->parent;
+	unsigned int ldepth = *depth;
+	int ret;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (parent == NULL) {
+		ERROR("Partition block link with no parent\n");
+		return -EINVAL;
+	}
+
+	return set_module_rate(parent, rate, orate, &ldepth);
+}
+
 static int set_module_rate(const struct s32cc_clk_obj *module,
 			   unsigned long rate, unsigned long *orate,
 			   unsigned int *depth)
@@ -1738,12 +1999,24 @@
 	case s32cc_shared_clkmux_t:
 		ret = set_mux_freq(module, rate, orate, depth);
 		break;
+	case s32cc_cgm_div_t:
+		ret = set_cgm_div_freq(module, rate, orate, depth);
+		break;
 	case s32cc_dfs_t:
 		ERROR("Setting the frequency of a DFS is not allowed!");
 		break;
 	case s32cc_dfs_div_t:
 		ret = set_dfs_div_freq(module, rate, orate, depth);
 		break;
+	case s32cc_part_block_link_t:
+		ret = set_part_block_link_freq(module, rate, orate, depth);
+		break;
+	case s32cc_part_t:
+		ERROR("It's not allowed to set the frequency of a partition !");
+		break;
+	case s32cc_part_block_t:
+		ERROR("It's not allowed to set the frequency of a partition block !");
+		break;
 	default:
 		break;
 	}
@@ -1801,6 +2074,9 @@
 	case s32cc_part_block_link_t:
 		ret = get_part_block_link_freq(module, drv, rate, ldepth);
 		break;
+	case s32cc_cgm_div_t:
+		ret = get_cgm_div_freq(module, drv, rate, ldepth);
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -1862,7 +2138,7 @@
 
 static struct s32cc_clk_obj *get_module_parent(const struct s32cc_clk_obj *module)
 {
-	static const get_parent_clb_t parents_clbs[12] = {
+	static const get_parent_clb_t parents_clbs[13] = {
 		[s32cc_clk_t] = get_clk_parent,
 		[s32cc_osc_t] = get_no_parent,
 		[s32cc_pll_t] = get_pll_parent,
@@ -1872,8 +2148,10 @@
 		[s32cc_dfs_t] = get_dfs_parent,
 		[s32cc_dfs_div_t] = get_dfs_div_parent,
 		[s32cc_part_t] = get_no_parent,
+		[s32cc_fixed_div_t] = get_fixed_div_parent,
 		[s32cc_part_block_t] = get_part_block_parent,
 		[s32cc_part_block_link_t] = get_part_block_link_parent,
+		[s32cc_cgm_div_t] = get_cgm_div_parent,
 	};
 	uint32_t index;
 
@@ -1980,11 +2258,12 @@
 
 static int s32cc_clk_mmap_regs(const struct s32cc_clk_drv *drv)
 {
-	const uintptr_t base_addrs[11] = {
+	const uintptr_t base_addrs[12] = {
 		drv->fxosc_base,
 		drv->armpll_base,
 		drv->periphpll_base,
 		drv->armdfs_base,
+		drv->periphdfs_base,
 		drv->cgm0_base,
 		drv->cgm1_base,
 		drv->cgm5_base,
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_modules.c b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
index f7af465..127453e 100644
--- a/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
@@ -68,6 +68,12 @@
 				 S32CC_CLK_FXOSC, 0, 0);
 static struct s32cc_clk cgm0_mux8_clk = S32CC_MODULE_CLK(cgm0_mux8);
 
+static struct s32cc_clkmux cgm0_mux14 =
+	S32CC_CLKMUX_INIT(S32CC_CGM0, 14, 2,
+			  S32CC_CLK_FIRC,
+			  S32CC_CLK_PERIPH_PLL_DFS3, 0, 0, 0);
+static struct s32cc_clk cgm0_mux14_clk = S32CC_MODULE_CLK(cgm0_mux14);
+
 /* XBAR */
 static struct s32cc_clk xbar_2x_clk =
 	S32CC_CHILD_CLK(cgm0_mux0_clk, 48 * MHZ, 800 * MHZ);
@@ -142,6 +148,14 @@
 static struct s32cc_clk periph_pll_phi3_clk =
 	S32CC_FREQ_MODULE_CLK(periph_pll_phi3_div, 0, 133333333);
 
+/* PERIPH DFS */
+static struct s32cc_dfs periphdfs =
+	S32CC_DFS_INIT(periphpll, S32CC_PERIPH_DFS);
+static struct s32cc_dfs_div periph_dfs3_div =
+	S32CC_DFS_DIV_INIT(periphdfs, 0);
+static struct s32cc_clk periph_dfs3_clk =
+	S32CC_FREQ_MODULE_CLK(periph_dfs3_div, 416 * MHZ, 800 * MHZ);
+
 /* DDR PLL */
 static struct s32cc_clkmux ddr_pll_mux =
 	S32CC_CLKMUX_INIT(S32CC_DDR_PLL, 0, 2,
@@ -175,6 +189,15 @@
 static struct s32cc_clk ddr_clk =
 	S32CC_FREQ_MODULE_CLK(ddr_block_link, 0, 800 * MHZ);
 
+/* SDHC_CLK */
+static struct s32cc_part_block part0_block0 =
+	S32CC_PART_BLOCK(&part0, s32cc_part_block0);
+static struct s32cc_cgm_div sdhc_div = S32CC_CGM_DIV_INIT(cgm0_mux14_clk, 0);
+static struct s32cc_part_block_link usdhc_block_link =
+	S32CC_PART_BLOCK_LINK(sdhc_div, &part0_block0);
+static struct s32cc_clk usdhc_clk =
+	S32CC_FREQ_MODULE_CLK(usdhc_block_link, 0, 400 * MHZ);
+
 static struct s32cc_clk *s32cc_hw_clk_list[37] = {
 	/* Oscillators */
 	[S32CC_CLK_ID(S32CC_CLK_FIRC)] = &firc_clk,
@@ -186,6 +209,8 @@
 	[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_DFS1)] = &arm_dfs1_clk,
 	/* PERIPH PLL */
 	[S32CC_CLK_ID(S32CC_CLK_PERIPH_PLL_PHI3)] = &periph_pll_phi3_clk,
+	/* PERIPH DFS */
+	[S32CC_CLK_ID(S32CC_CLK_PERIPH_PLL_DFS3)] = &periph_dfs3_clk,
 	/* DDR PLL */
 	[S32CC_CLK_ID(S32CC_CLK_DDR_PLL_PHI0)] = &ddr_pll_phi0_clk,
 };
@@ -196,7 +221,7 @@
 	.n_clks = ARRAY_SIZE(s32cc_hw_clk_list),
 };
 
-static struct s32cc_clk *s32cc_arch_clk_list[22] = {
+static struct s32cc_clk *s32cc_arch_clk_list[24] = {
 	/* ARM PLL */
 	[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_MUX)] = &arm_pll_mux_clk,
 	[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_VCO)] = &arm_pll_vco_clk,
@@ -206,6 +231,7 @@
 	/* MC_CGM0 */
 	[S32CC_CLK_ID(S32CC_CLK_MC_CGM0_MUX0)] = &cgm0_mux0_clk,
 	[S32CC_CLK_ID(S32CC_CLK_MC_CGM0_MUX8)] = &cgm0_mux8_clk,
+	[S32CC_CLK_ID(S32CC_CLK_MC_CGM0_MUX14)] = &cgm0_mux14_clk,
 	/* XBAR */
 	[S32CC_CLK_ID(S32CC_CLK_XBAR_2X)] = &xbar_2x_clk,
 	[S32CC_CLK_ID(S32CC_CLK_XBAR)] = &xbar_clk,
@@ -229,6 +255,8 @@
 	[S32CC_CLK_ID(S32CC_CLK_MC_CGM5_MUX0)] = &cgm5_mux0_clk,
 	/* DDR */
 	[S32CC_CLK_ID(S32CC_CLK_DDR)] = &ddr_clk,
+	/* USDHC */
+	[S32CC_CLK_ID(S32CC_CLK_USDHC)] = &usdhc_clk,
 };
 
 static struct s32cc_clk_array s32cc_arch_clocks = {
diff --git a/drivers/nxp/clk/s32cc/s32cc_early_clks.c b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
index f001568..92182a0 100644
--- a/drivers/nxp/clk/s32cc/s32cc_early_clks.c
+++ b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2024 NXP
+ * Copyright 2024-2025 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,6 +18,8 @@
 #define S32CC_PERIPH_PLL_PHI3_FREQ	UART_CLOCK_HZ
 #define S32CC_DDR_PLL_VCO_FREQ		(1600U * MHZ)
 #define S32CC_DDR_PLL_PHI0_FREQ		(800U * MHZ)
+#define S32CC_PERIPH_DFS_PHI3_FREQ	(800U * MHZ)
+#define S32CC_USDHC_FREQ		(400U * MHZ)
 
 static int setup_fxosc(void)
 {
@@ -180,6 +182,35 @@
 	return ret;
 }
 
+static int enable_usdhc_clk(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX14,
+			     S32CC_CLK_PERIPH_PLL_DFS3);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_DFS3,
+			   S32CC_PERIPH_DFS_PHI3_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_USDHC, S32CC_USDHC_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_enable(S32CC_CLK_USDHC);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
 int s32cc_init_core_clocks(void)
 {
 	int ret;
@@ -241,5 +272,10 @@
 		return ret;
 	}
 
+	ret = enable_usdhc_clk();
+	if (ret != 0) {
+		return ret;
+	}
+
 	return ret;
 }
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h
index d34dc22..63716e8 100644
--- a/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause */
 /*
- * Copyright 2024 NXP
+ * Copyright 2024-2025 NXP
  */
 #ifndef S32CC_CLK_IDS_H
 #define S32CC_CLK_IDS_H
@@ -103,4 +103,8 @@
 #define S32CC_CLK_MC_CGM5_MUX0			S32CC_ARCH_CLK(20)
 #define S32CC_CLK_DDR				S32CC_ARCH_CLK(21)
 
+/* USDHC clock */
+#define S32CC_CLK_MC_CGM0_MUX14			S32CC_ARCH_CLK(22)
+#define S32CC_CLK_USDHC				S32CC_ARCH_CLK(23)
+
 #endif /* S32CC_CLK_IDS_H */
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h
index c91f3b6..285aeb3 100644
--- a/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h
@@ -19,6 +19,7 @@
 	s32cc_pll_out_div_t,
 	s32cc_dfs_t,
 	s32cc_dfs_div_t,
+	s32cc_cgm_div_t,
 	s32cc_clkmux_t,
 	s32cc_shared_clkmux_t,
 	s32cc_fixed_div_t,
@@ -37,6 +38,7 @@
 	S32CC_CGM0,
 	S32CC_CGM1,
 	S32CC_DDR_PLL,
+	S32CC_PERIPH_DFS,
 	S32CC_CGM5,
 };
 
@@ -287,6 +289,22 @@
 	.block = (BLOCK),                        \
 }
 
+struct s32cc_cgm_div {
+	struct s32cc_clk_obj desc;
+	struct s32cc_clk_obj *parent;
+	unsigned long freq;
+	uint32_t index;
+};
+
+#define S32CC_CGM_DIV_INIT(PARENT, INDEX) \
+{                                         \
+	.desc = {                         \
+		.type = s32cc_cgm_div_t,  \
+	},                                \
+	.parent = &(PARENT).desc,         \
+	.index = (INDEX),                 \
+}
+
 static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
 {
 	uintptr_t osc_addr;
@@ -399,4 +417,12 @@
 	return (struct s32cc_part_block_link *)blk_link;
 }
 
+static inline struct s32cc_cgm_div *s32cc_obj2cgmdiv(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t cgm_div_addr;
+
+	cgm_div_addr = ((uintptr_t)mod) - offsetof(struct s32cc_cgm_div, desc);
+	return (struct s32cc_cgm_div *)cgm_div_addr;
+}
+
 #endif /* S32CC_CLK_MODULES_H */
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index 498dedf..3e6c9f2 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -56,6 +56,10 @@
 	if (psci_get_pstate_id(power_state) != 0U)
 		return PSCI_E_INVALID_PARAMS;
 
+#if PSCI_OS_INIT_MODE
+	req_state->last_at_pwrlvl = psci_get_pstate_pwrlvl(power_state);
+#endif /* __PSCI_OS_INIT_MODE__ */
+
 	return PSCI_E_SUCCESS;
 }
 
diff --git a/plat/qemu/common/common.mk b/plat/qemu/common/common.mk
index 5e3a61a..2dc89bc 100644
--- a/plat/qemu/common/common.mk
+++ b/plat/qemu/common/common.mk
@@ -153,4 +153,12 @@
 PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/aarch64/arm_pauth.c
 endif
 
+ifeq (${TRANSFER_LIST}, 1)
+include lib/transfer_list/transfer_list.mk
+endif
+
+ifeq (${HOB_LIST}, 1)
+include lib/hob/hob.mk
+endif
+
 endif
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index 70e9faf..bd75abc 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -39,10 +39,6 @@
 add-lib-optee 		:= 	yes
 endif
 
-ifeq (${TRANSFER_LIST},1)
-include lib/transfer_list/transfer_list.mk
-endif
-
 ifeq ($(NEED_BL32),yes)
 $(eval $(call add_define,QEMU_LOAD_BL32))
 endif
diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h
index 5cc20b9..85bd233 100644
--- a/plat/qemu/qemu_sbsa/include/platform_def.h
+++ b/plat/qemu/qemu_sbsa/include/platform_def.h
@@ -150,9 +150,19 @@
  */
 #define BL31_SIZE			0x400000
 #define BL31_BASE			(BL31_LIMIT - BL31_SIZE)
-#define BL31_LIMIT			(BL1_RW_BASE)
+#define BL31_LIMIT			(BL1_RW_BASE - FW_HANDOFF_SIZE)
 #define BL31_PROGBITS_LIMIT		BL1_RW_BASE
 
+#if TRANSFER_LIST
+#define FW_HANDOFF_BASE			BL31_LIMIT
+#define FW_HANDOFF_LIMIT		(FW_HANDOFF_BASE + FW_HANDOFF_SIZE)
+#define FW_HANDOFF_SIZE			0x4000
+#else
+#define FW_HANDOFF_SIZE			0
+#endif
+#if TRANSFER_LIST
+#define FW_NS_HANDOFF_BASE		(NS_IMAGE_OFFSET - FW_HANDOFF_SIZE)
+#endif
 
 /*
  * BL3-2 specific defines.
@@ -174,14 +184,14 @@
 #define PLAT_PHY_ADDR_SPACE_SIZE	(1ull << 42)
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(1ull << 42)
 #if SPM_MM
-#define MAX_MMAP_REGIONS		12
-#define MAX_XLAT_TABLES			12
+#define MAX_MMAP_REGIONS		13
+#define MAX_XLAT_TABLES			13
 #elif ENABLE_RME
-#define MAX_MMAP_REGIONS		14
-#define MAX_XLAT_TABLES			14
+#define MAX_MMAP_REGIONS		15
+#define MAX_XLAT_TABLES			15
 #else
-#define MAX_MMAP_REGIONS		11
-#define MAX_XLAT_TABLES			11
+#define MAX_MMAP_REGIONS		12
+#define MAX_XLAT_TABLES			12
 #endif
 #define MAX_IO_DEVICES			3
 #define MAX_IO_HANDLES			4
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 4d82991..94634f2 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -222,6 +222,7 @@
 	 * in this scenario where execution was trapped to EL3 due to FIQ.
 	 */
 	simd_ctx_save(NON_SECURE, false);
+	simd_ctx_restore(SECURE);
 #endif
 #endif
 
@@ -238,14 +239,8 @@
 	/* Mark current core as handling a secure interrupt. */
 	ctx->secure_interrupt_ongoing = true;
 
-#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
-	simd_ctx_restore(SECURE);
-#endif
 	rc = spmd_spm_core_sync_entry(ctx);
 
-#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
-	simd_ctx_save(SECURE, false);
-#endif
 	if (rc != 0ULL) {
 		ERROR("%s failed (%" PRId64 ") on CPU%u\n", __func__, rc, plat_my_core_pos());
 	}
@@ -258,6 +253,7 @@
 	cm_el1_sysregs_context_restore(NON_SECURE);
 
 #if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+	simd_ctx_save(SECURE, false);
 	simd_ctx_restore(NON_SECURE);
 #endif
 #endif