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(DT_NODELABEL(uart1), okay)
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(DT_NODELABEL(uart2), okay)
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(DT_NODELABEL(uart3), okay)
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(DT_NODELABEL(uart4), okay)
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 /* Enable RDC clock */
134 CLOCK_EnableClock(kCLOCK_Rdc);
135
136 /*
137 * The purpose to enable the following modules clock is to make
138 * sure the M4 core could work normally when A53 core
139 * enters the low power state
140 */
141 CLOCK_EnableClock(kCLOCK_Sim_display);
142 CLOCK_EnableClock(kCLOCK_Sim_m);
143 CLOCK_EnableClock(kCLOCK_Sim_main);
144 CLOCK_EnableClock(kCLOCK_Sim_s);
145 CLOCK_EnableClock(kCLOCK_Sim_wakeup);
146 CLOCK_EnableClock(kCLOCK_Debug);
147 CLOCK_EnableClock(kCLOCK_Dram);
148 CLOCK_EnableClock(kCLOCK_Sec_Debug);
149 }
150
nxp_mimx8mm6_init(void)151 static int nxp_mimx8mm6_init(void)
152 {
153
154 /* SoC specific RDC settings */
155 SOC_RdcInit();
156
157 /* SoC specific Clock settings */
158 SOC_ClockInit();
159
160 return 0;
161 }
162
163 SYS_INIT(nxp_mimx8mm6_init, PRE_KERNEL_1, 0);
164