feat(nxp-clk): add PERIPH PLL enablement

Peripheral PLL is one of the platform's PLLs, providing a clock for
peripherals such as UART, QSPI, uSDHC, SPI and CAN. Its source can be
either the FIRC or FXOSC oscillators. It has eight outputs (PHIs) and
their frequencies can be controlled programmatically using output
dividers. An additional output clocks the PERIPH DFS using the VCO
frequency of the PERIPH PLL.

Change-Id: I637294b2da94f35e95dc1750dad36c129a276bb9
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 d62eed7..84e76f7 100644
--- a/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
+++ b/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
@@ -9,6 +9,7 @@
 
 #define FXOSC_BASE_ADDR			(0x40050000UL)
 #define ARMPLL_BASE_ADDR		(0x40038000UL)
+#define PERIPHPLL_BASE_ADDR		(0x4003C000UL)
 #define ARM_DFS_BASE_ADDR		(0x40054000UL)
 #define CGM0_BASE_ADDR			(0x40030000UL)
 #define CGM1_BASE_ADDR			(0x40034000UL)
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
index e23d928..fed16a7 100644
--- a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
@@ -22,6 +22,7 @@
 struct s32cc_clk_drv {
 	uintptr_t fxosc_base;
 	uintptr_t armpll_base;
+	uintptr_t periphpll_base;
 	uintptr_t armdfs_base;
 	uintptr_t cgm0_base;
 	uintptr_t cgm1_base;
@@ -42,6 +43,7 @@
 	static struct s32cc_clk_drv driver = {
 		.fxosc_base = FXOSC_BASE_ADDR,
 		.armpll_base = ARMPLL_BASE_ADDR,
+		.periphpll_base = PERIPHPLL_BASE_ADDR,
 		.armdfs_base = ARM_DFS_BASE_ADDR,
 		.cgm0_base = CGM0_BASE_ADDR,
 		.cgm1_base = CGM1_BASE_ADDR,
@@ -91,6 +93,9 @@
 	case S32CC_ARM_PLL:
 		*base = drv->armpll_base;
 		break;
+	case S32CC_PERIPH_PLL:
+		*base = drv->periphpll_base;
+		break;
 	case S32CC_ARM_DFS:
 		*base = drv->armdfs_base;
 		break;
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_modules.c b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
index c4c73c7..91eacec 100644
--- a/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
@@ -107,7 +107,24 @@
 	S32CC_FREQ_MODULE_CLK(a53_core_div10, S32CC_A53_MIN_FREQ / 10,
 			      S32CC_A53_MAX_FREQ / 10);
 
-static struct s32cc_clk *s32cc_hw_clk_list[13] = {
+/* PERIPH PLL */
+static struct s32cc_clkmux periph_pll_mux =
+	S32CC_CLKMUX_INIT(S32CC_PERIPH_PLL, 0, 2,
+			  S32CC_CLK_FIRC,
+			  S32CC_CLK_FXOSC, 0, 0, 0);
+static struct s32cc_clk periph_pll_mux_clk =
+	S32CC_MODULE_CLK(periph_pll_mux);
+static struct s32cc_pll periphpll =
+	S32CC_PLL_INIT(periph_pll_mux_clk, S32CC_PERIPH_PLL, 2);
+static struct s32cc_clk periph_pll_vco_clk =
+	S32CC_FREQ_MODULE_CLK(periphpll, 1300 * MHZ, 2 * GHZ);
+
+static struct s32cc_pll_out_div periph_pll_phi3_div =
+	S32CC_PLL_OUT_DIV_INIT(periphpll, 3);
+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] = {
 	/* Oscillators */
 	[S32CC_CLK_ID(S32CC_CLK_FIRC)] = &firc_clk,
 	[S32CC_CLK_ID(S32CC_CLK_SIRC)] = &sirc_clk,
@@ -116,6 +133,8 @@
 	[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_PHI0)] = &arm_pll_phi0_clk,
 	/* ARM DFS */
 	[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,
 };
 
 static struct s32cc_clk_array s32cc_hw_clocks = {
@@ -124,10 +143,13 @@
 	.n_clks = ARRAY_SIZE(s32cc_hw_clk_list),
 };
 
-static struct s32cc_clk *s32cc_arch_clk_list[13] = {
+static struct s32cc_clk *s32cc_arch_clk_list[15] = {
 	/* 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,
+	/* PERIPH PLL */
+	[S32CC_CLK_ID(S32CC_CLK_PERIPH_PLL_MUX)] = &periph_pll_mux_clk,
+	[S32CC_CLK_ID(S32CC_CLK_PERIPH_PLL_VCO)] = &periph_pll_vco_clk,
 	/* MC_CGM0 */
 	[S32CC_CLK_ID(S32CC_CLK_MC_CGM0_MUX0)] = &cgm0_mux0_clk,
 	/* XBAR */
diff --git a/drivers/nxp/clk/s32cc/s32cc_early_clks.c b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
index 2c256a5..496724f 100644
--- a/drivers/nxp/clk/s32cc/s32cc_early_clks.c
+++ b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
@@ -8,11 +8,13 @@
 #include <s32cc-clk-ids.h>
 #include <s32cc-clk-utils.h>
 
-#define S32CC_FXOSC_FREQ	(40U * MHZ)
-#define S32CC_ARM_PLL_VCO_FREQ	(2U * GHZ)
-#define S32CC_ARM_PLL_PHI0_FREQ	(1U * GHZ)
-#define S32CC_A53_FREQ		(1U * GHZ)
-#define S32CC_XBAR_2X_FREQ	(800U * MHZ)
+#define S32CC_FXOSC_FREQ		(40U * MHZ)
+#define S32CC_ARM_PLL_VCO_FREQ		(2U * GHZ)
+#define S32CC_ARM_PLL_PHI0_FREQ		(1U * GHZ)
+#define S32CC_A53_FREQ			(1U * GHZ)
+#define S32CC_XBAR_2X_FREQ		(800U * MHZ)
+#define S32CC_PERIPH_PLL_VCO_FREQ	(2U * GHZ)
+#define S32CC_PERIPH_PLL_PHI3_FREQ	(125U * MHZ)
 
 static int enable_fxosc_clk(void)
 {
@@ -63,6 +65,38 @@
 	return ret;
 }
 
+static int enable_periph_pll(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_PERIPH_PLL_MUX, S32CC_CLK_FXOSC);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_VCO, S32CC_PERIPH_PLL_VCO_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_PHI3, S32CC_PERIPH_PLL_PHI3_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_enable(S32CC_CLK_PERIPH_PLL_VCO);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_enable(S32CC_CLK_PERIPH_PLL_PHI3);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
 static int enable_a53_clk(void)
 {
 	int ret;
@@ -128,6 +162,11 @@
 		return ret;
 	}
 
+	ret = enable_periph_pll();
+	if (ret != 0) {
+		return ret;
+	}
+
 	ret = enable_a53_clk();
 	if (ret != 0) {
 		return ret;