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