1 /*
2  * Copyright (c) 2020, Manivannan Sadhasivam <mani@kernel.org>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/device.h>
8 #include <fsl_clock.h>
9 #include <fsl_common.h>
10 #include <fsl_rdc.h>
11 #include <zephyr/init.h>
12 #include <zephyr/kernel.h>
13 #include <soc.h>
14 
15 #include <zephyr/dt-bindings/rdc/imx_rdc.h>
16 
17 /* OSC/PLL is already initialized by ROM and Cortex-A53 (u-boot) */
SOC_RdcInit(void)18 static void SOC_RdcInit(void)
19 {
20 	/* Move M4 core to specific RDC domain 1 */
21 	rdc_domain_assignment_t assignment = {0};
22 
23 	assignment.domainId = M4_DOMAIN_ID;
24 	RDC_SetMasterDomainAssignment(RDC, kRDC_Master_M4, &assignment);
25 
26 	/*
27 	 * The M4 core is running at domain 1, enable clock gate for
28 	 * Iomux to run at domain 1.
29 	 */
30 	CLOCK_EnableClock(kCLOCK_Iomux);
31 	CLOCK_EnableClock(kCLOCK_Ipmux1);
32 	CLOCK_EnableClock(kCLOCK_Ipmux2);
33 	CLOCK_EnableClock(kCLOCK_Ipmux3);
34 	CLOCK_EnableClock(kCLOCK_Ipmux4);
35 
36 	CLOCK_EnableClock(kCLOCK_Qspi);
37 
38 	/*
39 	 * The M4 core is running at domain 1, enable the PLL clock sources
40 	 * to domain 1.
41 	 */
42 	/* Enable SysPLL1 to Domain 1 */
43 	CLOCK_ControlGate(kCLOCK_SysPll1Gate, kCLOCK_ClockNeededAll);
44 	/* Enable SysPLL2 to Domain 1 */
45 	CLOCK_ControlGate(kCLOCK_SysPll2Gate, kCLOCK_ClockNeededAll);
46 	/* Enable SysPLL3 to Domain 1 */
47 	CLOCK_ControlGate(kCLOCK_SysPll3Gate, kCLOCK_ClockNeededAll);
48 	/* Enable AudioPLL1 to Domain 1 */
49 	CLOCK_ControlGate(kCLOCK_AudioPll1Gate, kCLOCK_ClockNeededAll);
50 	/* Enable AudioPLL2 to Domain 1 */
51 	CLOCK_ControlGate(kCLOCK_AudioPll2Gate, kCLOCK_ClockNeededAll);
52 	/* Enable VideoPLL1 to Domain 1 */
53 	CLOCK_ControlGate(kCLOCK_VideoPll1Gate, kCLOCK_ClockNeededAll);
54 }
55 
56 /* AUDIO PLL1 configuration */
57 static const ccm_analog_frac_pll_config_t g_audioPll1Config = {
58 	.refSel  = kANALOG_PllRefOsc24M, /* PLL reference OSC24M */
59 	.mainDiv = 655U,
60 	.dsm     = 23593U,
61 	.preDiv  = 5U,
62 	.postDiv = 2U, /* AUDIO PLL1 frequency  = 786432000HZ */
63 };
64 
65 /* AUDIO PLL2 configuration */
66 static const ccm_analog_frac_pll_config_t g_audioPll2Config = {
67 	.refSel  = kANALOG_PllRefOsc24M, /* PLL reference OSC24M */
68 	.mainDiv = 301U,
69 	.dsm     = 3670U,
70 	.preDiv  = 5U,
71 	.postDiv = 1U, /* AUDIO PLL2 frequency  = 722534399HZ */
72 };
73 
SOC_ClockInit(void)74 static void SOC_ClockInit(void)
75 {
76 	/*
77 	 * Switch AHB NOC root to 24M first in order to configure
78 	 * the SYSTEM PLL1
79 	 */
80 	CLOCK_SetRootMux(kCLOCK_RootAhb, kCLOCK_AhbRootmuxOsc24M);
81 
82 	/*
83 	 * Switch AXI M4 root to 24M first in order to configure
84 	 * the SYSTEM PLL2
85 	 */
86 	CLOCK_SetRootMux(kCLOCK_RootM4, kCLOCK_M4RootmuxOsc24M);
87 
88 	/* Init AUDIO PLL1 to run at 786432000HZ */
89 	CLOCK_InitAudioPll1(&g_audioPll1Config);
90 	/* Init AUDIO PLL2 to run at 722534399HZ */
91 	CLOCK_InitAudioPll2(&g_audioPll2Config);
92 
93 	CLOCK_SetRootDivider(kCLOCK_RootM4, 1U, 2U);
94 	/* Switch cortex-m4 to SYSTEM PLL1 */
95 	CLOCK_SetRootMux(kCLOCK_RootM4, kCLOCK_M4RootmuxSysPll1);
96 
97 	CLOCK_SetRootDivider(kCLOCK_RootAhb, 1U, 1U);
98 	/* Switch AHB to SYSTEM PLL1 DIV6 = 133MHZ */
99 	CLOCK_SetRootMux(kCLOCK_RootAhb, kCLOCK_AhbRootmuxSysPll1Div6);
100 
101 	/* Set root clock to 800MHZ/ 2= 400MHZ */
102 	CLOCK_SetRootDivider(kCLOCK_RootAudioAhb, 1U, 2U);
103 	/* switch AUDIO AHB to SYSTEM PLL1 */
104 	CLOCK_SetRootMux(kCLOCK_RootAudioAhb, kCLOCK_AudioAhbRootmuxSysPll1);
105 
106 #if defined(CONFIG_UART_MCUX_IUART)
107 #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(uart1))
108 	/* Set UART source to SysPLL1 Div10 80MHZ */
109 	CLOCK_SetRootMux(kCLOCK_RootUart1, kCLOCK_UartRootmuxSysPll1Div10);
110 	/* Set root clock to 80MHZ/ 1= 80MHZ */
111 	CLOCK_SetRootDivider(kCLOCK_RootUart1, 1U, 1U);
112 #endif
113 #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(uart2))
114 	/* Set UART source to SysPLL1 Div10 80MHZ */
115 	CLOCK_SetRootMux(kCLOCK_RootUart2, kCLOCK_UartRootmuxSysPll1Div10);
116 	/* Set root clock to 80MHZ/ 1= 80MHZ */
117 	CLOCK_SetRootDivider(kCLOCK_RootUart2, 1U, 1U);
118 #endif
119 #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(uart3))
120 	/* Set UART source to SysPLL1 Div10 80MHZ */
121 	CLOCK_SetRootMux(kCLOCK_RootUart3, kCLOCK_UartRootmuxSysPll1Div10);
122 	/* Set root clock to 80MHZ/ 1= 80MHZ */
123 	CLOCK_SetRootDivider(kCLOCK_RootUart3, 1U, 1U);
124 #endif
125 #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(uart4))
126 	/* Set UART source to SysPLL1 Div10 80MHZ */
127 	CLOCK_SetRootMux(kCLOCK_RootUart4, kCLOCK_UartRootmuxSysPll1Div10);
128 	/* Set root clock to 80MHZ/ 1= 80MHZ */
129 	CLOCK_SetRootDivider(kCLOCK_RootUart4, 1U, 1U);
130 #endif
131 #endif
132 
133 #if defined(CONFIG_SPI_MCUX_ECSPI)
134 #if DT_NODE_HAS_STATUS(DT_NODELABEL(ecspi1), okay)
135 	/* Set ECSPI1 source to SYSTEM PLL1 800MHZ */
136 	CLOCK_SetRootMux(kCLOCK_RootEcspi1, kCLOCK_EcspiRootmuxSysPll1);
137 	/* Set root clock to 800MHZ / 10 = 80MHZ */
138 	CLOCK_SetRootDivider(kCLOCK_RootEcspi1, 2U, 5U);
139 #endif
140 
141 #if DT_NODE_HAS_STATUS(DT_NODELABEL(ecspi2), okay)
142 	/* Set ECSPI2 source to SYSTEM PLL1 800MHZ */
143 	CLOCK_SetRootMux(kCLOCK_RootEcspi2, kCLOCK_EcspiRootmuxSysPll1);
144 	/* Set root clock to 800MHZ / 10 = 80MHZ */
145 	CLOCK_SetRootDivider(kCLOCK_RootEcspi2, 2U, 5U);
146 #endif
147 
148 #if DT_NODE_HAS_STATUS(DT_NODELABEL(ecspi3), okay)
149 	/* Set ECSPI3 source to SYSTEM PLL1 800MHZ */
150 	CLOCK_SetRootMux(kCLOCK_RootEcspi3, kCLOCK_EcspiRootmuxSysPll1);
151 	/* Set root clock to 800MHZ / 10 = 80MHZ */
152 	CLOCK_SetRootDivider(kCLOCK_RootEcspi3, 2U, 5U);
153 #endif
154 #endif
155 
156 	/* Enable RDC clock */
157 	CLOCK_EnableClock(kCLOCK_Rdc);
158 
159 	/*
160 	 * The purpose to enable the following modules clock is to make
161 	 * sure the M4 core could work normally when A53 core
162 	 * enters the low power state
163 	 */
164 	CLOCK_EnableClock(kCLOCK_Sim_display);
165 	CLOCK_EnableClock(kCLOCK_Sim_m);
166 	CLOCK_EnableClock(kCLOCK_Sim_main);
167 	CLOCK_EnableClock(kCLOCK_Sim_s);
168 	CLOCK_EnableClock(kCLOCK_Sim_wakeup);
169 	CLOCK_EnableClock(kCLOCK_Debug);
170 	CLOCK_EnableClock(kCLOCK_Dram);
171 	CLOCK_EnableClock(kCLOCK_Sec_Debug);
172 }
173 
soc_early_init_hook(void)174 void soc_early_init_hook(void)
175 {
176 
177 	/* SoC specific RDC settings */
178 	SOC_RdcInit();
179 
180 	/* SoC specific Clock settings */
181 	SOC_ClockInit();
182 }
183