Merge changes from topic "nxp-clk/add_ddr_clk" into integration

* changes:
  fix(nxp-clk): function parameter should not be modified
  feat(nxp-clk): enable the DDR clock
  feat(nxp-clk): add objects needed for DDR clock
  feat(nxp-clk): setup the DDR PLL
  feat(nxp-clk): add MC_ME utilities
  feat(nxp-clk): add partition reset utilities
  feat(nxp-clk): add partitions objects
diff --git a/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h b/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
index 84e76f7..e54d581 100644
--- a/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
+++ b/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
@@ -13,6 +13,11 @@
 #define ARM_DFS_BASE_ADDR		(0x40054000UL)
 #define CGM0_BASE_ADDR			(0x40030000UL)
 #define CGM1_BASE_ADDR			(0x40034000UL)
+#define DDRPLL_BASE_ADDR		(0x40044000UL)
+#define MC_ME_BASE_ADDR			(0x40088000UL)
+#define MC_RGM_BASE_ADDR		(0x40078000UL)
+#define RDC_BASE_ADDR			(0x40080000UL)
+#define MC_CGM5_BASE_ADDR		(0x40068000UL)
 
 /* FXOSC */
 #define FXOSC_CTRL(FXOSC)		((FXOSC) + 0x0UL)
diff --git a/drivers/nxp/clk/s32cc/include/s32cc-mc-me.h b/drivers/nxp/clk/s32cc/include/s32cc-mc-me.h
new file mode 100644
index 0000000..8249fc5
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/include/s32cc-mc-me.h
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright 2020-2021, 2023-2024 NXP
+ */
+#ifndef S32CC_MC_ME_H
+#define S32CC_MC_ME_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+int mc_me_enable_partition(uintptr_t mc_me, uintptr_t mc_rgm, uintptr_t rdc,
+			   uint32_t part);
+void mc_me_enable_part_cofb(uintptr_t mc_me, uint32_t partition_n, uint32_t block,
+			    bool check_status);
+
+#endif /* S32CC_MC_ME_H */
diff --git a/drivers/nxp/clk/s32cc/include/s32cc-mc-rgm.h b/drivers/nxp/clk/s32cc/include/s32cc-mc-rgm.h
index 5ff55fb..d6234da 100644
--- a/drivers/nxp/clk/s32cc/include/s32cc-mc-rgm.h
+++ b/drivers/nxp/clk/s32cc/include/s32cc-mc-rgm.h
@@ -8,5 +8,7 @@
 #include <stdint.h>
 
 void mc_rgm_periph_reset(uintptr_t rgm, uint32_t part, uint32_t value);
+void mc_rgm_release_part(uintptr_t rgm, uint32_t part);
+void mc_rgm_wait_part_deassert(uintptr_t rgm, uint32_t part);
 
 #endif /* MC_RGM_H */
