1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * AM43XX Clock init |
4 | * |
5 | * Copyright (C) 2013 Texas Instruments, Inc |
6 | * Tero Kristo (t-kristo@ti.com) |
7 | */ |
8 | |
9 | #include <linux/kernel.h> |
10 | #include <linux/list.h> |
11 | #include <linux/clk.h> |
12 | #include <linux/clk-provider.h> |
13 | #include <linux/clk/ti.h> |
14 | #include <dt-bindings/clock/am4.h> |
15 | |
16 | #include "clock.h" |
17 | |
18 | static const struct omap_clkctrl_reg_data am4_l3s_tsc_clkctrl_regs[] __initconst = { |
19 | { AM4_L3S_TSC_ADC_TSC_CLKCTRL, NULL, CLKF_SW_SUP, "adc_tsc_fck" }, |
20 | { 0 }, |
21 | }; |
22 | |
23 | static const char * const am4_synctimer_32kclk_parents[] __initconst = { |
24 | "mux_synctimer32k_ck" , |
25 | NULL, |
26 | }; |
27 | |
28 | static const struct omap_clkctrl_bit_data am4_counter_32k_bit_data[] __initconst = { |
29 | { 8, TI_CLK_GATE, am4_synctimer_32kclk_parents, NULL }, |
30 | { 0 }, |
31 | }; |
32 | |
33 | static const struct omap_clkctrl_reg_data am4_l4_wkup_aon_clkctrl_regs[] __initconst = { |
34 | { AM4_L4_WKUP_AON_WKUP_M3_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_NO_IDLEST, "sys_clkin_ck" }, |
35 | { AM4_L4_WKUP_AON_COUNTER_32K_CLKCTRL, am4_counter_32k_bit_data, CLKF_SW_SUP, "l4-wkup-aon-clkctrl:0008:8" }, |
36 | { 0 }, |
37 | }; |
38 | |
39 | static const char * const am4_gpio0_dbclk_parents[] __initconst = { |
40 | "gpio0_dbclk_mux_ck" , |
41 | NULL, |
42 | }; |
43 | |
44 | static const struct omap_clkctrl_bit_data am4_gpio1_bit_data[] __initconst = { |
45 | { 8, TI_CLK_GATE, am4_gpio0_dbclk_parents, NULL }, |
46 | { 0 }, |
47 | }; |
48 | |
49 | static const struct omap_clkctrl_reg_data am4_l4_wkup_clkctrl_regs[] __initconst = { |
50 | { AM4_L4_WKUP_L4_WKUP_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck" }, |
51 | { AM4_L4_WKUP_TIMER1_CLKCTRL, NULL, CLKF_SW_SUP, "timer1_fck" }, |
52 | { AM4_L4_WKUP_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "wdt1_fck" }, |
53 | { AM4_L4_WKUP_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck" }, |
54 | { AM4_L4_WKUP_UART1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck" }, |
55 | { AM4_L4_WKUP_SMARTREFLEX0_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex0_fck" }, |
56 | { AM4_L4_WKUP_SMARTREFLEX1_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex1_fck" }, |
57 | { AM4_L4_WKUP_CONTROL_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck" }, |
58 | { AM4_L4_WKUP_GPIO1_CLKCTRL, am4_gpio1_bit_data, CLKF_SW_SUP, "sys_clkin_ck" }, |
59 | { 0 }, |
60 | }; |
61 | |
62 | static const struct omap_clkctrl_reg_data am4_mpu_clkctrl_regs[] __initconst = { |
63 | { AM4_MPU_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_mpu_m2_ck" }, |
64 | { 0 }, |
65 | }; |
66 | |
67 | static const struct omap_clkctrl_reg_data am4_gfx_l3_clkctrl_regs[] __initconst = { |
68 | { AM4_GFX_L3_GFX_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_NO_IDLEST, "gfx_fck_div_ck" }, |
69 | { 0 }, |
70 | }; |
71 | |
72 | static const struct omap_clkctrl_reg_data am4_l4_rtc_clkctrl_regs[] __initconst = { |
73 | { AM4_L4_RTC_RTC_CLKCTRL, NULL, CLKF_SW_SUP, "clkdiv32k_ick" }, |
74 | { 0 }, |
75 | }; |
76 | |
77 | static const struct omap_clkctrl_reg_data am4_l3_clkctrl_regs[] __initconst = { |
78 | { AM4_L3_L3_MAIN_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, |
79 | { AM4_L3_AES_CLKCTRL, NULL, CLKF_SW_SUP, "aes0_fck" }, |
80 | { AM4_L3_DES_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, |
81 | { AM4_L3_L3_INSTR_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, |
82 | { AM4_L3_OCMCRAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, |
83 | { AM4_L3_SHAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, |
84 | { AM4_L3_TPCC_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, |
85 | { AM4_L3_TPTC0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, |
86 | { AM4_L3_TPTC1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, |
87 | { AM4_L3_TPTC2_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, |
88 | { AM4_L3_L4_HS_CLKCTRL, NULL, CLKF_SW_SUP, "l4hs_gclk" }, |
89 | { 0 }, |
90 | }; |
91 | |
92 | static const char * const am4_usb_otg_ss0_refclk960m_parents[] __initconst = { |
93 | "dpll_per_clkdcoldo" , |
94 | NULL, |
95 | }; |
96 | |
97 | static const struct omap_clkctrl_bit_data am4_usb_otg_ss0_bit_data[] __initconst = { |
98 | { 8, TI_CLK_GATE, am4_usb_otg_ss0_refclk960m_parents, NULL }, |
99 | { 0 }, |
100 | }; |
101 | |
102 | static const struct omap_clkctrl_bit_data am4_usb_otg_ss1_bit_data[] __initconst = { |
103 | { 8, TI_CLK_GATE, am4_usb_otg_ss0_refclk960m_parents, NULL }, |
104 | { 0 }, |
105 | }; |
106 | |
107 | static const struct omap_clkctrl_reg_data am4_l3s_clkctrl_regs[] __initconst = { |
108 | { AM4_L3S_VPFE0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, |
109 | { AM4_L3S_VPFE1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, |
110 | { AM4_L3S_GPMC_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk" }, |
111 | { AM4_L3S_ADC1_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk" }, |
112 | { AM4_L3S_MCASP0_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp0_fck" }, |
113 | { AM4_L3S_MCASP1_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp1_fck" }, |
114 | { AM4_L3S_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" }, |
115 | { AM4_L3S_QSPI_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk" }, |
116 | { AM4_L3S_USB_OTG_SS0_CLKCTRL, am4_usb_otg_ss0_bit_data, CLKF_SW_SUP, "l3s_gclk" }, |
117 | { AM4_L3S_USB_OTG_SS1_CLKCTRL, am4_usb_otg_ss1_bit_data, CLKF_SW_SUP, "l3s_gclk" }, |
118 | { 0 }, |
119 | }; |
120 | |
121 | static const struct omap_clkctrl_reg_data am4_pruss_ocp_clkctrl_regs[] __initconst = { |
122 | { AM4_PRUSS_OCP_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_NO_IDLEST, "pruss_ocp_gclk" }, |
123 | { 0 }, |
124 | }; |
125 | |
126 | static const char * const am4_gpio1_dbclk_parents[] __initconst = { |
127 | "clkdiv32k_ick" , |
128 | NULL, |
129 | }; |
130 | |
131 | static const struct omap_clkctrl_bit_data am4_gpio2_bit_data[] __initconst = { |
132 | { .bit: 8, .type: TI_CLK_GATE, .parents: am4_gpio1_dbclk_parents, NULL }, |
133 | { 0 }, |
134 | }; |
135 | |
136 | static const struct omap_clkctrl_bit_data am4_gpio3_bit_data[] __initconst = { |
137 | { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL }, |
138 | { 0 }, |
139 | }; |
140 | |
141 | static const struct omap_clkctrl_bit_data am4_gpio4_bit_data[] __initconst = { |
142 | { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL }, |
143 | { 0 }, |
144 | }; |
145 | |
146 | static const struct omap_clkctrl_bit_data am4_gpio5_bit_data[] __initconst = { |
147 | { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL }, |
148 | { 0 }, |
149 | }; |
150 | |
151 | static const struct omap_clkctrl_bit_data am4_gpio6_bit_data[] __initconst = { |
152 | { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL }, |
153 | { 0 }, |
154 | }; |
155 | |
156 | static const struct omap_clkctrl_reg_data am4_l4ls_clkctrl_regs[] __initconst = { |
157 | { AM4_L4LS_L4_LS_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, |
158 | { AM4_L4LS_D_CAN0_CLKCTRL, NULL, CLKF_SW_SUP, "dcan0_fck" }, |
159 | { AM4_L4LS_D_CAN1_CLKCTRL, NULL, CLKF_SW_SUP, "dcan1_fck" }, |
160 | { AM4_L4LS_EPWMSS0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, |
161 | { AM4_L4LS_EPWMSS1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, |
162 | { AM4_L4LS_EPWMSS2_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, |
163 | { AM4_L4LS_EPWMSS3_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, |
164 | { AM4_L4LS_EPWMSS4_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, |
165 | { AM4_L4LS_EPWMSS5_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, |
166 | { AM4_L4LS_ELM_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, |
167 | { AM4_L4LS_GPIO2_CLKCTRL, am4_gpio2_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, |
168 | { AM4_L4LS_GPIO3_CLKCTRL, am4_gpio3_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, |
169 | { AM4_L4LS_GPIO4_CLKCTRL, am4_gpio4_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, |
170 | { AM4_L4LS_GPIO5_CLKCTRL, am4_gpio5_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, |
171 | { AM4_L4LS_GPIO6_CLKCTRL, am4_gpio6_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, |
172 | { AM4_L4LS_HDQ1W_CLKCTRL, NULL, CLKF_SW_SUP, "func_12m_clk" }, |
173 | { AM4_L4LS_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, |
174 | { AM4_L4LS_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, |
175 | { AM4_L4LS_MAILBOX_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, |
176 | { AM4_L4LS_MMC1_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" }, |
177 | { AM4_L4LS_MMC2_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" }, |
178 | { AM4_L4LS_RNG_CLKCTRL, NULL, CLKF_SW_SUP, "rng_fck" }, |
179 | { AM4_L4LS_SPI0_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, |
180 | { AM4_L4LS_SPI1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, |
181 | { AM4_L4LS_SPI2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, |
182 | { AM4_L4LS_SPI3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, |
183 | { AM4_L4LS_SPI4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, |
184 | { AM4_L4LS_SPINLOCK_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, |
185 | { AM4_L4LS_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "timer2_fck" }, |
186 | { AM4_L4LS_TIMER3_CLKCTRL, NULL, CLKF_SW_SUP, "timer3_fck" }, |
187 | { AM4_L4LS_TIMER4_CLKCTRL, NULL, CLKF_SW_SUP, "timer4_fck" }, |
188 | { AM4_L4LS_TIMER5_CLKCTRL, NULL, CLKF_SW_SUP, "timer5_fck" }, |
189 | { AM4_L4LS_TIMER6_CLKCTRL, NULL, CLKF_SW_SUP, "timer6_fck" }, |
190 | { AM4_L4LS_TIMER7_CLKCTRL, NULL, CLKF_SW_SUP, "timer7_fck" }, |
191 | { AM4_L4LS_TIMER8_CLKCTRL, NULL, CLKF_SW_SUP, "timer8_fck" }, |
192 | { AM4_L4LS_TIMER9_CLKCTRL, NULL, CLKF_SW_SUP, "timer9_fck" }, |
193 | { AM4_L4LS_TIMER10_CLKCTRL, NULL, CLKF_SW_SUP, "timer10_fck" }, |
194 | { AM4_L4LS_TIMER11_CLKCTRL, NULL, CLKF_SW_SUP, "timer11_fck" }, |
195 | { AM4_L4LS_UART2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, |
196 | { AM4_L4LS_UART3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, |
197 | { AM4_L4LS_UART4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, |
198 | { AM4_L4LS_UART5_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, |
199 | { AM4_L4LS_UART6_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, |
200 | { AM4_L4LS_OCP2SCP0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, |
201 | { AM4_L4LS_OCP2SCP1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, |
202 | { 0 }, |
203 | }; |
204 | |
205 | static const struct omap_clkctrl_reg_data am4_emif_clkctrl_regs[] __initconst = { |
206 | { AM4_EMIF_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_ck" }, |
207 | { 0 }, |
208 | }; |
209 | |
210 | static const struct omap_clkctrl_reg_data am4_dss_clkctrl_regs[] __initconst = { |
211 | { AM4_DSS_DSS_CORE_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SET_RATE_PARENT, "disp_clk" }, |
212 | { 0 }, |
213 | }; |
214 | |
215 | static const struct omap_clkctrl_reg_data am4_cpsw_125mhz_clkctrl_regs[] __initconst = { |
216 | { AM4_CPSW_125MHZ_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk" }, |
217 | { 0 }, |
218 | }; |
219 | |
220 | const struct omap_clkctrl_data am4_clkctrl_data[] __initconst = { |
221 | { 0x44df2920, am4_l3s_tsc_clkctrl_regs }, |
222 | { 0x44df2a28, am4_l4_wkup_aon_clkctrl_regs }, |
223 | { 0x44df2a20, am4_l4_wkup_clkctrl_regs }, |
224 | { 0x44df8320, am4_mpu_clkctrl_regs }, |
225 | { 0x44df8420, am4_gfx_l3_clkctrl_regs }, |
226 | { 0x44df8520, am4_l4_rtc_clkctrl_regs }, |
227 | { 0x44df8820, am4_l3_clkctrl_regs }, |
228 | { 0x44df8868, am4_l3s_clkctrl_regs }, |
229 | { 0x44df8b20, am4_pruss_ocp_clkctrl_regs }, |
230 | { 0x44df8c20, am4_l4ls_clkctrl_regs }, |
231 | { 0x44df8f20, am4_emif_clkctrl_regs }, |
232 | { 0x44df9220, am4_dss_clkctrl_regs }, |
233 | { 0x44df9320, am4_cpsw_125mhz_clkctrl_regs }, |
234 | { 0 }, |
235 | }; |
236 | |
237 | const struct omap_clkctrl_data am438x_clkctrl_data[] __initconst = { |
238 | { 0x44df2920, am4_l3s_tsc_clkctrl_regs }, |
239 | { 0x44df2a28, am4_l4_wkup_aon_clkctrl_regs }, |
240 | { 0x44df2a20, am4_l4_wkup_clkctrl_regs }, |
241 | { 0x44df8320, am4_mpu_clkctrl_regs }, |
242 | { 0x44df8420, am4_gfx_l3_clkctrl_regs }, |
243 | { 0x44df8820, am4_l3_clkctrl_regs }, |
244 | { 0x44df8868, am4_l3s_clkctrl_regs }, |
245 | { 0x44df8b20, am4_pruss_ocp_clkctrl_regs }, |
246 | { 0x44df8c20, am4_l4ls_clkctrl_regs }, |
247 | { 0x44df8f20, am4_emif_clkctrl_regs }, |
248 | { 0x44df9220, am4_dss_clkctrl_regs }, |
249 | { 0x44df9320, am4_cpsw_125mhz_clkctrl_regs }, |
250 | { 0 }, |
251 | }; |
252 | |
253 | static struct ti_dt_clk am43xx_clks[] = { |
254 | DT_CLK(NULL, "timer_32k_ck" , "clkdiv32k_ick" ), |
255 | DT_CLK(NULL, "timer_sys_ck" , "sys_clkin_ck" ), |
256 | DT_CLK(NULL, "gpio0_dbclk" , "l4-wkup-clkctrl:0148:8" ), |
257 | DT_CLK(NULL, "gpio1_dbclk" , "l4ls-clkctrl:0058:8" ), |
258 | DT_CLK(NULL, "gpio2_dbclk" , "l4ls-clkctrl:0060:8" ), |
259 | DT_CLK(NULL, "gpio3_dbclk" , "l4ls-clkctrl:0068:8" ), |
260 | DT_CLK(NULL, "gpio4_dbclk" , "l4ls-clkctrl:0070:8" ), |
261 | DT_CLK(NULL, "gpio5_dbclk" , "l4ls-clkctrl:0078:8" ), |
262 | DT_CLK(NULL, "synctimer_32kclk" , "l4-wkup-aon-clkctrl:0008:8" ), |
263 | DT_CLK(NULL, "usb_otg_ss0_refclk960m" , "l3s-clkctrl:01f8:8" ), |
264 | DT_CLK(NULL, "usb_otg_ss1_refclk960m" , "l3s-clkctrl:0200:8" ), |
265 | { .node_name = NULL }, |
266 | }; |
267 | |
268 | static const char *enable_init_clks[] = { |
269 | /* AM4_L3_L3_MAIN_CLKCTRL, needed during suspend */ |
270 | "l3-clkctrl:0000:0" , |
271 | }; |
272 | |
273 | int __init am43xx_dt_clk_init(void) |
274 | { |
275 | struct clk *clk1, *clk2; |
276 | |
277 | ti_dt_clocks_register(oclks: am43xx_clks); |
278 | |
279 | omap2_clk_disable_autoidle_all(); |
280 | |
281 | omap2_clk_enable_init_clocks(clk_names: enable_init_clks, |
282 | ARRAY_SIZE(enable_init_clks)); |
283 | |
284 | ti_clk_add_aliases(); |
285 | |
286 | /* |
287 | * cpsw_cpts_rft_clk has got the choice of 3 clocksources |
288 | * dpll_core_m4_ck, dpll_core_m5_ck and dpll_disp_m2_ck. |
289 | * By default dpll_core_m4_ck is selected, witn this as clock |
290 | * source the CPTS doesnot work properly. It gives clockcheck errors |
291 | * while running PTP. |
292 | * clockcheck: clock jumped backward or running slower than expected! |
293 | * By selecting dpll_core_m5_ck as the clocksource fixes this issue. |
294 | * In AM335x dpll_core_m5_ck is the default clocksource. |
295 | */ |
296 | clk1 = clk_get_sys(NULL, con_id: "cpsw_cpts_rft_clk" ); |
297 | clk2 = clk_get_sys(NULL, con_id: "dpll_core_m5_ck" ); |
298 | clk_set_parent(clk: clk1, parent: clk2); |
299 | |
300 | return 0; |
301 | } |
302 | |