Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2019, Intel Corporation
0004  */
0005 #include <linux/slab.h>
0006 #include <linux/clk-provider.h>
0007 #include <linux/of_device.h>
0008 #include <linux/of_address.h>
0009 #include <linux/platform_device.h>
0010 
0011 #include <dt-bindings/clock/agilex-clock.h>
0012 
0013 #include "stratix10-clk.h"
0014 
0015 static const struct clk_parent_data pll_mux[] = {
0016     { .fw_name = "osc1",
0017       .name = "osc1", },
0018     { .fw_name = "cb-intosc-hs-div2-clk",
0019       .name = "cb-intosc-hs-div2-clk", },
0020     { .fw_name = "f2s-free-clk",
0021       .name = "f2s-free-clk", },
0022 };
0023 
0024 static const struct clk_parent_data boot_mux[] = {
0025     { .fw_name = "osc1",
0026       .name = "osc1", },
0027     { .fw_name = "cb-intosc-hs-div2-clk",
0028       .name = "cb-intosc-hs-div2-clk", },
0029 };
0030 
0031 static const struct clk_parent_data mpu_free_mux[] = {
0032     { .fw_name = "main_pll_c0",
0033       .name = "main_pll_c0", },
0034     { .fw_name = "peri_pll_c0",
0035       .name = "peri_pll_c0", },
0036     { .fw_name = "osc1",
0037       .name = "osc1", },
0038     { .fw_name = "cb-intosc-hs-div2-clk",
0039       .name = "cb-intosc-hs-div2-clk", },
0040     { .fw_name = "f2s-free-clk",
0041       .name = "f2s-free-clk", },
0042 };
0043 
0044 static const struct clk_parent_data noc_free_mux[] = {
0045     { .fw_name = "main_pll_c1",
0046       .name = "main_pll_c1", },
0047     { .fw_name = "peri_pll_c1",
0048       .name = "peri_pll_c1", },
0049     { .fw_name = "osc1",
0050       .name = "osc1", },
0051     { .fw_name = "cb-intosc-hs-div2-clk",
0052       .name = "cb-intosc-hs-div2-clk", },
0053     { .fw_name = "f2s-free-clk",
0054       .name = "f2s-free-clk", },
0055 };
0056 
0057 static const struct clk_parent_data emaca_free_mux[] = {
0058     { .fw_name = "main_pll_c2",
0059       .name = "main_pll_c2", },
0060     { .fw_name = "peri_pll_c2",
0061       .name = "peri_pll_c2", },
0062     { .fw_name = "osc1",
0063       .name = "osc1", },
0064     { .fw_name = "cb-intosc-hs-div2-clk",
0065       .name = "cb-intosc-hs-div2-clk", },
0066     { .fw_name = "f2s-free-clk",
0067       .name = "f2s-free-clk", },
0068 };
0069 
0070 static const struct clk_parent_data emacb_free_mux[] = {
0071     { .fw_name = "main_pll_c3",
0072       .name = "main_pll_c3", },
0073     { .fw_name = "peri_pll_c3",
0074       .name = "peri_pll_c3", },
0075     { .fw_name = "osc1",
0076       .name = "osc1", },
0077     { .fw_name = "cb-intosc-hs-div2-clk",
0078       .name = "cb-intosc-hs-div2-clk", },
0079     { .fw_name = "f2s-free-clk",
0080       .name = "f2s-free-clk", },
0081 };
0082 
0083 static const struct clk_parent_data emac_ptp_free_mux[] = {
0084     { .fw_name = "main_pll_c3",
0085       .name = "main_pll_c3", },
0086     { .fw_name = "peri_pll_c3",
0087       .name = "peri_pll_c3", },
0088     { .fw_name = "osc1",
0089       .name = "osc1", },
0090     { .fw_name = "cb-intosc-hs-div2-clk",
0091       .name = "cb-intosc-hs-div2-clk", },
0092     { .fw_name = "f2s-free-clk",
0093       .name = "f2s-free-clk", },
0094 };
0095 
0096 static const struct clk_parent_data gpio_db_free_mux[] = {
0097     { .fw_name = "main_pll_c3",
0098       .name = "main_pll_c3", },
0099     { .fw_name = "peri_pll_c3",
0100       .name = "peri_pll_c3", },
0101     { .fw_name = "osc1",
0102       .name = "osc1", },
0103     { .fw_name = "cb-intosc-hs-div2-clk",
0104       .name = "cb-intosc-hs-div2-clk", },
0105     { .fw_name = "f2s-free-clk",
0106       .name = "f2s-free-clk", },
0107 };
0108 
0109 static const struct clk_parent_data psi_ref_free_mux[] = {
0110     { .fw_name = "main_pll_c2",
0111       .name = "main_pll_c2", },
0112     { .fw_name = "peri_pll_c2",
0113       .name = "peri_pll_c2", },
0114     { .fw_name = "osc1",
0115       .name = "osc1", },
0116     { .fw_name = "cb-intosc-hs-div2-clk",
0117       .name = "cb-intosc-hs-div2-clk", },
0118     { .fw_name = "f2s-free-clk",
0119       .name = "f2s-free-clk", },
0120 };
0121 
0122 static const struct clk_parent_data sdmmc_free_mux[] = {
0123     { .fw_name = "main_pll_c3",
0124       .name = "main_pll_c3", },
0125     { .fw_name = "peri_pll_c3",
0126       .name = "peri_pll_c3", },
0127     { .fw_name = "osc1",
0128       .name = "osc1", },
0129     { .fw_name = "cb-intosc-hs-div2-clk",
0130       .name = "cb-intosc-hs-div2-clk", },
0131     { .fw_name = "f2s-free-clk",
0132       .name = "f2s-free-clk", },
0133 };
0134 
0135 static const struct clk_parent_data s2f_usr0_free_mux[] = {
0136     { .fw_name = "main_pll_c2",
0137       .name = "main_pll_c2", },
0138     { .fw_name = "peri_pll_c2",
0139       .name = "peri_pll_c2", },
0140     { .fw_name = "osc1",
0141       .name = "osc1", },
0142     { .fw_name = "cb-intosc-hs-div2-clk",
0143       .name = "cb-intosc-hs-div2-clk", },
0144     { .fw_name = "f2s-free-clk",
0145       .name = "f2s-free-clk", },
0146 };
0147 
0148 static const struct clk_parent_data s2f_usr1_free_mux[] = {
0149     { .fw_name = "main_pll_c2",
0150       .name = "main_pll_c2", },
0151     { .fw_name = "peri_pll_c2",
0152       .name = "peri_pll_c2", },
0153     { .fw_name = "osc1",
0154       .name = "osc1", },
0155     { .fw_name = "cb-intosc-hs-div2-clk",
0156       .name = "cb-intosc-hs-div2-clk", },
0157     { .fw_name = "f2s-free-clk",
0158       .name = "f2s-free-clk", },
0159 };
0160 
0161 static const struct clk_parent_data mpu_mux[] = {
0162     { .fw_name = "mpu_free_clk",
0163       .name = "mpu_free_clk", },
0164     { .fw_name = "boot_clk",
0165       .name = "boot_clk", },
0166 };
0167 
0168 static const struct clk_parent_data emac_mux[] = {
0169     { .fw_name = "emaca_free_clk",
0170       .name = "emaca_free_clk", },
0171     { .fw_name = "emacb_free_clk",
0172       .name = "emacb_free_clk", },
0173     { .fw_name = "boot_clk",
0174       .name = "boot_clk", },
0175 };
0176 
0177 static const struct clk_parent_data noc_mux[] = {
0178     { .fw_name = "noc_free_clk",
0179       .name = "noc_free_clk", },
0180     { .fw_name = "boot_clk",
0181       .name = "boot_clk", },
0182 };
0183 
0184 static const struct clk_parent_data sdmmc_mux[] = {
0185     { .fw_name = "sdmmc_free_clk",
0186       .name = "sdmmc_free_clk", },
0187     { .fw_name = "boot_clk",
0188       .name = "boot_clk", },
0189 };
0190 
0191 static const struct clk_parent_data s2f_user0_mux[] = {
0192     { .fw_name = "s2f_user0_free_clk",
0193       .name = "s2f_user0_free_clk", },
0194     { .fw_name = "boot_clk",
0195       .name = "boot_clk", },
0196 };
0197 
0198 static const struct clk_parent_data s2f_user1_mux[] = {
0199     { .fw_name = "s2f_user1_free_clk",
0200       .name = "s2f_user1_free_clk", },
0201     { .fw_name = "boot_clk",
0202       .name = "boot_clk", },
0203 };
0204 
0205 static const struct clk_parent_data psi_mux[] = {
0206     { .fw_name = "psi_ref_free_clk",
0207       .name = "psi_ref_free_clk", },
0208     { .fw_name = "boot_clk",
0209       .name = "boot_clk", },
0210 };
0211 
0212 static const struct clk_parent_data gpio_db_mux[] = {
0213     { .fw_name = "gpio_db_free_clk",
0214       .name = "gpio_db_free_clk", },
0215     { .fw_name = "boot_clk",
0216       .name = "boot_clk", },
0217 };
0218 
0219 static const struct clk_parent_data emac_ptp_mux[] = {
0220     { .fw_name = "emac_ptp_free_clk",
0221       .name = "emac_ptp_free_clk", },
0222     { .fw_name = "boot_clk",
0223       .name = "boot_clk", },
0224 };
0225 
0226 /* clocks in AO (always on) controller */
0227 static const struct stratix10_pll_clock agilex_pll_clks[] = {
0228     { AGILEX_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0,
0229       0x0},
0230     { AGILEX_MAIN_PLL_CLK, "main_pll", pll_mux, ARRAY_SIZE(pll_mux),
0231       0, 0x48},
0232     { AGILEX_PERIPH_PLL_CLK, "periph_pll", pll_mux, ARRAY_SIZE(pll_mux),
0233       0, 0x9c},
0234 };
0235 
0236 static const struct n5x_perip_c_clock n5x_main_perip_c_clks[] = {
0237     { AGILEX_MAIN_PLL_C0_CLK, "main_pll_c0", "main_pll", NULL, 1, 0, 0x54, 0},
0238     { AGILEX_MAIN_PLL_C1_CLK, "main_pll_c1", "main_pll", NULL, 1, 0, 0x54, 8},
0239     { AGILEX_MAIN_PLL_C2_CLK, "main_pll_c2", "main_pll", NULL, 1, 0, 0x54, 16},
0240     { AGILEX_MAIN_PLL_C3_CLK, "main_pll_c3", "main_pll", NULL, 1, 0, 0x54, 24},
0241     { AGILEX_PERIPH_PLL_C0_CLK, "peri_pll_c0", "periph_pll", NULL, 1, 0, 0xA8, 0},
0242     { AGILEX_PERIPH_PLL_C1_CLK, "peri_pll_c1", "periph_pll", NULL, 1, 0, 0xA8, 8},
0243     { AGILEX_PERIPH_PLL_C2_CLK, "peri_pll_c2", "periph_pll", NULL, 1, 0, 0xA8, 16},
0244     { AGILEX_PERIPH_PLL_C3_CLK, "peri_pll_c3", "periph_pll", NULL, 1, 0, 0xA8, 24},
0245 };
0246 
0247 static const struct stratix10_perip_c_clock agilex_main_perip_c_clks[] = {
0248     { AGILEX_MAIN_PLL_C0_CLK, "main_pll_c0", "main_pll", NULL, 1, 0, 0x58},
0249     { AGILEX_MAIN_PLL_C1_CLK, "main_pll_c1", "main_pll", NULL, 1, 0, 0x5C},
0250     { AGILEX_MAIN_PLL_C2_CLK, "main_pll_c2", "main_pll", NULL, 1, 0, 0x64},
0251     { AGILEX_MAIN_PLL_C3_CLK, "main_pll_c3", "main_pll", NULL, 1, 0, 0x68},
0252     { AGILEX_PERIPH_PLL_C0_CLK, "peri_pll_c0", "periph_pll", NULL, 1, 0, 0xAC},
0253     { AGILEX_PERIPH_PLL_C1_CLK, "peri_pll_c1", "periph_pll", NULL, 1, 0, 0xB0},
0254     { AGILEX_PERIPH_PLL_C2_CLK, "peri_pll_c2", "periph_pll", NULL, 1, 0, 0xB8},
0255     { AGILEX_PERIPH_PLL_C3_CLK, "peri_pll_c3", "periph_pll", NULL, 1, 0, 0xBC},
0256 };
0257 
0258 static const struct stratix10_perip_cnt_clock agilex_main_perip_cnt_clks[] = {
0259     { AGILEX_MPU_FREE_CLK, "mpu_free_clk", NULL, mpu_free_mux, ARRAY_SIZE(mpu_free_mux),
0260        0, 0x3C, 0, 0, 0},
0261     { AGILEX_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux),
0262       0, 0x40, 0, 0, 0},
0263     { AGILEX_L4_SYS_FREE_CLK, "l4_sys_free_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0,
0264       0, 4, 0x30, 1},
0265     { AGILEX_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux),
0266       0, 0xD4, 0, 0x88, 0},
0267     { AGILEX_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux),
0268       0, 0xD8, 0, 0x88, 1},
0269     { AGILEX_EMAC_PTP_FREE_CLK, "emac_ptp_free_clk", NULL, emac_ptp_free_mux,
0270       ARRAY_SIZE(emac_ptp_free_mux), 0, 0xDC, 0, 0x88, 2},
0271     { AGILEX_GPIO_DB_FREE_CLK, "gpio_db_free_clk", NULL, gpio_db_free_mux,
0272       ARRAY_SIZE(gpio_db_free_mux), 0, 0xE0, 0, 0x88, 3},
0273     { AGILEX_SDMMC_FREE_CLK, "sdmmc_free_clk", NULL, sdmmc_free_mux,
0274       ARRAY_SIZE(sdmmc_free_mux), 0, 0xE4, 0, 0, 0},
0275     { AGILEX_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", NULL, s2f_usr0_free_mux,
0276       ARRAY_SIZE(s2f_usr0_free_mux), 0, 0xE8, 0, 0x30, 2},
0277     { AGILEX_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", NULL, s2f_usr1_free_mux,
0278       ARRAY_SIZE(s2f_usr1_free_mux), 0, 0xEC, 0, 0x88, 5},
0279     { AGILEX_PSI_REF_FREE_CLK, "psi_ref_free_clk", NULL, psi_ref_free_mux,
0280       ARRAY_SIZE(psi_ref_free_mux), 0, 0xF0, 0, 0x88, 6},
0281 };
0282 
0283 static const struct stratix10_gate_clock agilex_gate_clks[] = {
0284     { AGILEX_MPU_CLK, "mpu_clk", NULL, mpu_mux, ARRAY_SIZE(mpu_mux), 0, 0x24,
0285       0, 0, 0, 0, 0x30, 0, 0},
0286     { AGILEX_MPU_PERIPH_CLK, "mpu_periph_clk", "mpu_clk", NULL, 1, 0, 0x24,
0287       0, 0, 0, 0, 0, 0, 4},
0288     { AGILEX_MPU_CCU_CLK, "mpu_ccu_clk", "mpu_clk", NULL, 1, 0, 0x24,
0289       0, 0, 0, 0, 0, 0, 2},
0290     { AGILEX_L4_MAIN_CLK, "l4_main_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
0291       1, 0x44, 0, 2, 0x30, 1, 0},
0292     { AGILEX_L4_MP_CLK, "l4_mp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
0293       2, 0x44, 8, 2, 0x30, 1, 0},
0294     /*
0295      * The l4_sp_clk feeds a 100 MHz clock to various peripherals, one of them
0296      * being the SP timers, thus cannot get gated.
0297      */
0298     { AGILEX_L4_SP_CLK, "l4_sp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), CLK_IS_CRITICAL, 0x24,
0299       3, 0x44, 16, 2, 0x30, 1, 0},
0300     { AGILEX_CS_AT_CLK, "cs_at_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
0301       4, 0x44, 24, 2, 0x30, 1, 0},
0302     { AGILEX_CS_TRACE_CLK, "cs_trace_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
0303       4, 0x44, 26, 2, 0x30, 1, 0},
0304     { AGILEX_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x24,
0305       4, 0x44, 28, 1, 0, 0, 0},
0306     { AGILEX_CS_TIMER_CLK, "cs_timer_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
0307       5, 0, 0, 0, 0x30, 1, 0},
0308     { AGILEX_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
0309       0, 0, 0, 0, 0x94, 26, 0},
0310     { AGILEX_EMAC1_CLK, "emac1_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
0311       1, 0, 0, 0, 0x94, 27, 0},
0312     { AGILEX_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
0313       2, 0, 0, 0, 0x94, 28, 0},
0314     { AGILEX_EMAC_PTP_CLK, "emac_ptp_clk", NULL, emac_ptp_mux, ARRAY_SIZE(emac_ptp_mux), 0, 0x7C,
0315       3, 0, 0, 0, 0x88, 2, 0},
0316     { AGILEX_GPIO_DB_CLK, "gpio_db_clk", NULL, gpio_db_mux, ARRAY_SIZE(gpio_db_mux), 0, 0x7C,
0317       4, 0x98, 0, 16, 0x88, 3, 0},
0318     { AGILEX_SDMMC_CLK, "sdmmc_clk", NULL, sdmmc_mux, ARRAY_SIZE(sdmmc_mux), 0, 0x7C,
0319       5, 0, 0, 0, 0x88, 4, 4},
0320     { AGILEX_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_user0_mux, ARRAY_SIZE(s2f_user0_mux), 0, 0x24,
0321       6, 0, 0, 0, 0x30, 2, 0},
0322     { AGILEX_S2F_USER1_CLK, "s2f_user1_clk", NULL, s2f_user1_mux, ARRAY_SIZE(s2f_user1_mux), 0, 0x7C,
0323       6, 0, 0, 0, 0x88, 5, 0},
0324     { AGILEX_PSI_REF_CLK, "psi_ref_clk", NULL, psi_mux, ARRAY_SIZE(psi_mux), 0, 0x7C,
0325       7, 0, 0, 0, 0x88, 6, 0},
0326     { AGILEX_USB_CLK, "usb_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
0327       8, 0, 0, 0, 0, 0, 0},
0328     { AGILEX_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
0329       9, 0, 0, 0, 0, 0, 0},
0330     { AGILEX_NAND_X_CLK, "nand_x_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
0331       10, 0, 0, 0, 0, 0, 0},
0332     { AGILEX_NAND_CLK, "nand_clk", "nand_x_clk", NULL, 1, 0, 0x7C,
0333       10, 0, 0, 0, 0, 0, 4},
0334     { AGILEX_NAND_ECC_CLK, "nand_ecc_clk", "nand_x_clk", NULL, 1, 0, 0x7C,
0335       10, 0, 0, 0, 0, 0, 4},
0336 };
0337 
0338 static int n5x_clk_register_c_perip(const struct n5x_perip_c_clock *clks,
0339                        int nums, struct stratix10_clock_data *data)
0340 {
0341     struct clk_hw *hw_clk;
0342     void __iomem *base = data->base;
0343     int i;
0344 
0345     for (i = 0; i < nums; i++) {
0346         hw_clk = n5x_register_periph(&clks[i], base);
0347         if (IS_ERR(hw_clk)) {
0348             pr_err("%s: failed to register clock %s\n",
0349                    __func__, clks[i].name);
0350             continue;
0351         }
0352         data->clk_data.hws[clks[i].id] = hw_clk;
0353     }
0354     return 0;
0355 }
0356 
0357 static int agilex_clk_register_c_perip(const struct stratix10_perip_c_clock *clks,
0358                        int nums, struct stratix10_clock_data *data)
0359 {
0360     struct clk_hw *hw_clk;
0361     void __iomem *base = data->base;
0362     int i;
0363 
0364     for (i = 0; i < nums; i++) {
0365         hw_clk = s10_register_periph(&clks[i], base);
0366         if (IS_ERR(hw_clk)) {
0367             pr_err("%s: failed to register clock %s\n",
0368                    __func__, clks[i].name);
0369             continue;
0370         }
0371         data->clk_data.hws[clks[i].id] = hw_clk;
0372     }
0373     return 0;
0374 }
0375 
0376 static int agilex_clk_register_cnt_perip(const struct stratix10_perip_cnt_clock *clks,
0377                      int nums, struct stratix10_clock_data *data)
0378 {
0379     struct clk_hw *hw_clk;
0380     void __iomem *base = data->base;
0381     int i;
0382 
0383     for (i = 0; i < nums; i++) {
0384         hw_clk = s10_register_cnt_periph(&clks[i], base);
0385         if (IS_ERR(hw_clk)) {
0386             pr_err("%s: failed to register clock %s\n",
0387                    __func__, clks[i].name);
0388             continue;
0389         }
0390         data->clk_data.hws[clks[i].id] = hw_clk;
0391     }
0392 
0393     return 0;
0394 }
0395 
0396 static int agilex_clk_register_gate(const struct stratix10_gate_clock *clks,
0397                     int nums, struct stratix10_clock_data *data)
0398 {
0399     struct clk_hw *hw_clk;
0400     void __iomem *base = data->base;
0401     int i;
0402 
0403     for (i = 0; i < nums; i++) {
0404         hw_clk = agilex_register_gate(&clks[i], base);
0405         if (IS_ERR(hw_clk)) {
0406             pr_err("%s: failed to register clock %s\n",
0407                    __func__, clks[i].name);
0408             continue;
0409         }
0410         data->clk_data.hws[clks[i].id] = hw_clk;
0411     }
0412 
0413     return 0;
0414 }
0415 
0416 static int agilex_clk_register_pll(const struct stratix10_pll_clock *clks,
0417                  int nums, struct stratix10_clock_data *data)
0418 {
0419     struct clk_hw *hw_clk;
0420     void __iomem *base = data->base;
0421     int i;
0422 
0423     for (i = 0; i < nums; i++) {
0424         hw_clk = agilex_register_pll(&clks[i], base);
0425         if (IS_ERR(hw_clk)) {
0426             pr_err("%s: failed to register clock %s\n",
0427                    __func__, clks[i].name);
0428             continue;
0429         }
0430         data->clk_data.hws[clks[i].id] = hw_clk;
0431     }
0432 
0433     return 0;
0434 }
0435 
0436 static int n5x_clk_register_pll(const struct stratix10_pll_clock *clks,
0437                  int nums, struct stratix10_clock_data *data)
0438 {
0439     struct clk_hw *hw_clk;
0440     void __iomem *base = data->base;
0441     int i;
0442 
0443     for (i = 0; i < nums; i++) {
0444         hw_clk = n5x_register_pll(&clks[i], base);
0445         if (IS_ERR(hw_clk)) {
0446             pr_err("%s: failed to register clock %s\n",
0447                    __func__, clks[i].name);
0448             continue;
0449         }
0450         data->clk_data.hws[clks[i].id] = hw_clk;
0451     }
0452 
0453     return 0;
0454 }
0455 
0456 static int agilex_clkmgr_init(struct platform_device *pdev)
0457 {
0458     struct device_node *np = pdev->dev.of_node;
0459     struct device *dev = &pdev->dev;
0460     struct stratix10_clock_data *clk_data;
0461     struct resource *res;
0462     void __iomem *base;
0463     int i, num_clks;
0464 
0465     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0466     base = devm_ioremap_resource(dev, res);
0467     if (IS_ERR(base))
0468         return PTR_ERR(base);
0469 
0470     num_clks = AGILEX_NUM_CLKS;
0471 
0472     clk_data = devm_kzalloc(dev, struct_size(clk_data, clk_data.hws,
0473                 num_clks), GFP_KERNEL);
0474     if (!clk_data)
0475         return -ENOMEM;
0476 
0477     for (i = 0; i < num_clks; i++)
0478         clk_data->clk_data.hws[i] = ERR_PTR(-ENOENT);
0479 
0480     clk_data->base = base;
0481     clk_data->clk_data.num = num_clks;
0482 
0483     agilex_clk_register_pll(agilex_pll_clks, ARRAY_SIZE(agilex_pll_clks), clk_data);
0484 
0485     agilex_clk_register_c_perip(agilex_main_perip_c_clks,
0486                  ARRAY_SIZE(agilex_main_perip_c_clks), clk_data);
0487 
0488     agilex_clk_register_cnt_perip(agilex_main_perip_cnt_clks,
0489                    ARRAY_SIZE(agilex_main_perip_cnt_clks),
0490                    clk_data);
0491 
0492     agilex_clk_register_gate(agilex_gate_clks, ARRAY_SIZE(agilex_gate_clks),
0493                   clk_data);
0494     of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data->clk_data);
0495     return 0;
0496 }
0497 
0498 static int n5x_clkmgr_init(struct platform_device *pdev)
0499 {
0500     struct device_node *np = pdev->dev.of_node;
0501     struct device *dev = &pdev->dev;
0502     struct stratix10_clock_data *clk_data;
0503     void __iomem *base;
0504     int i, num_clks;
0505 
0506     base = devm_platform_ioremap_resource(pdev, 0);
0507     if (IS_ERR(base))
0508         return PTR_ERR(base);
0509 
0510     num_clks = AGILEX_NUM_CLKS;
0511 
0512     clk_data = devm_kzalloc(dev, struct_size(clk_data, clk_data.hws,
0513                 num_clks), GFP_KERNEL);
0514     if (!clk_data)
0515         return -ENOMEM;
0516 
0517     for (i = 0; i < num_clks; i++)
0518         clk_data->clk_data.hws[i] = ERR_PTR(-ENOENT);
0519 
0520     clk_data->base = base;
0521     clk_data->clk_data.num = num_clks;
0522 
0523     n5x_clk_register_pll(agilex_pll_clks, ARRAY_SIZE(agilex_pll_clks), clk_data);
0524 
0525     n5x_clk_register_c_perip(n5x_main_perip_c_clks,
0526                  ARRAY_SIZE(n5x_main_perip_c_clks), clk_data);
0527 
0528     agilex_clk_register_cnt_perip(agilex_main_perip_cnt_clks,
0529                    ARRAY_SIZE(agilex_main_perip_cnt_clks),
0530                    clk_data);
0531 
0532     agilex_clk_register_gate(agilex_gate_clks, ARRAY_SIZE(agilex_gate_clks),
0533                   clk_data);
0534     of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data->clk_data);
0535     return 0;
0536 }
0537 
0538 static int agilex_clkmgr_probe(struct platform_device *pdev)
0539 {
0540     int (*probe_func)(struct platform_device *init_func);
0541 
0542     probe_func = of_device_get_match_data(&pdev->dev);
0543     if (!probe_func)
0544         return -ENODEV;
0545     return  probe_func(pdev);
0546 }
0547 
0548 static const struct of_device_id agilex_clkmgr_match_table[] = {
0549     { .compatible = "intel,agilex-clkmgr",
0550       .data = agilex_clkmgr_init },
0551     { .compatible = "intel,easic-n5x-clkmgr",
0552       .data = n5x_clkmgr_init },
0553     { }
0554 };
0555 
0556 static struct platform_driver agilex_clkmgr_driver = {
0557     .probe      = agilex_clkmgr_probe,
0558     .driver     = {
0559         .name   = "agilex-clkmgr",
0560         .suppress_bind_attrs = true,
0561         .of_match_table = agilex_clkmgr_match_table,
0562     },
0563 };
0564 
0565 static int __init agilex_clk_init(void)
0566 {
0567     return platform_driver_register(&agilex_clkmgr_driver);
0568 }
0569 core_initcall(agilex_clk_init);