cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

clk-agilex.c (17741B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (C) 2019, 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/agilex-clock.h>
     12
     13#include "stratix10-clk.h"
     14
     15static const struct clk_parent_data pll_mux[] = {
     16	{ .fw_name = "osc1",
     17	  .name = "osc1", },
     18	{ .fw_name = "cb-intosc-hs-div2-clk",
     19	  .name = "cb-intosc-hs-div2-clk", },
     20	{ .fw_name = "f2s-free-clk",
     21	  .name = "f2s-free-clk", },
     22};
     23
     24static const struct clk_parent_data boot_mux[] = {
     25	{ .fw_name = "osc1",
     26	  .name = "osc1", },
     27	{ .fw_name = "cb-intosc-hs-div2-clk",
     28	  .name = "cb-intosc-hs-div2-clk", },
     29};
     30
     31static const struct clk_parent_data mpu_free_mux[] = {
     32	{ .fw_name = "main_pll_c0",
     33	  .name = "main_pll_c0", },
     34	{ .fw_name = "peri_pll_c0",
     35	  .name = "peri_pll_c0", },
     36	{ .fw_name = "osc1",
     37	  .name = "osc1", },
     38	{ .fw_name = "cb-intosc-hs-div2-clk",
     39	  .name = "cb-intosc-hs-div2-clk", },
     40	{ .fw_name = "f2s-free-clk",
     41	  .name = "f2s-free-clk", },
     42};
     43
     44static const struct clk_parent_data noc_free_mux[] = {
     45	{ .fw_name = "main_pll_c1",
     46	  .name = "main_pll_c1", },
     47	{ .fw_name = "peri_pll_c1",
     48	  .name = "peri_pll_c1", },
     49	{ .fw_name = "osc1",
     50	  .name = "osc1", },
     51	{ .fw_name = "cb-intosc-hs-div2-clk",
     52	  .name = "cb-intosc-hs-div2-clk", },
     53	{ .fw_name = "f2s-free-clk",
     54	  .name = "f2s-free-clk", },
     55};
     56
     57static const struct clk_parent_data emaca_free_mux[] = {
     58	{ .fw_name = "main_pll_c2",
     59	  .name = "main_pll_c2", },
     60	{ .fw_name = "peri_pll_c2",
     61	  .name = "peri_pll_c2", },
     62	{ .fw_name = "osc1",
     63	  .name = "osc1", },
     64	{ .fw_name = "cb-intosc-hs-div2-clk",
     65	  .name = "cb-intosc-hs-div2-clk", },
     66	{ .fw_name = "f2s-free-clk",
     67	  .name = "f2s-free-clk", },
     68};
     69
     70static const struct clk_parent_data emacb_free_mux[] = {
     71	{ .fw_name = "main_pll_c3",
     72	  .name = "main_pll_c3", },
     73	{ .fw_name = "peri_pll_c3",
     74	  .name = "peri_pll_c3", },
     75	{ .fw_name = "osc1",
     76	  .name = "osc1", },
     77	{ .fw_name = "cb-intosc-hs-div2-clk",
     78	  .name = "cb-intosc-hs-div2-clk", },
     79	{ .fw_name = "f2s-free-clk",
     80	  .name = "f2s-free-clk", },
     81};
     82
     83static const struct clk_parent_data emac_ptp_free_mux[] = {
     84	{ .fw_name = "main_pll_c3",
     85	  .name = "main_pll_c3", },
     86	{ .fw_name = "peri_pll_c3",
     87	  .name = "peri_pll_c3", },
     88	{ .fw_name = "osc1",
     89	  .name = "osc1", },
     90	{ .fw_name = "cb-intosc-hs-div2-clk",
     91	  .name = "cb-intosc-hs-div2-clk", },
     92	{ .fw_name = "f2s-free-clk",
     93	  .name = "f2s-free-clk", },
     94};
     95
     96static const struct clk_parent_data gpio_db_free_mux[] = {
     97	{ .fw_name = "main_pll_c3",
     98	  .name = "main_pll_c3", },
     99	{ .fw_name = "peri_pll_c3",
    100	  .name = "peri_pll_c3", },
    101	{ .fw_name = "osc1",
    102	  .name = "osc1", },
    103	{ .fw_name = "cb-intosc-hs-div2-clk",
    104	  .name = "cb-intosc-hs-div2-clk", },
    105	{ .fw_name = "f2s-free-clk",
    106	  .name = "f2s-free-clk", },
    107};
    108
    109static const struct clk_parent_data psi_ref_free_mux[] = {
    110	{ .fw_name = "main_pll_c2",
    111	  .name = "main_pll_c2", },
    112	{ .fw_name = "peri_pll_c2",
    113	  .name = "peri_pll_c2", },
    114	{ .fw_name = "osc1",
    115	  .name = "osc1", },
    116	{ .fw_name = "cb-intosc-hs-div2-clk",
    117	  .name = "cb-intosc-hs-div2-clk", },
    118	{ .fw_name = "f2s-free-clk",
    119	  .name = "f2s-free-clk", },
    120};
    121
    122static const struct clk_parent_data sdmmc_free_mux[] = {
    123	{ .fw_name = "main_pll_c3",
    124	  .name = "main_pll_c3", },
    125	{ .fw_name = "peri_pll_c3",
    126	  .name = "peri_pll_c3", },
    127	{ .fw_name = "osc1",
    128	  .name = "osc1", },
    129	{ .fw_name = "cb-intosc-hs-div2-clk",
    130	  .name = "cb-intosc-hs-div2-clk", },
    131	{ .fw_name = "f2s-free-clk",
    132	  .name = "f2s-free-clk", },
    133};
    134
    135static const struct clk_parent_data s2f_usr0_free_mux[] = {
    136	{ .fw_name = "main_pll_c2",
    137	  .name = "main_pll_c2", },
    138	{ .fw_name = "peri_pll_c2",
    139	  .name = "peri_pll_c2", },
    140	{ .fw_name = "osc1",
    141	  .name = "osc1", },
    142	{ .fw_name = "cb-intosc-hs-div2-clk",
    143	  .name = "cb-intosc-hs-div2-clk", },
    144	{ .fw_name = "f2s-free-clk",
    145	  .name = "f2s-free-clk", },
    146};
    147
    148static const struct clk_parent_data s2f_usr1_free_mux[] = {
    149	{ .fw_name = "main_pll_c2",
    150	  .name = "main_pll_c2", },
    151	{ .fw_name = "peri_pll_c2",
    152	  .name = "peri_pll_c2", },
    153	{ .fw_name = "osc1",
    154	  .name = "osc1", },
    155	{ .fw_name = "cb-intosc-hs-div2-clk",
    156	  .name = "cb-intosc-hs-div2-clk", },
    157	{ .fw_name = "f2s-free-clk",
    158	  .name = "f2s-free-clk", },
    159};
    160
    161static const struct clk_parent_data mpu_mux[] = {
    162	{ .fw_name = "mpu_free_clk",
    163	  .name = "mpu_free_clk", },
    164	{ .fw_name = "boot_clk",
    165	  .name = "boot_clk", },
    166};
    167
    168static const struct clk_parent_data emac_mux[] = {
    169	{ .fw_name = "emaca_free_clk",
    170	  .name = "emaca_free_clk", },
    171	{ .fw_name = "emacb_free_clk",
    172	  .name = "emacb_free_clk", },
    173	{ .fw_name = "boot_clk",
    174	  .name = "boot_clk", },
    175};
    176
    177static const struct clk_parent_data noc_mux[] = {
    178	{ .fw_name = "noc_free_clk",
    179	  .name = "noc_free_clk", },
    180	{ .fw_name = "boot_clk",
    181	  .name = "boot_clk", },
    182};
    183
    184static const struct clk_parent_data sdmmc_mux[] = {
    185	{ .fw_name = "sdmmc_free_clk",
    186	  .name = "sdmmc_free_clk", },
    187	{ .fw_name = "boot_clk",
    188	  .name = "boot_clk", },
    189};
    190
    191static const struct clk_parent_data s2f_user0_mux[] = {
    192	{ .fw_name = "s2f_user0_free_clk",
    193	  .name = "s2f_user0_free_clk", },
    194	{ .fw_name = "boot_clk",
    195	  .name = "boot_clk", },
    196};
    197
    198static const struct clk_parent_data s2f_user1_mux[] = {
    199	{ .fw_name = "s2f_user1_free_clk",
    200	  .name = "s2f_user1_free_clk", },
    201	{ .fw_name = "boot_clk",
    202	  .name = "boot_clk", },
    203};
    204
    205static const struct clk_parent_data psi_mux[] = {
    206	{ .fw_name = "psi_ref_free_clk",
    207	  .name = "psi_ref_free_clk", },
    208	{ .fw_name = "boot_clk",
    209	  .name = "boot_clk", },
    210};
    211
    212static const struct clk_parent_data gpio_db_mux[] = {
    213	{ .fw_name = "gpio_db_free_clk",
    214	  .name = "gpio_db_free_clk", },
    215	{ .fw_name = "boot_clk",
    216	  .name = "boot_clk", },
    217};
    218
    219static const struct clk_parent_data emac_ptp_mux[] = {
    220	{ .fw_name = "emac_ptp_free_clk",
    221	  .name = "emac_ptp_free_clk", },
    222	{ .fw_name = "boot_clk",
    223	  .name = "boot_clk", },
    224};
    225
    226/* clocks in AO (always on) controller */
    227static const struct stratix10_pll_clock agilex_pll_clks[] = {
    228	{ AGILEX_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0,
    229	  0x0},
    230	{ AGILEX_MAIN_PLL_CLK, "main_pll", pll_mux, ARRAY_SIZE(pll_mux),
    231	  0, 0x48},
    232	{ AGILEX_PERIPH_PLL_CLK, "periph_pll", pll_mux, ARRAY_SIZE(pll_mux),
    233	  0, 0x9c},
    234};
    235
    236static const struct n5x_perip_c_clock n5x_main_perip_c_clks[] = {
    237	{ AGILEX_MAIN_PLL_C0_CLK, "main_pll_c0", "main_pll", NULL, 1, 0, 0x54, 0},
    238	{ AGILEX_MAIN_PLL_C1_CLK, "main_pll_c1", "main_pll", NULL, 1, 0, 0x54, 8},
    239	{ AGILEX_MAIN_PLL_C2_CLK, "main_pll_c2", "main_pll", NULL, 1, 0, 0x54, 16},
    240	{ AGILEX_MAIN_PLL_C3_CLK, "main_pll_c3", "main_pll", NULL, 1, 0, 0x54, 24},
    241	{ AGILEX_PERIPH_PLL_C0_CLK, "peri_pll_c0", "periph_pll", NULL, 1, 0, 0xA8, 0},
    242	{ AGILEX_PERIPH_PLL_C1_CLK, "peri_pll_c1", "periph_pll", NULL, 1, 0, 0xA8, 8},
    243	{ AGILEX_PERIPH_PLL_C2_CLK, "peri_pll_c2", "periph_pll", NULL, 1, 0, 0xA8, 16},
    244	{ AGILEX_PERIPH_PLL_C3_CLK, "peri_pll_c3", "periph_pll", NULL, 1, 0, 0xA8, 24},
    245};
    246
    247static const struct stratix10_perip_c_clock agilex_main_perip_c_clks[] = {
    248	{ AGILEX_MAIN_PLL_C0_CLK, "main_pll_c0", "main_pll", NULL, 1, 0, 0x58},
    249	{ AGILEX_MAIN_PLL_C1_CLK, "main_pll_c1", "main_pll", NULL, 1, 0, 0x5C},
    250	{ AGILEX_MAIN_PLL_C2_CLK, "main_pll_c2", "main_pll", NULL, 1, 0, 0x64},
    251	{ AGILEX_MAIN_PLL_C3_CLK, "main_pll_c3", "main_pll", NULL, 1, 0, 0x68},
    252	{ AGILEX_PERIPH_PLL_C0_CLK, "peri_pll_c0", "periph_pll", NULL, 1, 0, 0xAC},
    253	{ AGILEX_PERIPH_PLL_C1_CLK, "peri_pll_c1", "periph_pll", NULL, 1, 0, 0xB0},
    254	{ AGILEX_PERIPH_PLL_C2_CLK, "peri_pll_c2", "periph_pll", NULL, 1, 0, 0xB8},
    255	{ AGILEX_PERIPH_PLL_C3_CLK, "peri_pll_c3", "periph_pll", NULL, 1, 0, 0xBC},
    256};
    257
    258static const struct stratix10_perip_cnt_clock agilex_main_perip_cnt_clks[] = {
    259	{ AGILEX_MPU_FREE_CLK, "mpu_free_clk", NULL, mpu_free_mux, ARRAY_SIZE(mpu_free_mux),
    260	   0, 0x3C, 0, 0, 0},
    261	{ AGILEX_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux),
    262	  0, 0x40, 0, 0, 0},
    263	{ AGILEX_L4_SYS_FREE_CLK, "l4_sys_free_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0,
    264	  0, 4, 0x30, 1},
    265	{ AGILEX_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux),
    266	  0, 0xD4, 0, 0x88, 0},
    267	{ AGILEX_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux),
    268	  0, 0xD8, 0, 0x88, 1},
    269	{ AGILEX_EMAC_PTP_FREE_CLK, "emac_ptp_free_clk", NULL, emac_ptp_free_mux,
    270	  ARRAY_SIZE(emac_ptp_free_mux), 0, 0xDC, 0, 0x88, 2},
    271	{ AGILEX_GPIO_DB_FREE_CLK, "gpio_db_free_clk", NULL, gpio_db_free_mux,
    272	  ARRAY_SIZE(gpio_db_free_mux), 0, 0xE0, 0, 0x88, 3},
    273	{ AGILEX_SDMMC_FREE_CLK, "sdmmc_free_clk", NULL, sdmmc_free_mux,
    274	  ARRAY_SIZE(sdmmc_free_mux), 0, 0xE4, 0, 0, 0},
    275	{ AGILEX_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", NULL, s2f_usr0_free_mux,
    276	  ARRAY_SIZE(s2f_usr0_free_mux), 0, 0xE8, 0, 0x30, 2},
    277	{ AGILEX_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", NULL, s2f_usr1_free_mux,
    278	  ARRAY_SIZE(s2f_usr1_free_mux), 0, 0xEC, 0, 0x88, 5},
    279	{ AGILEX_PSI_REF_FREE_CLK, "psi_ref_free_clk", NULL, psi_ref_free_mux,
    280	  ARRAY_SIZE(psi_ref_free_mux), 0, 0xF0, 0, 0x88, 6},
    281};
    282
    283static const struct stratix10_gate_clock agilex_gate_clks[] = {
    284	{ AGILEX_MPU_CLK, "mpu_clk", NULL, mpu_mux, ARRAY_SIZE(mpu_mux), 0, 0x24,
    285	  0, 0, 0, 0, 0x30, 0, 0},
    286	{ AGILEX_MPU_PERIPH_CLK, "mpu_periph_clk", "mpu_clk", NULL, 1, 0, 0x24,
    287	  0, 0, 0, 0, 0, 0, 4},
    288	{ AGILEX_MPU_CCU_CLK, "mpu_ccu_clk", "mpu_clk", NULL, 1, 0, 0x24,
    289	  0, 0, 0, 0, 0, 0, 2},
    290	{ AGILEX_L4_MAIN_CLK, "l4_main_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
    291	  1, 0x44, 0, 2, 0x30, 1, 0},
    292	{ AGILEX_L4_MP_CLK, "l4_mp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
    293	  2, 0x44, 8, 2, 0x30, 1, 0},
    294	/*
    295	 * The l4_sp_clk feeds a 100 MHz clock to various peripherals, one of them
    296	 * being the SP timers, thus cannot get gated.
    297	 */
    298	{ AGILEX_L4_SP_CLK, "l4_sp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), CLK_IS_CRITICAL, 0x24,
    299	  3, 0x44, 16, 2, 0x30, 1, 0},
    300	{ AGILEX_CS_AT_CLK, "cs_at_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
    301	  4, 0x44, 24, 2, 0x30, 1, 0},
    302	{ AGILEX_CS_TRACE_CLK, "cs_trace_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
    303	  4, 0x44, 26, 2, 0x30, 1, 0},
    304	{ AGILEX_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x24,
    305	  4, 0x44, 28, 1, 0, 0, 0},
    306	{ AGILEX_CS_TIMER_CLK, "cs_timer_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
    307	  5, 0, 0, 0, 0x30, 1, 0},
    308	{ AGILEX_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
    309	  0, 0, 0, 0, 0x94, 26, 0},
    310	{ AGILEX_EMAC1_CLK, "emac1_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
    311	  1, 0, 0, 0, 0x94, 27, 0},
    312	{ AGILEX_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
    313	  2, 0, 0, 0, 0x94, 28, 0},
    314	{ AGILEX_EMAC_PTP_CLK, "emac_ptp_clk", NULL, emac_ptp_mux, ARRAY_SIZE(emac_ptp_mux), 0, 0x7C,
    315	  3, 0, 0, 0, 0x88, 2, 0},
    316	{ AGILEX_GPIO_DB_CLK, "gpio_db_clk", NULL, gpio_db_mux, ARRAY_SIZE(gpio_db_mux), 0, 0x7C,
    317	  4, 0x98, 0, 16, 0x88, 3, 0},
    318	{ AGILEX_SDMMC_CLK, "sdmmc_clk", NULL, sdmmc_mux, ARRAY_SIZE(sdmmc_mux), 0, 0x7C,
    319	  5, 0, 0, 0, 0x88, 4, 4},
    320	{ AGILEX_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_user0_mux, ARRAY_SIZE(s2f_user0_mux), 0, 0x24,
    321	  6, 0, 0, 0, 0x30, 2, 0},
    322	{ AGILEX_S2F_USER1_CLK, "s2f_user1_clk", NULL, s2f_user1_mux, ARRAY_SIZE(s2f_user1_mux), 0, 0x7C,
    323	  6, 0, 0, 0, 0x88, 5, 0},
    324	{ AGILEX_PSI_REF_CLK, "psi_ref_clk", NULL, psi_mux, ARRAY_SIZE(psi_mux), 0, 0x7C,
    325	  7, 0, 0, 0, 0x88, 6, 0},
    326	{ AGILEX_USB_CLK, "usb_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
    327	  8, 0, 0, 0, 0, 0, 0},
    328	{ AGILEX_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
    329	  9, 0, 0, 0, 0, 0, 0},
    330	{ AGILEX_NAND_X_CLK, "nand_x_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
    331	  10, 0, 0, 0, 0, 0, 0},
    332	{ AGILEX_NAND_CLK, "nand_clk", "nand_x_clk", NULL, 1, 0, 0x7C,
    333	  10, 0, 0, 0, 0, 0, 4},
    334	{ AGILEX_NAND_ECC_CLK, "nand_ecc_clk", "nand_x_clk", NULL, 1, 0, 0x7C,
    335	  10, 0, 0, 0, 0, 0, 4},
    336};
    337
    338static int n5x_clk_register_c_perip(const struct n5x_perip_c_clock *clks,
    339				       int nums, struct stratix10_clock_data *data)
    340{
    341	struct clk_hw *hw_clk;
    342	void __iomem *base = data->base;
    343	int i;
    344
    345	for (i = 0; i < nums; i++) {
    346		hw_clk = n5x_register_periph(&clks[i], base);
    347		if (IS_ERR(hw_clk)) {
    348			pr_err("%s: failed to register clock %s\n",
    349			       __func__, clks[i].name);
    350			continue;
    351		}
    352		data->clk_data.hws[clks[i].id] = hw_clk;
    353	}
    354	return 0;
    355}
    356
    357static int agilex_clk_register_c_perip(const struct stratix10_perip_c_clock *clks,
    358				       int nums, struct stratix10_clock_data *data)
    359{
    360	struct clk_hw *hw_clk;
    361	void __iomem *base = data->base;
    362	int i;
    363
    364	for (i = 0; i < nums; i++) {
    365		hw_clk = s10_register_periph(&clks[i], base);
    366		if (IS_ERR(hw_clk)) {
    367			pr_err("%s: failed to register clock %s\n",
    368			       __func__, clks[i].name);
    369			continue;
    370		}
    371		data->clk_data.hws[clks[i].id] = hw_clk;
    372	}
    373	return 0;
    374}
    375
    376static int agilex_clk_register_cnt_perip(const struct stratix10_perip_cnt_clock *clks,
    377					 int nums, struct stratix10_clock_data *data)
    378{
    379	struct clk_hw *hw_clk;
    380	void __iomem *base = data->base;
    381	int i;
    382
    383	for (i = 0; i < nums; i++) {
    384		hw_clk = s10_register_cnt_periph(&clks[i], base);
    385		if (IS_ERR(hw_clk)) {
    386			pr_err("%s: failed to register clock %s\n",
    387			       __func__, clks[i].name);
    388			continue;
    389		}
    390		data->clk_data.hws[clks[i].id] = hw_clk;
    391	}
    392
    393	return 0;
    394}
    395
    396static int agilex_clk_register_gate(const struct stratix10_gate_clock *clks,
    397				    int nums, struct stratix10_clock_data *data)
    398{
    399	struct clk_hw *hw_clk;
    400	void __iomem *base = data->base;
    401	int i;
    402
    403	for (i = 0; i < nums; i++) {
    404		hw_clk = agilex_register_gate(&clks[i], base);
    405		if (IS_ERR(hw_clk)) {
    406			pr_err("%s: failed to register clock %s\n",
    407			       __func__, clks[i].name);
    408			continue;
    409		}
    410		data->clk_data.hws[clks[i].id] = hw_clk;
    411	}
    412
    413	return 0;
    414}
    415
    416static int agilex_clk_register_pll(const struct stratix10_pll_clock *clks,
    417				 int nums, struct stratix10_clock_data *data)
    418{
    419	struct clk_hw *hw_clk;
    420	void __iomem *base = data->base;
    421	int i;
    422
    423	for (i = 0; i < nums; i++) {
    424		hw_clk = agilex_register_pll(&clks[i], base);
    425		if (IS_ERR(hw_clk)) {
    426			pr_err("%s: failed to register clock %s\n",
    427			       __func__, clks[i].name);
    428			continue;
    429		}
    430		data->clk_data.hws[clks[i].id] = hw_clk;
    431	}
    432
    433	return 0;
    434}
    435
    436static int n5x_clk_register_pll(const struct stratix10_pll_clock *clks,
    437				 int nums, struct stratix10_clock_data *data)
    438{
    439	struct clk_hw *hw_clk;
    440	void __iomem *base = data->base;
    441	int i;
    442
    443	for (i = 0; i < nums; i++) {
    444		hw_clk = n5x_register_pll(&clks[i], base);
    445		if (IS_ERR(hw_clk)) {
    446			pr_err("%s: failed to register clock %s\n",
    447			       __func__, clks[i].name);
    448			continue;
    449		}
    450		data->clk_data.hws[clks[i].id] = hw_clk;
    451	}
    452
    453	return 0;
    454}
    455
    456static int agilex_clkmgr_init(struct platform_device *pdev)
    457{
    458	struct device_node *np = pdev->dev.of_node;
    459	struct device *dev = &pdev->dev;
    460	struct stratix10_clock_data *clk_data;
    461	struct resource *res;
    462	void __iomem *base;
    463	int i, num_clks;
    464
    465	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    466	base = devm_ioremap_resource(dev, res);
    467	if (IS_ERR(base))
    468		return PTR_ERR(base);
    469
    470	num_clks = AGILEX_NUM_CLKS;
    471
    472	clk_data = devm_kzalloc(dev, struct_size(clk_data, clk_data.hws,
    473				num_clks), GFP_KERNEL);
    474	if (!clk_data)
    475		return -ENOMEM;
    476
    477	for (i = 0; i < num_clks; i++)
    478		clk_data->clk_data.hws[i] = ERR_PTR(-ENOENT);
    479
    480	clk_data->base = base;
    481	clk_data->clk_data.num = num_clks;
    482
    483	agilex_clk_register_pll(agilex_pll_clks, ARRAY_SIZE(agilex_pll_clks), clk_data);
    484
    485	agilex_clk_register_c_perip(agilex_main_perip_c_clks,
    486				 ARRAY_SIZE(agilex_main_perip_c_clks), clk_data);
    487
    488	agilex_clk_register_cnt_perip(agilex_main_perip_cnt_clks,
    489				   ARRAY_SIZE(agilex_main_perip_cnt_clks),
    490				   clk_data);
    491
    492	agilex_clk_register_gate(agilex_gate_clks, ARRAY_SIZE(agilex_gate_clks),
    493			      clk_data);
    494	of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data->clk_data);
    495	return 0;
    496}
    497
    498static int n5x_clkmgr_init(struct platform_device *pdev)
    499{
    500	struct device_node *np = pdev->dev.of_node;
    501	struct device *dev = &pdev->dev;
    502	struct stratix10_clock_data *clk_data;
    503	void __iomem *base;
    504	int i, num_clks;
    505
    506	base = devm_platform_ioremap_resource(pdev, 0);
    507	if (IS_ERR(base))
    508		return PTR_ERR(base);
    509
    510	num_clks = AGILEX_NUM_CLKS;
    511
    512	clk_data = devm_kzalloc(dev, struct_size(clk_data, clk_data.hws,
    513				num_clks), GFP_KERNEL);
    514	if (!clk_data)
    515		return -ENOMEM;
    516
    517	for (i = 0; i < num_clks; i++)
    518		clk_data->clk_data.hws[i] = ERR_PTR(-ENOENT);
    519
    520	clk_data->base = base;
    521	clk_data->clk_data.num = num_clks;
    522
    523	n5x_clk_register_pll(agilex_pll_clks, ARRAY_SIZE(agilex_pll_clks), clk_data);
    524
    525	n5x_clk_register_c_perip(n5x_main_perip_c_clks,
    526				 ARRAY_SIZE(n5x_main_perip_c_clks), clk_data);
    527
    528	agilex_clk_register_cnt_perip(agilex_main_perip_cnt_clks,
    529				   ARRAY_SIZE(agilex_main_perip_cnt_clks),
    530				   clk_data);
    531
    532	agilex_clk_register_gate(agilex_gate_clks, ARRAY_SIZE(agilex_gate_clks),
    533			      clk_data);
    534	of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data->clk_data);
    535	return 0;
    536}
    537
    538static int agilex_clkmgr_probe(struct platform_device *pdev)
    539{
    540	int (*probe_func)(struct platform_device *init_func);
    541
    542	probe_func = of_device_get_match_data(&pdev->dev);
    543	if (!probe_func)
    544		return -ENODEV;
    545	return	probe_func(pdev);
    546}
    547
    548static const struct of_device_id agilex_clkmgr_match_table[] = {
    549	{ .compatible = "intel,agilex-clkmgr",
    550	  .data = agilex_clkmgr_init },
    551	{ .compatible = "intel,easic-n5x-clkmgr",
    552	  .data = n5x_clkmgr_init },
    553	{ }
    554};
    555
    556static struct platform_driver agilex_clkmgr_driver = {
    557	.probe		= agilex_clkmgr_probe,
    558	.driver		= {
    559		.name	= "agilex-clkmgr",
    560		.suppress_bind_attrs = true,
    561		.of_match_table = agilex_clkmgr_match_table,
    562	},
    563};
    564
    565static int __init agilex_clk_init(void)
    566{
    567	return platform_driver_register(&agilex_clkmgr_driver);
    568}
    569core_initcall(agilex_clk_init);