diff --git a/drivers/nxp/clk/s32cc/mc_me.c b/drivers/nxp/clk/s32cc/mc_me.c
new file mode 100644
index 0000000..04d0425
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/mc_me.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <s32cc-mc-me.h>
+#include <s32cc-mc-rgm.h>
+
+#define MC_ME_MAX_PARTITIONS		(4U)
+
+#define MC_ME_CTL_KEY(MC_ME)		((MC_ME) + 0x0UL)
+#define MC_ME_CTL_KEY_KEY		(0x5AF0U)
+#define MC_ME_CTL_KEY_INVERTEDKEY	(0xA50FU)
+
+#define MC_ME_PRTN_N(MC_ME, PART)	((MC_ME) + 0x100UL + ((PART) * 0x200UL))
+#define MC_ME_PRTN_N_PCONF(MC_ME, PART)	(MC_ME_PRTN_N(MC_ME, PART))
+#define MC_ME_PRTN_N_PCE		BIT_32(0)
+#define MC_ME_PRTN_N_OSSE		BIT_32(2)
+#define MC_ME_PRTN_N_PUPD(MC_ME, PART)	(MC_ME_PRTN_N(MC_ME, PART) + 0x4UL)
+#define MC_ME_PRTN_N_PCUD		BIT_32(0)
+#define MC_ME_PRTN_N_OSSUD		BIT_32(2)
+#define MC_ME_PRTN_N_STAT(MC_ME, PART)	(MC_ME_PRTN_N(MC_ME, PART) + 0x8UL)
+#define MC_ME_PRTN_N_PCS		BIT_32(0)
+#define MC_ME_PRTN_N_COFB0_STAT(MC_ME, PART) \
+					(MC_ME_PRTN_N(MC_ME, PART) + 0x10UL)
+#define MC_ME_PRTN_N_COFB0_CLKEN(MC_ME, PART) \
+					(MC_ME_PRTN_N(MC_ME, PART) + 0x30UL)
+#define MC_ME_PRTN_N_REQ(PART)		BIT_32(PART)
+
+#define RDC_RD_CTRL(RDC, PART)		((RDC) + ((PART) * 0x4UL))
+#define RDC_CTRL_UNLOCK			BIT_32(31)
+#define RDC_RD_INTERCONNECT_DISABLE	BIT_32(3)
+
+#define RDC_RD_N_STATUS(RDC, PART)	((RDC) + ((PART) * 0x4UL) + 0x80UL)
+#define RDC_RD_INTERCONNECT_DISABLE_STAT \
+					BIT_32(4)
+
+static bool is_interconnect_disabled(uintptr_t rdc, uint32_t part)
+{
+	return ((mmio_read_32(RDC_RD_N_STATUS(rdc, part)) &
+		  RDC_RD_INTERCONNECT_DISABLE_STAT) != 0U);
+}
+
+static void enable_interconnect(uintptr_t rdc, uint32_t part)
+{
+	/* Unlock RDC register write */
+	mmio_setbits_32(RDC_RD_CTRL(rdc, part), RDC_CTRL_UNLOCK);
+
+	/* Clear corresponding RDC_RD_INTERCONNECT bit */
+	mmio_clrbits_32(RDC_RD_CTRL(rdc, part), RDC_RD_INTERCONNECT_DISABLE);
+
+	/* Wait until the interface gets enabled */
+	while (is_interconnect_disabled(rdc, part)) {
+	}
+
+	/* Lock RDC register write */
+	mmio_clrbits_32(RDC_RD_CTRL(rdc, part), RDC_CTRL_UNLOCK);
+}
+
+static int mc_me_check_partition_nb_valid(uint32_t part)
+{
+	if (part >= MC_ME_MAX_PARTITIONS) {
+		ERROR("Invalid partition %" PRIu32 "\n", part);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void part_pconf_write_pce(uintptr_t mc_me, uint32_t pce_bit,
+				 uint32_t part)
+{
+	mmio_clrsetbits_32(MC_ME_PRTN_N_PCONF(mc_me, part), MC_ME_PRTN_N_PCE,
+			   pce_bit & MC_ME_PRTN_N_PCE);
+}
+
+static void mc_me_apply_hw_changes(uintptr_t mc_me)
+{
+	mmio_write_32(MC_ME_CTL_KEY(mc_me), MC_ME_CTL_KEY_KEY);
+	mmio_write_32(MC_ME_CTL_KEY(mc_me), MC_ME_CTL_KEY_INVERTEDKEY);
+}
+
+static void part_pupd_update_and_wait(uintptr_t mc_me, uint32_t part,
+				      uint32_t mask)
+{
+	uint32_t pconf, stat;
+
+	mmio_setbits_32(MC_ME_PRTN_N_PUPD(mc_me, part), mask);
+
+	mc_me_apply_hw_changes(mc_me);
+
+	/* wait for the updates to apply */
+	pconf = mmio_read_32(MC_ME_PRTN_N_PCONF(mc_me, part));
+	do {
+		stat = mmio_read_32(MC_ME_PRTN_N_STAT(mc_me, part));
+	} while ((stat & mask) != (pconf & mask));
+}
+
+static void part_pconf_write_osse(uintptr_t mc_me, uint32_t osse_bit,
+				  uint32_t part)
+{
+	mmio_clrsetbits_32(MC_ME_PRTN_N_PCONF(mc_me, part), MC_ME_PRTN_N_OSSE,
+			   (osse_bit & MC_ME_PRTN_N_OSSE));
+}
+
+int mc_me_enable_partition(uintptr_t mc_me, uintptr_t mc_rgm, uintptr_t rdc,
+			   uint32_t part)
+{
+	uint32_t part_stat;
+	int ret;
+
+	/* Partition 0 is already enabled by BootROM */
+	if (part == 0U) {
+		return 0;
+	}
+
+	ret = mc_me_check_partition_nb_valid(part);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Enable a partition only if it's disabled */
+	part_stat = mmio_read_32(MC_ME_PRTN_N_STAT(mc_me, part));
+	if ((MC_ME_PRTN_N_PCS & part_stat) != 0U) {
+		return 0;
+	}
+
+	part_pconf_write_pce(mc_me, MC_ME_PRTN_N_PCE, part);
+	part_pupd_update_and_wait(mc_me, part, MC_ME_PRTN_N_PCUD);
+
+	enable_interconnect(rdc, part);
+
+	/* Release partition reset */
+	mc_rgm_release_part(mc_rgm, part);
+
+	/* Clear OSSE bit */
+	part_pconf_write_osse(mc_me, 0, part);
+
+	part_pupd_update_and_wait(mc_me, part, MC_ME_PRTN_N_OSSUD);
+
+	mc_rgm_wait_part_deassert(mc_rgm, part);
+
+	return 0;
+}
+
+void mc_me_enable_part_cofb(uintptr_t mc_me, uint32_t partition_n, uint32_t block,
+			    bool check_status)
+{
+	uint32_t block_mask = MC_ME_PRTN_N_REQ(block);
+	uintptr_t cofb_stat_addr;
+
+	mmio_setbits_32(MC_ME_PRTN_N_COFB0_CLKEN(mc_me, partition_n),
+			block_mask);
+
+	mmio_setbits_32(MC_ME_PRTN_N_PCONF(mc_me, partition_n),
+			MC_ME_PRTN_N_PCE);
+
+	part_pupd_update_and_wait(mc_me, partition_n, MC_ME_PRTN_N_PCUD);
+
+	cofb_stat_addr = MC_ME_PRTN_N_COFB0_STAT(mc_me, partition_n);
+	if (check_status) {
+		while ((mmio_read_32(cofb_stat_addr) & block_mask) == 0U) {
+		}
+	}
+}
diff --git a/drivers/nxp/clk/s32cc/mc_rgm.c b/drivers/nxp/clk/s32cc/mc_rgm.c
index cbf4022..c66b013 100644
--- a/drivers/nxp/clk/s32cc/mc_rgm.c
+++ b/drivers/nxp/clk/s32cc/mc_rgm.c
@@ -7,7 +7,10 @@
 #include <lib/utils_def.h>
 #include <s32cc-mc-rgm.h>
 
-#define MC_RGM_PRST(MC_RGM, PER)	((MC_RGM) + 0x40UL + ((PER) * 0x8UL))
+#define MC_RGM_PRST(RGM, PER)		((RGM) + 0x40UL + ((PER) * 0x8UL))
+#define MC_RGM_PRST_PERIPH_N_RST(PER)	BIT_32(PER)
+#define MC_RGM_PSTAT(RGM, PER)		((RGM) + 0x140UL + ((PER) * 0x8UL))
+#define MC_RGM_PSTAT_PERIPH(PER)	BIT_32(PER)
 
 /*  ERR051700
  *  Releasing more than one Software Resettable Domain (SRD)
@@ -63,3 +66,19 @@
 	mmio_write_32(MC_RGM_PRST(rgm, part), value);
 }
 #endif /* ERRATA_S32_051700 */
+
+void mc_rgm_release_part(uintptr_t rgm, uint32_t part)
+{
+	uint32_t reg;
+
+	reg = mmio_read_32(MC_RGM_PRST(rgm, part));
+	reg &= ~MC_RGM_PRST_PERIPH_N_RST(0);
+	mc_rgm_periph_reset(rgm, part, reg);
+}
+
+void mc_rgm_wait_part_deassert(uintptr_t rgm, uint32_t part)
+{
+	while ((mmio_read_32(MC_RGM_PSTAT(rgm, part)) &
+		MC_RGM_PSTAT_PERIPH(0)) != 0U) {
+	}
+}
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk.mk b/drivers/nxp/clk/s32cc/s32cc_clk.mk
index 2a9a376..602179e 100644
--- a/drivers/nxp/clk/s32cc/s32cc_clk.mk
+++ b/drivers/nxp/clk/s32cc/s32cc_clk.mk
@@ -10,6 +10,7 @@
 
 CLK_SOURCES		:= \
 	${PLAT_DRIVERS_PATH}/clk/s32cc/mc_rgm.c \
+	${PLAT_DRIVERS_PATH}/clk/s32cc/mc_me.c \
 	${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_clk_drv.c \
 	${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_clk_modules.c \
 	${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_clk_utils.c \
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
index 14b03d9..9b57607 100644
--- a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
@@ -4,15 +4,14 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #include <errno.h>
-
-#include <s32cc-clk-regs.h>
-
 #include <common/debug.h>
 #include <drivers/clk.h>
 #include <lib/mmio.h>
 #include <s32cc-clk-ids.h>
 #include <s32cc-clk-modules.h>
+#include <s32cc-clk-regs.h>
 #include <s32cc-clk-utils.h>
+#include <s32cc-mc-me.h>
 
 #define MAX_STACK_DEPTH		(40U)
 
@@ -26,6 +25,11 @@
 	uintptr_t armdfs_base;
 	uintptr_t cgm0_base;
 	uintptr_t cgm1_base;
+	uintptr_t cgm5_base;
+	uintptr_t ddrpll_base;
+	uintptr_t mc_me;
+	uintptr_t mc_rgm;
+	uintptr_t rdc;
 };
 
 static int update_stack_depth(unsigned int *depth)
@@ -47,6 +51,11 @@
 		.armdfs_base = ARM_DFS_BASE_ADDR,
 		.cgm0_base = CGM0_BASE_ADDR,
 		.cgm1_base = CGM1_BASE_ADDR,
+		.cgm5_base = MC_CGM5_BASE_ADDR,
+		.ddrpll_base = DDRPLL_BASE_ADDR,
+		.mc_me = MC_ME_BASE_ADDR,
+		.mc_rgm = MC_RGM_BASE_ADDR,
+		.rdc = RDC_BASE_ADDR,
 	};
 
 	return &driver;
@@ -86,6 +95,9 @@
 	case S32CC_PERIPH_PLL:
 		*base = drv->periphpll_base;
 		break;
+	case S32CC_DDR_PLL:
+		*base = drv->ddrpll_base;
+		break;
 	case S32CC_ARM_DFS:
 		*base = drv->armdfs_base;
 		break;
@@ -95,6 +107,9 @@
 	case S32CC_CGM1:
 		*base = drv->cgm1_base;
 		break;
+	case S32CC_CGM5:
+		*base = drv->cgm5_base;
+		break;
 	case S32CC_FIRC:
 		break;
 	case S32CC_SIRC:
@@ -140,9 +155,10 @@
 		      unsigned int depth)
 {
 	const struct s32cc_osc *osc = s32cc_obj2osc(module);
+	unsigned int ldepth = depth;
 	int ret = 0;
 
-	ret = update_stack_depth(&depth);
+	ret = update_stack_depth(&ldepth);
 	if (ret != 0) {
 		return ret;
 	}
@@ -321,11 +337,12 @@
 	const struct s32cc_pll *pll = s32cc_obj2pll(module);
 	const struct s32cc_clkmux *mux;
 	uintptr_t pll_addr = UL(0x0);
+	unsigned int ldepth = depth;
 	unsigned long sclk_freq;
 	uint32_t sclk_id;
 	int ret;
 
-	ret = update_stack_depth(&depth);
+	ret = update_stack_depth(&ldepth);
 	if (ret != 0) {
 		return ret;
 	}
@@ -421,11 +438,12 @@
 {
 	const struct s32cc_pll_out_div *pdiv = s32cc_obj2plldiv(module);
 	uintptr_t pll_addr = 0x0ULL;
+	unsigned int ldepth = depth;
 	const struct s32cc_pll *pll;
 	uint32_t dc;
 	int ret;
 
-	ret = update_stack_depth(&depth);
+	ret = update_stack_depth(&ldepth);
 	if (ret != 0) {
 		return ret;
 	}
@@ -562,10 +580,11 @@
 		      unsigned int depth)
 {
 	const struct s32cc_clkmux *mux = s32cc_obj2clkmux(module);
+	unsigned int ldepth = depth;
 	const struct s32cc_clk *clk;
 	int ret = 0;
 
-	ret = update_stack_depth(&depth);
+	ret = update_stack_depth(&ldepth);
 	if (ret != 0) {
 		return ret;
 	}
@@ -585,6 +604,7 @@
 	/* PLL mux will be enabled by PLL setup */
 	case S32CC_ARM_PLL:
 	case S32CC_PERIPH_PLL:
+	case S32CC_DDR_PLL:
 		break;
 	case S32CC_CGM1:
 		ret = enable_cgm_mux(mux, drv);
@@ -592,6 +612,9 @@
 	case S32CC_CGM0:
 		ret = enable_cgm_mux(mux, drv);
 		break;
+	case S32CC_CGM5:
+		ret = enable_cgm_mux(mux, drv);
+		break;
 	default:
 		ERROR("Unknown mux parent type: %d\n", mux->module);
 		ret = -EINVAL;
@@ -616,9 +639,10 @@
 		      const struct s32cc_clk_drv *drv,
 		      unsigned int depth)
 {
+	unsigned int ldepth = depth;
 	int ret = 0;
 
-	ret = update_stack_depth(&depth);
+	ret = update_stack_depth(&ldepth);
 	if (ret != 0) {
 		return ret;
 	}
@@ -782,13 +806,14 @@
 			  unsigned int depth)
 {
 	const struct s32cc_dfs_div *dfs_div = s32cc_obj2dfsdiv(module);
+	unsigned int ldepth = depth;
 	const struct s32cc_pll *pll;
 	const struct s32cc_dfs *dfs;
 	uintptr_t dfs_addr = 0UL;
 	uint32_t mfi, mfn;
 	int ret = 0;
 
-	ret = update_stack_depth(&depth);
+	ret = update_stack_depth(&ldepth);
 	if (ret != 0) {
 		return ret;
 	}
@@ -821,6 +846,86 @@
 			    const struct s32cc_clk_drv *drv,
 			    unsigned int depth);
 
+static int enable_part(struct s32cc_clk_obj *module,
+		       const struct s32cc_clk_drv *drv,
+		       unsigned int depth)
+{
+	const struct s32cc_part *part = s32cc_obj2part(module);
+	uint32_t part_no = part->partition_id;
+
+	if ((drv->mc_me == 0UL) || (drv->mc_rgm == 0UL) || (drv->rdc == 0UL)) {
+		return -EINVAL;
+	}
+
+	return mc_me_enable_partition(drv->mc_me, drv->mc_rgm, drv->rdc, part_no);
+}
+
+static int enable_part_block(struct s32cc_clk_obj *module,
+			     const struct s32cc_clk_drv *drv,
+			     unsigned int depth)
+{
+	const struct s32cc_part_block *block = s32cc_obj2partblock(module);
+	const struct s32cc_part *part = block->part;
+	uint32_t part_no = part->partition_id;
+	unsigned int ldepth = depth;
+	uint32_t cofb;
+	int ret;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if ((block->block >= s32cc_part_block0) &&
+	    (block->block <= s32cc_part_block15)) {
+		cofb = (uint32_t)block->block - (uint32_t)s32cc_part_block0;
+		mc_me_enable_part_cofb(drv->mc_me, part_no, cofb, block->status);
+	} else {
+		ERROR("Unknown partition block type: %d\n", block->block);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct s32cc_clk_obj *
+get_part_block_parent(const struct s32cc_clk_obj *module)
+{
+	const struct s32cc_part_block *block = s32cc_obj2partblock(module);
+
+	return &block->part->desc;
+}
+
+static int enable_module_with_refcount(struct s32cc_clk_obj *module,
+				       const struct s32cc_clk_drv *drv,
+				       unsigned int depth);
+
+static int enable_part_block_link(struct s32cc_clk_obj *module,
+				  const struct s32cc_clk_drv *drv,
+				  unsigned int depth)
+{
+	const struct s32cc_part_block_link *link = s32cc_obj2partblocklink(module);
+	struct s32cc_part_block *block = link->block;
+	unsigned int ldepth = depth;
+	int ret;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Move the enablement algorithm to partition tree */
+	return enable_module_with_refcount(&block->desc, drv, ldepth);
+}
+
+static struct s32cc_clk_obj *
+get_part_block_link_parent(const struct s32cc_clk_obj *module)
+{
+	const struct s32cc_part_block_link *link = s32cc_obj2partblocklink(module);
+
+	return link->parent;
+}
+
 static int no_enable(struct s32cc_clk_obj *module,
 		     const struct s32cc_clk_drv *drv,
 		     unsigned int depth)
@@ -832,24 +937,25 @@
 				 const struct s32cc_clk_drv *drv, bool leaf_node,
 				 unsigned int depth)
 {
+	unsigned int ldepth = depth;
 	int ret = 0;
 
 	if (mod == NULL) {
 		return 0;
 	}
 
-	ret = update_stack_depth(&depth);
+	ret = update_stack_depth(&ldepth);
 	if (ret != 0) {
 		return ret;
 	}
 
 	/* Refcount will be updated as part of the recursivity */
 	if (leaf_node) {
-		return en_cb(mod, drv, depth);
+		return en_cb(mod, drv, ldepth);
 	}
 
 	if (mod->refcount == 0U) {
-		ret = en_cb(mod, drv, depth);
+		ret = en_cb(mod, drv, ldepth);
 	}
 
 	if (ret == 0) {
@@ -866,7 +972,7 @@
 			 unsigned int depth)
 {
 	struct s32cc_clk_obj *parent = get_module_parent(module);
-	static const enable_clk_t enable_clbs[8] = {
+	static const enable_clk_t enable_clbs[12] = {
 		[s32cc_clk_t] = no_enable,
 		[s32cc_osc_t] = enable_osc,
 		[s32cc_pll_t] = enable_pll,
@@ -875,11 +981,15 @@
 		[s32cc_shared_clkmux_t] = enable_mux,
 		[s32cc_dfs_t] = enable_dfs,
 		[s32cc_dfs_div_t] = enable_dfs_div,
+		[s32cc_part_t] = enable_part,
+		[s32cc_part_block_t] = enable_part_block,
+		[s32cc_part_block_link_t] = enable_part_block_link,
 	};
+	unsigned int ldepth = depth;
 	uint32_t index;
 	int ret = 0;
 
-	ret = update_stack_depth(&depth);
+	ret = update_stack_depth(&ldepth);
 	if (ret != 0) {
 		return ret;
 	}
@@ -904,13 +1014,13 @@
 	parent = get_module_parent(module);
 
 	ret = exec_cb_with_refcount(enable_module, parent, drv,
-				    false, depth);
+				    false, ldepth);
 	if (ret != 0) {
 		return ret;
 	}
 
 	ret = exec_cb_with_refcount(enable_clbs[index], module, drv,
-				    true, depth);
+				    true, ldepth);
 	if (ret != 0) {
 		return ret;
 	}
@@ -1238,7 +1348,7 @@
 
 static struct s32cc_clk_obj *get_module_parent(const struct s32cc_clk_obj *module)
 {
-	static const get_parent_clb_t parents_clbs[8] = {
+	static const get_parent_clb_t parents_clbs[12] = {
 		[s32cc_clk_t] = get_clk_parent,
 		[s32cc_osc_t] = get_no_parent,
 		[s32cc_pll_t] = get_pll_parent,
@@ -1247,6 +1357,9 @@
 		[s32cc_shared_clkmux_t] = get_mux_parent,
 		[s32cc_dfs_t] = get_dfs_parent,
 		[s32cc_dfs_div_t] = get_dfs_div_parent,
+		[s32cc_part_t] = get_no_parent,
+		[s32cc_part_block_t] = get_part_block_parent,
+		[s32cc_part_block_link_t] = get_part_block_link_parent,
 	};
 	uint32_t index;
 
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_modules.c b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
index 17ded0e..71055ab 100644
--- a/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
@@ -10,6 +10,9 @@
 #define S32CC_A53_MIN_FREQ	(48UL * MHZ)
 #define S32CC_A53_MAX_FREQ	(1000UL * MHZ)
 
+/* Partitions */
+static struct s32cc_part part0 = S32CC_PART(0);
+
 /* Oscillators */
 static struct s32cc_osc fxosc =
 	S32CC_OSC_INIT(S32CC_FXOSC);
@@ -139,7 +142,40 @@
 static struct s32cc_clk periph_pll_phi3_clk =
 	S32CC_FREQ_MODULE_CLK(periph_pll_phi3_div, 0, 133333333);
 
-static struct s32cc_clk *s32cc_hw_clk_list[22] = {
+/* DDR PLL */
+static struct s32cc_clkmux ddr_pll_mux =
+	S32CC_CLKMUX_INIT(S32CC_DDR_PLL, 0, 2,
+			  S32CC_CLK_FIRC,
+			  S32CC_CLK_FXOSC, 0, 0, 0);
+static struct s32cc_clk ddr_pll_mux_clk =
+	S32CC_MODULE_CLK(ddr_pll_mux);
+static struct s32cc_pll ddrpll =
+	S32CC_PLL_INIT(ddr_pll_mux_clk, S32CC_DDR_PLL, 1);
+static struct s32cc_clk ddr_pll_vco_clk =
+	S32CC_FREQ_MODULE_CLK(ddrpll, 1300 * MHZ, 1600 * MHZ);
+
+static struct s32cc_pll_out_div ddr_pll_phi0_div =
+	S32CC_PLL_OUT_DIV_INIT(ddrpll, 0);
+static struct s32cc_clk ddr_pll_phi0_clk =
+	S32CC_FREQ_MODULE_CLK(ddr_pll_phi0_div, 0, 800 * MHZ);
+
+/* MC_CGM5 */
+static struct s32cc_clkmux cgm5_mux0 =
+	S32CC_SHARED_CLKMUX_INIT(S32CC_CGM5, 0, 2,
+				 S32CC_CLK_FIRC,
+				 S32CC_CLK_DDR_PLL_PHI0,
+				 0, 0, 0);
+static struct s32cc_clk cgm5_mux0_clk = S32CC_MODULE_CLK(cgm5_mux0);
+
+/* DDR clock */
+static struct s32cc_part_block part0_block1 =
+	S32CC_PART_BLOCK(&part0, s32cc_part_block1);
+static struct s32cc_part_block_link ddr_block_link =
+	S32CC_PART_BLOCK_LINK(cgm5_mux0_clk, &part0_block1);
+static struct s32cc_clk ddr_clk =
+	S32CC_FREQ_MODULE_CLK(ddr_block_link, 0, 800 * MHZ);
+
+static struct s32cc_clk *s32cc_hw_clk_list[37] = {
 	/* Oscillators */
 	[S32CC_CLK_ID(S32CC_CLK_FIRC)] = &firc_clk,
 	[S32CC_CLK_ID(S32CC_CLK_SIRC)] = &sirc_clk,
@@ -150,6 +186,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,
+	/* DDR PLL */
+	[S32CC_CLK_ID(S32CC_CLK_DDR_PLL_PHI0)] = &ddr_pll_phi0_clk,
 };
 
 static struct s32cc_clk_array s32cc_hw_clocks = {
@@ -158,7 +196,7 @@
 	.n_clks = ARRAY_SIZE(s32cc_hw_clk_list),
 };
 
-static struct s32cc_clk *s32cc_arch_clk_list[18] = {
+static struct s32cc_clk *s32cc_arch_clk_list[22] = {
 	/* 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,
@@ -184,6 +222,13 @@
 	/* Linflex */
 	[S32CC_CLK_ID(S32CC_CLK_LINFLEX)] = &linflex_clk,
 	[S32CC_CLK_ID(S32CC_CLK_LINFLEX_BAUD)] = &linflex_baud_clk,
+	/* DDR PLL */
+	[S32CC_CLK_ID(S32CC_CLK_DDR_PLL_MUX)] = &ddr_pll_mux_clk,
+	[S32CC_CLK_ID(S32CC_CLK_DDR_PLL_VCO)] = &ddr_pll_vco_clk,
+	/* MC_CGM5 */
+	[S32CC_CLK_ID(S32CC_CLK_MC_CGM5_MUX0)] = &cgm5_mux0_clk,
+	/* DDR */
+	[S32CC_CLK_ID(S32CC_CLK_DDR)] = &ddr_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 3f6d3d7..02b9df9 100644
--- a/drivers/nxp/clk/s32cc/s32cc_early_clks.c
+++ b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
@@ -16,6 +16,8 @@
 #define S32CC_XBAR_2X_FREQ		(800U * MHZ)
 #define S32CC_PERIPH_PLL_VCO_FREQ	(2U * GHZ)
 #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)
 
 static int setup_fxosc(void)
 {
@@ -139,6 +141,45 @@
 	return ret;
 }
 
+static int setup_ddr_pll(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_DDR_PLL_MUX, S32CC_CLK_FXOSC);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_DDR_PLL_VCO, S32CC_DDR_PLL_VCO_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_DDR_PLL_PHI0, S32CC_DDR_PLL_PHI0_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
+static int enable_ddr_clk(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_MC_CGM5_MUX0, S32CC_CLK_DDR_PLL_PHI0);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_enable(S32CC_CLK_DDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
 int s32cc_init_early_clks(void)
 {
 	int ret;
@@ -175,5 +216,15 @@
 		return ret;
 	}
 
+	ret = setup_ddr_pll();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = enable_ddr_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 de633ae..d34dc22 100644
--- a/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h
@@ -95,4 +95,12 @@
 #define S32CC_CLK_LINFLEX_BAUD			S32CC_ARCH_CLK(16)
 #define S32CC_CLK_LINFLEX			S32CC_ARCH_CLK(17)
 
+/* DDR PLL */
+#define S32CC_CLK_DDR_PLL_MUX			S32CC_ARCH_CLK(18)
+#define S32CC_CLK_DDR_PLL_VCO			S32CC_ARCH_CLK(19)
+
+/* DDR clock */
+#define S32CC_CLK_MC_CGM5_MUX0			S32CC_ARCH_CLK(20)
+#define S32CC_CLK_DDR				S32CC_ARCH_CLK(21)
+
 #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 a6d58cc..4837f79 100644
--- a/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h
@@ -22,6 +22,9 @@
 	s32cc_clkmux_t,
 	s32cc_shared_clkmux_t,
 	s32cc_fixed_div_t,
+	s32cc_part_t,
+	s32cc_part_block_t,
+	s32cc_part_block_link_t,
 };
 
 enum s32cc_clk_source {
@@ -33,6 +36,8 @@
 	S32CC_PERIPH_PLL,
 	S32CC_CGM0,
 	S32CC_CGM1,
+	S32CC_DDR_PLL,
+	S32CC_CGM5,
 };
 
 struct s32cc_clk_obj {
@@ -208,6 +213,76 @@
 #define S32CC_CHILD_CLK(PARENT, MIN_F, MAX_F) \
 	S32CC_FREQ_CLK(NULL, &(PARENT), MIN_F, MAX_F)
 
+struct s32cc_part {
+	struct s32cc_clk_obj desc;
+	uint32_t partition_id;
+};
+
+#define S32CC_PART(PART_NUM)          \
+{                                     \
+	.desc = {                     \
+		.type = s32cc_part_t, \
+	},                            \
+	.partition_id = (PART_NUM),   \
+}
+
+enum s32cc_part_block_type {
+	s32cc_part_block0,
+	s32cc_part_block1,
+	s32cc_part_block2,
+	s32cc_part_block3,
+	s32cc_part_block4,
+	s32cc_part_block5,
+	s32cc_part_block6,
+	s32cc_part_block7,
+	s32cc_part_block8,
+	s32cc_part_block9,
+	s32cc_part_block10,
+	s32cc_part_block11,
+	s32cc_part_block12,
+	s32cc_part_block13,
+	s32cc_part_block14,
+	s32cc_part_block15,
+};
+
+struct s32cc_part_block {
+	struct s32cc_clk_obj desc;
+	struct s32cc_part *part;
+	enum s32cc_part_block_type block;
+	bool status;
+};
+
+#define S32CC_PART_BLOCK_STATUS(PART_META, BLOCK_TYPE, STATUS) \
+{                                                              \
+	.desc = {                                              \
+		.type = s32cc_part_block_t,                    \
+	},                                                     \
+	.part = (PART_META),                                   \
+	.block = (BLOCK_TYPE),                                 \
+	.status = (STATUS),                                    \
+}
+
+#define S32CC_PART_BLOCK(PARENT, BLOCK_TYPE) \
+	S32CC_PART_BLOCK_STATUS(PARENT, BLOCK_TYPE, true)
+
+#define S32CC_PART_BLOCK_NO_STATUS(PARENT, BLOCK_TYPE) \
+	S32CC_PART_BLOCK_STATUS(PARENT, BLOCK_TYPE, false)
+
+struct s32cc_part_block_link {
+	struct s32cc_clk_obj desc;
+	struct s32cc_clk_obj *parent;
+	struct s32cc_part_block *block;
+};
+
+#define S32CC_PART_BLOCK_LINK(PARENT, BLOCK)     \
+{                                                \
+	.desc = {                                \
+		.type = s32cc_part_block_link_t, \
+	},                                       \
+	.parent = &(PARENT).desc,                \
+	.block = (BLOCK),                        \
+}
+
 static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
 {
 	uintptr_t osc_addr;
@@ -294,4 +369,30 @@
 	return (struct s32cc_dfs_div *)dfs_div_addr;
 }
 
+static inline struct s32cc_part *s32cc_obj2part(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t part_addr;
+
+	part_addr = ((uintptr_t)mod) - offsetof(struct s32cc_part, desc);
+	return (struct s32cc_part *)part_addr;
+}
+
+static inline struct s32cc_part_block *
+s32cc_obj2partblock(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t part_blk_addr;
+
+	part_blk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_part_block, desc);
+	return (struct s32cc_part_block *)part_blk_addr;
+}
+
+static inline struct s32cc_part_block_link *
+s32cc_obj2partblocklink(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t blk_link;
+
+	blk_link = ((uintptr_t)mod) - offsetof(struct s32cc_part_block_link, desc);
+	return (struct s32cc_part_block_link *)blk_link;
+}
+
 #endif /* S32CC_CLK_MODULES_H */