0001
0002
0003
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
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
0296
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);