xref: /openbmc/linux/drivers/clk/socfpga/clk-s10.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
107afb8dbSDinh Nguyen // SPDX-License-Identifier: GPL-2.0
207afb8dbSDinh Nguyen /*
307afb8dbSDinh Nguyen  * Copyright (C) 2017, Intel Corporation
407afb8dbSDinh Nguyen  */
507afb8dbSDinh Nguyen #include <linux/slab.h>
607afb8dbSDinh Nguyen #include <linux/clk-provider.h>
7*a96cbb14SRob Herring #include <linux/of.h>
807afb8dbSDinh Nguyen #include <linux/platform_device.h>
907afb8dbSDinh Nguyen 
1007afb8dbSDinh Nguyen #include <dt-bindings/clock/stratix10-clock.h>
1107afb8dbSDinh Nguyen 
1207afb8dbSDinh Nguyen #include "stratix10-clk.h"
1307afb8dbSDinh Nguyen 
14762d961aSDinh Nguyen static const struct clk_parent_data pll_mux[] = {
15762d961aSDinh Nguyen 	{ .fw_name = "osc1",
16762d961aSDinh Nguyen 	  .name = "osc1" },
17762d961aSDinh Nguyen 	{ .fw_name = "cb-intosc-hs-div2-clk",
18762d961aSDinh Nguyen 	  .name = "cb-intosc-hs-div2-clk" },
19762d961aSDinh Nguyen 	{ .fw_name = "f2s-free-clk",
20762d961aSDinh Nguyen 	  .name = "f2s-free-clk" },
21762d961aSDinh Nguyen };
2207afb8dbSDinh Nguyen 
23762d961aSDinh Nguyen static const struct clk_parent_data cntr_mux[] = {
24762d961aSDinh Nguyen 	{ .fw_name =  "main_pll",
25762d961aSDinh Nguyen 	  .name = "main_pll", },
26762d961aSDinh Nguyen 	{ .fw_name = "periph_pll",
27762d961aSDinh Nguyen 	  .name = "periph_pll", },
28762d961aSDinh Nguyen 	{ .fw_name = "osc1",
29762d961aSDinh Nguyen 	  .name = "osc1", },
30762d961aSDinh Nguyen 	{ .fw_name = "cb-intosc-hs-div2-clk",
31762d961aSDinh Nguyen 	  .name = "cb-intosc-hs-div2-clk", },
32762d961aSDinh Nguyen 	{ .fw_name = "f2s-free-clk",
33762d961aSDinh Nguyen 	  .name = "f2s-free-clk", },
34762d961aSDinh Nguyen };
3507afb8dbSDinh Nguyen 
36762d961aSDinh Nguyen static const struct clk_parent_data boot_mux[] = {
37762d961aSDinh Nguyen 	{ .fw_name = "osc1",
38762d961aSDinh Nguyen 	  .name = "osc1" },
39762d961aSDinh Nguyen 	{ .fw_name = "cb-intosc-hs-div2-clk",
40762d961aSDinh Nguyen 	  .name = "cb-intosc-hs-div2-clk" },
41762d961aSDinh Nguyen };
4207afb8dbSDinh Nguyen 
43762d961aSDinh Nguyen static const struct clk_parent_data noc_free_mux[] = {
44762d961aSDinh Nguyen 	{ .fw_name = "main_noc_base_clk",
45762d961aSDinh Nguyen 	  .name = "main_noc_base_clk", },
46762d961aSDinh Nguyen 	{ .fw_name = "peri_noc_base_clk",
47762d961aSDinh Nguyen 	  .name = "peri_noc_base_clk", },
48762d961aSDinh Nguyen 	{ .fw_name = "osc1",
49762d961aSDinh Nguyen 	  .name = "osc1", },
50762d961aSDinh Nguyen 	{ .fw_name = "cb-intosc-hs-div2-clk",
51762d961aSDinh Nguyen 	  .name = "cb-intosc-hs-div2-clk", },
52762d961aSDinh Nguyen 	{ .fw_name = "f2s-free-clk",
53762d961aSDinh Nguyen 	  .name = "f2s-free-clk", },
54762d961aSDinh Nguyen };
5507afb8dbSDinh Nguyen 
56762d961aSDinh Nguyen static const struct clk_parent_data emaca_free_mux[] = {
57762d961aSDinh Nguyen 	{ .fw_name = "peri_emaca_clk",
58762d961aSDinh Nguyen 	  .name = "peri_emaca_clk", },
59762d961aSDinh Nguyen 	{ .fw_name = "boot_clk",
60762d961aSDinh Nguyen 	  .name = "boot_clk", },
61762d961aSDinh Nguyen };
62762d961aSDinh Nguyen 
63762d961aSDinh Nguyen static const struct clk_parent_data emacb_free_mux[] = {
64762d961aSDinh Nguyen 	{ .fw_name = "peri_emacb_clk",
65762d961aSDinh Nguyen 	  .name = "peri_emacb_clk", },
66762d961aSDinh Nguyen 	{ .fw_name = "boot_clk",
67762d961aSDinh Nguyen 	  .name = "boot_clk", },
68762d961aSDinh Nguyen };
69762d961aSDinh Nguyen 
70762d961aSDinh Nguyen static const struct clk_parent_data emac_ptp_free_mux[] = {
71762d961aSDinh Nguyen 	{ .fw_name = "peri_emac_ptp_clk",
72762d961aSDinh Nguyen 	  .name = "peri_emac_ptp_clk", },
73762d961aSDinh Nguyen 	{ .fw_name = "boot_clk",
74762d961aSDinh Nguyen 	  .name = "boot_clk", },
75762d961aSDinh Nguyen };
76762d961aSDinh Nguyen 
77762d961aSDinh Nguyen static const struct clk_parent_data gpio_db_free_mux[] = {
78762d961aSDinh Nguyen 	{ .fw_name = "peri_gpio_db_clk",
79762d961aSDinh Nguyen 	  .name = "peri_gpio_db_clk", },
80762d961aSDinh Nguyen 	{ .fw_name = "boot_clk",
81762d961aSDinh Nguyen 	  .name = "boot_clk", },
82762d961aSDinh Nguyen };
83762d961aSDinh Nguyen 
84762d961aSDinh Nguyen static const struct clk_parent_data sdmmc_free_mux[] = {
85762d961aSDinh Nguyen 	{ .fw_name = "main_sdmmc_clk",
86762d961aSDinh Nguyen 	  .name = "main_sdmmc_clk", },
87762d961aSDinh Nguyen 	{ .fw_name = "boot_clk",
88762d961aSDinh Nguyen 	  .name = "boot_clk", },
89762d961aSDinh Nguyen };
90762d961aSDinh Nguyen 
91762d961aSDinh Nguyen static const struct clk_parent_data s2f_usr1_free_mux[] = {
92762d961aSDinh Nguyen 	{ .fw_name = "peri_s2f_usr1_clk",
93762d961aSDinh Nguyen 	  .name = "peri_s2f_usr1_clk", },
94762d961aSDinh Nguyen 	{ .fw_name = "boot_clk",
95762d961aSDinh Nguyen 	  .name = "boot_clk", },
96762d961aSDinh Nguyen };
97762d961aSDinh Nguyen 
98762d961aSDinh Nguyen static const struct clk_parent_data psi_ref_free_mux[] = {
99762d961aSDinh Nguyen 	{ .fw_name = "peri_psi_ref_clk",
100762d961aSDinh Nguyen 	  .name = "peri_psi_ref_clk", },
101762d961aSDinh Nguyen 	{ .fw_name = "boot_clk",
102762d961aSDinh Nguyen 	  .name = "boot_clk", },
103762d961aSDinh Nguyen };
104762d961aSDinh Nguyen 
105762d961aSDinh Nguyen static const struct clk_parent_data mpu_mux[] = {
106762d961aSDinh Nguyen 	{ .fw_name = "mpu_free_clk",
107762d961aSDinh Nguyen 	  .name = "mpu_free_clk", },
108762d961aSDinh Nguyen 	{ .fw_name = "boot_clk",
109762d961aSDinh Nguyen 	  .name = "boot_clk", },
110762d961aSDinh Nguyen };
111762d961aSDinh Nguyen 
112762d961aSDinh Nguyen static const struct clk_parent_data s2f_usr0_mux[] = {
113762d961aSDinh Nguyen 	{ .fw_name = "f2s-free-clk",
114762d961aSDinh Nguyen 	  .name = "f2s-free-clk", },
115762d961aSDinh Nguyen 	{ .fw_name = "boot_clk",
116762d961aSDinh Nguyen 	  .name = "boot_clk", },
117762d961aSDinh Nguyen };
118762d961aSDinh Nguyen 
119762d961aSDinh Nguyen static const struct clk_parent_data emac_mux[] = {
120762d961aSDinh Nguyen 	{ .fw_name = "emaca_free_clk",
121762d961aSDinh Nguyen 	  .name = "emaca_free_clk", },
122762d961aSDinh Nguyen 	{ .fw_name = "emacb_free_clk",
123762d961aSDinh Nguyen 	  .name = "emacb_free_clk", },
124762d961aSDinh Nguyen };
125762d961aSDinh Nguyen 
126762d961aSDinh Nguyen static const struct clk_parent_data noc_mux[] = {
127762d961aSDinh Nguyen 	{ .fw_name = "noc_free_clk",
128762d961aSDinh Nguyen 	  .name = "noc_free_clk", },
129762d961aSDinh Nguyen 	{ .fw_name = "boot_clk",
130762d961aSDinh Nguyen 	  .name = "boot_clk", },
131762d961aSDinh Nguyen };
132762d961aSDinh Nguyen 
133762d961aSDinh Nguyen static const struct clk_parent_data mpu_free_mux[] = {
134762d961aSDinh Nguyen 	{ .fw_name = "main_mpu_base_clk",
135762d961aSDinh Nguyen 	  .name = "main_mpu_base_clk", },
136762d961aSDinh Nguyen 	{ .fw_name = "peri_mpu_base_clk",
137762d961aSDinh Nguyen 	  .name = "peri_mpu_base_clk", },
138762d961aSDinh Nguyen 	{ .fw_name = "osc1",
139762d961aSDinh Nguyen 	  .name = "osc1", },
140762d961aSDinh Nguyen 	{ .fw_name = "cb-intosc-hs-div2-clk",
141762d961aSDinh Nguyen 	  .name = "cb-intosc-hs-div2-clk", },
142762d961aSDinh Nguyen 	{ .fw_name = "f2s-free-clk",
143762d961aSDinh Nguyen 	  .name = "f2s-free-clk", },
144762d961aSDinh Nguyen };
1452772ffd9SDinh Nguyen 
1466855ee83SDinh Nguyen static const struct clk_parent_data sdmmc_mux[] = {
1476855ee83SDinh Nguyen 	{ .fw_name = "sdmmc_free_clk",
1486855ee83SDinh Nguyen 	  .name = "sdmmc_free_clk", },
1496855ee83SDinh Nguyen 	{ .fw_name = "boot_clk",
1506855ee83SDinh Nguyen 	  .name = "boot_clk", },
1516855ee83SDinh Nguyen };
1526855ee83SDinh Nguyen 
1536855ee83SDinh Nguyen static const struct clk_parent_data s2f_user1_mux[] = {
1546855ee83SDinh Nguyen 	{ .fw_name = "s2f_user1_free_clk",
1556855ee83SDinh Nguyen 	  .name = "s2f_user1_free_clk", },
1566855ee83SDinh Nguyen 	{ .fw_name = "boot_clk",
1576855ee83SDinh Nguyen 	  .name = "boot_clk", },
1586855ee83SDinh Nguyen };
1596855ee83SDinh Nguyen 
1606855ee83SDinh Nguyen static const struct clk_parent_data psi_mux[] = {
1616855ee83SDinh Nguyen 	{ .fw_name = "psi_ref_free_clk",
1626855ee83SDinh Nguyen 	  .name = "psi_ref_free_clk", },
1636855ee83SDinh Nguyen 	{ .fw_name = "boot_clk",
1646855ee83SDinh Nguyen 	  .name = "boot_clk", },
1656855ee83SDinh Nguyen };
1666855ee83SDinh Nguyen 
1676855ee83SDinh Nguyen static const struct clk_parent_data gpio_db_mux[] = {
1686855ee83SDinh Nguyen 	{ .fw_name = "gpio_db_free_clk",
1696855ee83SDinh Nguyen 	  .name = "gpio_db_free_clk", },
1706855ee83SDinh Nguyen 	{ .fw_name = "boot_clk",
1716855ee83SDinh Nguyen 	  .name = "boot_clk", },
1726855ee83SDinh Nguyen };
1736855ee83SDinh Nguyen 
1746855ee83SDinh Nguyen static const struct clk_parent_data emac_ptp_mux[] = {
1756855ee83SDinh Nguyen 	{ .fw_name = "emac_ptp_free_clk",
1766855ee83SDinh Nguyen 	  .name = "emac_ptp_free_clk", },
1776855ee83SDinh Nguyen 	{ .fw_name = "boot_clk",
1786855ee83SDinh Nguyen 	  .name = "boot_clk", },
1796855ee83SDinh Nguyen };
1806855ee83SDinh Nguyen 
18107afb8dbSDinh Nguyen /* clocks in AO (always on) controller */
18207afb8dbSDinh Nguyen static const struct stratix10_pll_clock s10_pll_clks[] = {
18307afb8dbSDinh Nguyen 	{ STRATIX10_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0,
18407afb8dbSDinh Nguyen 	  0x0},
18507afb8dbSDinh Nguyen 	{ STRATIX10_MAIN_PLL_CLK, "main_pll", pll_mux, ARRAY_SIZE(pll_mux),
18607afb8dbSDinh Nguyen 	  0, 0x74},
18707afb8dbSDinh Nguyen 	{ STRATIX10_PERIPH_PLL_CLK, "periph_pll", pll_mux, ARRAY_SIZE(pll_mux),
18807afb8dbSDinh Nguyen 	  0, 0xe4},
18907afb8dbSDinh Nguyen };
19007afb8dbSDinh Nguyen 
19107afb8dbSDinh Nguyen static const struct stratix10_perip_c_clock s10_main_perip_c_clks[] = {
19207afb8dbSDinh Nguyen 	{ STRATIX10_MAIN_MPU_BASE_CLK, "main_mpu_base_clk", "main_pll", NULL, 1, 0, 0x84},
19307afb8dbSDinh Nguyen 	{ STRATIX10_MAIN_NOC_BASE_CLK, "main_noc_base_clk", "main_pll", NULL, 1, 0, 0x88},
19407afb8dbSDinh Nguyen 	{ STRATIX10_PERI_MPU_BASE_CLK, "peri_mpu_base_clk", "periph_pll", NULL, 1, 0,
19507afb8dbSDinh Nguyen 	  0xF4},
19607afb8dbSDinh Nguyen 	{ STRATIX10_PERI_NOC_BASE_CLK, "peri_noc_base_clk", "periph_pll", NULL, 1, 0,
19707afb8dbSDinh Nguyen 	  0xF8},
19807afb8dbSDinh Nguyen };
19907afb8dbSDinh Nguyen 
20007afb8dbSDinh Nguyen static const struct stratix10_perip_cnt_clock s10_main_perip_cnt_clks[] = {
2012772ffd9SDinh Nguyen 	{ STRATIX10_MPU_FREE_CLK, "mpu_free_clk", NULL, mpu_free_mux, ARRAY_SIZE(mpu_free_mux),
20207afb8dbSDinh Nguyen 	   0, 0x48, 0, 0, 0},
20307afb8dbSDinh Nguyen 	{ STRATIX10_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux),
204efbe21dfSDinh Nguyen 	  0, 0x4C, 0, 0x3C, 1},
20507afb8dbSDinh Nguyen 	{ STRATIX10_MAIN_EMACA_CLK, "main_emaca_clk", "main_noc_base_clk", NULL, 1, 0,
20607afb8dbSDinh Nguyen 	  0x50, 0, 0, 0},
20707afb8dbSDinh Nguyen 	{ STRATIX10_MAIN_EMACB_CLK, "main_emacb_clk", "main_noc_base_clk", NULL, 1, 0,
20807afb8dbSDinh Nguyen 	  0x54, 0, 0, 0},
20907afb8dbSDinh Nguyen 	{ STRATIX10_MAIN_EMAC_PTP_CLK, "main_emac_ptp_clk", "main_noc_base_clk", NULL, 1, 0,
21007afb8dbSDinh Nguyen 	  0x58, 0, 0, 0},
21107afb8dbSDinh Nguyen 	{ STRATIX10_MAIN_GPIO_DB_CLK, "main_gpio_db_clk", "main_noc_base_clk", NULL, 1, 0,
21207afb8dbSDinh Nguyen 	  0x5C, 0, 0, 0},
21307afb8dbSDinh Nguyen 	{ STRATIX10_MAIN_SDMMC_CLK, "main_sdmmc_clk", "main_noc_base_clk", NULL, 1, 0,
21407afb8dbSDinh Nguyen 	  0x60, 0, 0, 0},
21507afb8dbSDinh Nguyen 	{ STRATIX10_MAIN_S2F_USR0_CLK, "main_s2f_usr0_clk", NULL, cntr_mux, ARRAY_SIZE(cntr_mux),
21607afb8dbSDinh Nguyen 	  0, 0x64, 0, 0, 0},
21707afb8dbSDinh Nguyen 	{ STRATIX10_MAIN_S2F_USR1_CLK, "main_s2f_usr1_clk", "main_noc_base_clk", NULL, 1, 0,
21807afb8dbSDinh Nguyen 	  0x68, 0, 0, 0},
21907afb8dbSDinh Nguyen 	{ STRATIX10_MAIN_PSI_REF_CLK, "main_psi_ref_clk", "main_noc_base_clk", NULL, 1, 0,
22007afb8dbSDinh Nguyen 	  0x6C, 0, 0, 0},
22107afb8dbSDinh Nguyen 	{ STRATIX10_PERI_EMACA_CLK, "peri_emaca_clk", NULL, cntr_mux, ARRAY_SIZE(cntr_mux),
22207afb8dbSDinh Nguyen 	  0, 0xBC, 0, 0, 0},
22307afb8dbSDinh Nguyen 	{ STRATIX10_PERI_EMACB_CLK, "peri_emacb_clk", NULL, cntr_mux, ARRAY_SIZE(cntr_mux),
22407afb8dbSDinh Nguyen 	  0, 0xC0, 0, 0, 0},
22507afb8dbSDinh Nguyen 	{ STRATIX10_PERI_EMAC_PTP_CLK, "peri_emac_ptp_clk", NULL, cntr_mux, ARRAY_SIZE(cntr_mux),
22607afb8dbSDinh Nguyen 	  0, 0xC4, 0, 0, 0},
22707afb8dbSDinh Nguyen 	{ STRATIX10_PERI_GPIO_DB_CLK, "peri_gpio_db_clk", NULL, cntr_mux, ARRAY_SIZE(cntr_mux),
22807afb8dbSDinh Nguyen 	  0, 0xC8, 0, 0, 0},
22907afb8dbSDinh Nguyen 	{ STRATIX10_PERI_SDMMC_CLK, "peri_sdmmc_clk", NULL, cntr_mux, ARRAY_SIZE(cntr_mux),
23007afb8dbSDinh Nguyen 	  0, 0xCC, 0, 0, 0},
23107afb8dbSDinh Nguyen 	{ STRATIX10_PERI_S2F_USR0_CLK, "peri_s2f_usr0_clk", "peri_noc_base_clk", NULL, 1, 0,
23207afb8dbSDinh Nguyen 	  0xD0, 0, 0, 0},
23307afb8dbSDinh Nguyen 	{ STRATIX10_PERI_S2F_USR1_CLK, "peri_s2f_usr1_clk", NULL, cntr_mux, ARRAY_SIZE(cntr_mux),
23407afb8dbSDinh Nguyen 	  0, 0xD4, 0, 0, 0},
23507afb8dbSDinh Nguyen 	{ STRATIX10_PERI_PSI_REF_CLK, "peri_psi_ref_clk", "peri_noc_base_clk", NULL, 1, 0,
23607afb8dbSDinh Nguyen 	  0xD8, 0, 0, 0},
237efbe21dfSDinh Nguyen 	{ STRATIX10_L4_SYS_FREE_CLK, "l4_sys_free_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0,
238efbe21dfSDinh Nguyen 	  0, 4, 0x3C, 1},
23907afb8dbSDinh Nguyen 	{ STRATIX10_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux),
24016e3c572SDinh Nguyen 	  0, 0, 2, 0xB0, 0},
24107afb8dbSDinh Nguyen 	{ STRATIX10_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux),
24216e3c572SDinh Nguyen 	  0, 0, 2, 0xB0, 1},
24307afb8dbSDinh Nguyen 	{ STRATIX10_EMAC_PTP_FREE_CLK, "emac_ptp_free_clk", NULL, emac_ptp_free_mux,
244b02cf0c4SDinh Nguyen 	  ARRAY_SIZE(emac_ptp_free_mux), 0, 0, 2, 0xB0, 2},
24507afb8dbSDinh Nguyen 	{ STRATIX10_GPIO_DB_FREE_CLK, "gpio_db_free_clk", NULL, gpio_db_free_mux,
24607afb8dbSDinh Nguyen 	  ARRAY_SIZE(gpio_db_free_mux), 0, 0, 0, 0xB0, 3},
24707afb8dbSDinh Nguyen 	{ STRATIX10_SDMMC_FREE_CLK, "sdmmc_free_clk", NULL, sdmmc_free_mux,
24807afb8dbSDinh Nguyen 	  ARRAY_SIZE(sdmmc_free_mux), 0, 0, 0, 0xB0, 4},
24907afb8dbSDinh Nguyen 	{ STRATIX10_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", NULL, s2f_usr1_free_mux,
25007afb8dbSDinh Nguyen 	  ARRAY_SIZE(s2f_usr1_free_mux), 0, 0, 0, 0xB0, 5},
25107afb8dbSDinh Nguyen 	{ STRATIX10_PSI_REF_FREE_CLK, "psi_ref_free_clk", NULL, psi_ref_free_mux,
25207afb8dbSDinh Nguyen 	  ARRAY_SIZE(psi_ref_free_mux), 0, 0, 0, 0xB0, 6},
25307afb8dbSDinh Nguyen };
25407afb8dbSDinh Nguyen 
25507afb8dbSDinh Nguyen static const struct stratix10_gate_clock s10_gate_clks[] = {
25607afb8dbSDinh Nguyen 	{ STRATIX10_MPU_CLK, "mpu_clk", NULL, mpu_mux, ARRAY_SIZE(mpu_mux), 0, 0x30,
25707afb8dbSDinh Nguyen 	  0, 0, 0, 0, 0x3C, 0, 0},
25807afb8dbSDinh Nguyen 	{ STRATIX10_MPU_PERIPH_CLK, "mpu_periph_clk", "mpu_clk", NULL, 1, 0, 0x30,
25907afb8dbSDinh Nguyen 	  0, 0, 0, 0, 0, 0, 4},
26007afb8dbSDinh Nguyen 	{ STRATIX10_MPU_L2RAM_CLK, "mpu_l2ram_clk", "mpu_clk", NULL, 1, 0, 0x30,
26107afb8dbSDinh Nguyen 	  0, 0, 0, 0, 0, 0, 2},
262efbe21dfSDinh Nguyen 	{ STRATIX10_L4_MAIN_CLK, "l4_main_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30,
263efbe21dfSDinh Nguyen 	  1, 0x70, 0, 2, 0x3C, 1, 0},
264efbe21dfSDinh Nguyen 	{ STRATIX10_L4_MP_CLK, "l4_mp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30,
265efbe21dfSDinh Nguyen 	  2, 0x70, 8, 2, 0x3C, 1, 0},
266efbe21dfSDinh Nguyen 	{ STRATIX10_L4_SP_CLK, "l4_sp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), CLK_IS_CRITICAL, 0x30,
267efbe21dfSDinh Nguyen 	  3, 0x70, 16, 2, 0x3C, 1, 0},
268efbe21dfSDinh Nguyen 	{ STRATIX10_CS_AT_CLK, "cs_at_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30,
269efbe21dfSDinh Nguyen 	  4, 0x70, 24, 2, 0x3C, 1, 0},
270efbe21dfSDinh Nguyen 	{ STRATIX10_CS_TRACE_CLK, "cs_trace_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30,
271efbe21dfSDinh Nguyen 	  4, 0x70, 26, 2, 0x3C, 1, 0},
27207afb8dbSDinh Nguyen 	{ STRATIX10_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x30,
27307afb8dbSDinh Nguyen 	  4, 0x70, 28, 1, 0, 0, 0},
274efbe21dfSDinh Nguyen 	{ STRATIX10_CS_TIMER_CLK, "cs_timer_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30,
275efbe21dfSDinh Nguyen 	  5, 0, 0, 0, 0x3C, 1, 0},
27607afb8dbSDinh Nguyen 	{ STRATIX10_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_usr0_mux, ARRAY_SIZE(s2f_usr0_mux), 0, 0x30,
27707afb8dbSDinh Nguyen 	  6, 0, 0, 0, 0, 0, 0},
27807afb8dbSDinh Nguyen 	{ STRATIX10_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0xA4,
27907afb8dbSDinh Nguyen 	  0, 0, 0, 0, 0xDC, 26, 0},
28007afb8dbSDinh Nguyen 	{ STRATIX10_EMAC1_CLK, "emac1_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0xA4,
28107afb8dbSDinh Nguyen 	  1, 0, 0, 0, 0xDC, 27, 0},
28207afb8dbSDinh Nguyen 	{ STRATIX10_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0xA4,
28307afb8dbSDinh Nguyen 	  2, 0, 0, 0, 0xDC, 28, 0},
2846855ee83SDinh Nguyen 	{ STRATIX10_EMAC_PTP_CLK, "emac_ptp_clk", NULL, emac_ptp_mux, ARRAY_SIZE(emac_ptp_mux), 0, 0xA4,
2856855ee83SDinh Nguyen 	  3, 0, 0, 0, 0xB0, 2, 0},
2866855ee83SDinh Nguyen 	{ STRATIX10_GPIO_DB_CLK, "gpio_db_clk", NULL, gpio_db_mux, ARRAY_SIZE(gpio_db_mux), 0, 0xA4,
2876855ee83SDinh Nguyen 	  4, 0xE0, 0, 16, 0xB0, 3, 0},
2886855ee83SDinh Nguyen 	{ STRATIX10_SDMMC_CLK, "sdmmc_clk", NULL, sdmmc_mux, ARRAY_SIZE(sdmmc_mux), 0, 0xA4,
2896855ee83SDinh Nguyen 	  5, 0, 0, 0, 0xB0, 4, 4},
2906855ee83SDinh Nguyen 	{ STRATIX10_S2F_USER1_CLK, "s2f_user1_clk", NULL, s2f_user1_mux, ARRAY_SIZE(s2f_user1_mux), 0, 0xA4,
2916855ee83SDinh Nguyen 	  6, 0, 0, 0, 0xB0, 5, 0},
2926855ee83SDinh Nguyen 	{ STRATIX10_PSI_REF_CLK, "psi_ref_clk", NULL, psi_mux, ARRAY_SIZE(psi_mux), 0, 0xA4,
2936855ee83SDinh Nguyen 	  7, 0, 0, 0, 0xB0, 6, 0},
29407afb8dbSDinh Nguyen 	{ STRATIX10_USB_CLK, "usb_clk", "l4_mp_clk", NULL, 1, 0, 0xA4,
29507afb8dbSDinh Nguyen 	  8, 0, 0, 0, 0, 0, 0},
29607afb8dbSDinh Nguyen 	{ STRATIX10_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0xA4,
29707afb8dbSDinh Nguyen 	  9, 0, 0, 0, 0, 0, 0},
2983b5015c4SDinh Nguyen 	{ STRATIX10_NAND_X_CLK, "nand_x_clk", "l4_mp_clk", NULL, 1, 0, 0xA4,
29907afb8dbSDinh Nguyen 	  10, 0, 0, 0, 0, 0, 0},
3003b5015c4SDinh Nguyen 	{ STRATIX10_NAND_CLK, "nand_clk", "nand_x_clk", NULL, 1, 0, 0xA4,
3013b5015c4SDinh Nguyen 	  10, 0, 0, 0, 0, 0, 4},
3023b5015c4SDinh Nguyen 	{ STRATIX10_NAND_ECC_CLK, "nand_ecc_clk", "nand_x_clk", NULL, 1, 0, 0xA4,
3033b5015c4SDinh Nguyen 	  10, 0, 0, 0, 0, 0, 4},
30407afb8dbSDinh Nguyen };
30507afb8dbSDinh Nguyen 
s10_clk_register_c_perip(const struct stratix10_perip_c_clock * clks,int nums,struct stratix10_clock_data * data)30607afb8dbSDinh Nguyen static int s10_clk_register_c_perip(const struct stratix10_perip_c_clock *clks,
30707afb8dbSDinh Nguyen 				    int nums, struct stratix10_clock_data *data)
30807afb8dbSDinh Nguyen {
309ba7e2584SDinh Nguyen 	struct clk_hw *hw_clk;
31007afb8dbSDinh Nguyen 	void __iomem *base = data->base;
31107afb8dbSDinh Nguyen 	int i;
31207afb8dbSDinh Nguyen 
31307afb8dbSDinh Nguyen 	for (i = 0; i < nums; i++) {
314ba7e2584SDinh Nguyen 		hw_clk = s10_register_periph(&clks[i], base);
315ba7e2584SDinh Nguyen 		if (IS_ERR(hw_clk)) {
31607afb8dbSDinh Nguyen 			pr_err("%s: failed to register clock %s\n",
31707afb8dbSDinh Nguyen 			       __func__, clks[i].name);
31807afb8dbSDinh Nguyen 			continue;
31907afb8dbSDinh Nguyen 		}
320ba7e2584SDinh Nguyen 		data->clk_data.hws[clks[i].id] = hw_clk;
32107afb8dbSDinh Nguyen 	}
32207afb8dbSDinh Nguyen 	return 0;
32307afb8dbSDinh Nguyen }
32407afb8dbSDinh Nguyen 
s10_clk_register_cnt_perip(const struct stratix10_perip_cnt_clock * clks,int nums,struct stratix10_clock_data * data)32507afb8dbSDinh Nguyen static int s10_clk_register_cnt_perip(const struct stratix10_perip_cnt_clock *clks,
32607afb8dbSDinh Nguyen 				      int nums, struct stratix10_clock_data *data)
32707afb8dbSDinh Nguyen {
328ba7e2584SDinh Nguyen 	struct clk_hw *hw_clk;
32907afb8dbSDinh Nguyen 	void __iomem *base = data->base;
33007afb8dbSDinh Nguyen 	int i;
33107afb8dbSDinh Nguyen 
33207afb8dbSDinh Nguyen 	for (i = 0; i < nums; i++) {
333ba7e2584SDinh Nguyen 		hw_clk = s10_register_cnt_periph(&clks[i], base);
334ba7e2584SDinh Nguyen 		if (IS_ERR(hw_clk)) {
33507afb8dbSDinh Nguyen 			pr_err("%s: failed to register clock %s\n",
33607afb8dbSDinh Nguyen 			       __func__, clks[i].name);
33707afb8dbSDinh Nguyen 			continue;
33807afb8dbSDinh Nguyen 		}
339ba7e2584SDinh Nguyen 		data->clk_data.hws[clks[i].id] = hw_clk;
34007afb8dbSDinh Nguyen 	}
34107afb8dbSDinh Nguyen 
34207afb8dbSDinh Nguyen 	return 0;
34307afb8dbSDinh Nguyen }
34407afb8dbSDinh Nguyen 
s10_clk_register_gate(const struct stratix10_gate_clock * clks,int nums,struct stratix10_clock_data * data)34507afb8dbSDinh Nguyen static int s10_clk_register_gate(const struct stratix10_gate_clock *clks,
34607afb8dbSDinh Nguyen 				 int nums, struct stratix10_clock_data *data)
34707afb8dbSDinh Nguyen {
348ba7e2584SDinh Nguyen 	struct clk_hw *hw_clk;
34907afb8dbSDinh Nguyen 	void __iomem *base = data->base;
35007afb8dbSDinh Nguyen 	int i;
35107afb8dbSDinh Nguyen 
35207afb8dbSDinh Nguyen 	for (i = 0; i < nums; i++) {
353ba7e2584SDinh Nguyen 		hw_clk = s10_register_gate(&clks[i], base);
354ba7e2584SDinh Nguyen 		if (IS_ERR(hw_clk)) {
35507afb8dbSDinh Nguyen 			pr_err("%s: failed to register clock %s\n",
35607afb8dbSDinh Nguyen 			       __func__, clks[i].name);
35707afb8dbSDinh Nguyen 			continue;
35807afb8dbSDinh Nguyen 		}
359ba7e2584SDinh Nguyen 		data->clk_data.hws[clks[i].id] = hw_clk;
36007afb8dbSDinh Nguyen 	}
36107afb8dbSDinh Nguyen 
36207afb8dbSDinh Nguyen 	return 0;
36307afb8dbSDinh Nguyen }
36407afb8dbSDinh Nguyen 
s10_clk_register_pll(const struct stratix10_pll_clock * clks,int nums,struct stratix10_clock_data * data)36507afb8dbSDinh Nguyen static int s10_clk_register_pll(const struct stratix10_pll_clock *clks,
36607afb8dbSDinh Nguyen 				 int nums, struct stratix10_clock_data *data)
36707afb8dbSDinh Nguyen {
368ba7e2584SDinh Nguyen 	struct clk_hw *hw_clk;
36907afb8dbSDinh Nguyen 	void __iomem *base = data->base;
37007afb8dbSDinh Nguyen 	int i;
37107afb8dbSDinh Nguyen 
37207afb8dbSDinh Nguyen 	for (i = 0; i < nums; i++) {
373ba7e2584SDinh Nguyen 		hw_clk = s10_register_pll(&clks[i], base);
374ba7e2584SDinh Nguyen 		if (IS_ERR(hw_clk)) {
37507afb8dbSDinh Nguyen 			pr_err("%s: failed to register clock %s\n",
37607afb8dbSDinh Nguyen 			       __func__, clks[i].name);
37707afb8dbSDinh Nguyen 			continue;
37807afb8dbSDinh Nguyen 		}
379ba7e2584SDinh Nguyen 		data->clk_data.hws[clks[i].id] = hw_clk;
38007afb8dbSDinh Nguyen 	}
38107afb8dbSDinh Nguyen 
38207afb8dbSDinh Nguyen 	return 0;
38307afb8dbSDinh Nguyen }
38407afb8dbSDinh Nguyen 
s10_clkmgr_init(struct platform_device * pdev)385ba7e2584SDinh Nguyen static int s10_clkmgr_init(struct platform_device *pdev)
38607afb8dbSDinh Nguyen {
3871ace0dfdSDinh Nguyen 	struct device_node *np = pdev->dev.of_node;
3881ace0dfdSDinh Nguyen 	struct device *dev = &pdev->dev;
38907afb8dbSDinh Nguyen 	struct stratix10_clock_data *clk_data;
39007afb8dbSDinh Nguyen 	void __iomem *base;
391ba7e2584SDinh Nguyen 	int i, num_clks;
39207afb8dbSDinh Nguyen 
393b739bca9SCai Huoqing 	base = devm_platform_ioremap_resource(pdev, 0);
3941ace0dfdSDinh Nguyen 	if (IS_ERR(base)) {
39507afb8dbSDinh Nguyen 		pr_err("%s: failed to map clock registers\n", __func__);
396ba7e2584SDinh Nguyen 		return PTR_ERR(base);
39707afb8dbSDinh Nguyen 	}
39807afb8dbSDinh Nguyen 
399ba7e2584SDinh Nguyen 	num_clks = STRATIX10_NUM_CLKS;
400ba7e2584SDinh Nguyen 	clk_data = devm_kzalloc(dev, struct_size(clk_data, clk_data.hws,
401ba7e2584SDinh Nguyen 						 num_clks), GFP_KERNEL);
40207afb8dbSDinh Nguyen 	if (!clk_data)
403ba7e2584SDinh Nguyen 		return -ENOMEM;
404ba7e2584SDinh Nguyen 
405ba7e2584SDinh Nguyen 	for (i = 0; i < num_clks; i++)
406ba7e2584SDinh Nguyen 		clk_data->clk_data.hws[i] = ERR_PTR(-ENOENT);
40707afb8dbSDinh Nguyen 
40807afb8dbSDinh Nguyen 	clk_data->base = base;
409ba7e2584SDinh Nguyen 	clk_data->clk_data.num = num_clks;
41007afb8dbSDinh Nguyen 
41107afb8dbSDinh Nguyen 	s10_clk_register_pll(s10_pll_clks, ARRAY_SIZE(s10_pll_clks), clk_data);
41207afb8dbSDinh Nguyen 
41307afb8dbSDinh Nguyen 	s10_clk_register_c_perip(s10_main_perip_c_clks,
41407afb8dbSDinh Nguyen 				 ARRAY_SIZE(s10_main_perip_c_clks), clk_data);
41507afb8dbSDinh Nguyen 
41607afb8dbSDinh Nguyen 	s10_clk_register_cnt_perip(s10_main_perip_cnt_clks,
41707afb8dbSDinh Nguyen 				   ARRAY_SIZE(s10_main_perip_cnt_clks),
41807afb8dbSDinh Nguyen 				   clk_data);
41907afb8dbSDinh Nguyen 
42007afb8dbSDinh Nguyen 	s10_clk_register_gate(s10_gate_clks, ARRAY_SIZE(s10_gate_clks),
42107afb8dbSDinh Nguyen 			      clk_data);
422ba7e2584SDinh Nguyen 
423ba7e2584SDinh Nguyen 	of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data->clk_data);
42407afb8dbSDinh Nguyen 	return 0;
42507afb8dbSDinh Nguyen }
42607afb8dbSDinh Nguyen 
s10_clkmgr_probe(struct platform_device * pdev)42707afb8dbSDinh Nguyen static int s10_clkmgr_probe(struct platform_device *pdev)
42807afb8dbSDinh Nguyen {
4291ace0dfdSDinh Nguyen 	return	s10_clkmgr_init(pdev);
43007afb8dbSDinh Nguyen }
43107afb8dbSDinh Nguyen 
43207afb8dbSDinh Nguyen static const struct of_device_id stratix10_clkmgr_match_table[] = {
43307afb8dbSDinh Nguyen 	{ .compatible = "intel,stratix10-clkmgr",
43407afb8dbSDinh Nguyen 	  .data = s10_clkmgr_init },
43507afb8dbSDinh Nguyen 	{ }
43607afb8dbSDinh Nguyen };
43707afb8dbSDinh Nguyen 
43807afb8dbSDinh Nguyen static struct platform_driver stratix10_clkmgr_driver = {
43907afb8dbSDinh Nguyen 	.probe		= s10_clkmgr_probe,
44007afb8dbSDinh Nguyen 	.driver		= {
44107afb8dbSDinh Nguyen 		.name	= "stratix10-clkmgr",
442a6131547SDinh Nguyen 		.suppress_bind_attrs = true,
44307afb8dbSDinh Nguyen 		.of_match_table = stratix10_clkmgr_match_table,
44407afb8dbSDinh Nguyen 	},
44507afb8dbSDinh Nguyen };
44607afb8dbSDinh Nguyen 
s10_clk_init(void)44707afb8dbSDinh Nguyen static int __init s10_clk_init(void)
44807afb8dbSDinh Nguyen {
44907afb8dbSDinh Nguyen 	return platform_driver_register(&stratix10_clkmgr_driver);
45007afb8dbSDinh Nguyen }
45107afb8dbSDinh Nguyen core_initcall(s10_clk_init);
452