clk: socfpga: agilex5: add clock driver for Agilex5

Add the new Clock manager driver to support new Agilex5 platform. The new
driver got rid of the clk_parent_data structures as there are no 'clock-names'
property in the DT bindings and use parent_names internally. This is based on
the previous feedback from the maintainer.

Signed-off-by: Ang Tien Sung <tiensung.ang@altera.com>
Signed-off-by: Khairul Anuar Romli <khairul.anuar.romli@altera.com>
Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
This commit is contained in:
Khairul Anuar Romli
2025-10-22 22:52:58 -05:00
committed by Dinh Nguyen
parent 3a86608788
commit 2050b57ecd
7 changed files with 736 additions and 2 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ config CLK_INTEL_SOCFPGA32
default ARM && ARCH_INTEL_SOCFPGA
config CLK_INTEL_SOCFPGA64
bool "Intel Stratix / Agilex / N5X clock controller support" if COMPILE_TEST && (!ARM64 || !ARCH_INTEL_SOCFPGA)
bool "Intel Stratix / Agilex / N5X / Agilex5 clock controller support" if COMPILE_TEST && (!ARM64 || !ARCH_INTEL_SOCFPGA)
default ARM64 && ARCH_INTEL_SOCFPGA
endif # CLK_INTEL_SOCFPGA
+1 -1
View File
@@ -3,4 +3,4 @@ obj-$(CONFIG_CLK_INTEL_SOCFPGA32) += clk.o clk-gate.o clk-pll.o clk-periph.o \
clk-pll-a10.o clk-periph-a10.o clk-gate-a10.o
obj-$(CONFIG_CLK_INTEL_SOCFPGA64) += clk-s10.o \
clk-pll-s10.o clk-periph-s10.o clk-gate-s10.o \
clk-agilex.o
clk-agilex.o clk-agilex5.o
File diff suppressed because it is too large Load Diff
+53
View File
@@ -239,3 +239,56 @@ struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks, voi
}
return hw_clk;
}
struct clk_hw *agilex5_register_gate(const struct agilex5_gate_clock *clks, void __iomem *regbase)
{
struct clk_hw *hw_clk;
struct socfpga_gate_clk *socfpga_clk;
struct clk_init_data init;
int ret;
socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
if (!socfpga_clk)
return NULL;
socfpga_clk->hw.reg = regbase + clks->gate_reg;
socfpga_clk->hw.bit_idx = clks->gate_idx;
gateclk_ops.enable = clk_gate_ops.enable;
gateclk_ops.disable = clk_gate_ops.disable;
socfpga_clk->fixed_div = clks->fixed_div;
if (clks->div_reg)
socfpga_clk->div_reg = regbase + clks->div_reg;
else
socfpga_clk->div_reg = NULL;
socfpga_clk->width = clks->div_width;
socfpga_clk->shift = clks->div_offset;
if (clks->bypass_reg)
socfpga_clk->bypass_reg = regbase + clks->bypass_reg;
else
socfpga_clk->bypass_reg = NULL;
socfpga_clk->bypass_shift = clks->bypass_shift;
if (streq(clks->name, "cs_pdbg_clk"))
init.ops = &dbgclk_ops;
else
init.ops = &agilex_gateclk_ops;
init.name = clks->name;
init.flags = clks->flags;
init.num_parents = clks->num_parents;
init.parent_names = clks->parent_names;
socfpga_clk->hw.hw.init = &init;
hw_clk = &socfpga_clk->hw.hw;
ret = clk_hw_register(NULL, &socfpga_clk->hw.hw);
if (ret) {
kfree(socfpga_clk);
return ERR_PTR(ret);
}
return hw_clk;
}
+41
View File
@@ -214,3 +214,44 @@ struct clk_hw *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *c
}
return hw_clk;
}
struct clk_hw *agilex5_register_cnt_periph(const struct agilex5_perip_cnt_clock *clks,
void __iomem *regbase)
{
struct clk_hw *hw_clk;
struct socfpga_periph_clk *periph_clk;
struct clk_init_data init;
const char *name = clks->name;
int ret;
periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL);
if (WARN_ON(!periph_clk))
return NULL;
if (clks->offset)
periph_clk->hw.reg = regbase + clks->offset;
else
periph_clk->hw.reg = NULL;
if (clks->bypass_reg)
periph_clk->bypass_reg = regbase + clks->bypass_reg;
else
periph_clk->bypass_reg = NULL;
periph_clk->bypass_shift = clks->bypass_shift;
periph_clk->fixed_div = clks->fixed_divider;
init.name = name;
init.ops = &peri_cnt_clk_ops;
init.flags = clks->flags;
init.num_parents = clks->num_parents;
init.parent_names = clks->parent_names;
periph_clk->hw.hw.init = &init;
hw_clk = &periph_clk->hw.hw;
ret = clk_hw_register(NULL, hw_clk);
if (ret) {
kfree(periph_clk);
return ERR_PTR(ret);
}
return hw_clk;
}
+36
View File
@@ -304,3 +304,39 @@ struct clk_hw *n5x_register_pll(const struct stratix10_pll_clock *clks,
}
return hw_clk;
}
struct clk_hw *agilex5_register_pll(const struct agilex5_pll_clock *clks,
void __iomem *reg)
{
struct clk_hw *hw_clk;
struct socfpga_pll *pll_clk;
struct clk_init_data init;
const char *name = clks->name;
int ret;
pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);
if (WARN_ON(!pll_clk))
return NULL;
pll_clk->hw.reg = reg + clks->offset;
if (streq(name, SOCFPGA_BOOT_CLK))
init.ops = &clk_boot_ops;
else
init.ops = &agilex_clk_pll_ops;
init.name = name;
init.flags = clks->flags;
init.num_parents = clks->num_parents;
init.parent_names = clks->parent_names;
pll_clk->hw.hw.init = &init;
pll_clk->hw.bit_idx = SOCFPGA_PLL_POWER;
hw_clk = &pll_clk->hw.hw;
ret = clk_hw_register(NULL, hw_clk);
if (ret) {
kfree(pll_clk);
return ERR_PTR(ret);
}
return hw_clk;
}
+43
View File
@@ -73,12 +73,55 @@ struct stratix10_gate_clock {
u8 fixed_div;
};
struct agilex5_pll_clock {
unsigned int id;
const char *name;
const char * const *parent_names;
u8 num_parents;
unsigned long flags;
unsigned long offset;
};
struct agilex5_perip_cnt_clock {
unsigned int id;
const char *name;
const char * const *parent_names;
u8 num_parents;
unsigned long flags;
unsigned long offset;
u8 fixed_divider;
unsigned long bypass_reg;
unsigned long bypass_shift;
};
struct agilex5_gate_clock {
unsigned int id;
const char *name;
const char * const *parent_names;
u8 num_parents;
unsigned long flags;
unsigned long gate_reg;
u8 gate_idx;
unsigned long div_reg;
u8 div_offset;
u8 div_width;
unsigned long bypass_reg;
u8 bypass_shift;
u8 fixed_div;
};
struct clk_hw *s10_register_pll(const struct stratix10_pll_clock *clks,
void __iomem *reg);
struct clk_hw *agilex_register_pll(const struct stratix10_pll_clock *clks,
void __iomem *reg);
struct clk_hw *n5x_register_pll(const struct stratix10_pll_clock *clks,
void __iomem *reg);
struct clk_hw *agilex5_register_pll(const struct agilex5_pll_clock *clks,
void __iomem *reg);
struct clk_hw *agilex5_register_cnt_periph(const struct agilex5_perip_cnt_clock *clks,
void __iomem *regbase);
struct clk_hw *agilex5_register_gate(const struct agilex5_gate_clock *clks,
void __iomem *regbase);
struct clk_hw *s10_register_periph(const struct stratix10_perip_c_clock *clks,
void __iomem *reg);
struct clk_hw *n5x_register_periph(const struct n5x_perip_c_clock *clks,