]> Git Repo - linux.git/blob - drivers/clk/socfpga/clk-s10.c
mfd: cros-ec: Increase maximum mkbp event size
[linux.git] / drivers / clk / socfpga / clk-s10.c
1 // SPDX-License-Identifier:     GPL-2.0
2 /*
3  * Copyright (C) 2017, Intel Corporation
4  */
5 #include <linux/slab.h>
6 #include <linux/clk-provider.h>
7 #include <linux/of_device.h>
8 #include <linux/of_address.h>
9 #include <linux/platform_device.h>
10
11 #include <dt-bindings/clock/stratix10-clock.h>
12
13 #include "stratix10-clk.h"
14
15 static const char * const pll_mux[] = { "osc1", "cb_intosc_hs_div2_clk",
16                                         "f2s_free_clk",};
17 static const char * const cntr_mux[] = { "main_pll", "periph_pll",
18                                          "osc1", "cb_intosc_hs_div2_clk",
19                                          "f2s_free_clk"};
20 static const char * const boot_mux[] = { "osc1", "cb_intosc_hs_div2_clk",};
21
22 static const char * const noc_free_mux[] = {"main_noc_base_clk",
23                                             "peri_noc_base_clk",
24                                             "osc1", "cb_intosc_hs_div2_clk",
25                                             "f2s_free_clk"};
26
27 static const char * const emaca_free_mux[] = {"peri_emaca_clk", "boot_clk"};
28 static const char * const emacb_free_mux[] = {"peri_emacb_clk", "boot_clk"};
29 static const char * const emac_ptp_free_mux[] = {"peri_emac_ptp_clk", "boot_clk"};
30 static const char * const gpio_db_free_mux[] = {"peri_gpio_db_clk", "boot_clk"};
31 static const char * const sdmmc_free_mux[] = {"peri_sdmmc_clk", "boot_clk"};
32 static const char * const s2f_usr1_free_mux[] = {"peri_s2f_usr1_clk", "boot_clk"};
33 static const char * const psi_ref_free_mux[] = {"peri_psi_ref_clk", "boot_clk"};
34 static const char * const mpu_mux[] = { "mpu_free_clk", "boot_clk",};
35
36 static const char * const s2f_usr0_mux[] = {"f2s_free_clk", "boot_clk"};
37 static const char * const emac_mux[] = {"emaca_free_clk", "emacb_free_clk"};
38 static const char * const noc_mux[] = {"noc_free_clk", "boot_clk"};
39
40 /* clocks in AO (always on) controller */
41 static const struct stratix10_pll_clock s10_pll_clks[] = {
42         { STRATIX10_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0,
43           0x0},
44         { STRATIX10_MAIN_PLL_CLK, "main_pll", pll_mux, ARRAY_SIZE(pll_mux),
45           0, 0x74},
46         { STRATIX10_PERIPH_PLL_CLK, "periph_pll", pll_mux, ARRAY_SIZE(pll_mux),
47           0, 0xe4},
48 };
49
50 static const struct stratix10_perip_c_clock s10_main_perip_c_clks[] = {
51         { STRATIX10_MAIN_MPU_BASE_CLK, "main_mpu_base_clk", "main_pll", NULL, 1, 0, 0x84},
52         { STRATIX10_MAIN_NOC_BASE_CLK, "main_noc_base_clk", "main_pll", NULL, 1, 0, 0x88},
53         { STRATIX10_PERI_MPU_BASE_CLK, "peri_mpu_base_clk", "periph_pll", NULL, 1, 0,
54           0xF4},
55         { STRATIX10_PERI_NOC_BASE_CLK, "peri_noc_base_clk", "periph_pll", NULL, 1, 0,
56           0xF8},
57 };
58
59 static const struct stratix10_perip_cnt_clock s10_main_perip_cnt_clks[] = {
60         { STRATIX10_MPU_FREE_CLK, "mpu_free_clk", NULL, cntr_mux, ARRAY_SIZE(cntr_mux),
61            0, 0x48, 0, 0, 0},
62         { STRATIX10_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux),
63           0, 0x4C, 0, 0, 0},
64         { STRATIX10_MAIN_EMACA_CLK, "main_emaca_clk", "main_noc_base_clk", NULL, 1, 0,
65           0x50, 0, 0, 0},
66         { STRATIX10_MAIN_EMACB_CLK, "main_emacb_clk", "main_noc_base_clk", NULL, 1, 0,
67           0x54, 0, 0, 0},
68         { STRATIX10_MAIN_EMAC_PTP_CLK, "main_emac_ptp_clk", "main_noc_base_clk", NULL, 1, 0,
69           0x58, 0, 0, 0},
70         { STRATIX10_MAIN_GPIO_DB_CLK, "main_gpio_db_clk", "main_noc_base_clk", NULL, 1, 0,
71           0x5C, 0, 0, 0},
72         { STRATIX10_MAIN_SDMMC_CLK, "main_sdmmc_clk", "main_noc_base_clk", NULL, 1, 0,
73           0x60, 0, 0, 0},
74         { STRATIX10_MAIN_S2F_USR0_CLK, "main_s2f_usr0_clk", NULL, cntr_mux, ARRAY_SIZE(cntr_mux),
75           0, 0x64, 0, 0, 0},
76         { STRATIX10_MAIN_S2F_USR1_CLK, "main_s2f_usr1_clk", "main_noc_base_clk", NULL, 1, 0,
77           0x68, 0, 0, 0},
78         { STRATIX10_MAIN_PSI_REF_CLK, "main_psi_ref_clk", "main_noc_base_clk", NULL, 1, 0,
79           0x6C, 0, 0, 0},
80         { STRATIX10_PERI_EMACA_CLK, "peri_emaca_clk", NULL, cntr_mux, ARRAY_SIZE(cntr_mux),
81           0, 0xBC, 0, 0, 0},
82         { STRATIX10_PERI_EMACB_CLK, "peri_emacb_clk", NULL, cntr_mux, ARRAY_SIZE(cntr_mux),
83           0, 0xC0, 0, 0, 0},
84         { STRATIX10_PERI_EMAC_PTP_CLK, "peri_emac_ptp_clk", NULL, cntr_mux, ARRAY_SIZE(cntr_mux),
85           0, 0xC4, 0, 0, 0},
86         { STRATIX10_PERI_GPIO_DB_CLK, "peri_gpio_db_clk", NULL, cntr_mux, ARRAY_SIZE(cntr_mux),
87           0, 0xC8, 0, 0, 0},
88         { STRATIX10_PERI_SDMMC_CLK, "peri_sdmmc_clk", NULL, cntr_mux, ARRAY_SIZE(cntr_mux),
89           0, 0xCC, 0, 0, 0},
90         { STRATIX10_PERI_S2F_USR0_CLK, "peri_s2f_usr0_clk", "peri_noc_base_clk", NULL, 1, 0,
91           0xD0, 0, 0, 0},
92         { STRATIX10_PERI_S2F_USR1_CLK, "peri_s2f_usr1_clk", NULL, cntr_mux, ARRAY_SIZE(cntr_mux),
93           0, 0xD4, 0, 0, 0},
94         { STRATIX10_PERI_PSI_REF_CLK, "peri_psi_ref_clk", "peri_noc_base_clk", NULL, 1, 0,
95           0xD8, 0, 0, 0},
96         { STRATIX10_L4_SYS_FREE_CLK, "l4_sys_free_clk", "noc_free_clk", NULL, 1, 0,
97           0, 4, 0, 0},
98         { STRATIX10_NOC_CLK, "noc_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux),
99           0, 0, 0, 0x3C, 1},
100         { STRATIX10_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux),
101           0, 0, 4, 0xB0, 0},
102         { STRATIX10_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux),
103           0, 0, 4, 0xB0, 1},
104         { STRATIX10_EMAC_PTP_FREE_CLK, "emac_ptp_free_clk", NULL, emac_ptp_free_mux,
105           ARRAY_SIZE(emac_ptp_free_mux), 0, 0, 4, 0xB0, 2},
106         { STRATIX10_GPIO_DB_FREE_CLK, "gpio_db_free_clk", NULL, gpio_db_free_mux,
107           ARRAY_SIZE(gpio_db_free_mux), 0, 0, 0, 0xB0, 3},
108         { STRATIX10_SDMMC_FREE_CLK, "sdmmc_free_clk", NULL, sdmmc_free_mux,
109           ARRAY_SIZE(sdmmc_free_mux), 0, 0, 0, 0xB0, 4},
110         { STRATIX10_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", NULL, s2f_usr1_free_mux,
111           ARRAY_SIZE(s2f_usr1_free_mux), 0, 0, 0, 0xB0, 5},
112         { STRATIX10_PSI_REF_FREE_CLK, "psi_ref_free_clk", NULL, psi_ref_free_mux,
113           ARRAY_SIZE(psi_ref_free_mux), 0, 0, 0, 0xB0, 6},
114 };
115
116 static const struct stratix10_gate_clock s10_gate_clks[] = {
117         { STRATIX10_MPU_CLK, "mpu_clk", NULL, mpu_mux, ARRAY_SIZE(mpu_mux), 0, 0x30,
118           0, 0, 0, 0, 0x3C, 0, 0},
119         { STRATIX10_MPU_PERIPH_CLK, "mpu_periph_clk", "mpu_clk", NULL, 1, 0, 0x30,
120           0, 0, 0, 0, 0, 0, 4},
121         { STRATIX10_MPU_L2RAM_CLK, "mpu_l2ram_clk", "mpu_clk", NULL, 1, 0, 0x30,
122           0, 0, 0, 0, 0, 0, 2},
123         { STRATIX10_L4_MAIN_CLK, "l4_main_clk", "noc_clk", NULL, 1, 0, 0x30,
124           1, 0x70, 0, 2, 0, 0, 0},
125         { STRATIX10_L4_MP_CLK, "l4_mp_clk", "noc_clk", NULL, 1, 0, 0x30,
126           2, 0x70, 8, 2, 0, 0, 0},
127         { STRATIX10_L4_SP_CLK, "l4_sp_clk", "noc_clk", NULL, 1, CLK_IS_CRITICAL, 0x30,
128           3, 0x70, 16, 2, 0, 0, 0},
129         { STRATIX10_CS_AT_CLK, "cs_at_clk", "noc_clk", NULL, 1, 0, 0x30,
130           4, 0x70, 24, 2, 0, 0, 0},
131         { STRATIX10_CS_TRACE_CLK, "cs_trace_clk", "noc_clk", NULL, 1, 0, 0x30,
132           4, 0x70, 26, 2, 0, 0, 0},
133         { STRATIX10_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x30,
134           4, 0x70, 28, 1, 0, 0, 0},
135         { STRATIX10_CS_TIMER_CLK, "cs_timer_clk", "noc_clk", NULL, 1, 0, 0x30,
136           5, 0, 0, 0, 0, 0, 0},
137         { STRATIX10_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_usr0_mux, ARRAY_SIZE(s2f_usr0_mux), 0, 0x30,
138           6, 0, 0, 0, 0, 0, 0},
139         { STRATIX10_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0xA4,
140           0, 0, 0, 0, 0xDC, 26, 0},
141         { STRATIX10_EMAC1_CLK, "emac1_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0xA4,
142           1, 0, 0, 0, 0xDC, 27, 0},
143         { STRATIX10_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0xA4,
144           2, 0, 0, 0, 0xDC, 28, 0},
145         { STRATIX10_EMAC_PTP_CLK, "emac_ptp_clk", "emac_ptp_free_clk", NULL, 1, 0, 0xA4,
146           3, 0, 0, 0, 0, 0, 0},
147         { STRATIX10_GPIO_DB_CLK, "gpio_db_clk", "gpio_db_free_clk", NULL, 1, 0, 0xA4,
148           4, 0xE0, 0, 16, 0, 0, 0},
149         { STRATIX10_SDMMC_CLK, "sdmmc_clk", "sdmmc_free_clk", NULL, 1, 0, 0xA4,
150           5, 0, 0, 0, 0, 0, 4},
151         { STRATIX10_S2F_USER1_CLK, "s2f_user1_clk", "s2f_user1_free_clk", NULL, 1, 0, 0xA4,
152           6, 0, 0, 0, 0, 0, 0},
153         { STRATIX10_PSI_REF_CLK, "psi_ref_clk", "psi_ref_free_clk", NULL, 1, 0, 0xA4,
154           7, 0, 0, 0, 0, 0, 0},
155         { STRATIX10_USB_CLK, "usb_clk", "l4_mp_clk", NULL, 1, 0, 0xA4,
156           8, 0, 0, 0, 0, 0, 0},
157         { STRATIX10_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0xA4,
158           9, 0, 0, 0, 0, 0, 0},
159         { STRATIX10_NAND_CLK, "nand_clk", "l4_main_clk", NULL, 1, 0, 0xA4,
160           10, 0, 0, 0, 0, 0, 0},
161 };
162
163 static int s10_clk_register_c_perip(const struct stratix10_perip_c_clock *clks,
164                                     int nums, struct stratix10_clock_data *data)
165 {
166         struct clk *clk;
167         void __iomem *base = data->base;
168         int i;
169
170         for (i = 0; i < nums; i++) {
171                 clk = s10_register_periph(clks[i].name, clks[i].parent_name,
172                                           clks[i].parent_names, clks[i].num_parents,
173                                           clks[i].flags, base, clks[i].offset);
174                 if (IS_ERR(clk)) {
175                         pr_err("%s: failed to register clock %s\n",
176                                __func__, clks[i].name);
177                         continue;
178                 }
179                 data->clk_data.clks[clks[i].id] = clk;
180         }
181         return 0;
182 }
183
184 static int s10_clk_register_cnt_perip(const struct stratix10_perip_cnt_clock *clks,
185                                       int nums, struct stratix10_clock_data *data)
186 {
187         struct clk *clk;
188         void __iomem *base = data->base;
189         int i;
190
191         for (i = 0; i < nums; i++) {
192                 clk = s10_register_cnt_periph(clks[i].name, clks[i].parent_name,
193                                               clks[i].parent_names,
194                                               clks[i].num_parents,
195                                               clks[i].flags, base,
196                                               clks[i].offset,
197                                               clks[i].fixed_divider,
198                                               clks[i].bypass_reg,
199                                               clks[i].bypass_shift);
200                 if (IS_ERR(clk)) {
201                         pr_err("%s: failed to register clock %s\n",
202                                __func__, clks[i].name);
203                         continue;
204                 }
205                 data->clk_data.clks[clks[i].id] = clk;
206         }
207
208         return 0;
209 }
210
211 static int s10_clk_register_gate(const struct stratix10_gate_clock *clks,
212                                  int nums, struct stratix10_clock_data *data)
213 {
214         struct clk *clk;
215         void __iomem *base = data->base;
216         int i;
217
218         for (i = 0; i < nums; i++) {
219                 clk = s10_register_gate(clks[i].name, clks[i].parent_name,
220                                         clks[i].parent_names,
221                                         clks[i].num_parents,
222                                         clks[i].flags, base,
223                                         clks[i].gate_reg,
224                                         clks[i].gate_idx, clks[i].div_reg,
225                                         clks[i].div_offset, clks[i].div_width,
226                                         clks[i].bypass_reg,
227                                         clks[i].bypass_shift,
228                                         clks[i].fixed_div);
229                 if (IS_ERR(clk)) {
230                         pr_err("%s: failed to register clock %s\n",
231                                __func__, clks[i].name);
232                         continue;
233                 }
234                 data->clk_data.clks[clks[i].id] = clk;
235         }
236
237         return 0;
238 }
239
240 static int s10_clk_register_pll(const struct stratix10_pll_clock *clks,
241                                  int nums, struct stratix10_clock_data *data)
242 {
243         struct clk *clk;
244         void __iomem *base = data->base;
245         int i;
246
247         for (i = 0; i < nums; i++) {
248                 clk = s10_register_pll(clks[i].name, clks[i].parent_names,
249                                     clks[i].num_parents,
250                                     clks[i].flags, base,
251                                     clks[i].offset);
252                 if (IS_ERR(clk)) {
253                         pr_err("%s: failed to register clock %s\n",
254                                __func__, clks[i].name);
255                         continue;
256                 }
257                 data->clk_data.clks[clks[i].id] = clk;
258         }
259
260         return 0;
261 }
262
263 static struct stratix10_clock_data *__socfpga_s10_clk_init(struct platform_device *pdev,
264                                                     int nr_clks)
265 {
266         struct device_node *np = pdev->dev.of_node;
267         struct device *dev = &pdev->dev;
268         struct stratix10_clock_data *clk_data;
269         struct clk **clk_table;
270         struct resource *res;
271         void __iomem *base;
272
273         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
274         base = devm_ioremap_resource(dev, res);
275         if (IS_ERR(base)) {
276                 pr_err("%s: failed to map clock registers\n", __func__);
277                 return ERR_CAST(base);
278         }
279
280         clk_data = devm_kzalloc(dev, sizeof(*clk_data), GFP_KERNEL);
281         if (!clk_data)
282                 return ERR_PTR(-ENOMEM);
283
284         clk_data->base = base;
285         clk_table = devm_kcalloc(dev, nr_clks, sizeof(*clk_table), GFP_KERNEL);
286         if (!clk_table)
287                 return ERR_PTR(-ENOMEM);
288
289         clk_data->clk_data.clks = clk_table;
290         clk_data->clk_data.clk_num = nr_clks;
291         of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data->clk_data);
292         return clk_data;
293 }
294
295 static int s10_clkmgr_init(struct platform_device *pdev)
296 {
297         struct stratix10_clock_data *clk_data;
298
299         clk_data = __socfpga_s10_clk_init(pdev, STRATIX10_NUM_CLKS);
300         if (IS_ERR(clk_data))
301                 return PTR_ERR(clk_data);
302
303         s10_clk_register_pll(s10_pll_clks, ARRAY_SIZE(s10_pll_clks), clk_data);
304
305         s10_clk_register_c_perip(s10_main_perip_c_clks,
306                                  ARRAY_SIZE(s10_main_perip_c_clks), clk_data);
307
308         s10_clk_register_cnt_perip(s10_main_perip_cnt_clks,
309                                    ARRAY_SIZE(s10_main_perip_cnt_clks),
310                                    clk_data);
311
312         s10_clk_register_gate(s10_gate_clks, ARRAY_SIZE(s10_gate_clks),
313                               clk_data);
314         return 0;
315 }
316
317 static int s10_clkmgr_probe(struct platform_device *pdev)
318 {
319         return  s10_clkmgr_init(pdev);
320 }
321
322 static const struct of_device_id stratix10_clkmgr_match_table[] = {
323         { .compatible = "intel,stratix10-clkmgr",
324           .data = s10_clkmgr_init },
325         { }
326 };
327
328 static struct platform_driver stratix10_clkmgr_driver = {
329         .probe          = s10_clkmgr_probe,
330         .driver         = {
331                 .name   = "stratix10-clkmgr",
332                 .suppress_bind_attrs = true,
333                 .of_match_table = stratix10_clkmgr_match_table,
334         },
335 };
336
337 static int __init s10_clk_init(void)
338 {
339         return platform_driver_register(&stratix10_clkmgr_driver);
340 }
341 core_initcall(s10_clk_init);
This page took 0.078567 seconds and 4 git commands to generate.