162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2019, Intel Corporation
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci#include <linux/slab.h>
662306a36Sopenharmony_ci#include <linux/clk-provider.h>
762306a36Sopenharmony_ci#include <linux/of.h>
862306a36Sopenharmony_ci#include <linux/platform_device.h>
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <dt-bindings/clock/agilex-clock.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include "stratix10-clk.h"
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_cistatic const struct clk_parent_data pll_mux[] = {
1562306a36Sopenharmony_ci	{ .fw_name = "osc1",
1662306a36Sopenharmony_ci	  .name = "osc1", },
1762306a36Sopenharmony_ci	{ .fw_name = "cb-intosc-hs-div2-clk",
1862306a36Sopenharmony_ci	  .name = "cb-intosc-hs-div2-clk", },
1962306a36Sopenharmony_ci	{ .fw_name = "f2s-free-clk",
2062306a36Sopenharmony_ci	  .name = "f2s-free-clk", },
2162306a36Sopenharmony_ci};
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_cistatic const struct clk_parent_data boot_mux[] = {
2462306a36Sopenharmony_ci	{ .fw_name = "osc1",
2562306a36Sopenharmony_ci	  .name = "osc1", },
2662306a36Sopenharmony_ci	{ .fw_name = "cb-intosc-hs-div2-clk",
2762306a36Sopenharmony_ci	  .name = "cb-intosc-hs-div2-clk", },
2862306a36Sopenharmony_ci};
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_cistatic const struct clk_parent_data mpu_free_mux[] = {
3162306a36Sopenharmony_ci	{ .fw_name = "main_pll_c0",
3262306a36Sopenharmony_ci	  .name = "main_pll_c0", },
3362306a36Sopenharmony_ci	{ .fw_name = "peri_pll_c0",
3462306a36Sopenharmony_ci	  .name = "peri_pll_c0", },
3562306a36Sopenharmony_ci	{ .fw_name = "osc1",
3662306a36Sopenharmony_ci	  .name = "osc1", },
3762306a36Sopenharmony_ci	{ .fw_name = "cb-intosc-hs-div2-clk",
3862306a36Sopenharmony_ci	  .name = "cb-intosc-hs-div2-clk", },
3962306a36Sopenharmony_ci	{ .fw_name = "f2s-free-clk",
4062306a36Sopenharmony_ci	  .name = "f2s-free-clk", },
4162306a36Sopenharmony_ci};
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_cistatic const struct clk_parent_data noc_free_mux[] = {
4462306a36Sopenharmony_ci	{ .fw_name = "main_pll_c1",
4562306a36Sopenharmony_ci	  .name = "main_pll_c1", },
4662306a36Sopenharmony_ci	{ .fw_name = "peri_pll_c1",
4762306a36Sopenharmony_ci	  .name = "peri_pll_c1", },
4862306a36Sopenharmony_ci	{ .fw_name = "osc1",
4962306a36Sopenharmony_ci	  .name = "osc1", },
5062306a36Sopenharmony_ci	{ .fw_name = "cb-intosc-hs-div2-clk",
5162306a36Sopenharmony_ci	  .name = "cb-intosc-hs-div2-clk", },
5262306a36Sopenharmony_ci	{ .fw_name = "f2s-free-clk",
5362306a36Sopenharmony_ci	  .name = "f2s-free-clk", },
5462306a36Sopenharmony_ci};
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_cistatic const struct clk_parent_data emaca_free_mux[] = {
5762306a36Sopenharmony_ci	{ .fw_name = "main_pll_c2",
5862306a36Sopenharmony_ci	  .name = "main_pll_c2", },
5962306a36Sopenharmony_ci	{ .fw_name = "peri_pll_c2",
6062306a36Sopenharmony_ci	  .name = "peri_pll_c2", },
6162306a36Sopenharmony_ci	{ .fw_name = "osc1",
6262306a36Sopenharmony_ci	  .name = "osc1", },
6362306a36Sopenharmony_ci	{ .fw_name = "cb-intosc-hs-div2-clk",
6462306a36Sopenharmony_ci	  .name = "cb-intosc-hs-div2-clk", },
6562306a36Sopenharmony_ci	{ .fw_name = "f2s-free-clk",
6662306a36Sopenharmony_ci	  .name = "f2s-free-clk", },
6762306a36Sopenharmony_ci};
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_cistatic const struct clk_parent_data emacb_free_mux[] = {
7062306a36Sopenharmony_ci	{ .fw_name = "main_pll_c3",
7162306a36Sopenharmony_ci	  .name = "main_pll_c3", },
7262306a36Sopenharmony_ci	{ .fw_name = "peri_pll_c3",
7362306a36Sopenharmony_ci	  .name = "peri_pll_c3", },
7462306a36Sopenharmony_ci	{ .fw_name = "osc1",
7562306a36Sopenharmony_ci	  .name = "osc1", },
7662306a36Sopenharmony_ci	{ .fw_name = "cb-intosc-hs-div2-clk",
7762306a36Sopenharmony_ci	  .name = "cb-intosc-hs-div2-clk", },
7862306a36Sopenharmony_ci	{ .fw_name = "f2s-free-clk",
7962306a36Sopenharmony_ci	  .name = "f2s-free-clk", },
8062306a36Sopenharmony_ci};
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cistatic const struct clk_parent_data emac_ptp_free_mux[] = {
8362306a36Sopenharmony_ci	{ .fw_name = "main_pll_c3",
8462306a36Sopenharmony_ci	  .name = "main_pll_c3", },
8562306a36Sopenharmony_ci	{ .fw_name = "peri_pll_c3",
8662306a36Sopenharmony_ci	  .name = "peri_pll_c3", },
8762306a36Sopenharmony_ci	{ .fw_name = "osc1",
8862306a36Sopenharmony_ci	  .name = "osc1", },
8962306a36Sopenharmony_ci	{ .fw_name = "cb-intosc-hs-div2-clk",
9062306a36Sopenharmony_ci	  .name = "cb-intosc-hs-div2-clk", },
9162306a36Sopenharmony_ci	{ .fw_name = "f2s-free-clk",
9262306a36Sopenharmony_ci	  .name = "f2s-free-clk", },
9362306a36Sopenharmony_ci};
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_cistatic const struct clk_parent_data gpio_db_free_mux[] = {
9662306a36Sopenharmony_ci	{ .fw_name = "main_pll_c3",
9762306a36Sopenharmony_ci	  .name = "main_pll_c3", },
9862306a36Sopenharmony_ci	{ .fw_name = "peri_pll_c3",
9962306a36Sopenharmony_ci	  .name = "peri_pll_c3", },
10062306a36Sopenharmony_ci	{ .fw_name = "osc1",
10162306a36Sopenharmony_ci	  .name = "osc1", },
10262306a36Sopenharmony_ci	{ .fw_name = "cb-intosc-hs-div2-clk",
10362306a36Sopenharmony_ci	  .name = "cb-intosc-hs-div2-clk", },
10462306a36Sopenharmony_ci	{ .fw_name = "f2s-free-clk",
10562306a36Sopenharmony_ci	  .name = "f2s-free-clk", },
10662306a36Sopenharmony_ci};
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_cistatic const struct clk_parent_data psi_ref_free_mux[] = {
10962306a36Sopenharmony_ci	{ .fw_name = "main_pll_c2",
11062306a36Sopenharmony_ci	  .name = "main_pll_c2", },
11162306a36Sopenharmony_ci	{ .fw_name = "peri_pll_c2",
11262306a36Sopenharmony_ci	  .name = "peri_pll_c2", },
11362306a36Sopenharmony_ci	{ .fw_name = "osc1",
11462306a36Sopenharmony_ci	  .name = "osc1", },
11562306a36Sopenharmony_ci	{ .fw_name = "cb-intosc-hs-div2-clk",
11662306a36Sopenharmony_ci	  .name = "cb-intosc-hs-div2-clk", },
11762306a36Sopenharmony_ci	{ .fw_name = "f2s-free-clk",
11862306a36Sopenharmony_ci	  .name = "f2s-free-clk", },
11962306a36Sopenharmony_ci};
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_cistatic const struct clk_parent_data sdmmc_free_mux[] = {
12262306a36Sopenharmony_ci	{ .fw_name = "main_pll_c3",
12362306a36Sopenharmony_ci	  .name = "main_pll_c3", },
12462306a36Sopenharmony_ci	{ .fw_name = "peri_pll_c3",
12562306a36Sopenharmony_ci	  .name = "peri_pll_c3", },
12662306a36Sopenharmony_ci	{ .fw_name = "osc1",
12762306a36Sopenharmony_ci	  .name = "osc1", },
12862306a36Sopenharmony_ci	{ .fw_name = "cb-intosc-hs-div2-clk",
12962306a36Sopenharmony_ci	  .name = "cb-intosc-hs-div2-clk", },
13062306a36Sopenharmony_ci	{ .fw_name = "f2s-free-clk",
13162306a36Sopenharmony_ci	  .name = "f2s-free-clk", },
13262306a36Sopenharmony_ci};
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_cistatic const struct clk_parent_data s2f_usr0_free_mux[] = {
13562306a36Sopenharmony_ci	{ .fw_name = "main_pll_c2",
13662306a36Sopenharmony_ci	  .name = "main_pll_c2", },
13762306a36Sopenharmony_ci	{ .fw_name = "peri_pll_c2",
13862306a36Sopenharmony_ci	  .name = "peri_pll_c2", },
13962306a36Sopenharmony_ci	{ .fw_name = "osc1",
14062306a36Sopenharmony_ci	  .name = "osc1", },
14162306a36Sopenharmony_ci	{ .fw_name = "cb-intosc-hs-div2-clk",
14262306a36Sopenharmony_ci	  .name = "cb-intosc-hs-div2-clk", },
14362306a36Sopenharmony_ci	{ .fw_name = "f2s-free-clk",
14462306a36Sopenharmony_ci	  .name = "f2s-free-clk", },
14562306a36Sopenharmony_ci};
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_cistatic const struct clk_parent_data s2f_usr1_free_mux[] = {
14862306a36Sopenharmony_ci	{ .fw_name = "main_pll_c2",
14962306a36Sopenharmony_ci	  .name = "main_pll_c2", },
15062306a36Sopenharmony_ci	{ .fw_name = "peri_pll_c2",
15162306a36Sopenharmony_ci	  .name = "peri_pll_c2", },
15262306a36Sopenharmony_ci	{ .fw_name = "osc1",
15362306a36Sopenharmony_ci	  .name = "osc1", },
15462306a36Sopenharmony_ci	{ .fw_name = "cb-intosc-hs-div2-clk",
15562306a36Sopenharmony_ci	  .name = "cb-intosc-hs-div2-clk", },
15662306a36Sopenharmony_ci	{ .fw_name = "f2s-free-clk",
15762306a36Sopenharmony_ci	  .name = "f2s-free-clk", },
15862306a36Sopenharmony_ci};
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_cistatic const struct clk_parent_data mpu_mux[] = {
16162306a36Sopenharmony_ci	{ .fw_name = "mpu_free_clk",
16262306a36Sopenharmony_ci	  .name = "mpu_free_clk", },
16362306a36Sopenharmony_ci	{ .fw_name = "boot_clk",
16462306a36Sopenharmony_ci	  .name = "boot_clk", },
16562306a36Sopenharmony_ci};
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_cistatic const struct clk_parent_data emac_mux[] = {
16862306a36Sopenharmony_ci	{ .fw_name = "emaca_free_clk",
16962306a36Sopenharmony_ci	  .name = "emaca_free_clk", },
17062306a36Sopenharmony_ci	{ .fw_name = "emacb_free_clk",
17162306a36Sopenharmony_ci	  .name = "emacb_free_clk", },
17262306a36Sopenharmony_ci	{ .fw_name = "boot_clk",
17362306a36Sopenharmony_ci	  .name = "boot_clk", },
17462306a36Sopenharmony_ci};
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_cistatic const struct clk_parent_data noc_mux[] = {
17762306a36Sopenharmony_ci	{ .fw_name = "noc_free_clk",
17862306a36Sopenharmony_ci	  .name = "noc_free_clk", },
17962306a36Sopenharmony_ci	{ .fw_name = "boot_clk",
18062306a36Sopenharmony_ci	  .name = "boot_clk", },
18162306a36Sopenharmony_ci};
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_cistatic const struct clk_parent_data sdmmc_mux[] = {
18462306a36Sopenharmony_ci	{ .fw_name = "sdmmc_free_clk",
18562306a36Sopenharmony_ci	  .name = "sdmmc_free_clk", },
18662306a36Sopenharmony_ci	{ .fw_name = "boot_clk",
18762306a36Sopenharmony_ci	  .name = "boot_clk", },
18862306a36Sopenharmony_ci};
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_cistatic const struct clk_parent_data s2f_user0_mux[] = {
19162306a36Sopenharmony_ci	{ .fw_name = "s2f_user0_free_clk",
19262306a36Sopenharmony_ci	  .name = "s2f_user0_free_clk", },
19362306a36Sopenharmony_ci	{ .fw_name = "boot_clk",
19462306a36Sopenharmony_ci	  .name = "boot_clk", },
19562306a36Sopenharmony_ci};
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_cistatic const struct clk_parent_data s2f_user1_mux[] = {
19862306a36Sopenharmony_ci	{ .fw_name = "s2f_user1_free_clk",
19962306a36Sopenharmony_ci	  .name = "s2f_user1_free_clk", },
20062306a36Sopenharmony_ci	{ .fw_name = "boot_clk",
20162306a36Sopenharmony_ci	  .name = "boot_clk", },
20262306a36Sopenharmony_ci};
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_cistatic const struct clk_parent_data psi_mux[] = {
20562306a36Sopenharmony_ci	{ .fw_name = "psi_ref_free_clk",
20662306a36Sopenharmony_ci	  .name = "psi_ref_free_clk", },
20762306a36Sopenharmony_ci	{ .fw_name = "boot_clk",
20862306a36Sopenharmony_ci	  .name = "boot_clk", },
20962306a36Sopenharmony_ci};
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_cistatic const struct clk_parent_data gpio_db_mux[] = {
21262306a36Sopenharmony_ci	{ .fw_name = "gpio_db_free_clk",
21362306a36Sopenharmony_ci	  .name = "gpio_db_free_clk", },
21462306a36Sopenharmony_ci	{ .fw_name = "boot_clk",
21562306a36Sopenharmony_ci	  .name = "boot_clk", },
21662306a36Sopenharmony_ci};
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_cistatic const struct clk_parent_data emac_ptp_mux[] = {
21962306a36Sopenharmony_ci	{ .fw_name = "emac_ptp_free_clk",
22062306a36Sopenharmony_ci	  .name = "emac_ptp_free_clk", },
22162306a36Sopenharmony_ci	{ .fw_name = "boot_clk",
22262306a36Sopenharmony_ci	  .name = "boot_clk", },
22362306a36Sopenharmony_ci};
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci/* clocks in AO (always on) controller */
22662306a36Sopenharmony_cistatic const struct stratix10_pll_clock agilex_pll_clks[] = {
22762306a36Sopenharmony_ci	{ AGILEX_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0,
22862306a36Sopenharmony_ci	  0x0},
22962306a36Sopenharmony_ci	{ AGILEX_MAIN_PLL_CLK, "main_pll", pll_mux, ARRAY_SIZE(pll_mux),
23062306a36Sopenharmony_ci	  0, 0x48},
23162306a36Sopenharmony_ci	{ AGILEX_PERIPH_PLL_CLK, "periph_pll", pll_mux, ARRAY_SIZE(pll_mux),
23262306a36Sopenharmony_ci	  0, 0x9c},
23362306a36Sopenharmony_ci};
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_cistatic const struct n5x_perip_c_clock n5x_main_perip_c_clks[] = {
23662306a36Sopenharmony_ci	{ AGILEX_MAIN_PLL_C0_CLK, "main_pll_c0", "main_pll", NULL, 1, 0, 0x54, 0},
23762306a36Sopenharmony_ci	{ AGILEX_MAIN_PLL_C1_CLK, "main_pll_c1", "main_pll", NULL, 1, 0, 0x54, 8},
23862306a36Sopenharmony_ci	{ AGILEX_MAIN_PLL_C2_CLK, "main_pll_c2", "main_pll", NULL, 1, 0, 0x54, 16},
23962306a36Sopenharmony_ci	{ AGILEX_MAIN_PLL_C3_CLK, "main_pll_c3", "main_pll", NULL, 1, 0, 0x54, 24},
24062306a36Sopenharmony_ci	{ AGILEX_PERIPH_PLL_C0_CLK, "peri_pll_c0", "periph_pll", NULL, 1, 0, 0xA8, 0},
24162306a36Sopenharmony_ci	{ AGILEX_PERIPH_PLL_C1_CLK, "peri_pll_c1", "periph_pll", NULL, 1, 0, 0xA8, 8},
24262306a36Sopenharmony_ci	{ AGILEX_PERIPH_PLL_C2_CLK, "peri_pll_c2", "periph_pll", NULL, 1, 0, 0xA8, 16},
24362306a36Sopenharmony_ci	{ AGILEX_PERIPH_PLL_C3_CLK, "peri_pll_c3", "periph_pll", NULL, 1, 0, 0xA8, 24},
24462306a36Sopenharmony_ci};
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_cistatic const struct stratix10_perip_c_clock agilex_main_perip_c_clks[] = {
24762306a36Sopenharmony_ci	{ AGILEX_MAIN_PLL_C0_CLK, "main_pll_c0", "main_pll", NULL, 1, 0, 0x58},
24862306a36Sopenharmony_ci	{ AGILEX_MAIN_PLL_C1_CLK, "main_pll_c1", "main_pll", NULL, 1, 0, 0x5C},
24962306a36Sopenharmony_ci	{ AGILEX_MAIN_PLL_C2_CLK, "main_pll_c2", "main_pll", NULL, 1, 0, 0x64},
25062306a36Sopenharmony_ci	{ AGILEX_MAIN_PLL_C3_CLK, "main_pll_c3", "main_pll", NULL, 1, 0, 0x68},
25162306a36Sopenharmony_ci	{ AGILEX_PERIPH_PLL_C0_CLK, "peri_pll_c0", "periph_pll", NULL, 1, 0, 0xAC},
25262306a36Sopenharmony_ci	{ AGILEX_PERIPH_PLL_C1_CLK, "peri_pll_c1", "periph_pll", NULL, 1, 0, 0xB0},
25362306a36Sopenharmony_ci	{ AGILEX_PERIPH_PLL_C2_CLK, "peri_pll_c2", "periph_pll", NULL, 1, 0, 0xB8},
25462306a36Sopenharmony_ci	{ AGILEX_PERIPH_PLL_C3_CLK, "peri_pll_c3", "periph_pll", NULL, 1, 0, 0xBC},
25562306a36Sopenharmony_ci};
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_cistatic const struct stratix10_perip_cnt_clock agilex_main_perip_cnt_clks[] = {
25862306a36Sopenharmony_ci	{ AGILEX_MPU_FREE_CLK, "mpu_free_clk", NULL, mpu_free_mux, ARRAY_SIZE(mpu_free_mux),
25962306a36Sopenharmony_ci	   0, 0x3C, 0, 0, 0},
26062306a36Sopenharmony_ci	{ AGILEX_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux),
26162306a36Sopenharmony_ci	  0, 0x40, 0, 0, 0},
26262306a36Sopenharmony_ci	{ AGILEX_L4_SYS_FREE_CLK, "l4_sys_free_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0,
26362306a36Sopenharmony_ci	  0, 4, 0x30, 1},
26462306a36Sopenharmony_ci	{ AGILEX_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux),
26562306a36Sopenharmony_ci	  0, 0xD4, 0, 0x88, 0},
26662306a36Sopenharmony_ci	{ AGILEX_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux),
26762306a36Sopenharmony_ci	  0, 0xD8, 0, 0x88, 1},
26862306a36Sopenharmony_ci	{ AGILEX_EMAC_PTP_FREE_CLK, "emac_ptp_free_clk", NULL, emac_ptp_free_mux,
26962306a36Sopenharmony_ci	  ARRAY_SIZE(emac_ptp_free_mux), 0, 0xDC, 0, 0x88, 2},
27062306a36Sopenharmony_ci	{ AGILEX_GPIO_DB_FREE_CLK, "gpio_db_free_clk", NULL, gpio_db_free_mux,
27162306a36Sopenharmony_ci	  ARRAY_SIZE(gpio_db_free_mux), 0, 0xE0, 0, 0x88, 3},
27262306a36Sopenharmony_ci	{ AGILEX_SDMMC_FREE_CLK, "sdmmc_free_clk", NULL, sdmmc_free_mux,
27362306a36Sopenharmony_ci	  ARRAY_SIZE(sdmmc_free_mux), 0, 0xE4, 0, 0, 0},
27462306a36Sopenharmony_ci	{ AGILEX_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", NULL, s2f_usr0_free_mux,
27562306a36Sopenharmony_ci	  ARRAY_SIZE(s2f_usr0_free_mux), 0, 0xE8, 0, 0x30, 2},
27662306a36Sopenharmony_ci	{ AGILEX_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", NULL, s2f_usr1_free_mux,
27762306a36Sopenharmony_ci	  ARRAY_SIZE(s2f_usr1_free_mux), 0, 0xEC, 0, 0x88, 5},
27862306a36Sopenharmony_ci	{ AGILEX_PSI_REF_FREE_CLK, "psi_ref_free_clk", NULL, psi_ref_free_mux,
27962306a36Sopenharmony_ci	  ARRAY_SIZE(psi_ref_free_mux), 0, 0xF0, 0, 0x88, 6},
28062306a36Sopenharmony_ci};
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_cistatic const struct stratix10_gate_clock agilex_gate_clks[] = {
28362306a36Sopenharmony_ci	{ AGILEX_MPU_CLK, "mpu_clk", NULL, mpu_mux, ARRAY_SIZE(mpu_mux), 0, 0x24,
28462306a36Sopenharmony_ci	  0, 0, 0, 0, 0x30, 0, 0},
28562306a36Sopenharmony_ci	{ AGILEX_MPU_PERIPH_CLK, "mpu_periph_clk", "mpu_clk", NULL, 1, 0, 0x24,
28662306a36Sopenharmony_ci	  0, 0, 0, 0, 0, 0, 4},
28762306a36Sopenharmony_ci	{ AGILEX_MPU_CCU_CLK, "mpu_ccu_clk", "mpu_clk", NULL, 1, 0, 0x24,
28862306a36Sopenharmony_ci	  0, 0, 0, 0, 0, 0, 2},
28962306a36Sopenharmony_ci	{ AGILEX_L4_MAIN_CLK, "l4_main_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
29062306a36Sopenharmony_ci	  1, 0x44, 0, 2, 0x30, 1, 0},
29162306a36Sopenharmony_ci	{ AGILEX_L4_MP_CLK, "l4_mp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
29262306a36Sopenharmony_ci	  2, 0x44, 8, 2, 0x30, 1, 0},
29362306a36Sopenharmony_ci	/*
29462306a36Sopenharmony_ci	 * The l4_sp_clk feeds a 100 MHz clock to various peripherals, one of them
29562306a36Sopenharmony_ci	 * being the SP timers, thus cannot get gated.
29662306a36Sopenharmony_ci	 */
29762306a36Sopenharmony_ci	{ AGILEX_L4_SP_CLK, "l4_sp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), CLK_IS_CRITICAL, 0x24,
29862306a36Sopenharmony_ci	  3, 0x44, 16, 2, 0x30, 1, 0},
29962306a36Sopenharmony_ci	{ AGILEX_CS_AT_CLK, "cs_at_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
30062306a36Sopenharmony_ci	  4, 0x44, 24, 2, 0x30, 1, 0},
30162306a36Sopenharmony_ci	{ AGILEX_CS_TRACE_CLK, "cs_trace_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
30262306a36Sopenharmony_ci	  4, 0x44, 26, 2, 0x30, 1, 0},
30362306a36Sopenharmony_ci	{ AGILEX_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x24,
30462306a36Sopenharmony_ci	  4, 0x44, 28, 1, 0, 0, 0},
30562306a36Sopenharmony_ci	{ AGILEX_CS_TIMER_CLK, "cs_timer_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
30662306a36Sopenharmony_ci	  5, 0, 0, 0, 0x30, 1, 0},
30762306a36Sopenharmony_ci	{ AGILEX_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
30862306a36Sopenharmony_ci	  0, 0, 0, 0, 0x94, 26, 0},
30962306a36Sopenharmony_ci	{ AGILEX_EMAC1_CLK, "emac1_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
31062306a36Sopenharmony_ci	  1, 0, 0, 0, 0x94, 27, 0},
31162306a36Sopenharmony_ci	{ AGILEX_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
31262306a36Sopenharmony_ci	  2, 0, 0, 0, 0x94, 28, 0},
31362306a36Sopenharmony_ci	{ AGILEX_EMAC_PTP_CLK, "emac_ptp_clk", NULL, emac_ptp_mux, ARRAY_SIZE(emac_ptp_mux), 0, 0x7C,
31462306a36Sopenharmony_ci	  3, 0, 0, 0, 0x88, 2, 0},
31562306a36Sopenharmony_ci	{ AGILEX_GPIO_DB_CLK, "gpio_db_clk", NULL, gpio_db_mux, ARRAY_SIZE(gpio_db_mux), 0, 0x7C,
31662306a36Sopenharmony_ci	  4, 0x98, 0, 16, 0x88, 3, 0},
31762306a36Sopenharmony_ci	{ AGILEX_SDMMC_CLK, "sdmmc_clk", NULL, sdmmc_mux, ARRAY_SIZE(sdmmc_mux), 0, 0x7C,
31862306a36Sopenharmony_ci	  5, 0, 0, 0, 0x88, 4, 4},
31962306a36Sopenharmony_ci	{ AGILEX_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_user0_mux, ARRAY_SIZE(s2f_user0_mux), 0, 0x24,
32062306a36Sopenharmony_ci	  6, 0, 0, 0, 0x30, 2, 0},
32162306a36Sopenharmony_ci	{ AGILEX_S2F_USER1_CLK, "s2f_user1_clk", NULL, s2f_user1_mux, ARRAY_SIZE(s2f_user1_mux), 0, 0x7C,
32262306a36Sopenharmony_ci	  6, 0, 0, 0, 0x88, 5, 0},
32362306a36Sopenharmony_ci	{ AGILEX_PSI_REF_CLK, "psi_ref_clk", NULL, psi_mux, ARRAY_SIZE(psi_mux), 0, 0x7C,
32462306a36Sopenharmony_ci	  7, 0, 0, 0, 0x88, 6, 0},
32562306a36Sopenharmony_ci	{ AGILEX_USB_CLK, "usb_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
32662306a36Sopenharmony_ci	  8, 0, 0, 0, 0, 0, 0},
32762306a36Sopenharmony_ci	{ AGILEX_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
32862306a36Sopenharmony_ci	  9, 0, 0, 0, 0, 0, 0},
32962306a36Sopenharmony_ci	{ AGILEX_NAND_X_CLK, "nand_x_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
33062306a36Sopenharmony_ci	  10, 0, 0, 0, 0, 0, 0},
33162306a36Sopenharmony_ci	{ AGILEX_NAND_CLK, "nand_clk", "nand_x_clk", NULL, 1, 0, 0x7C,
33262306a36Sopenharmony_ci	  10, 0, 0, 0, 0, 0, 4},
33362306a36Sopenharmony_ci	{ AGILEX_NAND_ECC_CLK, "nand_ecc_clk", "nand_x_clk", NULL, 1, 0, 0x7C,
33462306a36Sopenharmony_ci	  10, 0, 0, 0, 0, 0, 4},
33562306a36Sopenharmony_ci};
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_cistatic int n5x_clk_register_c_perip(const struct n5x_perip_c_clock *clks,
33862306a36Sopenharmony_ci				       int nums, struct stratix10_clock_data *data)
33962306a36Sopenharmony_ci{
34062306a36Sopenharmony_ci	struct clk_hw *hw_clk;
34162306a36Sopenharmony_ci	void __iomem *base = data->base;
34262306a36Sopenharmony_ci	int i;
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ci	for (i = 0; i < nums; i++) {
34562306a36Sopenharmony_ci		hw_clk = n5x_register_periph(&clks[i], base);
34662306a36Sopenharmony_ci		if (IS_ERR(hw_clk)) {
34762306a36Sopenharmony_ci			pr_err("%s: failed to register clock %s\n",
34862306a36Sopenharmony_ci			       __func__, clks[i].name);
34962306a36Sopenharmony_ci			continue;
35062306a36Sopenharmony_ci		}
35162306a36Sopenharmony_ci		data->clk_data.hws[clks[i].id] = hw_clk;
35262306a36Sopenharmony_ci	}
35362306a36Sopenharmony_ci	return 0;
35462306a36Sopenharmony_ci}
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_cistatic int agilex_clk_register_c_perip(const struct stratix10_perip_c_clock *clks,
35762306a36Sopenharmony_ci				       int nums, struct stratix10_clock_data *data)
35862306a36Sopenharmony_ci{
35962306a36Sopenharmony_ci	struct clk_hw *hw_clk;
36062306a36Sopenharmony_ci	void __iomem *base = data->base;
36162306a36Sopenharmony_ci	int i;
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci	for (i = 0; i < nums; i++) {
36462306a36Sopenharmony_ci		hw_clk = s10_register_periph(&clks[i], base);
36562306a36Sopenharmony_ci		if (IS_ERR(hw_clk)) {
36662306a36Sopenharmony_ci			pr_err("%s: failed to register clock %s\n",
36762306a36Sopenharmony_ci			       __func__, clks[i].name);
36862306a36Sopenharmony_ci			continue;
36962306a36Sopenharmony_ci		}
37062306a36Sopenharmony_ci		data->clk_data.hws[clks[i].id] = hw_clk;
37162306a36Sopenharmony_ci	}
37262306a36Sopenharmony_ci	return 0;
37362306a36Sopenharmony_ci}
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_cistatic int agilex_clk_register_cnt_perip(const struct stratix10_perip_cnt_clock *clks,
37662306a36Sopenharmony_ci					 int nums, struct stratix10_clock_data *data)
37762306a36Sopenharmony_ci{
37862306a36Sopenharmony_ci	struct clk_hw *hw_clk;
37962306a36Sopenharmony_ci	void __iomem *base = data->base;
38062306a36Sopenharmony_ci	int i;
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_ci	for (i = 0; i < nums; i++) {
38362306a36Sopenharmony_ci		hw_clk = s10_register_cnt_periph(&clks[i], base);
38462306a36Sopenharmony_ci		if (IS_ERR(hw_clk)) {
38562306a36Sopenharmony_ci			pr_err("%s: failed to register clock %s\n",
38662306a36Sopenharmony_ci			       __func__, clks[i].name);
38762306a36Sopenharmony_ci			continue;
38862306a36Sopenharmony_ci		}
38962306a36Sopenharmony_ci		data->clk_data.hws[clks[i].id] = hw_clk;
39062306a36Sopenharmony_ci	}
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci	return 0;
39362306a36Sopenharmony_ci}
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_cistatic int agilex_clk_register_gate(const struct stratix10_gate_clock *clks,
39662306a36Sopenharmony_ci				    int nums, struct stratix10_clock_data *data)
39762306a36Sopenharmony_ci{
39862306a36Sopenharmony_ci	struct clk_hw *hw_clk;
39962306a36Sopenharmony_ci	void __iomem *base = data->base;
40062306a36Sopenharmony_ci	int i;
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_ci	for (i = 0; i < nums; i++) {
40362306a36Sopenharmony_ci		hw_clk = agilex_register_gate(&clks[i], base);
40462306a36Sopenharmony_ci		if (IS_ERR(hw_clk)) {
40562306a36Sopenharmony_ci			pr_err("%s: failed to register clock %s\n",
40662306a36Sopenharmony_ci			       __func__, clks[i].name);
40762306a36Sopenharmony_ci			continue;
40862306a36Sopenharmony_ci		}
40962306a36Sopenharmony_ci		data->clk_data.hws[clks[i].id] = hw_clk;
41062306a36Sopenharmony_ci	}
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci	return 0;
41362306a36Sopenharmony_ci}
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_cistatic int agilex_clk_register_pll(const struct stratix10_pll_clock *clks,
41662306a36Sopenharmony_ci				 int nums, struct stratix10_clock_data *data)
41762306a36Sopenharmony_ci{
41862306a36Sopenharmony_ci	struct clk_hw *hw_clk;
41962306a36Sopenharmony_ci	void __iomem *base = data->base;
42062306a36Sopenharmony_ci	int i;
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci	for (i = 0; i < nums; i++) {
42362306a36Sopenharmony_ci		hw_clk = agilex_register_pll(&clks[i], base);
42462306a36Sopenharmony_ci		if (IS_ERR(hw_clk)) {
42562306a36Sopenharmony_ci			pr_err("%s: failed to register clock %s\n",
42662306a36Sopenharmony_ci			       __func__, clks[i].name);
42762306a36Sopenharmony_ci			continue;
42862306a36Sopenharmony_ci		}
42962306a36Sopenharmony_ci		data->clk_data.hws[clks[i].id] = hw_clk;
43062306a36Sopenharmony_ci	}
43162306a36Sopenharmony_ci
43262306a36Sopenharmony_ci	return 0;
43362306a36Sopenharmony_ci}
43462306a36Sopenharmony_ci
43562306a36Sopenharmony_cistatic int n5x_clk_register_pll(const struct stratix10_pll_clock *clks,
43662306a36Sopenharmony_ci				 int nums, struct stratix10_clock_data *data)
43762306a36Sopenharmony_ci{
43862306a36Sopenharmony_ci	struct clk_hw *hw_clk;
43962306a36Sopenharmony_ci	void __iomem *base = data->base;
44062306a36Sopenharmony_ci	int i;
44162306a36Sopenharmony_ci
44262306a36Sopenharmony_ci	for (i = 0; i < nums; i++) {
44362306a36Sopenharmony_ci		hw_clk = n5x_register_pll(&clks[i], base);
44462306a36Sopenharmony_ci		if (IS_ERR(hw_clk)) {
44562306a36Sopenharmony_ci			pr_err("%s: failed to register clock %s\n",
44662306a36Sopenharmony_ci			       __func__, clks[i].name);
44762306a36Sopenharmony_ci			continue;
44862306a36Sopenharmony_ci		}
44962306a36Sopenharmony_ci		data->clk_data.hws[clks[i].id] = hw_clk;
45062306a36Sopenharmony_ci	}
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_ci	return 0;
45362306a36Sopenharmony_ci}
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_cistatic int agilex_clkmgr_init(struct platform_device *pdev)
45662306a36Sopenharmony_ci{
45762306a36Sopenharmony_ci	struct device_node *np = pdev->dev.of_node;
45862306a36Sopenharmony_ci	struct device *dev = &pdev->dev;
45962306a36Sopenharmony_ci	struct stratix10_clock_data *clk_data;
46062306a36Sopenharmony_ci	void __iomem *base;
46162306a36Sopenharmony_ci	int i, num_clks;
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_ci	base = devm_platform_ioremap_resource(pdev, 0);
46462306a36Sopenharmony_ci	if (IS_ERR(base))
46562306a36Sopenharmony_ci		return PTR_ERR(base);
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci	num_clks = AGILEX_NUM_CLKS;
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci	clk_data = devm_kzalloc(dev, struct_size(clk_data, clk_data.hws,
47062306a36Sopenharmony_ci				num_clks), GFP_KERNEL);
47162306a36Sopenharmony_ci	if (!clk_data)
47262306a36Sopenharmony_ci		return -ENOMEM;
47362306a36Sopenharmony_ci
47462306a36Sopenharmony_ci	for (i = 0; i < num_clks; i++)
47562306a36Sopenharmony_ci		clk_data->clk_data.hws[i] = ERR_PTR(-ENOENT);
47662306a36Sopenharmony_ci
47762306a36Sopenharmony_ci	clk_data->base = base;
47862306a36Sopenharmony_ci	clk_data->clk_data.num = num_clks;
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_ci	agilex_clk_register_pll(agilex_pll_clks, ARRAY_SIZE(agilex_pll_clks), clk_data);
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci	agilex_clk_register_c_perip(agilex_main_perip_c_clks,
48362306a36Sopenharmony_ci				 ARRAY_SIZE(agilex_main_perip_c_clks), clk_data);
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci	agilex_clk_register_cnt_perip(agilex_main_perip_cnt_clks,
48662306a36Sopenharmony_ci				   ARRAY_SIZE(agilex_main_perip_cnt_clks),
48762306a36Sopenharmony_ci				   clk_data);
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci	agilex_clk_register_gate(agilex_gate_clks, ARRAY_SIZE(agilex_gate_clks),
49062306a36Sopenharmony_ci			      clk_data);
49162306a36Sopenharmony_ci	of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data->clk_data);
49262306a36Sopenharmony_ci	return 0;
49362306a36Sopenharmony_ci}
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_cistatic int n5x_clkmgr_init(struct platform_device *pdev)
49662306a36Sopenharmony_ci{
49762306a36Sopenharmony_ci	struct device_node *np = pdev->dev.of_node;
49862306a36Sopenharmony_ci	struct device *dev = &pdev->dev;
49962306a36Sopenharmony_ci	struct stratix10_clock_data *clk_data;
50062306a36Sopenharmony_ci	void __iomem *base;
50162306a36Sopenharmony_ci	int i, num_clks;
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_ci	base = devm_platform_ioremap_resource(pdev, 0);
50462306a36Sopenharmony_ci	if (IS_ERR(base))
50562306a36Sopenharmony_ci		return PTR_ERR(base);
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci	num_clks = AGILEX_NUM_CLKS;
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci	clk_data = devm_kzalloc(dev, struct_size(clk_data, clk_data.hws,
51062306a36Sopenharmony_ci				num_clks), GFP_KERNEL);
51162306a36Sopenharmony_ci	if (!clk_data)
51262306a36Sopenharmony_ci		return -ENOMEM;
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_ci	for (i = 0; i < num_clks; i++)
51562306a36Sopenharmony_ci		clk_data->clk_data.hws[i] = ERR_PTR(-ENOENT);
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci	clk_data->base = base;
51862306a36Sopenharmony_ci	clk_data->clk_data.num = num_clks;
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci	n5x_clk_register_pll(agilex_pll_clks, ARRAY_SIZE(agilex_pll_clks), clk_data);
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_ci	n5x_clk_register_c_perip(n5x_main_perip_c_clks,
52362306a36Sopenharmony_ci				 ARRAY_SIZE(n5x_main_perip_c_clks), clk_data);
52462306a36Sopenharmony_ci
52562306a36Sopenharmony_ci	agilex_clk_register_cnt_perip(agilex_main_perip_cnt_clks,
52662306a36Sopenharmony_ci				   ARRAY_SIZE(agilex_main_perip_cnt_clks),
52762306a36Sopenharmony_ci				   clk_data);
52862306a36Sopenharmony_ci
52962306a36Sopenharmony_ci	agilex_clk_register_gate(agilex_gate_clks, ARRAY_SIZE(agilex_gate_clks),
53062306a36Sopenharmony_ci			      clk_data);
53162306a36Sopenharmony_ci	of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data->clk_data);
53262306a36Sopenharmony_ci	return 0;
53362306a36Sopenharmony_ci}
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_cistatic int agilex_clkmgr_probe(struct platform_device *pdev)
53662306a36Sopenharmony_ci{
53762306a36Sopenharmony_ci	int (*probe_func)(struct platform_device *init_func);
53862306a36Sopenharmony_ci
53962306a36Sopenharmony_ci	probe_func = of_device_get_match_data(&pdev->dev);
54062306a36Sopenharmony_ci	if (!probe_func)
54162306a36Sopenharmony_ci		return -ENODEV;
54262306a36Sopenharmony_ci	return	probe_func(pdev);
54362306a36Sopenharmony_ci}
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_cistatic const struct of_device_id agilex_clkmgr_match_table[] = {
54662306a36Sopenharmony_ci	{ .compatible = "intel,agilex-clkmgr",
54762306a36Sopenharmony_ci	  .data = agilex_clkmgr_init },
54862306a36Sopenharmony_ci	{ .compatible = "intel,easic-n5x-clkmgr",
54962306a36Sopenharmony_ci	  .data = n5x_clkmgr_init },
55062306a36Sopenharmony_ci	{ }
55162306a36Sopenharmony_ci};
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_cistatic struct platform_driver agilex_clkmgr_driver = {
55462306a36Sopenharmony_ci	.probe		= agilex_clkmgr_probe,
55562306a36Sopenharmony_ci	.driver		= {
55662306a36Sopenharmony_ci		.name	= "agilex-clkmgr",
55762306a36Sopenharmony_ci		.suppress_bind_attrs = true,
55862306a36Sopenharmony_ci		.of_match_table = agilex_clkmgr_match_table,
55962306a36Sopenharmony_ci	},
56062306a36Sopenharmony_ci};
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_cistatic int __init agilex_clk_init(void)
56362306a36Sopenharmony_ci{
56462306a36Sopenharmony_ci	return platform_driver_register(&agilex_clkmgr_driver);
56562306a36Sopenharmony_ci}
56662306a36Sopenharmony_cicore_initcall(agilex_clk_init);
567