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