[U-Boot] [RESEND PATCH v2 07/15] clk: agilex: Add clock driver for Agilex.

Ley Foon Tan lftan.linux at gmail.com
Wed Jul 10 23:03:04 UTC 2019


On Tue, Jul 9, 2019 at 1:13 PM Simon Goldschmidt
<simon.k.r.goldschmidt at gmail.com> wrote:
>
> Am 04.07.2019 um 10:56 schrieb Ley Foon Tan:
> > Add clock manager driver for Agilex. Provides clock initialization
> > and get_rate functions.
>
> Thanks for adding this to the patchset. This is quite a big change, I
> don't have the time currently to review it. Just a question to the
> message above: does 'clock' initialization mean it reads the
> initialization values from devicetree instead of reading them from qts
> header files? If so, is the code better integrated then the A10 code?
For S10 and Agilex, the initialization values is from handoff in FPGA
image, not from device tree as A10.
It is much simpler than A10 implementation.
>
> And further asked, if this works for Agilex, and you added
> "stratix10-clock.h", does this work for S10, too?
Actually "stratix10-clock.h" is from Linux tree,
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/dt-bindings/clock/stratix10-clock.h
I can add Linux commit ID in commit message.

>
> And what are the dependencies to Quartus versions here (e.g. for S10)?
No dependency. Index used in stratix10-clock.h is software defined
index not in HW.
>
> Regards,
> Simon
>
> >
> > stratix10-clock.h is from Linux commit ID     89727949ea1e.
> >
> > Signed-off-by: Chee Hong Ang <chee.hong.ang at intel.com>
> > Signed-off-by: Ley Foon Tan <ley.foon.tan at intel.com>
> >
> > ---
> > v2:
> > - Convert Clock driver to DM
> > ---
> >   .../mach-socfpga/include/mach/clock_manager.h |   2 +
> >   .../include/mach/clock_manager_agilex.h       | 327 ++++++++++
> >   drivers/clk/altera/Makefile                   |   1 +
> >   drivers/clk/altera/clk-agilex.c               | 568 ++++++++++++++++++
> >   include/dt-bindings/clock/stratix10-clock.h   |  84 +++
> >   5 files changed, 982 insertions(+)
> >   create mode 100644 arch/arm/mach-socfpga/include/mach/clock_manager_agilex.h
> >   create mode 100644 drivers/clk/altera/clk-agilex.c
> >   create mode 100644 include/dt-bindings/clock/stratix10-clock.h
> >
> > diff --git a/arch/arm/mach-socfpga/include/mach/clock_manager.h b/arch/arm/mach-socfpga/include/mach/clock_manager.h
> > index dd80e3a767..a3d5de59d2 100644
> > --- a/arch/arm/mach-socfpga/include/mach/clock_manager.h
> > +++ b/arch/arm/mach-socfpga/include/mach/clock_manager.h
> > @@ -18,6 +18,8 @@ void cm_print_clock_quick_summary(void);
> >   #include <asm/arch/clock_manager_arria10.h>
> >   #elif defined(CONFIG_TARGET_SOCFPGA_STRATIX10)
> >   #include <asm/arch/clock_manager_s10.h>
> > +#elif defined(CONFIG_TARGET_SOCFPGA_AGILEX)
> > +#include <asm/arch/clock_manager_agilex.h>
> >   #endif
> >
> >   #endif /* _CLOCK_MANAGER_H_ */
> > diff --git a/arch/arm/mach-socfpga/include/mach/clock_manager_agilex.h b/arch/arm/mach-socfpga/include/mach/clock_manager_agilex.h
> > new file mode 100644
> > index 0000000000..bf5e7c8775
> > --- /dev/null
> > +++ b/arch/arm/mach-socfpga/include/mach/clock_manager_agilex.h
> > @@ -0,0 +1,327 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (C) 2019 Intel Corporation <www.intel.com>
> > + */
> > +
> > +#ifndef      _CLOCK_MANAGER_AGILEX_
> > +#define      _CLOCK_MANAGER_AGILEX_
> > +
> > +#define CM_REG_READL(plat, reg)                      \
> > +             readl(plat->regs + (reg))
> > +
> > +#define CM_REG_WRITEL(plat, data, reg)               \
> > +             writel(data, plat->regs + (reg))
> > +
> > +#define CM_REG_CLRBITS(plat, mask, reg)              \
> > +             clrbits_le32(plat->regs + (reg), (mask))
> > +
> > +#define CM_REG_SETBITS(plat, mask, reg)              \
> > +             setbits_le32(plat->regs + (reg), (mask))
> > +
> > +#define CM_REG_CLRSETBITS(plat, mask, data, reg)     \
> > +             clrsetbits_le32(plat->regs + (reg), (mask), (data))
> > +
> > +const unsigned int cm_get_osc_clk_hz(void);
> > +const unsigned int cm_get_intosc_clk_hz(void);
> > +const unsigned int cm_get_fpga_clk_hz(void);
> > +
> > +#define CLKMGR_EOSC1_HZ              25000000
> > +#define CLKMGR_INTOSC_HZ     400000000
> > +#define CLKMGR_FPGA_CLK_HZ   50000000
> > +
> > +/* Clock configuration accessors */
> > +const struct cm_config * const cm_get_default_config(void);
> > +
> > +struct cm_config {
> > +     /* main group */
> > +     u32 main_pll_mpuclk;
> > +     u32 main_pll_nocclk;
> > +     u32 main_pll_nocdiv;
> > +     u32 main_pll_pllglob;
> > +     u32 main_pll_fdbck;
> > +     u32 main_pll_pllc0;
> > +     u32 main_pll_pllc1;
> > +     u32 main_pll_pllc2;
> > +     u32 main_pll_pllc3;
> > +     u32 main_pll_pllm;
> > +
> > +     /* peripheral group */
> > +     u32 per_pll_emacctl;
> > +     u32 per_pll_gpiodiv;
> > +     u32 per_pll_pllglob;
> > +     u32 per_pll_fdbck;
> > +     u32 per_pll_pllc0;
> > +     u32 per_pll_pllc1;
> > +     u32 per_pll_pllc2;
> > +     u32 per_pll_pllc3;
> > +     u32 per_pll_pllm;
> > +
> > +     /* altera group */
> > +     u32 alt_emacactr;
> > +     u32 alt_emacbctr;
> > +     u32 alt_emacptpctr;
> > +     u32 alt_gpiodbctr;
> > +     u32 alt_sdmmcctr;
> > +     u32 alt_s2fuser0ctr;
> > +     u32 alt_s2fuser1ctr;
> > +     u32 alt_psirefctr;
> > +
> > +     /* incoming clock */
> > +     u32 hps_osc_clk_hz;
> > +     u32 fpga_clk_hz;
> > +     u32 spare[3];
> > +};
> > +
> > +/* Register access with structure */
> > +struct socfpga_clock_manager_main_pll {
> > +     u32 en;
> > +     u32 ens;
> > +     u32 enr;
> > +     u32 bypass;
> > +     u32 bypasss;
> > +     u32 bypassr;
> > +     u32 mpuclk;
> > +     u32 nocclk;
> > +     u32 nocdiv;
> > +     u32 pllglob;
> > +     u32 fdbck;
> > +     u32 mem;
> > +     u32 memstat;
> > +     u32 pllc0;
> > +     u32 pllc1;
> > +     u32 vcocalib;
> > +     u32 pllc2;
> > +     u32 pllc3;
> > +     u32 pllm;
> > +     u32 fhop;
> > +     u32 ssc;
> > +     u32 lostlock;
> > +};
> > +
> > +struct socfpga_clock_manager_per_pll {
> > +     u32 en;
> > +     u32 ens;
> > +     u32 enr;
> > +     u32 bypass;
> > +     u32 bypasss;
> > +     u32 bypassr;
> > +     u32 emacctl;
> > +     u32 gpiodiv;
> > +     u32 pllglob;
> > +     u32 fdbck;
> > +     u32 mem;
> > +     u32 memstat;
> > +     u32 pllc0;
> > +     u32 pllc1;
> > +     u32 vcocalib;
> > +     u32 pllc2;
> > +     u32 pllc3;
> > +     u32 pllm;
> > +     u32 fhop;
> > +     u32 ssc;
> > +     u32 lostlock;
> > +};
> > +
> > +struct socfpga_clock_manager_alt_pll {
> > +     u32 jtag;
> > +     u32 emacactr;
> > +     u32 emacbctr;
> > +     u32 emacptpctr;
> > +     u32 gpiodbctr;
> > +     u32 sdmmcctr;
> > +     u32 s2fuser0ctr;
> > +     u32 s2fuser1ctr;
> > +     u32 psirefctr;
> > +     u32 extcntrst;
> > +};
> > +
> > +struct socfpga_clock_manager {
> > +     u32 ctrl;
> > +     u32 stat;
> > +     u32 testioctrl;
> > +     u32 intrgen;
> > +     u32 intrmsk;
> > +     u32 intrclr;
> > +     u32 intrsts;
> > +     u32 intrstk;
> > +     u32 intrraw;
> > +     struct socfpga_clock_manager_main_pll main_pll;
> > +     struct socfpga_clock_manager_per_pll per_pll;
> > +     struct socfpga_clock_manager_alt_pll alt_pll;
> > +};
> > +
> > +/* Register access with macro functions */
> > +/* Clock Manager registers */
> > +#define CM_REG_CTRL                          0
> > +#define CM_REG_STAT                          4
> > +#define CM_REG_TESTIOCTRL                    8
> > +#define CM_REG_INTRGEN                               0x0c
> > +#define CM_REG_INTRMSK                               0x10
> > +#define CM_REG_INTRCLR                               0x14
> > +#define CM_REG_INTRSTS                               0x18
> > +#define CM_REG_INTRSTK                               0x1c
> > +#define CM_REG_INTRRAW                               0x20
> > +
> > +/* Clock Manager Main PPL group registers */
> > +#define CM_MAINPLL_REG_EN                    0x24
> > +#define CM_MAINPLL_REG_ENS                   0x28
> > +#define CM_MAINPLL_REG_ENR                   0x2c
> > +#define CM_MAINPLL_REG_BYPASS                        0x30
> > +#define CM_MAINPLL_REG_BYPASSS                       0x34
> > +#define CM_MAINPLL_REG_BYPASSR                       0x38
> > +#define CM_MAINPLL_REG_MPUCLK                        0x3c
> > +#define CM_MAINPLL_REG_NOCCLK                        0x40
> > +#define CM_MAINPLL_REG_NOCDIV                        0x44
> > +#define CM_MAINPLL_REG_PLLGLOB                       0x48
> > +#define CM_MAINPLL_REG_FDBCK                 0x4c
> > +#define CM_MAINPLL_REG_MEM                   0x50
> > +#define CM_MAINPLL_REG_MEMSTAT                       0x54
> > +#define CM_MAINPLL_REG_PLLC0                 0x58
> > +#define CM_MAINPLL_REG_PLLC1                 0x5c
> > +#define CM_MAINPLL_REG_VCOCALIB                      0x60
> > +#define CM_MAINPLL_REG_PLLC2                 0x64
> > +#define CM_MAINPLL_REG_PLLC3                 0x68
> > +#define CM_MAINPLL_REG_PLLM                  0x6c
> > +#define CM_MAINPLL_REG_FHOP                  0x70
> > +#define CM_MAINPLL_REG_SSC                   0x74
> > +#define CM_MAINPLL_REG_LOSTLOCK                      0x78
> > +
> > +/* Clock Manager Peripheral PPL group registers */
> > +#define CM_PERPLL_REG_EN                     0x7c
> > +#define CM_PERPLL_REG_ENS                    0x80
> > +#define CM_PERPLL_REG_ENR                    0x84
> > +#define CM_PERPLL_REG_BYPASS                 0x88
> > +#define CM_PERPLL_REG_BYPASSS                        0x8c
> > +#define CM_PERPLL_REG_BYPASSR                        0x90
> > +#define CM_PERPLL_REG_EMACCTL                        0x94
> > +#define CM_PERPLL_REG_GPIODIV                        0x98
> > +#define CM_PERPLL_REG_PLLGLOB                        0x9c
> > +#define CM_PERPLL_REG_FDBCK                  0xa0
> > +#define CM_PERPLL_REG_MEM                    0xa4
> > +#define CM_PERPLL_REG_MEMSTAT                        0xa8
> > +#define CM_PERPLL_REG_PLLC0                  0xac
> > +#define CM_PERPLL_REG_PLLC1                  0xb0
> > +#define CM_PERPLL_REG_VCOCALIB                       0xb4
> > +#define CM_PERPLL_REG_PLLC2                  0xb8
> > +#define CM_PERPLL_REG_PLLC3                  0xbc
> > +#define CM_PERPLL_REG_PLLM                   0xc0
> > +#define CM_PERPLL_REG_FHOP                   0xc4
> > +#define CM_PERPLL_REG_SSC                    0xc8
> > +#define CM_PERPLL_REG_LOSTLOCK                       0xcc
> > +
> > +/* Clock Manager Altera group registers */
> > +#define CM_ALTERA_REG_JTAG                   0xd0
> > +#define CM_ALTERA_REG_EMACACTR                       0xd4
> > +#define CM_ALTERA_REG_EMACBCTR                       0xd8
> > +#define CM_ALTERA_REG_EMACPTPCTR             0xdc
> > +#define CM_ALTERA_REG_GPIODBCTR                      0xe0
> > +#define CM_ALTERA_REG_SDMMCCTR                       0xe4
> > +#define CM_ALTERA_REG_S2FUSER0CTR            0xe8
> > +#define CM_ALTERA_REG_S2FUSER1CTR            0xec
> > +#define CM_ALTERA_REG_PSIREFCTR                      0xf0
> > +#define CM_ALTERA_REG_EXTCNTRST                      0xf4
> > +
> > +#define CLKMGR_CTRL_BOOTMODE                 BIT(0)
> > +
> > +#define CLKMGR_STAT_BUSY                     BIT(0)
> > +#define CLKMGR_STAT_MAINPLL_LOCKED           BIT(8)
> > +#define CLKMGR_STAT_MAIN_TRANS                       BIT(9)
> > +#define CLKMGR_STAT_PERPLL_LOCKED            BIT(16)
> > +#define CLKMGR_STAT_PERF_TRANS                       BIT(17)
> > +#define CLKMGR_STAT_BOOTMODE                 BIT(24)
> > +#define CLKMGR_STAT_BOOTCLKSRC                       BIT(25)
> > +
> > +#define CLKMGR_STAT_ALLPLL_LOCKED_MASK               \
> > +             (CLKMGR_STAT_MAINPLL_LOCKED | CLKMGR_STAT_PERPLL_LOCKED)
> > +
> > +#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_CLKSRC_MASK                   GENMASK(18, 16)
> > +#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                    GENMASK(10, 0)
> > +
> > +#define CLKMGR_BYPASS_MAINPLL_ALL            0x7
> > +#define CLKMGR_BYPASS_PERPLL_ALL             0x7f
> > +
> > +#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_DIVIDER_MASK           0x3
> > +
> > +#define CLKMGR_PLLGLOB_PD_MASK                       BIT(0)
> > +#define CLKMGR_PLLGLOB_RST_MASK                      BIT(1)
> > +#define CLKMGR_PLLGLOB_AREFCLKDIV_MASK               GENMASK(11, 8)
> > +#define CLKMGR_PLLGLOB_DREFCLKDIV_MASK               GENMASK(13, 12)
> > +#define CLKMGR_PLLGLOB_REFCLKDIV_MASK                GENMASK(13, 8)
> > +#define CLKMGR_PLLGLOB_MODCLKDIV_MASK                GENMASK(24, 27)
> > +#define CLKMGR_PLLGLOB_AREFCLKDIV_OFFSET     8
> > +#define CLKMGR_PLLGLOB_DREFCLKDIV_OFFSET     12
> > +#define CLKMGR_PLLGLOB_REFCLKDIV_OFFSET              8
> > +#define CLKMGR_PLLGLOB_MODCLKDIV_OFFSET              24
> > +#define CLKMGR_PLLGLOB_VCO_PSRC_MASK         GENMASK(17, 16)
> > +#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_MEM_REQ_SET_MSK                       BIT(24)
> > +#define CLKMGR_MEM_WR_SET_MSK                        BIT(25)
> > +#define CLKMGR_MEM_ERR_MSK                   BIT(26)
> > +#define CLKMGR_MEM_WDAT_LSB_OFFSET           16
> > +#define CLKMGR_MEM_ADDR_MASK                 GENMASK(15, 0)
> > +#define CLKMGR_MEM_ADDR_START                        0x00004000
> > +
> > +#define CLKMGR_PLLCX_EN_SET_MSK                      BIT(27)
> > +#define CLKMGR_PLLCX_MUTE_SET_MSK            BIT(28)
> > +
> > +#define CLKMGR_VCOCALIB_MSCNT_MASK           GENMASK(23, 16)
> > +#define CLKMGR_VCOCALIB_MSCNT_OFFSET         16
> > +#define CLKMGR_VCOCALIB_HSCNT_MASK           GENMASK(9, 0)
> > +#define CLKMGR_VCOCALIB_MSCNT_CONST          100
> > +#define CLKMGR_VCOCALIB_HSCNT_CONST          4
> > +
> > +#define CLKMGR_PLLM_MDIV_MASK                        GENMASK(9, 0)
> > +
> > +#define CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK            BIT(5)
> > +#define CLKMGR_PERPLLGRP_EMACCTL_EMAC0SELB_OFFSET    26
> > +#define CLKMGR_PERPLLGRP_EMACCTL_EMAC0SELB_MASK              BIT(26)
> > +#define CLKMGR_PERPLLGRP_EMACCTL_EMAC1SELB_OFFSET    27
> > +#define CLKMGR_PERPLLGRP_EMACCTL_EMAC1SELB_MASK              BIT(27)
> > +#define CLKMGR_PERPLLGRP_EMACCTL_EMAC2SELB_OFFSET    28
> > +#define CLKMGR_PERPLLGRP_EMACCTL_EMAC2SELB_MASK              BIT(28)
> > +
> > +#define CLKMGR_ALT_EMACCTR_SRC_OFFSET                16
> > +#define CLKMGR_ALT_EMACCTR_SRC_MASK          GENMASK(18, 16)
> > +#define CLKMGR_ALT_EMACCTR_CNT_OFFSET                0
> > +#define CLKMGR_ALT_EMACCTR_CNT_MASK          GENMASK(10, 0)
> > +
> > +#define CLKMGR_ALT_EXTCNTRST_EMACACNTRST     BIT(0)
> > +#define CLKMGR_ALT_EXTCNTRST_EMACBCNTRST     BIT(1)
> > +#define CLKMGR_ALT_EXTCNTRST_EMACPTPCNTRST   BIT(2)
> > +#define CLKMGR_ALT_EXTCNTRST_GPIODBCNTRST    BIT(3)
> > +#define CLKMGR_ALT_EXTCNTRST_SDMMCCNTRST     BIT(4)
> > +#define CLKMGR_ALT_EXTCNTRST_S2FUSER0CNTRST  BIT(5)
> > +#define CLKMGR_ALT_EXTCNTRST_S2FUSER1CNTRST  BIT(6)
> > +#define CLKMGR_ALT_EXTCNTRST_PSIREFCNTRST    BIT(7)
> > +#define CLKMGR_ALT_EXTCNTRST_ALLCNTRST               \
> > +             (CLKMGR_ALT_EXTCNTRST_EMACACNTRST | \
> > +              CLKMGR_ALT_EXTCNTRST_EMACBCNTRST | \
> > +              CLKMGR_ALT_EXTCNTRST_EMACPTPCNTRST | \
> > +              CLKMGR_ALT_EXTCNTRST_GPIODBCNTRST | \
> > +              CLKMGR_ALT_EXTCNTRST_SDMMCCNTRST | \
> > +              CLKMGR_ALT_EXTCNTRST_S2FUSER0CNTRST | \
> > +              CLKMGR_ALT_EXTCNTRST_S2FUSER1CNTRST | \
> > +              CLKMGR_ALT_EXTCNTRST_PSIREFCNTRST)
> > +#endif /* _CLOCK_MANAGER_AGILEX_ */
> > diff --git a/drivers/clk/altera/Makefile b/drivers/clk/altera/Makefile
> > index a3ae8b24b0..96215ad5c4 100644
> > --- a/drivers/clk/altera/Makefile
> > +++ b/drivers/clk/altera/Makefile
> > @@ -3,4 +3,5 @@
> >   # Copyright (C) 2018 Marek Vasut <marex at denx.de>
> >   #
> >
> > +obj-$(CONFIG_TARGET_SOCFPGA_AGILEX) += clk-agilex.o
> >   obj-$(CONFIG_TARGET_SOCFPGA_ARRIA10) += clk-arria10.o
> > diff --git a/drivers/clk/altera/clk-agilex.c b/drivers/clk/altera/clk-agilex.c
> > new file mode 100644
> > index 0000000000..052d5e97f4
> > --- /dev/null
> > +++ b/drivers/clk/altera/clk-agilex.c
> > @@ -0,0 +1,568 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2019 Intel Corporation <www.intel.com>
> > + */
> > +
> > +#include <common.h>
> > +#include <asm/io.h>
> > +#include <clk-uclass.h>
> > +#include <dm.h>
> > +#include <dm/lists.h>
> > +#include <dm/util.h>
> > +#include <dt-bindings/clock/stratix10-clock.h>
> > +
> > +#include <asm/arch/clock_manager.h>
> > +
> > +DECLARE_GLOBAL_DATA_PTR;
> > +
> > +struct socfpga_clk_platdata {
> > +     void __iomem *regs;
> > +};
> > +
> > +/*
> > + * function to write the bypass register which requires a poll of the
> > + * busy bit
> > + */
> > +static void clk_write_bypass_mainpll(struct socfpga_clk_platdata *plat, u32 val)
> > +{
> > +     CM_REG_WRITEL(plat, val, CM_MAINPLL_REG_BYPASS);
> > +     cm_wait_for_fsm();
> > +}
> > +
> > +static void clk_write_bypass_perpll(struct socfpga_clk_platdata *plat, u32 val)
> > +{
> > +     CM_REG_WRITEL(plat, val, CM_PERPLL_REG_BYPASS);
> > +     cm_wait_for_fsm();
> > +}
> > +
> > +/* function to write the ctrl register which requires a poll of the busy bit */
> > +static void clk_write_ctrl(struct socfpga_clk_platdata *plat, u32 val)
> > +{
> > +     CM_REG_WRITEL(plat, val, CM_REG_CTRL);
> > +     cm_wait_for_fsm();
> > +}
> > +
> > +#define MEMBUS_MAINPLL                               0
> > +#define MEMBUS_PERPLL                                1
> > +#define MEMBUS_TIMEOUT                               1000
> > +#define MEMBUS_ADDR_CLKSLICE                 0x27
> > +#define MEMBUS_CLKSLICE_SYNC_MODE_EN         0x80
> > +
> > +static int membus_wait_for_req(struct socfpga_clk_platdata *plat, u32 pll,
> > +                            int timeout)
> > +{
> > +     int cnt = 0;
> > +     u32 req_status;
> > +
> > +     if (pll == MEMBUS_MAINPLL)
> > +             req_status = CM_REG_READL(plat, CM_MAINPLL_REG_MEM);
> > +     else
> > +             req_status = CM_REG_READL(plat, CM_PERPLL_REG_MEM);
> > +
> > +     while ((cnt < timeout) && (req_status & CLKMGR_MEM_REQ_SET_MSK)) {
> > +             if (pll == MEMBUS_MAINPLL)
> > +                     req_status = CM_REG_READL(plat, CM_MAINPLL_REG_MEM);
> > +             else
> > +                     req_status = CM_REG_READL(plat, CM_PERPLL_REG_MEM);
> > +             cnt++;
> > +     }
> > +
> > +     if (cnt >= timeout)
> > +             return -ETIMEDOUT;
> > +
> > +     return 0;
> > +}
> > +
> > +static int membus_write_pll(struct socfpga_clk_platdata *plat, u32 pll,
> > +                         u32 addr_offset, u32 wdat, int timeout)
> > +{
> > +     u32 addr;
> > +     u32 val;
> > +
> > +     addr = ((addr_offset | CLKMGR_MEM_ADDR_START) & CLKMGR_MEM_ADDR_MASK);
> > +
> > +     val = (CLKMGR_MEM_REQ_SET_MSK | CLKMGR_MEM_WR_SET_MSK |
> > +            (wdat << CLKMGR_MEM_WDAT_LSB_OFFSET) | addr);
> > +
> > +     if (pll == MEMBUS_MAINPLL)
> > +             CM_REG_WRITEL(plat, val, CM_MAINPLL_REG_MEM);
> > +     else
> > +             CM_REG_WRITEL(plat, val, CM_PERPLL_REG_MEM);
> > +
> > +     debug("MEMBUS: Write 0x%08x to addr = 0x%08x\n", wdat, addr);
> > +
> > +     return membus_wait_for_req(plat, pll, timeout);
> > +}
> > +
> > +static int membus_read_pll(struct socfpga_clk_platdata *plat, u32 pll,
> > +                        u32 addr_offset, u32 *rdata, int timeout)
> > +{
> > +     u32 addr;
> > +     u32 val;
> > +
> > +     addr = ((addr_offset | CLKMGR_MEM_ADDR_START) & CLKMGR_MEM_ADDR_MASK);
> > +
> > +     val = ((CLKMGR_MEM_REQ_SET_MSK & ~CLKMGR_MEM_WR_SET_MSK) | addr);
> > +
> > +     if (pll == MEMBUS_MAINPLL)
> > +             CM_REG_WRITEL(plat, val, CM_MAINPLL_REG_MEM);
> > +     else
> > +             CM_REG_WRITEL(plat, val, CM_PERPLL_REG_MEM);
> > +
> > +     *rdata = 0;
> > +
> > +     if (membus_wait_for_req(plat, pll, timeout))
> > +             return -ETIMEDOUT;
> > +
> > +     if (pll == MEMBUS_MAINPLL)
> > +             *rdata = CM_REG_READL(plat, CM_MAINPLL_REG_MEMSTAT);
> > +     else
> > +             *rdata = CM_REG_READL(plat, CM_PERPLL_REG_MEMSTAT);
> > +
> > +     debug("MEMBUS: Read 0x%08x from addr = 0x%08x\n", *rdata, addr);
> > +
> > +     return 0;
> > +}
> > +
> > +static u32 calc_vocalib_pll(u32 pllm, u32 pllglob)
> > +{
> > +     u32 mdiv, refclkdiv, arefclkdiv, drefclkdiv, mscnt, hscnt, vcocalib;
> > +
> > +     mdiv = pllm & CLKMGR_PLLM_MDIV_MASK;
> > +     arefclkdiv = (pllglob & CLKMGR_PLLGLOB_AREFCLKDIV_MASK) >>
> > +                   CLKMGR_PLLGLOB_AREFCLKDIV_OFFSET;
> > +     drefclkdiv = (pllglob & CLKMGR_PLLGLOB_DREFCLKDIV_MASK) >>
> > +                   CLKMGR_PLLGLOB_DREFCLKDIV_OFFSET;
> > +     refclkdiv = (pllglob & CLKMGR_PLLGLOB_REFCLKDIV_MASK) >>
> > +                  CLKMGR_PLLGLOB_REFCLKDIV_OFFSET;
> > +     mscnt = CLKMGR_VCOCALIB_MSCNT_CONST / (mdiv * BIT(drefclkdiv));
> > +     if (!mscnt)
> > +             mscnt = 1;
> > +     hscnt = (mdiv * mscnt * BIT(drefclkdiv) / refclkdiv) -
> > +             CLKMGR_VCOCALIB_HSCNT_CONST;
> > +     vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) |
> > +                ((mscnt << CLKMGR_VCOCALIB_MSCNT_OFFSET) &
> > +                  CLKMGR_VCOCALIB_MSCNT_MASK);
> > +
> > +     /* Dump all the pll calibration settings for debug purposes */
> > +     debug("mdiv          : %d\n", mdiv);
> > +     debug("arefclkdiv    : %d\n", arefclkdiv);
> > +     debug("drefclkdiv    : %d\n", drefclkdiv);
> > +     debug("refclkdiv     : %d\n", refclkdiv);
> > +     debug("mscnt         : %d\n", mscnt);
> > +     debug("hscnt         : %d\n", hscnt);
> > +     debug("vcocalib      : 0x%08x\n", vcocalib);
> > +
> > +     return vcocalib;
> > +}
> > +
> > +/*
> > + * 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_platdata *plat = dev_get_platdata(dev);
> > +     u32 vcocalib;
> > +     u32 rdata;
> > +
> > +     if (!cfg)
> > +             return;
> > +
> > +     /* Put both PLLs in bypass */
> > +     clk_write_bypass_mainpll(plat, CLKMGR_BYPASS_MAINPLL_ALL);
> > +     clk_write_bypass_perpll(plat, CLKMGR_BYPASS_PERPLL_ALL);
> > +
> > +     /* Put both PLLs in Reset and Power Down */
> > +     CM_REG_CLRBITS(plat, CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK,
> > +                    CM_MAINPLL_REG_PLLGLOB);
> > +     CM_REG_CLRBITS(plat, CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK,
> > +                    CM_PERPLL_REG_PLLGLOB);
> > +
> > +     /* setup main PLL dividers where calculate the vcocalib value */
> > +     vcocalib = calc_vocalib_pll(cfg->main_pll_pllm, cfg->main_pll_pllglob);
> > +     CM_REG_WRITEL(plat, cfg->main_pll_pllglob & ~CLKMGR_PLLGLOB_RST_MASK,
> > +                   CM_MAINPLL_REG_PLLGLOB);
> > +     CM_REG_WRITEL(plat, cfg->main_pll_fdbck, CM_MAINPLL_REG_FDBCK);
> > +     CM_REG_WRITEL(plat, vcocalib, CM_MAINPLL_REG_VCOCALIB);
> > +     CM_REG_WRITEL(plat, cfg->main_pll_pllc0, CM_MAINPLL_REG_PLLC0);
> > +     CM_REG_WRITEL(plat, cfg->main_pll_pllc1, CM_MAINPLL_REG_PLLC1);
> > +     CM_REG_WRITEL(plat, cfg->main_pll_pllc2, CM_MAINPLL_REG_PLLC2);
> > +     CM_REG_WRITEL(plat, cfg->main_pll_pllc3, CM_MAINPLL_REG_PLLC3);
> > +     CM_REG_WRITEL(plat, cfg->main_pll_pllm, CM_MAINPLL_REG_PLLM);
> > +     CM_REG_WRITEL(plat, cfg->main_pll_mpuclk, CM_MAINPLL_REG_MPUCLK);
> > +     CM_REG_WRITEL(plat, cfg->main_pll_nocclk, CM_MAINPLL_REG_NOCCLK);
> > +     CM_REG_WRITEL(plat, cfg->main_pll_nocdiv, CM_MAINPLL_REG_NOCDIV);
> > +
> > +     /* setup peripheral PLL dividers where calculate the vcocalib value */
> > +     vcocalib = calc_vocalib_pll(cfg->per_pll_pllm, cfg->per_pll_pllglob);
> > +     CM_REG_WRITEL(plat, cfg->per_pll_pllglob & ~CLKMGR_PLLGLOB_RST_MASK,
> > +                   CM_PERPLL_REG_PLLGLOB);
> > +     CM_REG_WRITEL(plat, cfg->per_pll_fdbck, CM_PERPLL_REG_FDBCK);
> > +     CM_REG_WRITEL(plat, vcocalib, CM_PERPLL_REG_VCOCALIB);
> > +     CM_REG_WRITEL(plat, cfg->per_pll_pllc0, CM_PERPLL_REG_PLLC0);
> > +     CM_REG_WRITEL(plat, cfg->per_pll_pllc1, CM_PERPLL_REG_PLLC1);
> > +     CM_REG_WRITEL(plat, cfg->per_pll_pllc2, CM_PERPLL_REG_PLLC2);
> > +     CM_REG_WRITEL(plat, cfg->per_pll_pllc3, CM_PERPLL_REG_PLLC3);
> > +     CM_REG_WRITEL(plat, cfg->per_pll_pllm, CM_PERPLL_REG_PLLM);
> > +     CM_REG_WRITEL(plat, cfg->per_pll_emacctl, CM_PERPLL_REG_EMACCTL);
> > +     CM_REG_WRITEL(plat, cfg->per_pll_gpiodiv, CM_PERPLL_REG_GPIODIV);
> > +
> > +     /* Take both PLL out of reset and power up */
> > +     CM_REG_SETBITS(plat, CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK,
> > +                    CM_MAINPLL_REG_PLLGLOB);
> > +     CM_REG_SETBITS(plat, CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK,
> > +                    CM_PERPLL_REG_PLLGLOB);
> > +
> > +     /* Membus programming to set mainpll and perripll to
> > +      * source synchronous mode
> > +      */
> > +     membus_read_pll(plat, MEMBUS_MAINPLL, MEMBUS_ADDR_CLKSLICE, &rdata,
> > +                     MEMBUS_TIMEOUT);
> > +     membus_write_pll(plat, MEMBUS_MAINPLL, MEMBUS_ADDR_CLKSLICE,
> > +                      (rdata | MEMBUS_CLKSLICE_SYNC_MODE_EN),
> > +                      MEMBUS_TIMEOUT);
> > +     membus_read_pll(plat, MEMBUS_PERPLL, MEMBUS_ADDR_CLKSLICE, &rdata,
> > +                     MEMBUS_TIMEOUT);
> > +     membus_write_pll(plat, MEMBUS_PERPLL, MEMBUS_ADDR_CLKSLICE,
> > +                      (rdata | MEMBUS_CLKSLICE_SYNC_MODE_EN),
> > +                      MEMBUS_TIMEOUT);
> > +
> > +     cm_wait_for_lock(CLKMGR_STAT_ALLPLL_LOCKED_MASK);
> > +
> > +     /* Configure ping pong counters in altera group */
> > +     CM_REG_WRITEL(plat, cfg->alt_emacactr, CM_ALTERA_REG_EMACACTR);
> > +     CM_REG_WRITEL(plat, cfg->alt_emacbctr, CM_ALTERA_REG_EMACBCTR);
> > +     CM_REG_WRITEL(plat, cfg->alt_emacptpctr, CM_ALTERA_REG_EMACPTPCTR);
> > +     CM_REG_WRITEL(plat, cfg->alt_gpiodbctr, CM_ALTERA_REG_GPIODBCTR);
> > +     CM_REG_WRITEL(plat, cfg->alt_sdmmcctr, CM_ALTERA_REG_SDMMCCTR);
> > +     CM_REG_WRITEL(plat, cfg->alt_s2fuser0ctr, CM_ALTERA_REG_S2FUSER0CTR);
> > +     CM_REG_WRITEL(plat, cfg->alt_s2fuser1ctr, CM_ALTERA_REG_S2FUSER1CTR);
> > +     CM_REG_WRITEL(plat, cfg->alt_psirefctr, CM_ALTERA_REG_PSIREFCTR);
> > +
> > +     /* Take all PLLs out of bypass */
> > +     clk_write_bypass_mainpll(plat, 0);
> > +     clk_write_bypass_perpll(plat, 0);
> > +
> > +     /* Clear the loss of lock bits (write 1 to clear) */
> > +     CM_REG_CLRBITS(plat, CLKMGR_INTER_PERPLLLOST_MASK |
> > +                    CLKMGR_INTER_MAINPLLLOST_MASK, CM_REG_INTRCLR);
> > +
> > +     /* Take all ping pong counters out of reset */
> > +     CM_REG_CLRBITS(plat, CLKMGR_ALT_EXTCNTRST_ALLCNTRST,
> > +                    CM_ALTERA_REG_EXTCNTRST);
> > +
> > +     /* Out of boot mode */
> > +     clk_write_ctrl(plat,
> > +                    CM_REG_READL(plat, CM_REG_CTRL) & ~CLKMGR_CTRL_BOOTMODE);
> > +}
> > +
> > +static u64 clk_get_vco_clk_hz(struct socfpga_clk_platdata *plat,
> > +                           u32 pllglob_reg, u32 pllm_reg)
> > +{
> > +      u64 fref, arefdiv, mdiv, reg, vco;
> > +
> > +     reg = CM_REG_READL(plat, pllglob_reg);
> > +
> > +     fref = (reg & CLKMGR_PLLGLOB_VCO_PSRC_MASK) >>
> > +             CLKMGR_PLLGLOB_VCO_PSRC_OFFSET;
> > +
> > +     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;
> > +     }
> > +
> > +     arefdiv = (reg & CLKMGR_PLLGLOB_AREFCLKDIV_MASK) >>
> > +                CLKMGR_PLLGLOB_AREFCLKDIV_OFFSET;
> > +
> > +     mdiv = CM_REG_READL(plat, pllm_reg) & CLKMGR_PLLM_MDIV_MASK;
> > +
> > +     vco = fref / arefdiv;
> > +     vco = vco * mdiv;
> > +
> > +     return vco;
> > +}
> > +
> > +static u64 clk_get_main_vco_clk_hz(struct socfpga_clk_platdata *plat)
> > +{
> > +     return clk_get_vco_clk_hz(plat, CM_MAINPLL_REG_PLLGLOB,
> > +                              CM_MAINPLL_REG_PLLM);
> > +}
> > +
> > +static u64 clk_get_per_vco_clk_hz(struct socfpga_clk_platdata *plat)
> > +{
> > +     return clk_get_vco_clk_hz(plat, CM_PERPLL_REG_PLLGLOB,
> > +                              CM_PERPLL_REG_PLLM);
> > +}
> > +
> > +static u32 clk_get_5_1_clk_src(struct socfpga_clk_platdata *plat, u64 reg)
> > +{
> > +     u32 clksrc = CM_REG_READL(plat, reg);
> > +
> > +     return (clksrc & CLKMGR_CLKSRC_MASK) >> CLKMGR_CLKSRC_OFFSET;
> > +}
> > +
> > +static u64 clk_get_clksrc_hz(struct socfpga_clk_platdata *plat, u32 clksrc_reg,
> > +                          u32 main_reg, u32 per_reg)
> > +{
> > +     u64 clock;
> > +     u32 clklsrc = clk_get_5_1_clk_src(plat, clksrc_reg);
> > +
> > +     switch (clklsrc) {
> > +     case CLKMGR_CLKSRC_MAIN:
> > +             clock = clk_get_main_vco_clk_hz(plat);
> > +             clock /= (CM_REG_READL(plat, main_reg) &
> > +                       CLKMGR_CLKCNT_MSK);
> > +             break;
> > +
> > +     case CLKMGR_CLKSRC_PER:
> > +             clock = clk_get_per_vco_clk_hz(plat);
> > +             clock /= (CM_REG_READL(plat, per_reg) &
> > +                       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;
> > +}
> > +
> > +static u64 clk_get_mpu_clk_hz(struct socfpga_clk_platdata *plat)
> > +{
> > +     u64 clock = clk_get_clksrc_hz(plat, CM_MAINPLL_REG_MPUCLK,
> > +                                   CM_MAINPLL_REG_PLLC0,
> > +                                   CM_PERPLL_REG_PLLC0);
> > +
> > +     clock /= 1 + (CM_REG_READL(plat, CM_MAINPLL_REG_MPUCLK) &
> > +              CLKMGR_CLKCNT_MSK);
> > +
> > +     return clock;
> > +}
> > +
> > +static u32 clk_get_l3_main_clk_hz(struct socfpga_clk_platdata *plat)
> > +{
> > +     return clk_get_clksrc_hz(plat, CM_MAINPLL_REG_NOCCLK,
> > +                                   CM_MAINPLL_REG_PLLC1,
> > +                                   CM_PERPLL_REG_PLLC1);
> > +}
> > +
> > +static u32 clk_get_l4_main_clk_hz(struct socfpga_clk_platdata *plat)
> > +{
> > +     u64 clock = clk_get_l3_main_clk_hz(plat);
> > +
> > +     clock /= BIT((CM_REG_READL(plat, CM_MAINPLL_REG_NOCDIV) >>
> > +           CLKMGR_NOCDIV_L4MAIN_OFFSET) &
> > +           CLKMGR_NOCDIV_DIVIDER_MASK);
> > +
> > +     return clock;
> > +}
> > +
> > +static u32 clk_get_sdmmc_clk_hz(struct socfpga_clk_platdata *plat)
> > +{
> > +     u64 clock = clk_get_clksrc_hz(plat, CM_ALTERA_REG_SDMMCCTR,
> > +                                   CM_MAINPLL_REG_PLLC3,
> > +                                   CM_PERPLL_REG_PLLC3);
> > +
> > +     clock /= 1 + (CM_REG_READL(plat, CM_ALTERA_REG_SDMMCCTR) &
> > +              CLKMGR_CLKCNT_MSK);
> > +
> > +     return clock / 4;
> > +}
> > +
> > +static u32 clk_get_l4_sp_clk_hz(struct socfpga_clk_platdata *plat)
> > +{
> > +     u64 clock = clk_get_l3_main_clk_hz(plat);
> > +
> > +     clock /= BIT((CM_REG_READL(plat, CM_MAINPLL_REG_NOCDIV) >>
> > +                   CLKMGR_NOCDIV_L4SPCLK_OFFSET) &
> > +                   CLKMGR_NOCDIV_DIVIDER_MASK);
> > +
> > +     return clock;
> > +}
> > +
> > +static u32 clk_get_l4_mp_clk_hz(struct socfpga_clk_platdata *plat)
> > +{
> > +     u64 clock = clk_get_l3_main_clk_hz(plat);
> > +
> > +     clock /= BIT((CM_REG_READL(plat, CM_MAINPLL_REG_NOCDIV) >>
> > +                   CLKMGR_NOCDIV_L4MPCLK_OFFSET) &
> > +                   CLKMGR_NOCDIV_DIVIDER_MASK);
> > +
> > +     return clock;
> > +}
> > +
> > +static u32 clk_get_l4_sys_free_clk_hz(struct socfpga_clk_platdata *plat)
> > +{
> > +     if (CM_REG_READL(plat, CM_REG_STAT) & CLKMGR_STAT_BOOTMODE)
> > +             return clk_get_l3_main_clk_hz(plat) / 2;
> > +
> > +     return clk_get_l3_main_clk_hz(plat) / 4;
> > +}
> > +
> > +static u32 clk_get_emac_clk_hz(struct socfpga_clk_platdata *plat, u32 emac_id)
> > +{
> > +     bool emacsel_a;
> > +     u32 ctl;
> > +     u32 ctr_reg;
> > +     u32 clock;
> > +     u32 div;
> > +     u32 reg;
> > +
> > +     /* Get EMAC clock source */
> > +     ctl = CM_REG_READL(plat, CM_PERPLL_REG_EMACCTL);
> > +     if (emac_id == STRATIX10_EMAC0_CLK)
> > +             ctl = (ctl >> CLKMGR_PERPLLGRP_EMACCTL_EMAC0SELB_OFFSET) &
> > +                    CLKMGR_PERPLLGRP_EMACCTL_EMAC0SELB_MASK;
> > +     else if (emac_id == STRATIX10_EMAC1_CLK)
> > +             ctl = (ctl >> CLKMGR_PERPLLGRP_EMACCTL_EMAC1SELB_OFFSET) &
> > +                    CLKMGR_PERPLLGRP_EMACCTL_EMAC1SELB_MASK;
> > +     else if (emac_id == STRATIX10_EMAC2_CLK)
> > +             ctl = (ctl >> CLKMGR_PERPLLGRP_EMACCTL_EMAC2SELB_OFFSET) &
> > +                    CLKMGR_PERPLLGRP_EMACCTL_EMAC2SELB_MASK;
> > +     else
> > +             return 0;
> > +
> > +     if (ctl) {
> > +             /* EMAC B source */
> > +             emacsel_a = false;
> > +             ctr_reg = CM_ALTERA_REG_EMACBCTR;
> > +     } else {
> > +             /* EMAC A source */
> > +             emacsel_a = true;
> > +             ctr_reg = CM_ALTERA_REG_EMACACTR;
> > +     }
> > +
> > +     reg = CM_REG_READL(plat, ctr_reg);
> > +     clock = (reg & CLKMGR_ALT_EMACCTR_SRC_MASK)
> > +              >> CLKMGR_ALT_EMACCTR_SRC_OFFSET;
> > +     div = (reg & CLKMGR_ALT_EMACCTR_CNT_MASK)
> > +             >> CLKMGR_ALT_EMACCTR_CNT_OFFSET;
> > +
> > +     switch (clock) {
> > +     case CLKMGR_CLKSRC_MAIN:
> > +             clock = clk_get_main_vco_clk_hz(plat);
> > +             if (emacsel_a) {
> > +                     clock /= (CM_REG_READL(plat, CM_MAINPLL_REG_PLLC2) &
> > +                               CLKMGR_CLKCNT_MSK);
> > +             } else {
> > +                     clock /= (CM_REG_READL(plat, CM_MAINPLL_REG_PLLC3) &
> > +                               CLKMGR_CLKCNT_MSK);
> > +             }
> > +             break;
> > +
> > +     case CLKMGR_CLKSRC_PER:
> > +             clock = clk_get_per_vco_clk_hz(plat);
> > +             if (emacsel_a) {
> > +                     clock /= (CM_REG_READL(plat, CM_PERPLL_REG_PLLC2) &
> > +                               CLKMGR_CLKCNT_MSK);
> > +             } else {
> > +                     clock /= (CM_REG_READL(plat, CM_PERPLL_REG_PLLC3) &
> > +                               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 + div;
> > +
> > +     return clock;
> > +}
> > +
> > +static ulong socfpga_clk_get_rate(struct clk *clk)
> > +{
> > +     struct socfpga_clk_platdata *plat = dev_get_platdata(clk->dev);
> > +
> > +     switch (clk->id) {
> > +     case STRATIX10_MPU_CLK:
> > +             return clk_get_mpu_clk_hz(plat);
> > +     case STRATIX10_L4_MAIN_CLK:
> > +             return clk_get_l4_main_clk_hz(plat);
> > +     case STRATIX10_L4_SYS_FREE_CLK:
> > +             return clk_get_l4_sys_free_clk_hz(plat);
> > +     case STRATIX10_L4_MP_CLK:
> > +             return clk_get_l4_mp_clk_hz(plat);
> > +     case STRATIX10_L4_SP_CLK:
> > +             return clk_get_l4_sp_clk_hz(plat);
> > +     case STRATIX10_SDMMC_CLK:
> > +             return clk_get_sdmmc_clk_hz(plat);
> > +     case STRATIX10_EMAC0_CLK:
> > +     case STRATIX10_EMAC1_CLK:
> > +     case STRATIX10_EMAC2_CLK:
> > +             return clk_get_emac_clk_hz(plat, clk->id);
> > +     case STRATIX10_USB_CLK:
> > +             return clk_get_l4_mp_clk_hz(plat);
> > +     default:
> > +             return -ENXIO;
> > +     }
> > +}
> > +
> > +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_ofdata_to_platdata(struct udevice *dev)
> > +{
> > +     struct socfpga_clk_platdata *plat = dev_get_platdata(dev);
> > +     fdt_addr_t addr;
> > +
> > +     addr = devfdt_get_addr(dev);
> > +     if (addr == FDT_ADDR_T_NONE)
> > +             return -EINVAL;
> > +     plat->regs = (void __iomem *)addr;
> > +
> > +     return 0;
> > +}
> > +
> > +static struct clk_ops socfpga_clk_ops = {
> > +     .get_rate       = socfpga_clk_get_rate,
> > +};
> > +
> > +static const struct udevice_id socfpga_clk_match[] = {
> > +     { .compatible = "intel,agilex-clkmgr" },
> > +     {}
> > +};
> > +
> > +U_BOOT_DRIVER(socfpga_agilex_clk) = {
> > +     .name           = "clk-agilex",
> > +     .id             = UCLASS_CLK,
> > +     .of_match       = socfpga_clk_match,
> > +     .ops            = &socfpga_clk_ops,
> > +     .probe          = socfpga_clk_probe,
> > +     .ofdata_to_platdata = socfpga_clk_ofdata_to_platdata,
> > +     .platdata_auto_alloc_size = sizeof(struct socfpga_clk_platdata),
> > +};
> > diff --git a/include/dt-bindings/clock/stratix10-clock.h b/include/dt-bindings/clock/stratix10-clock.h
> > new file mode 100644
> > index 0000000000..95f58eea85
> > --- /dev/null
> > +++ b/include/dt-bindings/clock/stratix10-clock.h
> > @@ -0,0 +1,84 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (C) 2017, Intel Corporation
> > + */
> > +
> > +#ifndef __STRATIX10_CLOCK_H
> > +#define __STRATIX10_CLOCK_H
> > +
> > +/* fixed rate clocks */
> > +#define STRATIX10_OSC1                       0
> > +#define STRATIX10_CB_INTOSC_HS_DIV2_CLK      1
> > +#define STRATIX10_CB_INTOSC_LS_CLK   2
> > +#define STRATIX10_F2S_FREE_CLK               3
> > +
> > +/* fixed factor clocks */
> > +#define STRATIX10_L4_SYS_FREE_CLK    4
> > +#define STRATIX10_MPU_PERIPH_CLK     5
> > +#define STRATIX10_MPU_L2RAM_CLK              6
> > +#define STRATIX10_SDMMC_CIU_CLK              7
> > +
> > +/* PLL clocks */
> > +#define STRATIX10_MAIN_PLL_CLK               8
> > +#define STRATIX10_PERIPH_PLL_CLK     9
> > +#define STRATIX10_BOOT_CLK           10
> > +
> > +/* Periph clocks */
> > +#define STRATIX10_MAIN_MPU_BASE_CLK  11
> > +#define STRATIX10_MAIN_NOC_BASE_CLK  12
> > +#define STRATIX10_MAIN_EMACA_CLK     13
> > +#define STRATIX10_MAIN_EMACB_CLK     14
> > +#define STRATIX10_MAIN_EMAC_PTP_CLK  15
> > +#define STRATIX10_MAIN_GPIO_DB_CLK   16
> > +#define STRATIX10_MAIN_SDMMC_CLK     17
> > +#define STRATIX10_MAIN_S2F_USR0_CLK  18
> > +#define STRATIX10_MAIN_S2F_USR1_CLK  19
> > +#define STRATIX10_MAIN_PSI_REF_CLK   20
> > +
> > +#define STRATIX10_PERI_MPU_BASE_CLK  21
> > +#define STRATIX10_PERI_NOC_BASE_CLK  22
> > +#define STRATIX10_PERI_EMACA_CLK     23
> > +#define STRATIX10_PERI_EMACB_CLK     24
> > +#define STRATIX10_PERI_EMAC_PTP_CLK  25
> > +#define STRATIX10_PERI_GPIO_DB_CLK   26
> > +#define STRATIX10_PERI_SDMMC_CLK     27
> > +#define STRATIX10_PERI_S2F_USR0_CLK  28
> > +#define STRATIX10_PERI_S2F_USR1_CLK  29
> > +#define STRATIX10_PERI_PSI_REF_CLK   30
> > +
> > +#define STRATIX10_MPU_FREE_CLK               31
> > +#define STRATIX10_NOC_FREE_CLK               32
> > +#define STRATIX10_S2F_USR0_CLK               33
> > +#define STRATIX10_NOC_CLK            34
> > +#define STRATIX10_EMAC_A_FREE_CLK    35
> > +#define STRATIX10_EMAC_B_FREE_CLK    36
> > +#define STRATIX10_EMAC_PTP_FREE_CLK  37
> > +#define STRATIX10_GPIO_DB_FREE_CLK   38
> > +#define STRATIX10_SDMMC_FREE_CLK     39
> > +#define STRATIX10_S2F_USER1_FREE_CLK 40
> > +#define STRATIX10_PSI_REF_FREE_CLK   41
> > +
> > +/* Gate clocks */
> > +#define STRATIX10_MPU_CLK            42
> > +#define STRATIX10_L4_MAIN_CLK                43
> > +#define STRATIX10_L4_MP_CLK          44
> > +#define STRATIX10_L4_SP_CLK          45
> > +#define STRATIX10_CS_AT_CLK          46
> > +#define STRATIX10_CS_TRACE_CLK               47
> > +#define STRATIX10_CS_PDBG_CLK                48
> > +#define STRATIX10_CS_TIMER_CLK               49
> > +#define STRATIX10_S2F_USER0_CLK              50
> > +#define STRATIX10_S2F_USER1_CLK              51
> > +#define STRATIX10_EMAC0_CLK          52
> > +#define STRATIX10_EMAC1_CLK          53
> > +#define STRATIX10_EMAC2_CLK          54
> > +#define STRATIX10_EMAC_PTP_CLK               55
> > +#define STRATIX10_GPIO_DB_CLK                56
> > +#define STRATIX10_SDMMC_CLK          57
> > +#define STRATIX10_PSI_REF_CLK                58
> > +#define STRATIX10_USB_CLK            59
> > +#define STRATIX10_SPI_M_CLK          60
> > +#define STRATIX10_NAND_CLK           61
> > +#define STRATIX10_NUM_CLKS           62
> > +
> > +#endif       /* __STRATIX10_CLOCK_H */
> >
>


More information about the U-Boot mailing list