1 /*
2 * Copyright (c) 2017, NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/init.h>
8 #include <soc.h>
9 #include <zephyr/dt-bindings/rdc/imx_rdc.h>
10 #include <zephyr/devicetree.h>
11 #include "wdog_imx.h"
12
13 /* Initialize clock. */
SOC_ClockInit(void)14 void SOC_ClockInit(void)
15 {
16 /* OSC/PLL is already initialized by Cortex-A7 (u-boot) */
17
18 /*
19 * Disable WDOG3
20 * Note : The WDOG clock Root is shared by all the 4 WDOGs,
21 * so Zephyr code should avoid closing it
22 */
23 CCM_UpdateRoot(CCM, ccmRootWdog, ccmRootmuxWdogOsc24m, 0, 0);
24 CCM_EnableRoot(CCM, ccmRootWdog);
25 CCM_ControlGate(CCM, ccmCcgrGateWdog3, ccmClockNeededRun);
26
27 RDC_SetPdapAccess(RDC, rdcPdapWdog3,
28 RDC_DOMAIN_PERM(M4_DOMAIN_ID, RDC_DOMAIN_PERM_RW),
29 false, false);
30
31 WDOG_DisablePowerdown(WDOG3);
32
33 CCM_ControlGate(CCM, ccmCcgrGateWdog3, ccmClockNotNeeded);
34
35 /* We need system PLL Div2 to run M4 core */
36 CCM_ControlGate(CCM, ccmPllGateSys, ccmClockNeededRun);
37 CCM_ControlGate(CCM, ccmPllGateSysDiv2, ccmClockNeededRun);
38
39 /* Enable clock gate for IP bridge and IO mux */
40 CCM_ControlGate(CCM, ccmCcgrGateIpmux1, ccmClockNeededRun);
41 CCM_ControlGate(CCM, ccmCcgrGateIpmux2, ccmClockNeededRun);
42 CCM_ControlGate(CCM, ccmCcgrGateIpmux3, ccmClockNeededRun);
43 CCM_ControlGate(CCM, ccmCcgrGateIomux, ccmClockNeededRun);
44 CCM_ControlGate(CCM, ccmCcgrGateIomuxLpsr, ccmClockNeededRun);
45
46 /* Enable clock gate for RDC */
47 CCM_ControlGate(CCM, ccmCcgrGateRdc, ccmClockNeededRun);
48 }
49
SOC_RdcInit(void)50 void SOC_RdcInit(void)
51 {
52 /* Move M4 core to specific RDC domain */
53 RDC_SetDomainID(RDC, rdcMdaM4, M4_DOMAIN_ID, false);
54 }
55
56 #ifdef CONFIG_GPIO_IMX
nxp_mcimx7_gpio_config(void)57 static void nxp_mcimx7_gpio_config(void)
58 {
59
60 #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio1), okay)
61 RDC_SetPdapAccess(RDC, rdcPdapGpio1, RDC_DT_VAL(gpio1), false, false);
62 /* Enable gpio clock gate */
63 CCM_ControlGate(CCM, ccmCcgrGateGpio1, ccmClockNeededRunWait);
64 #endif
65
66
67 #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio2), okay)
68 RDC_SetPdapAccess(RDC, rdcPdapGpio2, RDC_DT_VAL(gpio2), false, false);
69 /* Enable gpio clock gate */
70 CCM_ControlGate(CCM, ccmCcgrGateGpio2, ccmClockNeededRunWait);
71 #endif
72
73
74 #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio7), okay)
75 RDC_SetPdapAccess(RDC, rdcPdapGpio7, RDC_DT_VAL(gpio7), false, false);
76 /* Enable gpio clock gate */
77 CCM_ControlGate(CCM, ccmCcgrGateGpio7, ccmClockNeededRunWait);
78 #endif
79
80 }
81 #endif /* CONFIG_GPIO_IMX */
82
83 #ifdef CONFIG_UART_IMX
nxp_mcimx7_uart_config(void)84 static void nxp_mcimx7_uart_config(void)
85 {
86
87 #if DT_NODE_HAS_STATUS(DT_NODELABEL(uart2), okay)
88 /* We need to grasp board uart exclusively */
89 RDC_SetPdapAccess(RDC, rdcPdapUart2, RDC_DT_VAL(uart2), false, false);
90 /* Select clock derived from OSC clock(24M) */
91 CCM_UpdateRoot(CCM, ccmRootUart2, ccmRootmuxUartOsc24m, 0, 0);
92 /* Enable uart clock */
93 CCM_EnableRoot(CCM, ccmRootUart2);
94 /*
95 * IC Limitation
96 * M4 stop will cause A7 UART lose functionality
97 * So we need UART clock all the time
98 */
99 CCM_ControlGate(CCM, ccmCcgrGateUart2, ccmClockNeededAll);
100 #endif
101
102 #if DT_NODE_HAS_STATUS(DT_NODELABEL(uart6), okay)
103 /* We need to grasp board uart exclusively */
104 RDC_SetPdapAccess(RDC, rdcPdapUart6, RDC_DT_VAL(uart6), false, false);
105 /* Select clock derived from OSC clock(24M) */
106 CCM_UpdateRoot(CCM, ccmRootUart6, ccmRootmuxUartOsc24m, 0, 0);
107 /* Enable uart clock */
108 CCM_EnableRoot(CCM, ccmRootUart6);
109 /*
110 * IC Limitation
111 * M4 stop will cause A7 UART lose functionality
112 * So we need UART clock all the time
113 */
114 CCM_ControlGate(CCM, ccmCcgrGateUart6, ccmClockNeededAll);
115 #endif
116 }
117 #endif /* CONFIG_UART_IMX */
118
119
120 #ifdef CONFIG_I2C_IMX
nxp_mcimx7_i2c_config(void)121 static void nxp_mcimx7_i2c_config(void)
122 {
123
124 #if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay)
125 /* In this example, we need to grasp board I2C exclusively */
126 RDC_SetPdapAccess(RDC, rdcPdapI2c1, RDC_DT_VAL(i2c1), false, false);
127 /* Select I2C clock derived from OSC clock(24M) */
128 CCM_UpdateRoot(CCM, ccmRootI2c1, ccmRootmuxI2cOsc24m, 0, 0);
129 /* Enable I2C clock */
130 CCM_EnableRoot(CCM, ccmRootI2c1);
131 CCM_ControlGate(CCM, ccmCcgrGateI2c1, ccmClockNeededRunWait);
132 #endif
133
134 #if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay)
135 /* In this example, we need to grasp board I2C exclusively */
136 RDC_SetPdapAccess(RDC, rdcPdapI2c2, RDC_DT_VAL(i2c2), false, false);
137 /* Select I2C clock derived from OSC clock(24M) */
138 CCM_UpdateRoot(CCM, ccmRootI2c2, ccmRootmuxI2cOsc24m, 0, 0);
139 /* Enable I2C clock */
140 CCM_EnableRoot(CCM, ccmRootI2c2);
141 CCM_ControlGate(CCM, ccmCcgrGateI2c2, ccmClockNeededRunWait);
142 #endif
143
144 #if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c3), okay)
145 /* In this example, we need to grasp board I2C exclusively */
146 RDC_SetPdapAccess(RDC, rdcPdapI2c3, RDC_DT_VAL(i2c3), false, false);
147 /* Select I2C clock derived from OSC clock(24M) */
148 CCM_UpdateRoot(CCM, ccmRootI2c3, ccmRootmuxI2cOsc24m, 0, 0);
149 /* Enable I2C clock */
150 CCM_EnableRoot(CCM, ccmRootI2c3);
151 CCM_ControlGate(CCM, ccmCcgrGateI2c3, ccmClockNeededRunWait);
152 #endif
153
154 #if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c4), okay)
155 /* In this example, we need to grasp board I2C exclusively */
156 RDC_SetPdapAccess(RDC, rdcPdapI2c4, RDC_DT_VAL(i2c4), false, false);
157 /* Select I2C clock derived from OSC clock(24M) */
158 CCM_UpdateRoot(CCM, ccmRootI2c4, ccmRootmuxI2cOsc24m, 0, 0);
159 /* Enable I2C clock */
160 CCM_EnableRoot(CCM, ccmRootI2c4);
161 CCM_ControlGate(CCM, ccmCcgrGateI2c4, ccmClockNeededRunWait);
162 #endif
163
164 }
165 #endif /* CONFIG_I2C_IMX */
166
167 #ifdef CONFIG_PWM_IMX
nxp_mcimx7_pwm_config(void)168 static void nxp_mcimx7_pwm_config(void)
169 {
170
171 #if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm1), okay)
172 /* We need to grasp board pwm exclusively */
173 RDC_SetPdapAccess(RDC, rdcPdapPwm1, RDC_DT_VAL(pwm1), false, false);
174 /* Select clock derived from OSC clock(24M) */
175 CCM_UpdateRoot(CCM, ccmRootPwm1, ccmRootmuxPwmOsc24m, 0, 0);
176 /* Enable pwm clock */
177 CCM_EnableRoot(CCM, ccmRootPwm1);
178 CCM_ControlGate(CCM, ccmCcgrGatePwm1, ccmClockNeededAll);
179 #endif
180
181 #if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm2), okay)
182 /* We need to grasp board pwm exclusively */
183 RDC_SetPdapAccess(RDC, rdcPdapPwm2, RDC_DT_VAL(pwm2), false, false);
184 /* Select clock derived from OSC clock(24M) */
185 CCM_UpdateRoot(CCM, ccmRootPwm2, ccmRootmuxPwmOsc24m, 0, 0);
186 /* Enable pwm clock */
187 CCM_EnableRoot(CCM, ccmRootPwm2);
188 CCM_ControlGate(CCM, ccmCcgrGatePwm2, ccmClockNeededAll);
189 #endif
190
191 #if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm3), okay)
192 /* We need to grasp board pwm exclusively */
193 RDC_SetPdapAccess(RDC, rdcPdapPwm3, RDC_DT_VAL(pwm3), false, false);
194 /* Select clock derived from OSC clock(24M) */
195 CCM_UpdateRoot(CCM, ccmRootPwm3, ccmRootmuxPwmOsc24m, 0, 0);
196 /* Enable pwm clock */
197 CCM_EnableRoot(CCM, ccmRootPwm3);
198 CCM_ControlGate(CCM, ccmCcgrGatePwm3, ccmClockNeededAll);
199 #endif
200
201 #if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm4), okay)
202 /* We need to grasp board pwm exclusively */
203 RDC_SetPdapAccess(RDC, rdcPdapPwm4, RDC_DT_VAL(pwm4), false, false);
204 /* Select clock derived from OSC clock(24M) */
205 CCM_UpdateRoot(CCM, ccmRootPwm4, ccmRootmuxPwmOsc24m, 0, 0);
206 /* Enable pwm clock */
207 CCM_EnableRoot(CCM, ccmRootPwm4);
208 CCM_ControlGate(CCM, ccmCcgrGatePwm4, ccmClockNeededAll);
209 #endif
210
211 }
212 #endif /* CONFIG_PWM_IMX */
213
214 #ifdef CONFIG_IPM_IMX
nxp_mcimx7_mu_config(void)215 static void nxp_mcimx7_mu_config(void)
216 {
217 /* Set access to MU B for M4 core */
218 RDC_SetPdapAccess(RDC, rdcPdapMuB, RDC_DT_VAL(mub), false, false);
219
220 /* Enable clock gate for MU*/
221 CCM_ControlGate(CCM, ccmCcgrGateMu, ccmClockNeededRun);
222 }
223 #endif /* CONFIG_IPM_IMX */
224
nxp_mcimx7_init(void)225 static int nxp_mcimx7_init(void)
226 {
227
228 /* SoC specific RDC settings */
229 SOC_RdcInit();
230
231 /* BoC specific clock settings */
232 SOC_ClockInit();
233
234 #ifdef CONFIG_GPIO_IMX
235 nxp_mcimx7_gpio_config();
236 #endif /* CONFIG_GPIO_IMX */
237
238 #ifdef CONFIG_UART_IMX
239 nxp_mcimx7_uart_config();
240 #endif /* CONFIG_UART_IMX */
241
242 #ifdef CONFIG_I2C_IMX
243 nxp_mcimx7_i2c_config();
244 #endif /* CONFIG_I2C_IMX */
245
246 #ifdef CONFIG_PWM_IMX
247 nxp_mcimx7_pwm_config();
248 #endif /* CONFIG_PWM_IMX */
249
250 #ifdef CONFIG_IPM_IMX
251 nxp_mcimx7_mu_config();
252 #endif /* CONFIG_IPM_IMX */
253
254 return 0;
255 }
256
257 SYS_INIT(nxp_mcimx7_init, PRE_KERNEL_1, 0);
258