feat(nxp-clk): enable the DDR clock

Enable the DDR clock by setting up its reset block, the associated
partition and configuring the clock tree above the MC_CGM mux.

Change-Id: Idfed24b3e74a189df87f9782886a91b906cd2022
Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc@nxp.com>
diff --git a/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h b/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
index f49f875..e54d581 100644
--- a/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
+++ b/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
@@ -14,6 +14,10 @@
 #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/s32cc_clk_drv.c b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
index 009bd6b..2ff227d 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,7 +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)
@@ -48,7 +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;
@@ -100,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:
@@ -598,6 +608,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;
@@ -827,6 +840,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)
@@ -872,7 +965,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,
@@ -881,6 +974,9 @@
 		[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,
 	};
 	uint32_t index;
 	int ret = 0;
@@ -1244,7 +1340,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,
@@ -1253,6 +1349,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_early_clks.c b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
index 512ee55..02b9df9 100644
--- a/drivers/nxp/clk/s32cc/s32cc_early_clks.c
+++ b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
@@ -163,6 +163,23 @@
 	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;
@@ -204,5 +221,10 @@
 		return ret;
 	}
 
+	ret = enable_ddr_clk();
+	if (ret != 0) {
+		return ret;
+	}
+
 	return ret;
 }