xref: /rk3399_ARM-atf/drivers/nxp/clk/s32cc/s32cc_early_clks.c (revision 8f64ed92c42f050c4217870e03ce48f95d4c251f)
166af5425SGhennadi Procopciuc /*
247b3a825SGhennadi Procopciuc  * Copyright 2024-2025 NXP
366af5425SGhennadi Procopciuc  *
466af5425SGhennadi Procopciuc  * SPDX-License-Identifier: BSD-3-Clause
566af5425SGhennadi Procopciuc  */
666af5425SGhennadi Procopciuc #include <drivers/clk.h>
7e4462daeSGhennadi Procopciuc #include <platform_def.h>
866af5425SGhennadi Procopciuc #include <s32cc-clk-drv.h>
966af5425SGhennadi Procopciuc #include <s32cc-clk-ids.h>
10*c0cbf5adSKhristine Andreea Barbulescu #include <s32cc-clk-regs.h>
11*c0cbf5adSKhristine Andreea Barbulescu #include <s32cc-mc-rgm.h>
1266af5425SGhennadi Procopciuc #include <s32cc-clk-utils.h>
1366af5425SGhennadi Procopciuc 
1466af5425SGhennadi Procopciuc #define S32CC_FXOSC_FREQ		(40U * MHZ)
157ad4e231SGhennadi Procopciuc #define S32CC_ARM_PLL_VCO_FREQ		(2U * GHZ)
16de950ef0SGhennadi Procopciuc #define S32CC_ARM_PLL_PHI0_FREQ		(1U * GHZ)
1764e0c226SGhennadi Procopciuc #define S32CC_A53_FREQ			(1U * GHZ)
18b8ad8800SGhennadi Procopciuc #define S32CC_XBAR_2X_FREQ		(800U * MHZ)
198653352aSGhennadi Procopciuc #define S32CC_PERIPH_PLL_VCO_FREQ	(2U * GHZ)
20e4462daeSGhennadi Procopciuc #define S32CC_PERIPH_PLL_PHI3_FREQ	UART_CLOCK_HZ
2118c2b137SGhennadi Procopciuc #define S32CC_DDR_PLL_VCO_FREQ		(1600U * MHZ)
2218c2b137SGhennadi Procopciuc #define S32CC_DDR_PLL_PHI0_FREQ		(800U * MHZ)
2347b3a825SGhennadi Procopciuc #define S32CC_PERIPH_DFS_PHI3_FREQ	(800U * MHZ)
249c640e09SGhennadi Procopciuc #define S32CC_USDHC_FREQ		(200U * MHZ)
2566af5425SGhennadi Procopciuc 
26*c0cbf5adSKhristine Andreea Barbulescu #define S32CC_DDR_RESET_TIMEOUT_US 1000000U
27*c0cbf5adSKhristine Andreea Barbulescu 
setup_fxosc(void)285300040bSGhennadi Procopciuc static int setup_fxosc(void)
2966af5425SGhennadi Procopciuc {
3066af5425SGhennadi Procopciuc 	int ret;
3166af5425SGhennadi Procopciuc 
32d3869455SGhennadi Procopciuc 	ret = clk_set_rate(S32CC_CLK_FXOSC, S32CC_FXOSC_FREQ, NULL);
33d3869455SGhennadi Procopciuc 	if (ret != 0) {
34d3869455SGhennadi Procopciuc 		return ret;
35d3869455SGhennadi Procopciuc 	}
36d3869455SGhennadi Procopciuc 
37d3869455SGhennadi Procopciuc 	return ret;
38d3869455SGhennadi Procopciuc }
39d3869455SGhennadi Procopciuc 
setup_arm_pll(void)405300040bSGhennadi Procopciuc static int setup_arm_pll(void)
41d3869455SGhennadi Procopciuc {
42d3869455SGhennadi Procopciuc 	int ret;
4366af5425SGhennadi Procopciuc 
4483af4504SGhennadi Procopciuc 	ret = clk_set_parent(S32CC_CLK_ARM_PLL_MUX, S32CC_CLK_FXOSC);
4583af4504SGhennadi Procopciuc 	if (ret != 0) {
4683af4504SGhennadi Procopciuc 		return ret;
4783af4504SGhennadi Procopciuc 	}
4883af4504SGhennadi Procopciuc 
497ad4e231SGhennadi Procopciuc 	ret = clk_set_rate(S32CC_CLK_ARM_PLL_VCO, S32CC_ARM_PLL_VCO_FREQ, NULL);
507ad4e231SGhennadi Procopciuc 	if (ret != 0) {
517ad4e231SGhennadi Procopciuc 		return ret;
527ad4e231SGhennadi Procopciuc 	}
537ad4e231SGhennadi Procopciuc 
54de950ef0SGhennadi Procopciuc 	ret = clk_set_rate(S32CC_CLK_ARM_PLL_PHI0, S32CC_ARM_PLL_PHI0_FREQ, NULL);
55de950ef0SGhennadi Procopciuc 	if (ret != 0) {
56de950ef0SGhennadi Procopciuc 		return ret;
57de950ef0SGhennadi Procopciuc 	}
58de950ef0SGhennadi Procopciuc 
59b5101c45SGhennadi Procopciuc 	return ret;
60b5101c45SGhennadi Procopciuc }
61b5101c45SGhennadi Procopciuc 
setup_periph_pll(void)625300040bSGhennadi Procopciuc static int setup_periph_pll(void)
638653352aSGhennadi Procopciuc {
648653352aSGhennadi Procopciuc 	int ret;
658653352aSGhennadi Procopciuc 
668653352aSGhennadi Procopciuc 	ret = clk_set_parent(S32CC_CLK_PERIPH_PLL_MUX, S32CC_CLK_FXOSC);
678653352aSGhennadi Procopciuc 	if (ret != 0) {
688653352aSGhennadi Procopciuc 		return ret;
698653352aSGhennadi Procopciuc 	}
708653352aSGhennadi Procopciuc 
718653352aSGhennadi Procopciuc 	ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_VCO, S32CC_PERIPH_PLL_VCO_FREQ, NULL);
728653352aSGhennadi Procopciuc 	if (ret != 0) {
738653352aSGhennadi Procopciuc 		return ret;
748653352aSGhennadi Procopciuc 	}
758653352aSGhennadi Procopciuc 
768653352aSGhennadi Procopciuc 	ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_PHI3, S32CC_PERIPH_PLL_PHI3_FREQ, NULL);
778653352aSGhennadi Procopciuc 	if (ret != 0) {
788653352aSGhennadi Procopciuc 		return ret;
798653352aSGhennadi Procopciuc 	}
808653352aSGhennadi Procopciuc 
818653352aSGhennadi Procopciuc 	return ret;
828653352aSGhennadi Procopciuc }
838653352aSGhennadi Procopciuc 
enable_a53_clk(void)84d3869455SGhennadi Procopciuc static int enable_a53_clk(void)
85d3869455SGhennadi Procopciuc {
86d3869455SGhennadi Procopciuc 	int ret;
87d3869455SGhennadi Procopciuc 
88d3869455SGhennadi Procopciuc 	ret = clk_set_parent(S32CC_CLK_MC_CGM1_MUX0, S32CC_CLK_ARM_PLL_PHI0);
89d3869455SGhennadi Procopciuc 	if (ret != 0) {
90d3869455SGhennadi Procopciuc 		return ret;
91d3869455SGhennadi Procopciuc 	}
92d3869455SGhennadi Procopciuc 
93d3869455SGhennadi Procopciuc 	ret = clk_set_rate(S32CC_CLK_A53_CORE, S32CC_A53_FREQ, NULL);
94d3869455SGhennadi Procopciuc 	if (ret != 0) {
95d3869455SGhennadi Procopciuc 		return ret;
96d3869455SGhennadi Procopciuc 	}
97d3869455SGhennadi Procopciuc 
987004f678SGhennadi Procopciuc 	ret = clk_enable(S32CC_CLK_A53_CORE);
997004f678SGhennadi Procopciuc 	if (ret != 0) {
1007004f678SGhennadi Procopciuc 		return ret;
1017004f678SGhennadi Procopciuc 	}
1027004f678SGhennadi Procopciuc 
10366af5425SGhennadi Procopciuc 	return ret;
10466af5425SGhennadi Procopciuc }
105d3869455SGhennadi Procopciuc 
enable_xbar_clk(void)106b8ad8800SGhennadi Procopciuc static int enable_xbar_clk(void)
107b8ad8800SGhennadi Procopciuc {
108b8ad8800SGhennadi Procopciuc 	int ret;
109b8ad8800SGhennadi Procopciuc 
110b8ad8800SGhennadi Procopciuc 	ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX0, S32CC_CLK_ARM_PLL_DFS1);
111b8ad8800SGhennadi Procopciuc 	if (ret != 0) {
112b8ad8800SGhennadi Procopciuc 		return ret;
113b8ad8800SGhennadi Procopciuc 	}
114b8ad8800SGhennadi Procopciuc 
115b8ad8800SGhennadi Procopciuc 	ret = clk_set_rate(S32CC_CLK_XBAR_2X, S32CC_XBAR_2X_FREQ, NULL);
116b8ad8800SGhennadi Procopciuc 	if (ret != 0) {
117b8ad8800SGhennadi Procopciuc 		return ret;
118b8ad8800SGhennadi Procopciuc 	}
119b8ad8800SGhennadi Procopciuc 
120b8ad8800SGhennadi Procopciuc 	ret = clk_enable(S32CC_CLK_ARM_PLL_DFS1);
121b8ad8800SGhennadi Procopciuc 	if (ret != 0) {
122b8ad8800SGhennadi Procopciuc 		return ret;
123b8ad8800SGhennadi Procopciuc 	}
124b8ad8800SGhennadi Procopciuc 
125b8ad8800SGhennadi Procopciuc 	ret = clk_enable(S32CC_CLK_XBAR_2X);
126b8ad8800SGhennadi Procopciuc 	if (ret != 0) {
127b8ad8800SGhennadi Procopciuc 		return ret;
128b8ad8800SGhennadi Procopciuc 	}
129b8ad8800SGhennadi Procopciuc 
130b8ad8800SGhennadi Procopciuc 	return ret;
131b8ad8800SGhennadi Procopciuc }
132b8ad8800SGhennadi Procopciuc 
enable_uart_clk(void)133e4462daeSGhennadi Procopciuc static int enable_uart_clk(void)
134e4462daeSGhennadi Procopciuc {
135e4462daeSGhennadi Procopciuc 	int ret;
136e4462daeSGhennadi Procopciuc 
137e4462daeSGhennadi Procopciuc 	ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX8, S32CC_CLK_PERIPH_PLL_PHI3);
138e4462daeSGhennadi Procopciuc 	if (ret != 0) {
139e4462daeSGhennadi Procopciuc 		return ret;
140e4462daeSGhennadi Procopciuc 	}
141e4462daeSGhennadi Procopciuc 
142e4462daeSGhennadi Procopciuc 	ret = clk_enable(S32CC_CLK_LINFLEX_BAUD);
143e4462daeSGhennadi Procopciuc 	if (ret != 0) {
144e4462daeSGhennadi Procopciuc 		return ret;
145e4462daeSGhennadi Procopciuc 	}
146e4462daeSGhennadi Procopciuc 
147e4462daeSGhennadi Procopciuc 	return ret;
148e4462daeSGhennadi Procopciuc }
149e4462daeSGhennadi Procopciuc 
setup_ddr_pll(void)15018c2b137SGhennadi Procopciuc static int setup_ddr_pll(void)
15118c2b137SGhennadi Procopciuc {
15218c2b137SGhennadi Procopciuc 	int ret;
15318c2b137SGhennadi Procopciuc 
15418c2b137SGhennadi Procopciuc 	ret = clk_set_parent(S32CC_CLK_DDR_PLL_MUX, S32CC_CLK_FXOSC);
15518c2b137SGhennadi Procopciuc 	if (ret != 0) {
15618c2b137SGhennadi Procopciuc 		return ret;
15718c2b137SGhennadi Procopciuc 	}
15818c2b137SGhennadi Procopciuc 
15918c2b137SGhennadi Procopciuc 	ret = clk_set_rate(S32CC_CLK_DDR_PLL_VCO, S32CC_DDR_PLL_VCO_FREQ, NULL);
16018c2b137SGhennadi Procopciuc 	if (ret != 0) {
16118c2b137SGhennadi Procopciuc 		return ret;
16218c2b137SGhennadi Procopciuc 	}
16318c2b137SGhennadi Procopciuc 
16418c2b137SGhennadi Procopciuc 	ret = clk_set_rate(S32CC_CLK_DDR_PLL_PHI0, S32CC_DDR_PLL_PHI0_FREQ, NULL);
16518c2b137SGhennadi Procopciuc 	if (ret != 0) {
16618c2b137SGhennadi Procopciuc 		return ret;
16718c2b137SGhennadi Procopciuc 	}
16818c2b137SGhennadi Procopciuc 
16918c2b137SGhennadi Procopciuc 	return ret;
17018c2b137SGhennadi Procopciuc }
17118c2b137SGhennadi Procopciuc 
enable_ddr_clk(void)1728a4f840bSGhennadi Procopciuc static int enable_ddr_clk(void)
1738a4f840bSGhennadi Procopciuc {
1748a4f840bSGhennadi Procopciuc 	int ret;
1758a4f840bSGhennadi Procopciuc 
1768a4f840bSGhennadi Procopciuc 	ret = clk_set_parent(S32CC_CLK_MC_CGM5_MUX0, S32CC_CLK_DDR_PLL_PHI0);
1778a4f840bSGhennadi Procopciuc 	if (ret != 0) {
1788a4f840bSGhennadi Procopciuc 		return ret;
1798a4f840bSGhennadi Procopciuc 	}
1808a4f840bSGhennadi Procopciuc 
1818a4f840bSGhennadi Procopciuc 	ret = clk_enable(S32CC_CLK_DDR);
1828a4f840bSGhennadi Procopciuc 	if (ret != 0) {
1838a4f840bSGhennadi Procopciuc 		return ret;
1848a4f840bSGhennadi Procopciuc 	}
1858a4f840bSGhennadi Procopciuc 
1868a4f840bSGhennadi Procopciuc 	return ret;
1878a4f840bSGhennadi Procopciuc }
1888a4f840bSGhennadi Procopciuc 
enable_usdhc_clk(void)18947b3a825SGhennadi Procopciuc static int enable_usdhc_clk(void)
19047b3a825SGhennadi Procopciuc {
19147b3a825SGhennadi Procopciuc 	int ret;
19247b3a825SGhennadi Procopciuc 
19347b3a825SGhennadi Procopciuc 	ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX14,
19447b3a825SGhennadi Procopciuc 			     S32CC_CLK_PERIPH_PLL_DFS3);
19547b3a825SGhennadi Procopciuc 	if (ret != 0) {
19647b3a825SGhennadi Procopciuc 		return ret;
19747b3a825SGhennadi Procopciuc 	}
19847b3a825SGhennadi Procopciuc 
19947b3a825SGhennadi Procopciuc 	ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_DFS3,
20047b3a825SGhennadi Procopciuc 			   S32CC_PERIPH_DFS_PHI3_FREQ, NULL);
20147b3a825SGhennadi Procopciuc 	if (ret != 0) {
20247b3a825SGhennadi Procopciuc 		return ret;
20347b3a825SGhennadi Procopciuc 	}
20447b3a825SGhennadi Procopciuc 
20547b3a825SGhennadi Procopciuc 	ret = clk_set_rate(S32CC_CLK_USDHC, S32CC_USDHC_FREQ, NULL);
20647b3a825SGhennadi Procopciuc 	if (ret != 0) {
20747b3a825SGhennadi Procopciuc 		return ret;
20847b3a825SGhennadi Procopciuc 	}
20947b3a825SGhennadi Procopciuc 
21047b3a825SGhennadi Procopciuc 	ret = clk_enable(S32CC_CLK_USDHC);
21147b3a825SGhennadi Procopciuc 	if (ret != 0) {
21247b3a825SGhennadi Procopciuc 		return ret;
21347b3a825SGhennadi Procopciuc 	}
21447b3a825SGhennadi Procopciuc 
21547b3a825SGhennadi Procopciuc 	return ret;
21647b3a825SGhennadi Procopciuc }
21747b3a825SGhennadi Procopciuc 
plat_deassert_ddr_reset(void)218*c0cbf5adSKhristine Andreea Barbulescu int plat_deassert_ddr_reset(void)
219*c0cbf5adSKhristine Andreea Barbulescu {
220*c0cbf5adSKhristine Andreea Barbulescu 	int err;
221*c0cbf5adSKhristine Andreea Barbulescu 
222*c0cbf5adSKhristine Andreea Barbulescu 	clk_disable(S32CC_CLK_DDR);
223*c0cbf5adSKhristine Andreea Barbulescu 
224*c0cbf5adSKhristine Andreea Barbulescu 	err = clk_set_parent(S32CC_CLK_MC_CGM5_MUX0, S32CC_CLK_FIRC);
225*c0cbf5adSKhristine Andreea Barbulescu 	if (err != 0) {
226*c0cbf5adSKhristine Andreea Barbulescu 		return err;
227*c0cbf5adSKhristine Andreea Barbulescu 	}
228*c0cbf5adSKhristine Andreea Barbulescu 
229*c0cbf5adSKhristine Andreea Barbulescu 	err = clk_enable(S32CC_CLK_DDR);
230*c0cbf5adSKhristine Andreea Barbulescu 	if (err != 0) {
231*c0cbf5adSKhristine Andreea Barbulescu 		return err;
232*c0cbf5adSKhristine Andreea Barbulescu 	}
233*c0cbf5adSKhristine Andreea Barbulescu 
234*c0cbf5adSKhristine Andreea Barbulescu 	err = mc_rgm_ddr_reset(MC_RGM_BASE_ADDR, S32CC_DDR_RESET_TIMEOUT_US);
235*c0cbf5adSKhristine Andreea Barbulescu 	if (err != 0) {
236*c0cbf5adSKhristine Andreea Barbulescu 		return err;
237*c0cbf5adSKhristine Andreea Barbulescu 	}
238*c0cbf5adSKhristine Andreea Barbulescu 
239*c0cbf5adSKhristine Andreea Barbulescu 	return enable_ddr_clk();
240*c0cbf5adSKhristine Andreea Barbulescu }
241*c0cbf5adSKhristine Andreea Barbulescu 
s32cc_init_core_clocks(void)24261b5ef21SGhennadi Procopciuc int s32cc_init_core_clocks(void)
243d3869455SGhennadi Procopciuc {
244d3869455SGhennadi Procopciuc 	int ret;
245d3869455SGhennadi Procopciuc 
24661b5ef21SGhennadi Procopciuc 	ret = s32cc_clk_register_drv(false);
247514c7380SGhennadi Procopciuc 	if (ret != 0) {
248514c7380SGhennadi Procopciuc 		return ret;
249514c7380SGhennadi Procopciuc 	}
250d3869455SGhennadi Procopciuc 
2515300040bSGhennadi Procopciuc 	ret = setup_fxosc();
252d3869455SGhennadi Procopciuc 	if (ret != 0) {
253d3869455SGhennadi Procopciuc 		return ret;
254d3869455SGhennadi Procopciuc 	}
255d3869455SGhennadi Procopciuc 
2565300040bSGhennadi Procopciuc 	ret = setup_arm_pll();
2578653352aSGhennadi Procopciuc 	if (ret != 0) {
2588653352aSGhennadi Procopciuc 		return ret;
2598653352aSGhennadi Procopciuc 	}
2608653352aSGhennadi Procopciuc 
261d3869455SGhennadi Procopciuc 	ret = enable_a53_clk();
262d3869455SGhennadi Procopciuc 	if (ret != 0) {
263d3869455SGhennadi Procopciuc 		return ret;
264d3869455SGhennadi Procopciuc 	}
265d3869455SGhennadi Procopciuc 
266b8ad8800SGhennadi Procopciuc 	ret = enable_xbar_clk();
267b8ad8800SGhennadi Procopciuc 	if (ret != 0) {
268b8ad8800SGhennadi Procopciuc 		return ret;
269b8ad8800SGhennadi Procopciuc 	}
270b8ad8800SGhennadi Procopciuc 
27161b5ef21SGhennadi Procopciuc 	return ret;
27261b5ef21SGhennadi Procopciuc }
27361b5ef21SGhennadi Procopciuc 
s32cc_init_early_clks(void)27461b5ef21SGhennadi Procopciuc int s32cc_init_early_clks(void)
27561b5ef21SGhennadi Procopciuc {
27661b5ef21SGhennadi Procopciuc 	int ret;
27761b5ef21SGhennadi Procopciuc 
27861b5ef21SGhennadi Procopciuc 	ret = s32cc_clk_register_drv(true);
27961b5ef21SGhennadi Procopciuc 	if (ret != 0) {
28061b5ef21SGhennadi Procopciuc 		return ret;
28161b5ef21SGhennadi Procopciuc 	}
28261b5ef21SGhennadi Procopciuc 
2835300040bSGhennadi Procopciuc 	ret = setup_periph_pll();
2845300040bSGhennadi Procopciuc 	if (ret != 0) {
2855300040bSGhennadi Procopciuc 		return ret;
2865300040bSGhennadi Procopciuc 	}
2875300040bSGhennadi Procopciuc 
288e4462daeSGhennadi Procopciuc 	ret = enable_uart_clk();
289e4462daeSGhennadi Procopciuc 	if (ret != 0) {
290e4462daeSGhennadi Procopciuc 		return ret;
291e4462daeSGhennadi Procopciuc 	}
292e4462daeSGhennadi Procopciuc 
29318c2b137SGhennadi Procopciuc 	ret = setup_ddr_pll();
29418c2b137SGhennadi Procopciuc 	if (ret != 0) {
29518c2b137SGhennadi Procopciuc 		return ret;
29618c2b137SGhennadi Procopciuc 	}
29718c2b137SGhennadi Procopciuc 
2988a4f840bSGhennadi Procopciuc 	ret = enable_ddr_clk();
2998a4f840bSGhennadi Procopciuc 	if (ret != 0) {
3008a4f840bSGhennadi Procopciuc 		return ret;
3018a4f840bSGhennadi Procopciuc 	}
3028a4f840bSGhennadi Procopciuc 
30347b3a825SGhennadi Procopciuc 	ret = enable_usdhc_clk();
30447b3a825SGhennadi Procopciuc 	if (ret != 0) {
30547b3a825SGhennadi Procopciuc 		return ret;
30647b3a825SGhennadi Procopciuc 	}
30747b3a825SGhennadi Procopciuc 
308d3869455SGhennadi Procopciuc 	return ret;
309d3869455SGhennadi Procopciuc }
310