[PATCH v2 7/9] clk: s10: Refactor S10 clock driver
Yuslaimi, Alif Zakuan
alif.zakuan.yuslaimi at altera.com
Thu May 14 07:47:11 CEST 2026
Hi Tien Fong,
On 8/5/2026 1:48 pm, Chee, Tien Fong wrote:
> Hi Alif,
>
>
> On 28/4/2026 11:48 am, alif.zakuan.yuslaimi at altera.com wrote:
>> From: Alif Zakuan Yuslaimi <alif.zakuan.yuslaimi at altera.com>
>>
>> Refactor Stratix10 clock manager driver to support driver model,
>> following
>> Agilex clock driver.
>>
>> Create a new clock driver, clk-s10.c, for Stratix10 which supports the
>> driver model. This allows several APIs such as enable/disable clock, and
>> get clock rate to be supported.
>>
>> This driver will be initialized during SPL to bring up the clock as early
>> as possible. The clock initialization process are refactored into this
>> new
>> driver from clock_manager_s10.c during clock driver probe.
>>
>> Excluding Stratix10 from legacy method of obtaining clkmgr base
>> address in
>> mach-socfpga/misc.c as the base address is already obtained during clock
>> driver probe during SPL initialization.
>>
>> Signed-off-by: Alif Zakuan Yuslaimi <alif.zakuan.yuslaimi at altera.com>
>> ---
>> MAINTAINERS | 1 +
>> arch/arm/mach-socfpga/Kconfig | 2 +
>> arch/arm/mach-socfpga/clock_manager_s10.c | 449 ++-----------
>> .../include/mach/clock_manager_s10.h | 176 +----
>> arch/arm/mach-socfpga/misc.c | 3 +-
>> arch/arm/mach-socfpga/spl_s10.c | 7 +-
>> drivers/clk/altera/Makefile | 1 +
>> drivers/clk/altera/clk-s10.c | 603 ++++++++++++++++++
>> drivers/clk/altera/clk-s10.h | 202 ++++++
>> 9 files changed, 873 insertions(+), 571 deletions(-)
>> create mode 100644 drivers/clk/altera/clk-s10.c
>> create mode 100644 drivers/clk/altera/clk-s10.h
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index d1173126fc6..032f0ee97fc 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -159,6 +159,7 @@ F: arch/arm/mach-socfpga/
>> F: board/altera/stratix10-socdk/
>> F: board/intel/agilex-socdk/
>> F: configs/socfpga_*
>> +F: drivers/clk/altera/
>> F: drivers/ddr/altera/
>> F: drivers/power/domain/altr-pmgr-agilex5.c
>> F: drivers/sysreset/sysreset_socfpga*
>> diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/
>> Kconfig
>> index fb98b647442..aa1f3e761cd 100644
>> --- a/arch/arm/mach-socfpga/Kconfig
>> +++ b/arch/arm/mach-socfpga/Kconfig
>> @@ -146,8 +146,10 @@ config ARCH_SOCFPGA_STRATIX10
>> select ARMV8_MULTIENTRY
>> select ARMV8_SET_SMPEN
>> select BINMAN if SPL_ATF
>> + select CLK
>> select FPGA_INTEL_SDM_MAILBOX
>> select GICV2
>> + select SPL_CLK if SPL
>> select ARCH_SOCFPGA_SOC64
>> choice
>> diff --git a/arch/arm/mach-socfpga/clock_manager_s10.c b/arch/arm/
>> mach-socfpga/clock_manager_s10.c
>> index fd27470f967..df636f14f93 100644
>> --- a/arch/arm/mach-socfpga/clock_manager_s10.c
>> +++ b/arch/arm/mach-socfpga/clock_manager_s10.c
>> @@ -1,425 +1,78 @@
>> // SPDX-License-Identifier: GPL-2.0
>> /*
>> - * Copyright (C) 2016-2023 Intel Corporation <www.intel.com>
>
>
> all prior copyright notices to be retained
>
>
Noted, I will re-add this in v3.
>> + * Copyright (C) 2026 Altera Corporation <www.altera.com>
>> *
>> */
>> -#include <compiler.h>
>> -#include <dm/device.h>
>> -#include <linux/errno.h>
>> -#include <asm/io.h>
>> +#include <clk.h>
>> +#include <dm.h>
>> +#include <log.h>
>> +#include <malloc.h>
>> #include <asm/arch/clock_manager.h>
>> -#include <asm/arch/handoff_soc64.h>
>> #include <asm/arch/system_manager.h>
>> +#include <asm/io.h>
>> +#include <dt-bindings/clock/stratix10-clock.h>
>> -/*
>> - * function to write the bypass register which requires a poll of the
>> - * busy bit
>> - */
>> -static void cm_write_bypass_mainpll(u32 val)
>> -{
>> - writel(val, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_BYPASS);
>> - cm_wait_for_fsm();
>> -}
>> -
>> -static void cm_write_bypass_perpll(u32 val)
>> -{
>> - writel(val, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_BYPASS);
>> - cm_wait_for_fsm();
>> -}
>> -
>> -/* function to write the ctrl register which requires a poll of the
>> busy bit */
>> -static void cm_write_ctrl(u32 val)
>> -{
>> - writel(val, socfpga_get_clkmgr_addr() + CLKMGR_S10_CTRL);
>> - cm_wait_for_fsm();
>> -}
>> -
>> -/*
>> - * Setup clocks while making no assumptions about previous state of
>> the clocks.
>> - */
>> -void cm_basic_init(const struct cm_config * const cfg)
>> -{
>> - u32 mdiv, refclkdiv, mscnt, hscnt, vcocalib;
>> -
>> - if (cfg == 0)
>> - return;
>> -
>> - /* Put all plls in bypass */
>> - cm_write_bypass_mainpll(CLKMGR_BYPASS_MAINPLL_ALL);
>> - cm_write_bypass_perpll(CLKMGR_BYPASS_PERPLL_ALL);
>> -
>> - /* setup main PLL dividers where calculate the vcocalib value */
>> - mdiv = (cfg->main_pll_fdbck >> CLKMGR_FDBCK_MDIV_OFFSET) &
>> - CLKMGR_FDBCK_MDIV_MASK;
>> - refclkdiv = (cfg->main_pll_pllglob >>
>> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
>> - CLKMGR_PLLGLOB_REFCLKDIV_MASK;
>> - mscnt = CLKMGR_MSCNT_CONST / (CLKMGR_MDIV_CONST + mdiv) / refclkdiv;
>> - hscnt = (mdiv + CLKMGR_MDIV_CONST) * mscnt / refclkdiv -
>> - CLKMGR_HSCNT_CONST;
>> - vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) |
>> - ((mscnt & CLKMGR_VCOCALIB_MSCNT_MASK) <<
>> - CLKMGR_VCOCALIB_MSCNT_OFFSET);
>> -
>> - writel((cfg->main_pll_pllglob & ~CLKMGR_PLLGLOB_PD_MASK &
>> - ~CLKMGR_PLLGLOB_RST_MASK),
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLGLOB);
>> - writel(cfg->main_pll_fdbck,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_FDBCK);
>> - writel(vcocalib,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_VCOCALIB);
>> - writel(cfg->main_pll_pllc0,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLC0);
>> - writel(cfg->main_pll_pllc1,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLC1);
>> - writel(cfg->main_pll_nocdiv,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_NOCDIV);
>> -
>> - /* setup peripheral PLL dividers */
>> - /* calculate the vcocalib value */
>> - mdiv = (cfg->per_pll_fdbck >> CLKMGR_FDBCK_MDIV_OFFSET) &
>> - CLKMGR_FDBCK_MDIV_MASK;
>> - refclkdiv = (cfg->per_pll_pllglob >>
>> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
>> - CLKMGR_PLLGLOB_REFCLKDIV_MASK;
>> - mscnt = CLKMGR_MSCNT_CONST / (CLKMGR_MDIV_CONST + mdiv) / refclkdiv;
>> - hscnt = (mdiv + CLKMGR_MDIV_CONST) * mscnt / refclkdiv -
>> - CLKMGR_HSCNT_CONST;
>> - vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) |
>> - ((mscnt & CLKMGR_VCOCALIB_MSCNT_MASK) <<
>> - CLKMGR_VCOCALIB_MSCNT_OFFSET);
>> -
>> - writel((cfg->per_pll_pllglob & ~CLKMGR_PLLGLOB_PD_MASK &
>> - ~CLKMGR_PLLGLOB_RST_MASK),
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLGLOB);
>> - writel(cfg->per_pll_fdbck,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_FDBCK);
>> - writel(vcocalib,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_VCOCALIB);
>> - writel(cfg->per_pll_pllc0,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLC0);
>> - writel(cfg->per_pll_pllc1,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLC1);
>> - writel(cfg->per_pll_emacctl,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_EMACCTL);
>> - writel(cfg->per_pll_gpiodiv,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_GPIODIV);
>> -
>> - /* Take both PLL out of reset and power up */
>> - setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLGLOB,
>> - CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK);
>> - setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLGLOB,
>> - CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK);
>> -
>> -#define LOCKED_MASK \
>> - (CLKMGR_STAT_MAINPLL_LOCKED | \
>> - CLKMGR_STAT_PERPLL_LOCKED)
>> -
>> - cm_wait_for_lock(LOCKED_MASK);
>> -
>> - /*
>> - * Dividers for C2 to C9 only init after PLLs are lock. As dividers
>> - * only take effect upon value change, we shall set a maximum
>> value as
>> - * default value.
>> - */
>> - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_MPUCLK);
>> - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_NOCCLK);
>> - writel(0xff, socfpga_get_clkmgr_addr() +
>> CLKMGR_S10_MAINPLL_CNTR2CLK);
>> - writel(0xff, socfpga_get_clkmgr_addr() +
>> CLKMGR_S10_MAINPLL_CNTR3CLK);
>> - writel(0xff, socfpga_get_clkmgr_addr() +
>> CLKMGR_S10_MAINPLL_CNTR4CLK);
>> - writel(0xff, socfpga_get_clkmgr_addr() +
>> CLKMGR_S10_MAINPLL_CNTR5CLK);
>> - writel(0xff, socfpga_get_clkmgr_addr() +
>> CLKMGR_S10_MAINPLL_CNTR6CLK);
>> - writel(0xff, socfpga_get_clkmgr_addr() +
>> CLKMGR_S10_MAINPLL_CNTR7CLK);
>> - writel(0xff, socfpga_get_clkmgr_addr() +
>> CLKMGR_S10_MAINPLL_CNTR8CLK);
>> - writel(0xff, socfpga_get_clkmgr_addr() +
>> CLKMGR_S10_MAINPLL_CNTR9CLK);
>> - writel(0xff, socfpga_get_clkmgr_addr() +
>> CLKMGR_S10_PERPLL_CNTR2CLK);
>> - writel(0xff, socfpga_get_clkmgr_addr() +
>> CLKMGR_S10_PERPLL_CNTR3CLK);
>> - writel(0xff, socfpga_get_clkmgr_addr() +
>> CLKMGR_S10_PERPLL_CNTR4CLK);
>> - writel(0xff, socfpga_get_clkmgr_addr() +
>> CLKMGR_S10_PERPLL_CNTR5CLK);
>> - writel(0xff, socfpga_get_clkmgr_addr() +
>> CLKMGR_S10_PERPLL_CNTR6CLK);
>> - writel(0xff, socfpga_get_clkmgr_addr() +
>> CLKMGR_S10_PERPLL_CNTR7CLK);
>> - writel(0xff, socfpga_get_clkmgr_addr() +
>> CLKMGR_S10_PERPLL_CNTR8CLK);
>> - writel(0xff, socfpga_get_clkmgr_addr() +
>> CLKMGR_S10_PERPLL_CNTR9CLK);
>> -
>> - writel(cfg->main_pll_mpuclk,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_MPUCLK);
>> - writel(cfg->main_pll_nocclk,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_NOCCLK);
>> - writel(cfg->main_pll_cntr2clk,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR2CLK);
>> - writel(cfg->main_pll_cntr3clk,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR3CLK);
>> - writel(cfg->main_pll_cntr4clk,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR4CLK);
>> - writel(cfg->main_pll_cntr5clk,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR5CLK);
>> - writel(cfg->main_pll_cntr6clk,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR6CLK);
>> - writel(cfg->main_pll_cntr7clk,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR7CLK);
>> - writel(cfg->main_pll_cntr8clk,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR8CLK);
>> - writel(cfg->main_pll_cntr9clk,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR9CLK);
>> - writel(cfg->per_pll_cntr2clk,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR2CLK);
>> - writel(cfg->per_pll_cntr3clk,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR3CLK);
>> - writel(cfg->per_pll_cntr4clk,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR4CLK);
>> - writel(cfg->per_pll_cntr5clk,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR5CLK);
>> - writel(cfg->per_pll_cntr6clk,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR6CLK);
>> - writel(cfg->per_pll_cntr7clk,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR7CLK);
>> - writel(cfg->per_pll_cntr8clk,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR8CLK);
>> - writel(cfg->per_pll_cntr9clk,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR9CLK);
>> -
>> - /* Take all PLLs out of bypass */
>> - cm_write_bypass_mainpll(0);
>> - cm_write_bypass_perpll(0);
>> -
>> - /* clear safe mode / out of boot mode */
>> - cm_write_ctrl(readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_CTRL) &
>> - ~(CLKMGR_CTRL_SAFEMODE));
>> -
>> - /* Now ungate non-hw-managed clocks */
>> - writel(~0, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_EN);
>> - writel(~0, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_EN);
>> -
>> - /* Clear the loss of lock bits (write 1 to clear) */
>> - writel(CLKMGR_INTER_PERPLLLOST_MASK |
>> - CLKMGR_INTER_MAINPLLLOST_MASK,
>> - socfpga_get_clkmgr_addr() + CLKMGR_S10_INTRCLR);
>> -}
>> -
>> -static unsigned long cm_get_main_vco_clk_hz(void)
>> +static ulong cm_get_rate_dm(u32 id)
>> {
>> - unsigned long fref, refdiv, mdiv, reg, vco;
>> -
>> - reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLGLOB);
>> -
>> - fref = (reg >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET) &
>> - CLKMGR_PLLGLOB_VCO_PSRC_MASK;
>> - switch (fref) {
>> - case CLKMGR_VCO_PSRC_EOSC1:
>> - fref = cm_get_osc_clk_hz();
>> - break;
>> - case CLKMGR_VCO_PSRC_INTOSC:
>> - fref = cm_get_intosc_clk_hz();
>> - break;
>> - case CLKMGR_VCO_PSRC_F2S:
>> - fref = cm_get_fpga_clk_hz();
>> - break;
>> + struct udevice *dev;
>> + struct clk clk;
>> + ulong rate;
>> + int ret;
>> +
>> + ret = uclass_get_device_by_driver(UCLASS_CLK,
>> + DM_DRIVER_GET(socfpga_s10_clk),
>> + &dev);
>> + if (ret)
>> + return 0;
>> +
>> + clk.id = id;
>> + ret = clk_request(dev, &clk);
>> + if (ret < 0)
>> + return 0;
>> +
>> + rate = clk_get_rate(&clk);
>> +
>> + if ((rate == (unsigned long)-ENOSYS) ||
>> + (rate == (unsigned long)-ENXIO) ||
>> + (rate == (unsigned long)-EIO)) {
>> + debug("%s id %u: clk_get_rate err: %ld\n",
>> + __func__, id, rate);
>> + return 0;
>> }
>> - refdiv = (reg >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
>> - CLKMGR_PLLGLOB_REFCLKDIV_MASK;
>> -
>> - reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_FDBCK);
>> - mdiv = (reg >> CLKMGR_FDBCK_MDIV_OFFSET) & CLKMGR_FDBCK_MDIV_MASK;
>> -
>> - vco = fref / refdiv;
>> - vco = vco * (CLKMGR_MDIV_CONST + mdiv);
>> - return vco;
>> + return rate;
>> }
>> -static unsigned long cm_get_per_vco_clk_hz(void)
>> +static u32 cm_get_rate_dm_khz(u32 id)
>> {
>> - unsigned long fref, refdiv, mdiv, reg, vco;
>> -
>> - reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLGLOB);
>> -
>> - fref = (reg >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET) &
>> - CLKMGR_PLLGLOB_VCO_PSRC_MASK;
>> - switch (fref) {
>> - case CLKMGR_VCO_PSRC_EOSC1:
>> - fref = cm_get_osc_clk_hz();
>> - break;
>> - case CLKMGR_VCO_PSRC_INTOSC:
>> - fref = cm_get_intosc_clk_hz();
>> - break;
>> - case CLKMGR_VCO_PSRC_F2S:
>> - fref = cm_get_fpga_clk_hz();
>> - break;
>> - }
>> -
>> - refdiv = (reg >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
>> - CLKMGR_PLLGLOB_REFCLKDIV_MASK;
>> -
>> - reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_FDBCK);
>> - mdiv = (reg >> CLKMGR_FDBCK_MDIV_OFFSET) & CLKMGR_FDBCK_MDIV_MASK;
>> -
>> - vco = fref / refdiv;
>> - vco = vco * (CLKMGR_MDIV_CONST + mdiv);
>> - return vco;
>> + return cm_get_rate_dm(id) / 1000;
>> }
>> unsigned long cm_get_mpu_clk_hz(void)
>> {
>> - unsigned long clock = readl(socfpga_get_clkmgr_addr() +
>> - CLKMGR_S10_MAINPLL_MPUCLK);
>> -
>> - clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK;
>> -
>> - switch (clock) {
>> - case CLKMGR_CLKSRC_MAIN:
>> - clock = cm_get_main_vco_clk_hz();
>> - clock /= (readl(socfpga_get_clkmgr_addr() +
>> - CLKMGR_S10_MAINPLL_PLLC0) &
>> - CLKMGR_PLLC0_DIV_MASK);
>> - break;
>> -
>> - case CLKMGR_CLKSRC_PER:
>> - clock = cm_get_per_vco_clk_hz();
>> - clock /= (readl(socfpga_get_clkmgr_addr() +
>> - CLKMGR_S10_PERPLL_PLLC0) &
>> - CLKMGR_CLKCNT_MSK);
>> - break;
>> -
>> - case CLKMGR_CLKSRC_OSC1:
>> - clock = cm_get_osc_clk_hz();
>> - break;
>> -
>> - case CLKMGR_CLKSRC_INTOSC:
>> - clock = cm_get_intosc_clk_hz();
>> - break;
>> -
>> - case CLKMGR_CLKSRC_FPGA:
>> - clock = cm_get_fpga_clk_hz();
>> - break;
>> - }
>> -
>> - clock /= 1 + (readl(socfpga_get_clkmgr_addr() +
>> - CLKMGR_S10_MAINPLL_MPUCLK) & CLKMGR_CLKCNT_MSK);
>> - return clock;
>> -}
>> -
>> -unsigned int cm_get_l3_main_clk_hz(void)
>> -{
>> - u32 clock = readl(socfpga_get_clkmgr_addr() +
>> - CLKMGR_S10_MAINPLL_NOCCLK);
>> -
>> - clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK;
>> -
>> - switch (clock) {
>> - case CLKMGR_CLKSRC_MAIN:
>> - clock = cm_get_main_vco_clk_hz();
>> - clock /= (readl(socfpga_get_clkmgr_addr() +
>> - CLKMGR_S10_MAINPLL_PLLC1) &
>> - CLKMGR_PLLC0_DIV_MASK);
>> - break;
>> -
>> - case CLKMGR_CLKSRC_PER:
>> - clock = cm_get_per_vco_clk_hz();
>> - clock /= (readl(socfpga_get_clkmgr_addr() +
>> - CLKMGR_S10_PERPLL_PLLC1) & CLKMGR_CLKCNT_MSK);
>> - break;
>> -
>> - case CLKMGR_CLKSRC_OSC1:
>> - clock = cm_get_osc_clk_hz();
>> - break;
>> -
>> - case CLKMGR_CLKSRC_INTOSC:
>> - clock = cm_get_intosc_clk_hz();
>> - break;
>> -
>> - case CLKMGR_CLKSRC_FPGA:
>> - clock = cm_get_fpga_clk_hz();
>> - break;
>> - }
>> -
>> - clock /= 1 + (readl(socfpga_get_clkmgr_addr() +
>> - CLKMGR_S10_MAINPLL_NOCCLK) & CLKMGR_CLKCNT_MSK);
>> - return clock;
>> -}
>> -
>> -unsigned int cm_get_mmc_controller_clk_hz(void)
>> -{
>> - u32 clock = readl(socfpga_get_clkmgr_addr() +
>> - CLKMGR_S10_PERPLL_CNTR6CLK);
>> -
>> - clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK;
>> -
>> - switch (clock) {
>> - case CLKMGR_CLKSRC_MAIN:
>> - clock = cm_get_l3_main_clk_hz();
>> - clock /= 1 + (readl(socfpga_get_clkmgr_addr() +
>> - CLKMGR_S10_MAINPLL_CNTR6CLK) &
>> - CLKMGR_CLKCNT_MSK);
>> - break;
>> -
>> - case CLKMGR_CLKSRC_PER:
>> - clock = cm_get_l3_main_clk_hz();
>> - clock /= 1 + (readl(socfpga_get_clkmgr_addr() +
>> - CLKMGR_S10_PERPLL_CNTR6CLK) &
>> - CLKMGR_CLKCNT_MSK);
>> - break;
>> -
>> - case CLKMGR_CLKSRC_OSC1:
>> - clock = cm_get_osc_clk_hz();
>> - break;
>> -
>> - case CLKMGR_CLKSRC_INTOSC:
>> - clock = cm_get_intosc_clk_hz();
>> - break;
>> -
>> - case CLKMGR_CLKSRC_FPGA:
>> - clock = cm_get_fpga_clk_hz();
>> - break;
>> - }
>> - return clock / 4;
>> -}
>> -
>> -unsigned int cm_get_l4_sp_clk_hz(void)
>> -{
>> - u32 clock = cm_get_l3_main_clk_hz();
>> -
>> - clock /= (1 << ((readl(socfpga_get_clkmgr_addr() +
>> - CLKMGR_S10_MAINPLL_NOCDIV) >>
>> - CLKMGR_NOCDIV_L4SPCLK_OFFSET) & CLKMGR_CLKCNT_MSK));
>> - return clock;
>> -}
>> -
>> -unsigned int cm_get_spi_controller_clk_hz(void)
>> -{
>> - u32 clock = cm_get_l3_main_clk_hz();
>> -
>> - clock /= (1 << ((readl(socfpga_get_clkmgr_addr() +
>> - CLKMGR_S10_MAINPLL_NOCDIV) >>
>> - CLKMGR_NOCDIV_L4MAIN_OFFSET) & CLKMGR_CLKCNT_MSK));
>> - return clock;
>> + return cm_get_rate_dm(STRATIX10_MPU_CLK);
>> }
>> unsigned int cm_get_l4_sys_free_clk_hz(void)
>> {
>> - return cm_get_l3_main_clk_hz() / 4;
>> -}
>> -
>> -/*
>> - * Override weak dw_spi_get_clk implementation in designware_spi.c
>> driver
>> - */
>> -
>> -int dw_spi_get_clk(struct udevice *bus, ulong *rate)
>> -{
>> - *rate = cm_get_spi_controller_clk_hz();
>> - if (!*rate) {
>> - printf("SPI: clock rate is zero");
>> - return -EINVAL;
>> - }
>> -
>> - return 0;
>
>
> The dw_spi_get_clk() removal and the missing STRATIX10_L4_MAIN_CLK(from
> upstream dts) in socfpga_clk_get_rate() have impacted
>
> the use case where someone enables spi at ffda4000 or spi at ffda5000 in a
> board DTS for a general-purpose SPI peripheral (not the use case spi0 =
> &qspi alias)
>
>
I get your point, I will introduce a new function to get clock rate for
STRATIX10_L4_MAIN_CLK clock in v3.
>> + return cm_get_rate_dm(STRATIX10_L4_SYS_FREE_CLK);
>> }
>> void cm_print_clock_quick_summary(void)
>> {
>> - printf("MPU %d kHz\n", (u32)(cm_get_mpu_clk_hz() / 1000));
>> - printf("L3 main %d kHz\n", cm_get_l3_main_clk_hz() / 1000);
>> - printf("Main VCO %d kHz\n", (u32)(cm_get_main_vco_clk_hz() /
>> 1000));
>> - printf("Per VCO %d kHz\n", (u32)(cm_get_per_vco_clk_hz() /
>> 1000));
>> - printf("EOSC1 %d kHz\n", cm_get_osc_clk_hz() / 1000);
>> - printf("HPS MMC %d kHz\n", cm_get_mmc_controller_clk_hz() /
>> 1000);
>> - printf("UART %d kHz\n", cm_get_l4_sp_clk_hz() / 1000);
>> + printf("MPU %d kHz\n",
>> + cm_get_rate_dm_khz(STRATIX10_MPU_CLK));
>> + printf("L3 main %d kHz\n",
>> + cm_get_rate_dm_khz(STRATIX10_NOC_CLK));
>> + printf("Main VCO %d kHz\n",
>> + cm_get_rate_dm_khz(STRATIX10_MAIN_PLL_CLK));
>> + printf("Per VCO %d kHz\n",
>> + cm_get_rate_dm_khz(STRATIX10_PERIPH_PLL_CLK));
>> + printf("EOSC1 %d kHz\n",
>> + cm_get_rate_dm_khz(STRATIX10_OSC1));
>> + printf("HPS MMC %d kHz\n",
>> + cm_get_rate_dm_khz(STRATIX10_SDMMC_CLK));
>> + printf("UART %d kHz\n",
>> + cm_get_rate_dm_khz(STRATIX10_L4_SP_CLK));
>> }
>> diff --git a/arch/arm/mach-socfpga/include/mach/clock_manager_s10.h b/
>> arch/arm/mach-socfpga/include/mach/clock_manager_s10.h
>> index 5dcbda9473e..e5ff0648b86 100644
>> --- a/arch/arm/mach-socfpga/include/mach/clock_manager_s10.h
>> +++ b/arch/arm/mach-socfpga/include/mach/clock_manager_s10.h
>> @@ -1,177 +1,13 @@
>> -/* SPDX-License-Identifier: GPL-2.0
>> - *
>> - * Copyright (C) 2016-2019 Intel Corporation <www.intel.com>
>
>
> all prior copyright notices to be retained
>
>
Sure, I will re-add this in v3.
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + * Copyright (C) 2026 Altera Corporation <www.altera.com>
>> *
>> */
>> -#ifndef _CLOCK_MANAGER_S10_
>> -#define _CLOCK_MANAGER_S10_
>> +#ifndef _CLOCK_MANAGER_S10_
>> +#define _CLOCK_MANAGER_S10_
>> #include <asm/arch/clock_manager_soc64.h>
>> -#include <linux/bitops.h>
>> -
>> -/* Clock speed accessors */
>> -unsigned long cm_get_sdram_clk_hz(void);
>> -unsigned int cm_get_l4_sp_clk_hz(void);
>> -unsigned int cm_get_mmc_controller_clk_hz(void);
>> -unsigned int cm_get_spi_controller_clk_hz(void);
>> -
>> -struct cm_config {
>> - /* main group */
>> - u32 main_pll_mpuclk;
>> - u32 main_pll_nocclk;
>> - u32 main_pll_cntr2clk;
>> - u32 main_pll_cntr3clk;
>> - u32 main_pll_cntr4clk;
>> - u32 main_pll_cntr5clk;
>> - u32 main_pll_cntr6clk;
>> - u32 main_pll_cntr7clk;
>> - u32 main_pll_cntr8clk;
>> - u32 main_pll_cntr9clk;
>> - u32 main_pll_nocdiv;
>> - u32 main_pll_pllglob;
>> - u32 main_pll_fdbck;
>> - u32 main_pll_pllc0;
>> - u32 main_pll_pllc1;
>> - u32 spare;
>> -
>> - /* peripheral group */
>> - u32 per_pll_cntr2clk;
>> - u32 per_pll_cntr3clk;
>> - u32 per_pll_cntr4clk;
>> - u32 per_pll_cntr5clk;
>> - u32 per_pll_cntr6clk;
>> - u32 per_pll_cntr7clk;
>> - u32 per_pll_cntr8clk;
>> - u32 per_pll_cntr9clk;
>> - u32 per_pll_emacctl;
>> - u32 per_pll_gpiodiv;
>> - u32 per_pll_pllglob;
>> - u32 per_pll_fdbck;
>> - u32 per_pll_pllc0;
>> - u32 per_pll_pllc1;
>> -
>> - /* incoming clock */
>> - u32 hps_osc_clk_hz;
>> - u32 fpga_clk_hz;
>> -};
>> -
>> -void cm_basic_init(const struct cm_config * const cfg);
>> -
>> -/* Control status */
>> -#define CLKMGR_S10_CTRL 0x00
>> -#define CLKMGR_S10_STAT 0x04
>> -#define CLKMGR_S10_INTRCLR 0x14
>> -/* Mainpll group */
>> -#define CLKMGR_S10_MAINPLL_EN 0x30
>> -#define CLKMGR_S10_MAINPLL_BYPASS 0x3c
>> -#define CLKMGR_S10_MAINPLL_MPUCLK 0x48
>> -#define CLKMGR_S10_MAINPLL_NOCCLK 0x4c
>> -#define CLKMGR_S10_MAINPLL_CNTR2CLK 0x50
>> -#define CLKMGR_S10_MAINPLL_CNTR3CLK 0x54
>> -#define CLKMGR_S10_MAINPLL_CNTR4CLK 0x58
>> -#define CLKMGR_S10_MAINPLL_CNTR5CLK 0x5c
>> -#define CLKMGR_S10_MAINPLL_CNTR6CLK 0x60
>> -#define CLKMGR_S10_MAINPLL_CNTR7CLK 0x64
>> -#define CLKMGR_S10_MAINPLL_CNTR8CLK 0x68
>> -#define CLKMGR_S10_MAINPLL_CNTR9CLK 0x6c
>> -#define CLKMGR_S10_MAINPLL_NOCDIV 0x70
>> -#define CLKMGR_S10_MAINPLL_PLLGLOB 0x74
>> -#define CLKMGR_S10_MAINPLL_FDBCK 0x78
>> -#define CLKMGR_S10_MAINPLL_MEMSTAT 0x80
>> -#define CLKMGR_S10_MAINPLL_PLLC0 0x84
>> -#define CLKMGR_S10_MAINPLL_PLLC1 0x88
>> -#define CLKMGR_S10_MAINPLL_VCOCALIB 0x8c
>> -/* Periphpll group */
>> -#define CLKMGR_S10_PERPLL_EN 0xa4
>> -#define CLKMGR_S10_PERPLL_BYPASS 0xb0
>> -#define CLKMGR_S10_PERPLL_CNTR2CLK 0xbc
>> -#define CLKMGR_S10_PERPLL_CNTR3CLK 0xc0
>> -#define CLKMGR_S10_PERPLL_CNTR4CLK 0xc4
>> -#define CLKMGR_S10_PERPLL_CNTR5CLK 0xc8
>> -#define CLKMGR_S10_PERPLL_CNTR6CLK 0xcc
>> -#define CLKMGR_S10_PERPLL_CNTR7CLK 0xd0
>> -#define CLKMGR_S10_PERPLL_CNTR8CLK 0xd4
>> -#define CLKMGR_S10_PERPLL_CNTR9CLK 0xd8
>> -#define CLKMGR_S10_PERPLL_EMACCTL 0xdc
>> -#define CLKMGR_S10_PERPLL_GPIODIV 0xe0
>> -#define CLKMGR_S10_PERPLL_PLLGLOB 0xe4
>> -#define CLKMGR_S10_PERPLL_FDBCK 0xe8
>> -#define CLKMGR_S10_PERPLL_MEMSTAT 0xf0
>> -#define CLKMGR_S10_PERPLL_PLLC0 0xf4
>> -#define CLKMGR_S10_PERPLL_PLLC1 0xf8
>> -#define CLKMGR_S10_PERPLL_VCOCALIB 0xfc
>> -
>> -#define CLKMGR_STAT CLKMGR_S10_STAT
>> -#define CLKMGR_INTER CLKMGR_S10_INTER
>> -#define CLKMGR_PERPLL_EN CLKMGR_S10_PERPLL_EN
>> -
>> -#define CLKMGR_CTRL_SAFEMODE BIT(0)
>> -#define CLKMGR_BYPASS_MAINPLL_ALL 0x00000007
>> -#define CLKMGR_BYPASS_PERPLL_ALL 0x0000007f
>> -
>> -#define CLKMGR_INTER_MAINPLLLOCKED_MASK 0x00000001
>> -#define CLKMGR_INTER_PERPLLLOCKED_MASK 0x00000002
>> -#define CLKMGR_INTER_MAINPLLLOST_MASK 0x00000004
>> -#define CLKMGR_INTER_PERPLLLOST_MASK 0x00000008
>> -#define CLKMGR_STAT_BUSY BIT(0)
>> -#define CLKMGR_STAT_MAINPLL_LOCKED BIT(8)
>> -#define CLKMGR_STAT_PERPLL_LOCKED BIT(9)
>> -
>> -#define CLKMGR_PLLGLOB_PD_MASK 0x00000001
>> -#define CLKMGR_PLLGLOB_RST_MASK 0x00000002
>> -#define CLKMGR_PLLGLOB_VCO_PSRC_MASK 0x3
>> -#define CLKMGR_PLLGLOB_VCO_PSRC_OFFSET 16
>> -#define CLKMGR_VCO_PSRC_EOSC1 0
>> -#define CLKMGR_VCO_PSRC_INTOSC 1
>> -#define CLKMGR_VCO_PSRC_F2S 2
>> -#define CLKMGR_PLLGLOB_REFCLKDIV_MASK 0x3f
>> -#define CLKMGR_PLLGLOB_REFCLKDIV_OFFSET 8
>> -
>> -#define CLKMGR_CLKSRC_MASK 0x7
>> -#define CLKMGR_CLKSRC_OFFSET 16
>> -#define CLKMGR_CLKSRC_MAIN 0
>> -#define CLKMGR_CLKSRC_PER 1
>> -#define CLKMGR_CLKSRC_OSC1 2
>> -#define CLKMGR_CLKSRC_INTOSC 3
>> -#define CLKMGR_CLKSRC_FPGA 4
>> -#define CLKMGR_CLKCNT_MSK 0x7ff
>> -
>> -#define CLKMGR_FDBCK_MDIV_MASK 0xff
>> -#define CLKMGR_FDBCK_MDIV_OFFSET 24
>> -
>> -#define CLKMGR_PLLC0_DIV_MASK 0xff
>> -#define CLKMGR_PLLC1_DIV_MASK 0xff
>> -#define CLKMGR_PLLC0_EN_OFFSET 27
>> -#define CLKMGR_PLLC1_EN_OFFSET 24
>> -
>> -#define CLKMGR_NOCDIV_L4MAIN_OFFSET 0
>> -#define CLKMGR_NOCDIV_L4MPCLK_OFFSET 8
>> -#define CLKMGR_NOCDIV_L4SPCLK_OFFSET 16
>> -#define CLKMGR_NOCDIV_CSATCLK_OFFSET 24
>> -#define CLKMGR_NOCDIV_CSTRACECLK_OFFSET 26
>> -#define CLKMGR_NOCDIV_CSPDBGCLK_OFFSET 28
>> -
>> -#define CLKMGR_NOCDIV_L4SPCLK_MASK 0x3
>> -#define CLKMGR_NOCDIV_DIV1 0
>> -#define CLKMGR_NOCDIV_DIV2 1
>> -#define CLKMGR_NOCDIV_DIV4 2
>> -#define CLKMGR_NOCDIV_DIV8 3
>> -#define CLKMGR_CSPDBGCLK_DIV1 0
>> -#define CLKMGR_CSPDBGCLK_DIV4 1
>> -
>> -#define CLKMGR_MSCNT_CONST 200
>> -#define CLKMGR_MDIV_CONST 6
>> -#define CLKMGR_HSCNT_CONST 9
>> -
>> -#define CLKMGR_VCOCALIB_MSCNT_MASK 0xff
>> -#define CLKMGR_VCOCALIB_MSCNT_OFFSET 9
>> -#define CLKMGR_VCOCALIB_HSCNT_MASK 0xff
>> -
>> -#define CLKMGR_EMACCTL_EMAC0SEL_OFFSET 26
>> -#define CLKMGR_EMACCTL_EMAC1SEL_OFFSET 27
>> -#define CLKMGR_EMACCTL_EMAC2SEL_OFFSET 28
>> -
>> -#define CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK 0x00000020
>> +#include "../../../../../drivers/clk/altera/clk-s10.h"
>> #endif /* _CLOCK_MANAGER_S10_ */
>> diff --git a/arch/arm/mach-socfpga/misc.c b/arch/arm/mach-socfpga/misc.c
>> index 418d7dfb572..6d7128c77be 100644
>> --- a/arch/arm/mach-socfpga/misc.c
>> +++ b/arch/arm/mach-socfpga/misc.c
>> @@ -276,7 +276,8 @@ void socfpga_get_managers_addr(void)
>> &socfpga_clkmgr_base);
>> else if (!IS_ENABLED(CONFIG_ARCH_SOCFPGA_AGILEX) &&
>> !IS_ENABLED(CONFIG_ARCH_SOCFPGA_AGILEX7M) &&
>> - !IS_ENABLED(CONFIG_ARCH_SOCFPGA_AGILEX5))
>> + !IS_ENABLED(CONFIG_ARCH_SOCFPGA_AGILEX5) &&
>> + !IS_ENABLED(CONFIG_ARCH_SOCFPGA_STRATIX10))
>> ret = socfpga_get_base_addr("altr,clk-mgr",
>> &socfpga_clkmgr_base);
>> diff --git a/arch/arm/mach-socfpga/spl_s10.c b/arch/arm/mach-socfpga/
>> spl_s10.c
>> index b05bec2cbc1..ace029557f3 100644
>> --- a/arch/arm/mach-socfpga/spl_s10.c
>> +++ b/arch/arm/mach-socfpga/spl_s10.c
>> @@ -37,7 +37,6 @@ u32 reset_flag(void)
>> void board_init_f(ulong dummy)
>> {
>> - const struct cm_config *cm_default_cfg = cm_get_default_config();
>> int ret;
>> struct udevice *dev;
>> @@ -75,7 +74,11 @@ void board_init_f(ulong dummy)
>> sysmgr_pinmux_init();
>> /* configuring the HPS clocks */
>> - cm_basic_init(cm_default_cfg);
>> + ret = uclass_get_device(UCLASS_CLK, 0, &dev);
>> + if (ret) {
>> + debug("Clock init failed: %d\n", ret);
>> + hang();
>> + }
>> #ifdef CONFIG_DEBUG_UART
>> socfpga_per_reset(SOCFPGA_RESET(UART0), 0);
>> diff --git a/drivers/clk/altera/Makefile b/drivers/clk/altera/Makefile
>> index 693446b3d89..e961d059820 100644
>> --- a/drivers/clk/altera/Makefile
>> +++ b/drivers/clk/altera/Makefile
>> @@ -9,3 +9,4 @@ obj-$(CONFIG_ARCH_SOCFPGA_ARRIA10) += clk-arria10.o
>> obj-$(CONFIG_ARCH_SOCFPGA_N5X) += clk-n5x.o
>> obj-$(CONFIG_ARCH_SOCFPGA_N5X) += clk-mem-n5x.o
>> obj-$(CONFIG_ARCH_SOCFPGA_AGILEX5) += clk-agilex5.o
>> +obj-$(CONFIG_ARCH_SOCFPGA_STRATIX10) += clk-s10.o
>> diff --git a/drivers/clk/altera/clk-s10.c b/drivers/clk/altera/clk-s10.c
>> new file mode 100644
>> index 00000000000..c6492e0cb43
>> --- /dev/null
>> +++ b/drivers/clk/altera/clk-s10.c
>> @@ -0,0 +1,603 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>
>
> NEW FILE, but derived from Intel code
>
> Copyright (C) 2016-2023 Intel Corporation <www.intel.com> ← must add
> (code origin)
>
>
I will add this in v3.
>> + * Copyright (C) 2026 Altera Corporation <www.altera.com>
>> + *
>> + */
>> +
>> +#include <log.h>
>> +#include <wait_bit.h>
>> +#include <asm/io.h>
>> +#include <asm/system.h>
>> +#include <clk-uclass.h>
>> +#include <dm.h>
>> +#include <dm/lists.h>
>> +#include <dm/util.h>
>> +#include <dt-bindings/clock/stratix10-clock.h>
>> +#include <linux/bitfield.h>
>> +#include <linux/bitops.h>
>> +#include <asm/arch/clock_manager.h>
>> +
>> +struct socfpga_clk_plat {
>> + void __iomem *regs;
>> + int pllgrp;
>> + int bitmask;
>> +};
>> +
>> +/*
>> + * function to write the bypass register which requires a poll of the
>> + * busy bit
>> + */
>> +static void clk_write_bypass_mainpll(struct socfpga_clk_plat *plat,
>> u32 val)
>> +{
>> + void __iomem *base = plat->regs;
>> +
>> + CM_REG_WRITEL(plat, val, CLKMGR_MAINPLL_BYPASS);
>> +
>> + wait_for_bit_le32(base + CLKMGR_STAT,
>> + CLKMGR_STAT_BUSY, false, 20000, false);
>> +}
>> +
>> +static void clk_write_bypass_perpll(struct socfpga_clk_plat *plat,
>> u32 val)
>> +{
>> + void __iomem *base = plat->regs;
>> +
>> + CM_REG_WRITEL(plat, val, CLKMGR_PERPLL_BYPASS);
>> +
>> + wait_for_bit_le32(base + CLKMGR_STAT,
>> + CLKMGR_STAT_BUSY, false, 20000, false);
>> +}
>> +
>> +/* function to write the ctrl register which requires a poll of the
>> busy bit */
>> +static void clk_write_ctrl(struct socfpga_clk_plat *plat, u32 val)
>> +{
>> + void __iomem *base = plat->regs;
>> +
>> + CM_REG_WRITEL(plat, val, CLKMGR_CTRL);
>> +
>> + wait_for_bit_le32(base + CLKMGR_STAT,
>> + CLKMGR_STAT_BUSY, false, 20000, false);
>> +}
>> +
>> +/*
>> + * Setup clocks while making no assumptions about previous state of
>> the clocks.
>> + */
>> +static void clk_basic_init(struct udevice *dev,
>> + const struct cm_config * const cfg)
>> +{
>> + struct socfpga_clk_plat *plat = dev_get_plat(dev);
>> + u32 mdiv, refclkdiv, mscnt, hscnt, vcocalib;
>> + uintptr_t base_addr = (uintptr_t)plat->regs;
>> +
>> + if (!cfg)
>> + return;
>> +
>> + /* Put all plls in bypass */
>> + clk_write_bypass_mainpll(plat, CLKMGR_BYPASS_MAINPLL_ALL);
>> + clk_write_bypass_perpll(plat, CLKMGR_BYPASS_PERPLL_ALL);
>> +
>> + /* setup main PLL dividers where calculate the vcocalib value */
>> + mdiv = (cfg->main_pll_fdbck >> CLKMGR_FDBCK_MDIV_OFFSET) &
>> + CLKMGR_FDBCK_MDIV_MASK;
>> + refclkdiv = (cfg->main_pll_pllglob >>
>> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
>> + CLKMGR_PLLGLOB_REFCLKDIV_MASK;
>> + mscnt = CLKMGR_MSCNT_CONST / (CLKMGR_MDIV_CONST + mdiv) / refclkdiv;
>> + hscnt = (mdiv + CLKMGR_MDIV_CONST) * mscnt / refclkdiv -
>> + CLKMGR_HSCNT_CONST;
>> + vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) |
>> + ((mscnt & CLKMGR_VCOCALIB_MSCNT_MASK) <<
>> + CLKMGR_VCOCALIB_MSCNT_OFFSET);
>> +
>> + writel((cfg->main_pll_pllglob & ~CLKMGR_PLLGLOB_PD_MASK &
>> + ~CLKMGR_PLLGLOB_RST_MASK),
>> + base_addr + CLKMGR_MAINPLL_PLLGLOB);
>> + writel(cfg->main_pll_fdbck,
>> + base_addr + CLKMGR_MAINPLL_FDBCK);
>> + writel(vcocalib,
>> + base_addr + CLKMGR_MAINPLL_VCOCALIB);
>> + writel(cfg->main_pll_pllc0,
>> + base_addr + CLKMGR_MAINPLL_PLLC0);
>> + writel(cfg->main_pll_pllc1,
>> + base_addr + CLKMGR_MAINPLL_PLLC1);
>> + writel(cfg->main_pll_nocdiv,
>> + base_addr + CLKMGR_MAINPLL_NOCDIV);
>> +
>> + /* setup peripheral PLL dividers */
>> + /* calculate the vcocalib value */
>> + mdiv = (cfg->per_pll_fdbck >> CLKMGR_FDBCK_MDIV_OFFSET) &
>> + CLKMGR_FDBCK_MDIV_MASK;
>> + refclkdiv = (cfg->per_pll_pllglob >>
>> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
>> + CLKMGR_PLLGLOB_REFCLKDIV_MASK;
>> + mscnt = CLKMGR_MSCNT_CONST / (CLKMGR_MDIV_CONST + mdiv) / refclkdiv;
>> + hscnt = (mdiv + CLKMGR_MDIV_CONST) * mscnt / refclkdiv -
>> + CLKMGR_HSCNT_CONST;
>> + vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) |
>> + ((mscnt & CLKMGR_VCOCALIB_MSCNT_MASK) <<
>> + CLKMGR_VCOCALIB_MSCNT_OFFSET);
>> +
>> + writel((cfg->per_pll_pllglob & ~CLKMGR_PLLGLOB_PD_MASK &
>> + ~CLKMGR_PLLGLOB_RST_MASK),
>> + base_addr + CLKMGR_PERPLL_PLLGLOB);
>> + writel(cfg->per_pll_fdbck,
>> + base_addr + CLKMGR_PERPLL_FDBCK);
>> + writel(vcocalib,
>> + base_addr + CLKMGR_PERPLL_VCOCALIB);
>> + writel(cfg->per_pll_pllc0,
>> + base_addr + CLKMGR_PERPLL_PLLC0);
>> + writel(cfg->per_pll_pllc1,
>> + base_addr + CLKMGR_PERPLL_PLLC1);
>> + writel(cfg->per_pll_emacctl,
>> + base_addr + CLKMGR_PERPLL_EMACCTL);
>> + writel(cfg->per_pll_gpiodiv,
>> + base_addr + CLKMGR_PERPLL_GPIODIV);
>> +
>> + /* Take both PLL out of reset and power up */
>> + setbits_le32(base_addr + CLKMGR_MAINPLL_PLLGLOB,
>> + CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK);
>> + setbits_le32(base_addr + CLKMGR_PERPLL_PLLGLOB,
>> + CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK);
>> +
>> + wait_for_bit_le32((const void *)(base_addr + CLKMGR_STAT),
>> + CLKMGR_STAT_ALLPLL_LOCKED_MASK, true, 20000, false);
>> +
>> + /*
>> + * Dividers for C2 to C9 only init after PLLs are lock. As dividers
>> + * only take effect upon value change, we shall set a maximum
>> value as
>> + * default value.
>> + */
>> + writel(0xff, base_addr + CLKMGR_MAINPLL_MPUCLK);
>> + writel(0xff, base_addr + CLKMGR_MAINPLL_NOCCLK);
>> + writel(0xff, base_addr + CLKMGR_MAINPLL_CNTR2CLK);
>> + writel(0xff, base_addr + CLKMGR_MAINPLL_CNTR3CLK);
>> + writel(0xff, base_addr + CLKMGR_MAINPLL_CNTR4CLK);
>> + writel(0xff, base_addr + CLKMGR_MAINPLL_CNTR5CLK);
>> + writel(0xff, base_addr + CLKMGR_MAINPLL_CNTR6CLK);
>> + writel(0xff, base_addr + CLKMGR_MAINPLL_CNTR7CLK);
>> + writel(0xff, base_addr + CLKMGR_MAINPLL_CNTR8CLK);
>> + writel(0xff, base_addr + CLKMGR_MAINPLL_CNTR9CLK);
>> + writel(0xff, base_addr + CLKMGR_PERPLL_CNTR2CLK);
>> + writel(0xff, base_addr + CLKMGR_PERPLL_CNTR3CLK);
>> + writel(0xff, base_addr + CLKMGR_PERPLL_CNTR4CLK);
>> + writel(0xff, base_addr + CLKMGR_PERPLL_CNTR5CLK);
>> + writel(0xff, base_addr + CLKMGR_PERPLL_CNTR6CLK);
>> + writel(0xff, base_addr + CLKMGR_PERPLL_CNTR7CLK);
>> + writel(0xff, base_addr + CLKMGR_PERPLL_CNTR8CLK);
>> + writel(0xff, base_addr + CLKMGR_PERPLL_CNTR9CLK);
>> +
>> + writel(cfg->main_pll_mpuclk,
>> + base_addr + CLKMGR_MAINPLL_MPUCLK);
>> + writel(cfg->main_pll_nocclk,
>> + base_addr + CLKMGR_MAINPLL_NOCCLK);
>> + writel(cfg->main_pll_cntr2clk,
>> + base_addr + CLKMGR_MAINPLL_CNTR2CLK);
>> + writel(cfg->main_pll_cntr3clk,
>> + base_addr + CLKMGR_MAINPLL_CNTR3CLK);
>> + writel(cfg->main_pll_cntr4clk,
>> + base_addr + CLKMGR_MAINPLL_CNTR4CLK);
>> + writel(cfg->main_pll_cntr5clk,
>> + base_addr + CLKMGR_MAINPLL_CNTR5CLK);
>> + writel(cfg->main_pll_cntr6clk,
>> + base_addr + CLKMGR_MAINPLL_CNTR6CLK);
>> + writel(cfg->main_pll_cntr7clk,
>> + base_addr + CLKMGR_MAINPLL_CNTR7CLK);
>> + writel(cfg->main_pll_cntr8clk,
>> + base_addr + CLKMGR_MAINPLL_CNTR8CLK);
>> + writel(cfg->main_pll_cntr9clk,
>> + base_addr + CLKMGR_MAINPLL_CNTR9CLK);
>> + writel(cfg->per_pll_cntr2clk,
>> + base_addr + CLKMGR_PERPLL_CNTR2CLK);
>> + writel(cfg->per_pll_cntr3clk,
>> + base_addr + CLKMGR_PERPLL_CNTR3CLK);
>> + writel(cfg->per_pll_cntr4clk,
>> + base_addr + CLKMGR_PERPLL_CNTR4CLK);
>> + writel(cfg->per_pll_cntr5clk,
>> + base_addr + CLKMGR_PERPLL_CNTR5CLK);
>> + writel(cfg->per_pll_cntr6clk,
>> + base_addr + CLKMGR_PERPLL_CNTR6CLK);
>> + writel(cfg->per_pll_cntr7clk,
>> + base_addr + CLKMGR_PERPLL_CNTR7CLK);
>> + writel(cfg->per_pll_cntr8clk,
>> + base_addr + CLKMGR_PERPLL_CNTR8CLK);
>> + writel(cfg->per_pll_cntr9clk,
>> + base_addr + CLKMGR_PERPLL_CNTR9CLK);
>> +
>> + /* Take all PLLs out of bypass */
>> + clk_write_bypass_mainpll(plat, 0);
>> + clk_write_bypass_perpll(plat, 0);
>> +
>> +#ifdef COUNTER_FREQUENCY_REAL
>> + u32 cntfrq = COUNTER_FREQUENCY_REAL;
>> + u32 counter_freq = 0;
>> +
>> + /* Update with accurate clock frequency */
>> + if (current_el() == 3) {
>> + asm volatile("msr cntfrq_el0, %0" : : "r" (cntfrq) : "memory");
>> + asm volatile("mrs %0, cntfrq_el0" : "=r" (counter_freq));
>> + debug("Counter freq = 0x%x\n", counter_freq);
>> + }
>> +#endif
>> +
>> + /* clear safe mode / out of boot mode */
>> + clk_write_ctrl(plat, readl(base_addr + CLKMGR_CTRL) &
>> + ~(CLKMGR_CTRL_SAFEMODE));
>> +
>> + /* Now ungate non-hw-managed clocks */
>> + writel(~0, base_addr + CLKMGR_MAINPLL_EN);
>> + writel(~0, base_addr + CLKMGR_PERPLL_EN);
>> +
>> + /* Clear the loss of lock bits (write 1 to clear) */
>> + writel(CLKMGR_INTER_PERPLLLOST_MASK |
>> + CLKMGR_INTER_MAINPLLLOST_MASK,
>> + base_addr + CLKMGR_INTRCLR);
>> +}
>> +
>> +static u64 clk_get_vco_clk_hz(struct socfpga_clk_plat *plat,
>> + u32 pllglob_reg, u32 fdbck_reg)
>> +{
>> + u64 fref, refdiv, mdiv, reg, vco;
>> +
>> + reg = CM_REG_READL(plat, pllglob_reg);
>> +
>> + fref = (reg >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET) &
>> + CLKMGR_PLLGLOB_VCO_PSRC_MASK;
>> +
>> + switch (fref) {
>> + case CLKMGR_VCO_PSRC_EOSC1:
>> + fref = cm_get_osc_clk_hz();
>> + break;
>> + case CLKMGR_VCO_PSRC_INTOSC:
>> + fref = cm_get_intosc_clk_hz();
>> + break;
>> + case CLKMGR_VCO_PSRC_F2S:
>> + fref = cm_get_fpga_clk_hz();
>> + break;
>> + }
>> +
>> + refdiv = (reg >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
>> + CLKMGR_PLLGLOB_REFCLKDIV_MASK;
>> +
>> + reg = CM_REG_READL(plat, fdbck_reg);
>> + mdiv = (reg >> CLKMGR_FDBCK_MDIV_OFFSET) & CLKMGR_FDBCK_MDIV_MASK;
>> +
>> + vco = fref / refdiv;
>> + vco = vco * (CLKMGR_MDIV_CONST + mdiv);
>> +
>> + return vco;
>> +}
>> +
>> +static u64 clk_get_main_vco_clk_hz(struct socfpga_clk_plat *plat)
>> +{
>> + return clk_get_vco_clk_hz(plat, CLKMGR_MAINPLL_PLLGLOB,
>> + CLKMGR_MAINPLL_FDBCK);
>> +}
>> +
>> +static u64 clk_get_per_vco_clk_hz(struct socfpga_clk_plat *plat)
>> +{
>> + return clk_get_vco_clk_hz(plat, CLKMGR_PERPLL_PLLGLOB,
>> + CLKMGR_PERPLL_FDBCK);
>> +}
>> +
>> +static u32 clk_get_5_1_clk_src(struct socfpga_clk_plat *plat, u64 reg)
>> +{
>> + u32 clksrc = CM_REG_READL(plat, reg);
>> +
>> + return (clksrc >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK;
>> +}
>> +
>> +static u64 clk_get_mpu_clk_hz(struct socfpga_clk_plat *plat)
>> +{
>> + u64 clock;
>> + u32 clklsrc = clk_get_5_1_clk_src(plat, CLKMGR_MAINPLL_MPUCLK);
>> +
>> + switch (clklsrc) {
>> + case CLKMGR_CLKSRC_MAIN:
>> + clock = clk_get_main_vco_clk_hz(plat);
>> + clock /= (CM_REG_READL(plat, CLKMGR_MAINPLL_PLLC0) &
>> + CLKMGR_PLLC0_DIV_MASK);
>> + break;
>> + case CLKMGR_CLKSRC_PER:
>> + clock = clk_get_per_vco_clk_hz(plat);
>> + clock /= (CM_REG_READL(plat, CLKMGR_PERPLL_PLLC0) &
>> + CLKMGR_CLKCNT_MSK);
>> + break;
>> + case CLKMGR_CLKSRC_OSC1:
>> + clock = cm_get_osc_clk_hz();
>> + break;
>> + case CLKMGR_CLKSRC_INTOSC:
>> + clock = cm_get_intosc_clk_hz();
>> + break;
>> + case CLKMGR_CLKSRC_FPGA:
>> + clock = cm_get_fpga_clk_hz();
>> + break;
>> + default:
>> + return 0;
>> + }
>> +
>> + clock /= 1 + (CM_REG_READL(plat, CLKMGR_MAINPLL_MPUCLK) &
>> + CLKMGR_CLKCNT_MSK);
>> +
>> + return clock;
>> +}
>> +
>> +static u32 clk_get_l3_main_clk_hz(struct socfpga_clk_plat *plat)
>> +{
>> + u64 clock;
>> + u32 clklsrc = clk_get_5_1_clk_src(plat, CLKMGR_MAINPLL_NOCCLK);
>> +
>> + switch (clklsrc) {
>> + case CLKMGR_CLKSRC_MAIN:
>> + clock = clk_get_main_vco_clk_hz(plat);
>> + clock /= (CM_REG_READL(plat, CLKMGR_MAINPLL_PLLC1) &
>> + CLKMGR_PLLC0_DIV_MASK);
>> + break;
>> + case CLKMGR_CLKSRC_PER:
>> + clock = clk_get_per_vco_clk_hz(plat);
>> + clock /= (CM_REG_READL(plat, CLKMGR_PERPLL_PLLC1) &
>> + CLKMGR_CLKCNT_MSK);
>> + break;
>> + case CLKMGR_CLKSRC_OSC1:
>> + clock = cm_get_osc_clk_hz();
>> + break;
>> + case CLKMGR_CLKSRC_INTOSC:
>> + clock = cm_get_intosc_clk_hz();
>> + break;
>> + case CLKMGR_CLKSRC_FPGA:
>> + clock = cm_get_fpga_clk_hz();
>> + break;
>> + default:
>> + return 0;
>> + }
>> +
>> + clock /= 1 + (CM_REG_READL(plat, CLKMGR_MAINPLL_NOCCLK) &
>> + CLKMGR_CLKCNT_MSK);
>> +
>> + return clock;
>> +}
>> +
>> +static u32 clk_get_sdmmc_clk_hz(struct socfpga_clk_plat *plat)
>> +{
>> + u32 clock;
>> + u32 clklsrc = clk_get_5_1_clk_src(plat, CLKMGR_PERPLL_CNTR6CLK);
>> +
>> + switch (clklsrc) {
>> + case CLKMGR_CLKSRC_MAIN:
>> + clock = clk_get_l3_main_clk_hz(plat);
>> + clock /= 1 + (CM_REG_READL(plat, CLKMGR_MAINPLL_CNTR6CLK) &
>> CLKMGR_CLKCNT_MSK);
>> + break;
>> + case CLKMGR_CLKSRC_PER:
>> + clock = clk_get_l3_main_clk_hz(plat);
>> + clock /= 1 + (CM_REG_READL(plat, CLKMGR_PERPLL_CNTR6CLK) &
>> CLKMGR_CLKCNT_MSK);
>> + break;
>> + case CLKMGR_CLKSRC_OSC1:
>> + clock = cm_get_osc_clk_hz();
>> + break;
>> + case CLKMGR_CLKSRC_INTOSC:
>> + clock = cm_get_intosc_clk_hz();
>> + break;
>> + case CLKMGR_CLKSRC_FPGA:
>> + clock = cm_get_fpga_clk_hz();
>> + break;
>> + default:
>> + return 0;
>> + }
>> +
>> + return clock / 4;
>> +}
>> +
>> +static u32 clk_get_l4_sp_clk_hz(struct socfpga_clk_plat *plat)
>> +{
>> + u64 clock = clk_get_l3_main_clk_hz(plat);
>> +
>> + clock /= BIT((CM_REG_READL(plat, CLKMGR_MAINPLL_NOCDIV) >>
>> + CLKMGR_NOCDIV_L4SPCLK_OFFSET) &
>> + CLKMGR_CLKCNT_MSK);
>> +
>> + return clock;
>> +}
>> +
>> +static u32 clk_get_l4_sys_free_clk_hz(struct socfpga_clk_plat *plat)
>> +{
>> + if (CM_REG_READL(plat, CLKMGR_STAT) & CLKMGR_STAT_BOOTMODE)
>> + return clk_get_l3_main_clk_hz(plat) / 2;
>> +
>> + return clk_get_l3_main_clk_hz(plat) / 4;
>> +}
>> +
>> +static ulong socfpga_clk_get_rate(struct clk *clk)
>> +{
>> + struct socfpga_clk_plat *plat = dev_get_plat(clk->dev);
>> +
>> + switch (clk->id) {
>> + case STRATIX10_MPU_CLK:
>> + return clk_get_mpu_clk_hz(plat);
>> + case STRATIX10_NOC_CLK:
>> + return clk_get_l3_main_clk_hz(plat);
>> + case STRATIX10_MAIN_PLL_CLK:
>> + return clk_get_main_vco_clk_hz(plat);
>> + case STRATIX10_PERIPH_PLL_CLK:
>> + return clk_get_per_vco_clk_hz(plat);
>> + case STRATIX10_OSC1:
>> + return cm_get_osc_clk_hz();
>> + case STRATIX10_SDMMC_CLK:
>> + return clk_get_sdmmc_clk_hz(plat);
>> + case STRATIX10_L4_SP_CLK:
>> + return clk_get_l4_sp_clk_hz(plat);
>> + case STRATIX10_L4_SYS_FREE_CLK:
>> + return clk_get_l4_sys_free_clk_hz(plat);
>
>
> missing STRATIX10_L4_MAIN_CLK(from upstream dts for spi0/1), please
> check whether is name diff between U-Boot & Linux, or missing.
>
>
I will add new case for STRATIX10_L4_MAIN_CLK and its own function to
retrieve the clock rate in v3.
>> + default:
>> + return -ENXIO;
>> + }
>> +}
>> +
>> +static int bitmask_from_clk_id(struct clk *clk)
>> +{
>> + struct socfpga_clk_plat *plat = dev_get_plat(clk->dev);
>> +
>> + switch (clk->id) {
>> + case STRATIX10_MPU_CLK:
>> + plat->pllgrp = CLKMGR_MAINPLL_EN;
>> + plat->bitmask = CLKMGR_MAINPLLGRP_EN_MPUCLK_MASK;
>> + break;
>> + case STRATIX10_L4_MAIN_CLK:
>> + plat->pllgrp = CLKMGR_MAINPLL_EN;
>> + plat->bitmask = CLKMGR_MAINPLLGRP_EN_L4MAINCLK_MASK;
>> + break;
>> + case STRATIX10_L4_MP_CLK:
>> + case STRATIX10_NAND_X_CLK:
>> + plat->pllgrp = CLKMGR_MAINPLL_EN;
>> + plat->bitmask = CLKMGR_MAINPLLGRP_EN_L4MPCLK_MASK;
>> + break;
>> + case STRATIX10_L4_SP_CLK:
>> + plat->pllgrp = CLKMGR_MAINPLL_EN;
>> + plat->bitmask = CLKMGR_MAINPLLGRP_EN_L4SPCLK_MASK;
>> + break;
>> + case STRATIX10_CS_AT_CLK:
>> + plat->pllgrp = CLKMGR_MAINPLL_EN;
>> + plat->bitmask = CLKMGR_MAINPLLGRP_EN_CSCLK_MASK;
>> + break;
>> + case STRATIX10_CS_TRACE_CLK:
>> + plat->pllgrp = CLKMGR_MAINPLL_EN;
>> + plat->bitmask = CLKMGR_MAINPLLGRP_EN_CSCLK_MASK;
>> + break;
>> + case STRATIX10_CS_PDBG_CLK:
>> + plat->pllgrp = CLKMGR_MAINPLL_EN;
>> + plat->bitmask = CLKMGR_MAINPLLGRP_EN_CSCLK_MASK;
>> + break;
>> + case STRATIX10_CS_TIMER_CLK:
>> + plat->pllgrp = CLKMGR_MAINPLL_EN;
>> + plat->bitmask = CLKMGR_MAINPLLGRP_EN_CSTIMERCLK_MASK;
>> + break;
>> + case STRATIX10_S2F_USER0_CLK:
>> + plat->pllgrp = CLKMGR_MAINPLL_EN;
>> + plat->bitmask = CLKMGR_MAINPLLGRP_EN_S2FUSER0CLK_MASK;
>> + break;
>> + case STRATIX10_EMAC0_CLK:
>> + plat->pllgrp = CLKMGR_PERPLL_EN;
>> + plat->bitmask = CLKMGR_PERPLLGRP_EN_EMAC0CLK_MASK;
>> + break;
>> + case STRATIX10_EMAC1_CLK:
>> + plat->pllgrp = CLKMGR_PERPLL_EN;
>> + plat->bitmask = CLKMGR_PERPLLGRP_EN_EMAC1CLK_MASK;
>> + break;
>> + case STRATIX10_EMAC2_CLK:
>> + plat->pllgrp = CLKMGR_PERPLL_EN;
>> + plat->bitmask = CLKMGR_PERPLLGRP_EN_EMAC2CLK_MASK;
>> + break;
>> + case STRATIX10_EMAC_PTP_CLK:
>> + plat->pllgrp = CLKMGR_PERPLL_EN;
>> + plat->bitmask = CLKMGR_PERPLLGRP_EN_EMACPTPCLK_MASK;
>> + break;
>> + case STRATIX10_GPIO_DB_CLK:
>> + plat->pllgrp = CLKMGR_PERPLL_EN;
>> + plat->bitmask = CLKMGR_PERPLLGRP_EN_GPIODBCLK_MASK;
>> + break;
>> + case STRATIX10_SDMMC_CLK:
>> + plat->pllgrp = CLKMGR_PERPLL_EN;
>> + plat->bitmask = CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK;
>> + break;
>> + case STRATIX10_S2F_USER1_CLK:
>> + plat->pllgrp = CLKMGR_PERPLL_EN;
>> + plat->bitmask = CLKMGR_PERPLLGRP_EN_S2FUSER1CLK_MASK;
>> + break;
>> + case STRATIX10_PSI_REF_CLK:
>> + plat->pllgrp = CLKMGR_PERPLL_EN;
>> + plat->bitmask = CLKMGR_PERPLLGRP_EN_PSIREFCLK_MASK;
>> + break;
>> + case STRATIX10_USB_CLK:
>> + plat->pllgrp = CLKMGR_PERPLL_EN;
>> + plat->bitmask = CLKMGR_PERPLLGRP_EN_USBCLK_MASK;
>> + break;
>> + case STRATIX10_SPI_M_CLK:
>> + plat->pllgrp = CLKMGR_PERPLL_EN;
>> + plat->bitmask = CLKMGR_PERPLLGRP_EN_SPIMCLK_MASK;
>> + break;
>> + case STRATIX10_NAND_CLK:
>> + plat->pllgrp = CLKMGR_PERPLL_EN;
>> + plat->bitmask = CLKMGR_PERPLLGRP_EN_NANDCLK_MASK;
>> + break;
>> + case STRATIX10_L4_SYS_FREE_CLK:
>> + return -EOPNOTSUPP;
>> + default:
>> + return -ENXIO;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static int socfpga_clk_enable(struct clk *clk)
>> +{
>> + struct socfpga_clk_plat *plat = dev_get_plat(clk->dev);
>> + uintptr_t base_addr = (uintptr_t)plat->regs;
>> + int ret;
>> +
>> + ret = bitmask_from_clk_id(clk);
>> + if (ret == -EOPNOTSUPP)
>> + return 0;
>> +
>> + if (ret)
>> + return ret;
>> +
>> + setbits_le32(base_addr + plat->pllgrp, plat->bitmask);
>> +
>> + return 0;
>> +}
>> +
>> +static int socfpga_clk_disable(struct clk *clk)
>> +{
>> + struct socfpga_clk_plat *plat = dev_get_plat(clk->dev);
>> + uintptr_t base_addr = (uintptr_t)plat->regs;
>> + int ret;
>> +
>> + ret = bitmask_from_clk_id(clk);
>> + if (ret == -EOPNOTSUPP)
>> + return 0;
>> +
>> + if (ret)
>> + return ret;
>> +
>> + clrbits_le32(base_addr + plat->pllgrp, plat->bitmask);
>> +
>> + return 0;
>> +}
>> +
>> +static int socfpga_clk_probe(struct udevice *dev)
>> +{
>> + const struct cm_config *cm_default_cfg = cm_get_default_config();
>> +
>> + clk_basic_init(dev, cm_default_cfg);
>> +
>> + return 0;
>> +}
>> +
>> +static int socfpga_clk_of_to_plat(struct udevice *dev)
>> +{
>> + struct socfpga_clk_plat *plat = dev_get_plat(dev);
>> + fdt_addr_t addr;
>> +
>> + addr = dev_read_addr(dev);
>> + if (addr == FDT_ADDR_T_NONE)
>> + return -EINVAL;
>> + plat->regs = (void __iomem *)addr;
>> +
>> + return 0;
>> +}
>> +
>> +static struct clk_ops socfpga_clk_ops = {
>> + .enable = socfpga_clk_enable,
>> + .disable = socfpga_clk_disable,
>> + .get_rate = socfpga_clk_get_rate,
>> +};
>> +
>> +static const struct udevice_id socfpga_clk_match[] = {
>> + { .compatible = "intel,stratix10-clkmgr" },
>> + {}
>> +};
>> +
>> +U_BOOT_DRIVER(socfpga_s10_clk) = {
>> + .name = "clk-s10",
>> + .id = UCLASS_CLK,
>> + .of_match = socfpga_clk_match,
>> + .ops = &socfpga_clk_ops,
>> + .probe = socfpga_clk_probe,
>> + .of_to_plat = socfpga_clk_of_to_plat,
>> + .plat_auto = sizeof(struct socfpga_clk_plat),
>> +};
>> diff --git a/drivers/clk/altera/clk-s10.h b/drivers/clk/altera/clk-s10.h
>> new file mode 100644
>> index 00000000000..f5be1e68500
>> --- /dev/null
>> +++ b/drivers/clk/altera/clk-s10.h
>> @@ -0,0 +1,202 @@
>> +/* SPDX-License-Identifier: GPL-2.0
>> + *
>
>
> NEW FILE, but derived from Intel code
>
> Copyright (C) 2016-2023 Intel Corporation <www.intel.com> ← must add
> (code origin)
>
>
I will add this in v3.
>> + * Copyright (C) 2026 Altera Corporation <www.altera.com>
>> + *
>> + */
>> +
>> +#ifndef _CLK_S10_
>> +#define _CLK_S10_
>> +
>
>
> Best regards,
>
> Tien Fong
>
More information about the U-Boot
mailing list