[U-Boot] [RESEND PATCH v2 07/15] clk: agilex: Add clock driver for Agilex.
Simon Goldschmidt
simon.k.r.goldschmidt at gmail.com
Fri Jul 12 10:47:01 UTC 2019
On Thu, Jul 11, 2019 at 1:03 AM Ley Foon Tan <lftan.linux at gmail.com> wrote:
>
> 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.
You already did that. My question was: does this clock driver work for
Stratix10, too, given the name of the file you imported?
Regards,
Simon
>
> >
> > 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