[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