On 01/10/2017 06:20 AM, Chee Tien Fong wrote: > From: Tien Fong Chee <tien.fong.c...@intel.com> > > The drivers is restructured such common functions, gen5 functions, and > arria10 functions are moved to clock_manager.c, clock_manager_gen5 and > clock_manager_arria10 respectively. > > Signed-off-by: Tien Fong Chee <tien.fong.c...@intel.com> > Cc: Marek Vasut <ma...@denx.de> > Cc: Dinh Nguyen <dingnu...@kernel.org> > Cc: Ching Liang See <chin.liang....@intel.com> > Cc: Tien Fong <skywind...@gmail.com> > --- > arch/arm/mach-socfpga/clock_manager.c | 752 +++++++--------- > arch/arm/mach-socfpga/clock_manager_arria10.c | 954 > +++++++++++++++++++++ > .../{clock_manager.c => clock_manager_gen5.c} | 240 +----- > arch/arm/mach-socfpga/include/mach/clock_manager.h | 356 ++++++-- > 4 files changed, 1573 insertions(+), 729 deletions(-) > create mode 100644 arch/arm/mach-socfpga/clock_manager_arria10.c > copy arch/arm/mach-socfpga/{clock_manager.c => clock_manager_gen5.c} (62%) > > diff --git a/arch/arm/mach-socfpga/clock_manager.c > b/arch/arm/mach-socfpga/clock_manager.c > index aa71636..d209f7d 100644 > --- a/arch/arm/mach-socfpga/clock_manager.c > +++ b/arch/arm/mach-socfpga/clock_manager.c > @@ -1,5 +1,5 @@ > /* > - * Copyright (C) 2013 Altera Corporation <www.altera.com> > + * Copyright (C) 2013-2016 Altera Corporation <www.altera.com> > * > * SPDX-License-Identifier: GPL-2.0+ > */ > @@ -7,416 +7,287 @@ > #include <common.h> > #include <asm/io.h> > #include <asm/arch/clock_manager.h> > +#include <fdtdec.h> > > DECLARE_GLOBAL_DATA_PTR; > > +/* Function prototypes */ > +/* Common prototypes */ > +unsigned int cm_get_l4_sp_clk_hz(void); > +unsigned int cm_get_qspi_controller_clk_hz(void); > +unsigned int cm_get_mmc_controller_clk_hz(void); > +unsigned int cm_get_spi_controller_clk_hz(void); > +static void cm_print_clock_quick_summary(void); > +int do_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); > +void cm_wait_for_lock(uint32_t mask); > +void cm_wait_for_fsm(void); > +unsigned int cm_get_main_vco_clk_hz(void); > +unsigned int cm_get_per_vco_clk_hz(void); > +unsigned long cm_get_mpu_clk_hz(void); > + > static const struct socfpga_clock_manager *clock_manager_base = > (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS; > > -static void cm_wait_for_lock(uint32_t mask) > +/* Common functions */ > +int set_cpu_clk_info(void) > { > - register uint32_t inter_val; > - uint32_t retry = 0; > - do { > - inter_val = readl(&clock_manager_base->inter) & mask; > - if (inter_val == mask) > - retry++; > - else > - retry = 0; > - if (retry >= 10) > - break; > - } while (1); > -} > + /* Calculate the clock frequencies required for drivers */ > + cm_get_l4_sp_clk_hz(); > + cm_get_mmc_controller_clk_hz(); > > -/* function to poll in the fsm busy bit */ > -static void cm_wait_for_fsm(void) > -{ > - while (readl(&clock_manager_base->stat) & CLKMGR_STAT_BUSY) > - ; > -} > + gd->bd->bi_arm_freq = cm_get_mpu_clk_hz() / 1000000; > + gd->bd->bi_dsp_freq = 0; > > -/* > - * function to write the bypass register which requires a poll of the > - * busy bit > - */ > -static void cm_write_bypass(uint32_t val) > -{ > - writel(val, &clock_manager_base->bypass); > - cm_wait_for_fsm(); > -} > +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) > + gd->bd->bi_ddr_freq = cm_get_sdram_clk_hz() / 1000000; > +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) > + gd->bd->bi_ddr_freq = 0;
What ? This cannot work ... > +#endif > > -/* function to write the ctrl register which requires a poll of the busy bit > */ > -static void cm_write_ctrl(uint32_t val) > -{ > - writel(val, &clock_manager_base->ctrl); > - cm_wait_for_fsm(); > + return 0; > } > > -/* function to write a clock register that has phase information */ > -static void cm_write_with_phase(uint32_t value, > - uint32_t reg_address, uint32_t mask) > +unsigned int cm_get_spi_controller_clk_hz(void) > { > - /* poll until phase is zero */ > - while (readl(reg_address) & mask) > - ; > + uint32_t clock = 0; > > - writel(value, reg_address); > +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) > + uint32_t reg; > + clock = cm_get_per_vco_clk_hz(); > > - while (readl(reg_address) & mask) > - ; > -} > + /* get the clock prior L4 SP divider (periph_base_clk) */ > + reg = readl(&clock_manager_base->per_pll.perbaseclk); > + clock /= (reg + 1); > +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) > + clock = cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB); > +#endif You might want to consider separate clock manager for A10 and Gen5 to avoid the massive ifdeffery. > -/* > - * Setup clocks while making no assumptions about previous state of the > clocks. > - * > - * Start by being paranoid and gate all sw managed clocks > - * Put all plls in bypass > - * Put all plls VCO registers back to reset value (bandgap power down). > - * Put peripheral and main pll src to reset value to avoid glitch. > - * Delay 5 us. > - * Deassert bandgap power down and set numerator and denominator > - * Start 7 us timer. > - * set internal dividers > - * Wait for 7 us timer. > - * Enable plls > - * Set external dividers while plls are locking > - * Wait for pll lock > - * Assert/deassert outreset all. > - * Take all pll's out of bypass > - * Clear safe mode > - * set source main and peripheral clocks > - * Ungate clocks > - */ > + return clock; > +} > > -void cm_basic_init(const struct cm_config * const cfg) > +unsigned int cm_get_qspi_controller_clk_hz(void) > { > - unsigned long end; > - > - /* Start by being paranoid and gate all sw managed clocks */ > - > - /* > - * We need to disable nandclk > - * and then do another apb access before disabling > - * gatting off the rest of the periperal clocks. > - */ > - writel(~CLKMGR_PERPLLGRP_EN_NANDCLK_MASK & > - readl(&clock_manager_base->per_pll.en), > - &clock_manager_base->per_pll.en); > - > - /* DO NOT GATE OFF DEBUG CLOCKS & BRIDGE CLOCKS */ > - writel(CLKMGR_MAINPLLGRP_EN_DBGTIMERCLK_MASK | > - CLKMGR_MAINPLLGRP_EN_DBGTRACECLK_MASK | > - CLKMGR_MAINPLLGRP_EN_DBGCLK_MASK | > - CLKMGR_MAINPLLGRP_EN_DBGATCLK_MASK | > - CLKMGR_MAINPLLGRP_EN_S2FUSER0CLK_MASK | > - CLKMGR_MAINPLLGRP_EN_L4MPCLK_MASK, > - &clock_manager_base->main_pll.en); > - > - writel(0, &clock_manager_base->sdr_pll.en); > - > - /* now we can gate off the rest of the peripheral clocks */ > - writel(0, &clock_manager_base->per_pll.en); > - > - /* Put all plls in bypass */ > - cm_write_bypass(CLKMGR_BYPASS_PERPLL | CLKMGR_BYPASS_SDRPLL | > - CLKMGR_BYPASS_MAINPLL); > - > - /* Put all plls VCO registers back to reset value. */ > - writel(CLKMGR_MAINPLLGRP_VCO_RESET_VALUE & > - ~CLKMGR_MAINPLLGRP_VCO_REGEXTSEL_MASK, > - &clock_manager_base->main_pll.vco); > - writel(CLKMGR_PERPLLGRP_VCO_RESET_VALUE & > - ~CLKMGR_PERPLLGRP_VCO_REGEXTSEL_MASK, > - &clock_manager_base->per_pll.vco); > - writel(CLKMGR_SDRPLLGRP_VCO_RESET_VALUE & > - ~CLKMGR_SDRPLLGRP_VCO_REGEXTSEL_MASK, > - &clock_manager_base->sdr_pll.vco); > - > - /* > - * The clocks to the flash devices and the L4_MAIN clocks can > - * glitch when coming out of safe mode if their source values > - * are different from their reset value. So the trick it to > - * put them back to their reset state, and change input > - * after exiting safe mode but before ungating the clocks. > - */ > - writel(CLKMGR_PERPLLGRP_SRC_RESET_VALUE, > - &clock_manager_base->per_pll.src); > - writel(CLKMGR_MAINPLLGRP_L4SRC_RESET_VALUE, > - &clock_manager_base->main_pll.l4src); > - > - /* read back for the required 5 us delay. */ > - readl(&clock_manager_base->main_pll.vco); > - readl(&clock_manager_base->per_pll.vco); > - readl(&clock_manager_base->sdr_pll.vco); > - > - > - /* > - * We made sure bgpwr down was assert for 5 us. Now deassert BG PWR DN > - * with numerator and denominator. > - */ > - writel(cfg->main_vco_base, &clock_manager_base->main_pll.vco); > - writel(cfg->peri_vco_base, &clock_manager_base->per_pll.vco); > - writel(cfg->sdram_vco_base, &clock_manager_base->sdr_pll.vco); > - > - /* > - * Time starts here. Must wait 7 us from > - * BGPWRDN_SET(0) to VCO_ENABLE_SET(1). > - */ > - end = timer_get_us() + 7; > - > - /* main mpu */ > - writel(cfg->mpuclk, &clock_manager_base->main_pll.mpuclk); > - > - /* main main clock */ > - writel(cfg->mainclk, &clock_manager_base->main_pll.mainclk); > - > - /* main for dbg */ > - writel(cfg->dbgatclk, &clock_manager_base->main_pll.dbgatclk); > - > - /* main for cfgs2fuser0clk */ > - writel(cfg->cfg2fuser0clk, > - &clock_manager_base->main_pll.cfgs2fuser0clk); > - > - /* Peri emac0 50 MHz default to RMII */ > - writel(cfg->emac0clk, &clock_manager_base->per_pll.emac0clk); > - > - /* Peri emac1 50 MHz default to RMII */ > - writel(cfg->emac1clk, &clock_manager_base->per_pll.emac1clk); > - > - /* Peri QSPI */ > - writel(cfg->mainqspiclk, &clock_manager_base->main_pll.mainqspiclk); > - > - writel(cfg->perqspiclk, &clock_manager_base->per_pll.perqspiclk); > - > - /* Peri pernandsdmmcclk */ > - writel(cfg->mainnandsdmmcclk, > - &clock_manager_base->main_pll.mainnandsdmmcclk); > - > - writel(cfg->pernandsdmmcclk, > - &clock_manager_base->per_pll.pernandsdmmcclk); > - > - /* Peri perbaseclk */ > - writel(cfg->perbaseclk, &clock_manager_base->per_pll.perbaseclk); > - > - /* Peri s2fuser1clk */ > - writel(cfg->s2fuser1clk, &clock_manager_base->per_pll.s2fuser1clk); > - > - /* 7 us must have elapsed before we can enable the VCO */ > - while (timer_get_us() < end) > - ; > - > - /* Enable vco */ > - /* main pll vco */ > - writel(cfg->main_vco_base | CLKMGR_MAINPLLGRP_VCO_EN, > - &clock_manager_base->main_pll.vco); > + uint32_t clock = 0; > > - /* periferal pll */ > - writel(cfg->peri_vco_base | CLKMGR_MAINPLLGRP_VCO_EN, > - &clock_manager_base->per_pll.vco); > - > - /* sdram pll vco */ > - writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN, > - &clock_manager_base->sdr_pll.vco); > - > - /* L3 MP and L3 SP */ > - writel(cfg->maindiv, &clock_manager_base->main_pll.maindiv); > - > - writel(cfg->dbgdiv, &clock_manager_base->main_pll.dbgdiv); > - > - writel(cfg->tracediv, &clock_manager_base->main_pll.tracediv); > - > - /* L4 MP, L4 SP, can0, and can1 */ > - writel(cfg->perdiv, &clock_manager_base->per_pll.div); > - > - writel(cfg->gpiodiv, &clock_manager_base->per_pll.gpiodiv); > - > -#define LOCKED_MASK \ > - (CLKMGR_INTER_SDRPLLLOCKED_MASK | \ > - CLKMGR_INTER_PERPLLLOCKED_MASK | \ > - CLKMGR_INTER_MAINPLLLOCKED_MASK) > - > - cm_wait_for_lock(LOCKED_MASK); > - > - /* write the sdram clock counters before toggling outreset all */ > - writel(cfg->ddrdqsclk & CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK, > - &clock_manager_base->sdr_pll.ddrdqsclk); > +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) > + uint32_t reg; > + /* identify the source of QSPI clock */ > + reg = readl(&clock_manager_base->per_pll.src); > + reg = (reg & CLKMGR_PERPLLGRP_SRC_QSPI_MASK) >> > + CLKMGR_PERPLLGRP_SRC_QSPI_OFFSET; > > - writel(cfg->ddr2xdqsclk & CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_MASK, > - &clock_manager_base->sdr_pll.ddr2xdqsclk); > + if (reg == CLKMGR_QSPI_CLK_SRC_F2S) { > + clock = cm_get_f2s_per_ref_clk_hz(); > + } else if (reg == CLKMGR_QSPI_CLK_SRC_MAIN) { > + clock = cm_get_main_vco_clk_hz(); > > - writel(cfg->ddrdqclk & CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_MASK, > - &clock_manager_base->sdr_pll.ddrdqclk); > + /* get the qspi clock */ > + reg = readl(&clock_manager_base->main_pll.mainqspiclk); > + clock /= (reg + 1); > + } else if (reg == CLKMGR_QSPI_CLK_SRC_PER) { > + clock = cm_get_per_vco_clk_hz(); > > - writel(cfg->s2fuser2clk & CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_MASK, > - &clock_manager_base->sdr_pll.s2fuser2clk); > + /* get the qspi clock */ > + reg = readl(&clock_manager_base->per_pll.perqspiclk); > + clock /= (reg + 1); > + } > +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) > + clock = cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MAINCLK_LSB); > +#endif > > - /* > - * after locking, but before taking out of bypass > - * assert/deassert outresetall > - */ > - uint32_t mainvco = readl(&clock_manager_base->main_pll.vco); > + return clock; > +} > > - /* assert main outresetall */ > - writel(mainvco | CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK, > - &clock_manager_base->main_pll.vco); > +void cm_wait_for_lock(uint32_t mask) > +{ > + register uint32_t inter_val; > + uint32_t retry = 0; > + do { > +#if defined(CONFIG_TARGET_SOCFPGA_ARRIA10) > + inter_val = readl(&clock_manager_base->stat) & mask; > +#elif defined(CONFIG_TARGET_SOCFPGA_GEN5) > + inter_val = readl(&clock_manager_base->inter) & mask; > +#endif > + /* Wait for stable lock */ > + if (inter_val == mask) > + retry++; > + else > + retry = 0; > + if (retry >= 10) > + break; > + } while (1); > +} > > - uint32_t periphvco = readl(&clock_manager_base->per_pll.vco); > +unsigned long cm_get_mpu_clk_hz(void) > +{ > + uint32_t reg, clk_hz; > +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) > + clk_hz = cm_get_main_vco_clk_hz(); > > - /* assert pheriph outresetall */ > - writel(periphvco | CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK, > - &clock_manager_base->per_pll.vco); > + /* get the MPU clock */ > + reg = readl(&clock_manager_base->altera.mpuclk); > + clk_hz /= (reg + 1); > + reg = readl(&clock_manager_base->main_pll.mpuclk); > + clk_hz /= (reg + 1); > +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) > + uint32_t clk_src, mainmpuclk_reg; > > - /* assert sdram outresetall */ > - writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN| > - CLKMGR_SDRPLLGRP_VCO_OUTRESETALL, > - &clock_manager_base->sdr_pll.vco); > + mainmpuclk_reg = readl(&clock_manager_base->main_pll.mpuclk); > > - /* deassert main outresetall */ > - writel(mainvco & ~CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK, > - &clock_manager_base->main_pll.vco); > + clk_src = (mainmpuclk_reg >> CLKMGR_MAINPLL_MPUCLK_SRC_LSB) & > + CLKMGR_MAINPLL_MPUCLK_SRC_MSK; > > - /* deassert pheriph outresetall */ > - writel(periphvco & ~CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK, > - &clock_manager_base->per_pll.vco); > + reg = readl(&clock_manager_base->altera.mpuclk); > + /* Check MPU clock source: main, periph, osc1, intosc or f2s? */ > + switch (clk_src) { > + case CLKMGR_MAINPLL_MPUCLK_SRC_MAIN: > + clk_hz = cm_get_main_vco_clk_hz(); > + clk_hz /= ((reg & CLKMGR_MAINPLL_MPUCLK_CNT_MSK) > + + 1); > + break; > + case CLKMGR_MAINPLL_MPUCLK_SRC_PERI: > + clk_hz = cm_get_per_vco_clk_hz(); > + clk_hz /= (((reg >> CLKMGR_MAINPLL_MPUCLK_PERICNT_LSB) & > + CLKMGR_MAINPLL_MPUCLK_CNT_MSK) + 1); > + break; > + case CLKMGR_MAINPLL_MPUCLK_SRC_OSC1: > + clk_hz = eosc1_hz; > + break; > + case CLKMGR_MAINPLL_MPUCLK_SRC_INTOSC: > + clk_hz = cb_intosc_hz; > + break; > + case CLKMGR_MAINPLL_MPUCLK_SRC_FPGA: > + clk_hz = f2s_free_hz; > + break; > + default: > + printf("cm_get_mpu_clk_hz invalid clk_src %d\n", clk_src); > + return 0; > + } > > - /* deassert sdram outresetall */ > - writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN, > - &clock_manager_base->sdr_pll.vco); > + clk_hz /= ((mainmpuclk_reg & CLKMGR_MAINPLL_MPUCLK_CNT_MSK) + 1); > +#endif > > - /* > - * now that we've toggled outreset all, all the clocks > - * are aligned nicely; so we can change any phase. > - */ > - cm_write_with_phase(cfg->ddrdqsclk, > - (uint32_t)&clock_manager_base->sdr_pll.ddrdqsclk, > - CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_MASK); > + return clk_hz; > +} > > - /* SDRAM DDR2XDQSCLK */ > - cm_write_with_phase(cfg->ddr2xdqsclk, > - (uint32_t)&clock_manager_base->sdr_pll.ddr2xdqsclk, > - CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_MASK); > +unsigned int cm_get_per_vco_clk_hz(void) > +{ > + uint32_t src_hz = 0; > + uint32_t clk_src = 0; > + uint32_t numer = 0; > + uint32_t denom = 0; > + uint32_t vco = 0; > > - cm_write_with_phase(cfg->ddrdqclk, > - (uint32_t)&clock_manager_base->sdr_pll.ddrdqclk, > - CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_MASK); > +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) > + /* identify PER PLL clock source */ > + clk_src = readl(&clock_manager_base->per_pll.vco); > + clk_src = (clk_src & CLKMGR_PERPLLGRP_VCO_SSRC_MASK) >> > + CLKMGR_PERPLLGRP_VCO_SSRC_OFFSET; > + if (clk_src == CLKMGR_VCO_SSRC_EOSC1) > + src_hz = cm_get_osc_clk_hz(1); > + else if (clk_src == CLKMGR_VCO_SSRC_EOSC2) > + src_hz = cm_get_osc_clk_hz(2); > + else if (clk_src == CLKMGR_VCO_SSRC_F2S) > + src_hz = cm_get_f2s_per_ref_clk_hz(); > > - cm_write_with_phase(cfg->s2fuser2clk, > - (uint32_t)&clock_manager_base->sdr_pll.s2fuser2clk, > - CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_MASK); > + /* get the PER VCO clock */ > + vco = readl(&clock_manager_base->per_pll.vco); > + > + numer = (vco & CLKMGR_PERPLLGRP_VCO_NUMER_MASK) >> > + CLKMGR_PERPLLGRP_VCO_NUMER_OFFSET; > + > + denom = (vco & CLKMGR_PERPLLGRP_VCO_DENOM_MASK) >> > + CLKMGR_PERPLLGRP_VCO_DENOM_OFFSET; > + > +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) > + clk_src = readl(&clock_manager_base->per_pll.vco0); > + > + clk_src = (clk_src >> CLKMGR_PERPLL_VCO0_PSRC_LSB) & > + CLKMGR_PERPLL_VCO0_PSRC_MSK; > + > + if (clk_src == CLKMGR_PERPLL_VCO0_PSRC_EOSC) { > + src_hz = eosc1_hz; > + } else if (clk_src == CLKMGR_PERPLL_VCO0_PSRC_E_INTOSC) { > + src_hz = cb_intosc_hz; > + } else if (clk_src == CLKMGR_PERPLL_VCO0_PSRC_F2S) { > + src_hz = f2s_free_hz; > + } else if (clk_src == CLKMGR_PERPLL_VCO0_PSRC_MAIN) { > + src_hz = cm_get_main_vco_clk_hz(); > + src_hz /= (readl > + (&clock_manager_base->main_pll.cntr15clk) & > + CLKMGR_MAINPLL_CNTRCLK_MSK) + 1; > + } else { > + printf("cm_get_per_vco_clk_hz invalid clk_src %d\n", clk_src); > + return 0; > + } > > - /* Take all three PLLs out of bypass when safe mode is cleared. */ > - cm_write_bypass(0); > + vco = readl(&clock_manager_base->per_pll.vco1); > > - /* clear safe mode */ > - cm_write_ctrl(readl(&clock_manager_base->ctrl) | CLKMGR_CTRL_SAFEMODE); > + numer = vco & CLKMGR_PERPLL_VCO1_NUMER_MSK; > > - /* > - * now that safe mode is clear with clocks gated > - * it safe to change the source mux for the flashes the the L4_MAIN > - */ > - writel(cfg->persrc, &clock_manager_base->per_pll.src); > - writel(cfg->l4src, &clock_manager_base->main_pll.l4src); > + denom = (vco >> CLKMGR_PERPLL_VCO1_DENOM_LSB) & > + CLKMGR_PERPLL_VCO1_DENOM_MSK; > +#endif > > - /* Now ungate non-hw-managed clocks */ > - writel(~0, &clock_manager_base->main_pll.en); > - writel(~0, &clock_manager_base->per_pll.en); > - writel(~0, &clock_manager_base->sdr_pll.en); > + vco = src_hz; > + vco /= (1 + denom); > + vco *= (1 + numer); > > - /* Clear the loss of lock bits (write 1 to clear) */ > - writel(CLKMGR_INTER_SDRPLLLOST_MASK | CLKMGR_INTER_PERPLLLOST_MASK | > - CLKMGR_INTER_MAINPLLLOST_MASK, > - &clock_manager_base->inter); > + return vco; > } > > -static unsigned int cm_get_main_vco_clk_hz(void) > +unsigned int cm_get_main_vco_clk_hz(void) > { > - uint32_t reg, clock; > + uint32_t src_hz, numer, denom, vco; > > +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) > /* get the main VCO clock */ > - reg = readl(&clock_manager_base->main_pll.vco); > - clock = cm_get_osc_clk_hz(1); > - clock /= ((reg & CLKMGR_MAINPLLGRP_VCO_DENOM_MASK) >> > - CLKMGR_MAINPLLGRP_VCO_DENOM_OFFSET) + 1; > - clock *= ((reg & CLKMGR_MAINPLLGRP_VCO_NUMER_MASK) >> > - CLKMGR_MAINPLLGRP_VCO_NUMER_OFFSET) + 1; > - > - return clock; > -} > - > -static unsigned int cm_get_per_vco_clk_hz(void) > -{ > - uint32_t reg, clock = 0; > - > - /* identify PER PLL clock source */ > - reg = readl(&clock_manager_base->per_pll.vco); > - reg = (reg & CLKMGR_PERPLLGRP_VCO_SSRC_MASK) >> > - CLKMGR_PERPLLGRP_VCO_SSRC_OFFSET; > - if (reg == CLKMGR_VCO_SSRC_EOSC1) > - clock = cm_get_osc_clk_hz(1); > - else if (reg == CLKMGR_VCO_SSRC_EOSC2) > - clock = cm_get_osc_clk_hz(2); > - else if (reg == CLKMGR_VCO_SSRC_F2S) > - clock = cm_get_f2s_per_ref_clk_hz(); > - > - /* get the PER VCO clock */ > - reg = readl(&clock_manager_base->per_pll.vco); > - clock /= ((reg & CLKMGR_PERPLLGRP_VCO_DENOM_MASK) >> > - CLKMGR_PERPLLGRP_VCO_DENOM_OFFSET) + 1; > - clock *= ((reg & CLKMGR_PERPLLGRP_VCO_NUMER_MASK) >> > - CLKMGR_PERPLLGRP_VCO_NUMER_OFFSET) + 1; > - > - return clock; > -} > + vco = readl(&clock_manager_base->main_pll.vco); > + > + numer = ((vco & CLKMGR_MAINPLLGRP_VCO_NUMER_MASK) >> > + CLKMGR_MAINPLLGRP_VCO_NUMER_OFFSET); > + denom = ((vco & CLKMGR_MAINPLLGRP_VCO_DENOM_MASK) >> > + CLKMGR_MAINPLLGRP_VCO_DENOM_OFFSET); > + > + src_hz = cm_get_osc_clk_hz(1); > +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) > + uint32_t clk_src = readl(&clock_manager_base->main_pll.vco0); > + > + clk_src = (clk_src >> CLKMGR_MAINPLL_VCO0_PSRC_LSB) & > + CLKMGR_MAINPLL_VCO0_PSRC_MSK; > + > + if (clk_src == CLKMGR_MAINPLL_VCO0_PSRC_EOSC) { > + src_hz = eosc1_hz; > + } else if (clk_src == CLKMGR_MAINPLL_VCO0_PSRC_E_INTOSC) { > + src_hz = cb_intosc_hz; > + } else if (clk_src == CLKMGR_MAINPLL_VCO0_PSRC_F2S) { > + src_hz = f2s_free_hz; > + } else { > + printf("cm_get_main_vco_clk_hz invalid clk_src %d\n", clk_src); > + return 0; > + } > > -unsigned long cm_get_mpu_clk_hz(void) > -{ > - uint32_t reg, clock; > + vco = readl(&clock_manager_base->main_pll.vco1); > > - clock = cm_get_main_vco_clk_hz(); > + numer = vco & CLKMGR_MAINPLL_VCO1_NUMER_MSK; > > - /* get the MPU clock */ > - reg = readl(&clock_manager_base->altera.mpuclk); > - clock /= (reg + 1); > - reg = readl(&clock_manager_base->main_pll.mpuclk); > - clock /= (reg + 1); > - return clock; > -} > + denom = (vco >> CLKMGR_MAINPLL_VCO1_DENOM_LSB) & > + CLKMGR_MAINPLL_VCO1_DENOM_MSK; > +#endif > > -unsigned long cm_get_sdram_clk_hz(void) > -{ > - uint32_t reg, clock = 0; > - > - /* identify SDRAM PLL clock source */ > - reg = readl(&clock_manager_base->sdr_pll.vco); > - reg = (reg & CLKMGR_SDRPLLGRP_VCO_SSRC_MASK) >> > - CLKMGR_SDRPLLGRP_VCO_SSRC_OFFSET; > - if (reg == CLKMGR_VCO_SSRC_EOSC1) > - clock = cm_get_osc_clk_hz(1); > - else if (reg == CLKMGR_VCO_SSRC_EOSC2) > - clock = cm_get_osc_clk_hz(2); > - else if (reg == CLKMGR_VCO_SSRC_F2S) > - clock = cm_get_f2s_sdr_ref_clk_hz(); > - > - /* get the SDRAM VCO clock */ > - reg = readl(&clock_manager_base->sdr_pll.vco); > - clock /= ((reg & CLKMGR_SDRPLLGRP_VCO_DENOM_MASK) >> > - CLKMGR_SDRPLLGRP_VCO_DENOM_OFFSET) + 1; > - clock *= ((reg & CLKMGR_SDRPLLGRP_VCO_NUMER_MASK) >> > - CLKMGR_SDRPLLGRP_VCO_NUMER_OFFSET) + 1; > - > - /* get the SDRAM (DDR_DQS) clock */ > - reg = readl(&clock_manager_base->sdr_pll.ddrdqsclk); > - reg = (reg & CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK) >> > - CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_OFFSET; > - clock /= (reg + 1); > + vco = src_hz; > + vco /= (1 + denom); > + vco *= (1 + numer); > > - return clock; > + return vco; > } > > unsigned int cm_get_l4_sp_clk_hz(void) > { > - uint32_t reg, clock = 0; > + uint32_t clock = 0; > > +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) > + uint32_t reg; > /* identify the source of L4 SP clock */ > reg = readl(&clock_manager_base->main_pll.l4src); > reg = (reg & CLKMGR_MAINPLLGRP_L4SRC_L4SP) >> > @@ -443,106 +314,117 @@ unsigned int cm_get_l4_sp_clk_hz(void) > reg = (reg & CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_MASK) >> > CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_OFFSET; > clock = clock / (1 << reg); > - > +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) > + clock = cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4SPCLK_LSB); > +#endif > return clock; > } > > -unsigned int cm_get_mmc_controller_clk_hz(void) > +/* function to poll in the fsm busy bit */ > +void cm_wait_for_fsm(void) > { > - uint32_t reg, clock = 0; > - > - /* identify the source of MMC clock */ > - reg = readl(&clock_manager_base->per_pll.src); > - reg = (reg & CLKMGR_PERPLLGRP_SRC_SDMMC_MASK) >> > - CLKMGR_PERPLLGRP_SRC_SDMMC_OFFSET; > - > - if (reg == CLKMGR_SDMMC_CLK_SRC_F2S) { > - clock = cm_get_f2s_per_ref_clk_hz(); > - } else if (reg == CLKMGR_SDMMC_CLK_SRC_MAIN) { > - clock = cm_get_main_vco_clk_hz(); > - > - /* get the SDMMC clock */ > - reg = readl(&clock_manager_base->main_pll.mainnandsdmmcclk); > - clock /= (reg + 1); > - } else if (reg == CLKMGR_SDMMC_CLK_SRC_PER) { > - clock = cm_get_per_vco_clk_hz(); > - > - /* get the SDMMC clock */ > - reg = readl(&clock_manager_base->per_pll.pernandsdmmcclk); > - clock /= (reg + 1); > - } > - > - /* further divide by 4 as we have fixed divider at wrapper */ > - clock /= 4; > - return clock; > + while (readl(&clock_manager_base->stat) & > + CLKMGR_CLKMGR_STAT_BUSY_SET_MSK); > } > > -unsigned int cm_get_qspi_controller_clk_hz(void) > +unsigned int cm_get_mmc_controller_clk_hz(void) > { > - uint32_t reg, clock = 0; > - > - /* identify the source of QSPI clock */ > - reg = readl(&clock_manager_base->per_pll.src); > - reg = (reg & CLKMGR_PERPLLGRP_SRC_QSPI_MASK) >> > - CLKMGR_PERPLLGRP_SRC_QSPI_OFFSET; > + uint32_t clk_hz = 0; > + uint32_t clk_input = 0; > + > +#if defined(CONFIG_TARGET_SOCFPGA_ARRIA10) > + clk_input = readl(&clock_manager_base->per_pll.cntr6clk); > + clk_input = (clk_input >> CLKMGR_PERPLL_CNTR6CLK_SRC_LSB) & > + CLKMGR_PERPLLGRP_SRC_MSK; > +#elif defined(CONFIG_TARGET_SOCFPGA_GEN5) > + clk_input = readl(&clock_manager_base->per_pll.src); > + clk_input = (clk_input & CLKMGR_PERPLLGRP_SRC_SDMMC_MASK) >> > + CLKMGR_PERPLLGRP_SRC_SDMMC_OFFSET; > +#endif > + > + switch (clk_input) { > +#if defined(CONFIG_TARGET_SOCFPGA_ARRIA10) > + case CLKMGR_PERPLLGRP_SRC_MAIN: > + clk_hz = cm_get_main_vco_clk_hz(); > + clk_hz /= 1 + > + (readl > + (&clock_manager_base->main_pll.cntr6clk) & > + CLKMGR_MAINPLL_CNTRCLK_MSK); > + break; > + > + case CLKMGR_PERPLLGRP_SRC_PERI: > + clk_hz = cm_get_per_vco_clk_hz(); > + clk_hz /= 1 + (readl > + (&clock_manager_base->per_pll.cntr6clk) & > + CLKMGR_PERPLL_CNTRCLK_MSK); > + break; > + > + case CLKMGR_PERPLLGRP_SRC_OSC1: > + clk_hz = eosc1_hz; > + break; > + > + case CLKMGR_PERPLLGRP_SRC_INTOSC: > + clk_hz = cb_intosc_hz; > + break; > + > + case CLKMGR_PERPLLGRP_SRC_FPGA: > + clk_hz = f2s_free_hz; > + break; > +#elif defined(CONFIG_TARGET_SOCFPGA_GEN5) > + case CLKMGR_SDMMC_CLK_SRC_F2S: > + clk_hz = cm_get_f2s_per_ref_clk_hz(); > + break; > + > + case CLKMGR_SDMMC_CLK_SRC_MAIN: > + clk_hz = cm_get_main_vco_clk_hz(); > > - if (reg == CLKMGR_QSPI_CLK_SRC_F2S) { > - clock = cm_get_f2s_per_ref_clk_hz(); > - } else if (reg == CLKMGR_QSPI_CLK_SRC_MAIN) { > - clock = cm_get_main_vco_clk_hz(); > + /* get the SDMMC clock */ > + clk_input = > + readl(&clock_manager_base->main_pll.mainnandsdmmcclk); > + clk_hz /= (clk_input + 1); > + break; > > - /* get the qspi clock */ > - reg = readl(&clock_manager_base->main_pll.mainqspiclk); > - clock /= (reg + 1); > - } else if (reg == CLKMGR_QSPI_CLK_SRC_PER) { > - clock = cm_get_per_vco_clk_hz(); > + case CLKMGR_SDMMC_CLK_SRC_PER: > + clk_hz = cm_get_per_vco_clk_hz(); > > - /* get the qspi clock */ > - reg = readl(&clock_manager_base->per_pll.perqspiclk); > - clock /= (reg + 1); > + /* get the SDMMC clock */ > + clk_input = > + readl(&clock_manager_base->per_pll.pernandsdmmcclk); > + clk_hz /= (clk_input + 1); > + break; > +#endif > } > - > - return clock; > -} > - > -unsigned int cm_get_spi_controller_clk_hz(void) > -{ > - uint32_t reg, clock = 0; > - > - clock = cm_get_per_vco_clk_hz(); > - > - /* get the clock prior L4 SP divider (periph_base_clk) */ > - reg = readl(&clock_manager_base->per_pll.perbaseclk); > - clock /= (reg + 1); > - > - return clock; > + return clk_hz/4; > } > > static void cm_print_clock_quick_summary(void) > { > printf("MPU %10ld kHz\n", cm_get_mpu_clk_hz() / 1000); > + printf("MMC %8d kHz\n", cm_get_mmc_controller_clk_hz() / 1000); > + printf("QSPI %8d kHz\n", > + cm_get_qspi_controller_clk_hz() / 1000); > + printf("SPI %8d kHz\n", cm_get_spi_controller_clk_hz() / 1000); > +#if defined(CONFIG_TARGET_SOCFPGA_ARRIA10) > + printf("EOSC1 %8d kHz\n", eosc1_hz / 1000); > + printf("cb_intosc %8d kHz\n", cb_intosc_hz / 1000); > + printf("f2s_free %8d kHz\n", f2s_free_hz / 1000); > + printf("Main VCO %8d kHz\n", cm_get_main_vco_clk_hz()/1000); > + printf("NOC %8d kHz\n", cm_get_noc_clk_hz()/1000); > + printf("L4 Main %8d kHz\n", > + cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MAINCLK_LSB)/1000); > + printf("L4 MP %8d kHz\n", > + cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB)/1000); > + printf("L4 SP %8d kHz\n", > + cm_get_l4_sp_clk_hz()/1000); > + printf("L4 sys free %8d kHz\n", cm_l4_sys_free_clk_hz/1000); > +#elif defined(CONFIG_TARGET_SOCFPGA_GEN5) > printf("DDR %10ld kHz\n", cm_get_sdram_clk_hz() / 1000); > printf("EOSC1 %8d kHz\n", cm_get_osc_clk_hz(1) / 1000); > printf("EOSC2 %8d kHz\n", cm_get_osc_clk_hz(2) / 1000); > printf("F2S_SDR_REF %8d kHz\n", cm_get_f2s_sdr_ref_clk_hz() / 1000); > printf("F2S_PER_REF %8d kHz\n", cm_get_f2s_per_ref_clk_hz() / 1000); > - printf("MMC %8d kHz\n", cm_get_mmc_controller_clk_hz() / 1000); > - printf("QSPI %8d kHz\n", cm_get_qspi_controller_clk_hz() / 1000); > printf("UART %8d kHz\n", cm_get_l4_sp_clk_hz() / 1000); > - printf("SPI %8d kHz\n", cm_get_spi_controller_clk_hz() / 1000); > -} > - > -int set_cpu_clk_info(void) > -{ > - /* Calculate the clock frequencies required for drivers */ > - cm_get_l4_sp_clk_hz(); > - cm_get_mmc_controller_clk_hz(); > - > - gd->bd->bi_arm_freq = cm_get_mpu_clk_hz() / 1000000; > - gd->bd->bi_dsp_freq = 0; > - gd->bd->bi_ddr_freq = cm_get_sdram_clk_hz() / 1000000; > - > - return 0; > +#endif > } > > int do_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) > diff --git a/arch/arm/mach-socfpga/clock_manager_arria10.c > b/arch/arm/mach-socfpga/clock_manager_arria10.c > new file mode 100644 > index 0000000..93165b4 > --- /dev/null > +++ b/arch/arm/mach-socfpga/clock_manager_arria10.c > @@ -0,0 +1,954 @@ > +/* > + * Copyright (C) 2016, Intel Corporation > + * > + * SPDX-License-Identifier: GPL-2.0 > + */ > + > +#include <common.h> > +#include <asm/io.h> > +#include <asm/arch/clock_manager.h> > +#include <fdtdec.h> > + > +DECLARE_GLOBAL_DATA_PTR; > + > +int cm_basic_init(const void* blob); > +uint32_t eosc1_hz; > +uint32_t cb_intosc_hz; > +uint32_t f2s_free_hz; > +unsigned int cm_l4_main_clk_hz; > +unsigned int cm_l4_sp_clk_hz; > +unsigned int cm_l4_mp_clk_hz; > +unsigned int cm_l4_sys_free_clk_hz; > + > +struct strtopu32 { > + const char *str; > + uint32_t *p; > +}; > + > +struct mainpll_cfg { > + uint32_t vco0_psrc; > + uint32_t vco1_denom; > + uint32_t vco1_numer; > + uint32_t mpuclk; > + uint32_t mpuclk_cnt; > + uint32_t mpuclk_src; > + uint32_t nocclk; > + uint32_t nocclk_cnt; > + uint32_t nocclk_src; > + uint32_t cntr2clk_cnt; > + uint32_t cntr3clk_cnt; > + uint32_t cntr4clk_cnt; > + uint32_t cntr5clk_cnt; > + uint32_t cntr6clk_cnt; > + uint32_t cntr7clk_cnt; > + uint32_t cntr7clk_src; > + uint32_t cntr8clk_cnt; > + uint32_t cntr9clk_cnt; > + uint32_t cntr9clk_src; > + uint32_t cntr15clk_cnt; > + uint32_t nocdiv_l4mainclk; > + uint32_t nocdiv_l4mpclk; > + uint32_t nocdiv_l4spclk; > + uint32_t nocdiv_csatclk; > + uint32_t nocdiv_cstraceclk; > + uint32_t nocdiv_cspdbclk; > +}; > + > +struct perpll_cfg { > + uint32_t vco0_psrc; > + uint32_t vco1_denom; > + uint32_t vco1_numer; > + uint32_t cntr2clk_cnt; > + uint32_t cntr2clk_src; > + uint32_t cntr3clk_cnt; > + uint32_t cntr3clk_src; > + uint32_t cntr4clk_cnt; > + uint32_t cntr4clk_src; > + uint32_t cntr5clk_cnt; > + uint32_t cntr5clk_src; > + uint32_t cntr6clk_cnt; > + uint32_t cntr6clk_src; > + uint32_t cntr7clk_cnt; > + uint32_t cntr8clk_cnt; > + uint32_t cntr8clk_src; > + uint32_t cntr9clk_cnt; > + uint32_t emacctl_emac0sel; > + uint32_t emacctl_emac1sel; > + uint32_t emacctl_emac2sel; > + uint32_t gpiodiv_gpiodbclk; > +}; > + > +struct alteragrp_cfg { > + uint32_t nocclk; > + uint32_t mpuclk; > +}; > + > +unsigned int cm_get_noc_clk_hz(void); > +unsigned int cm_get_l4_noc_hz(unsigned int nocdivshift); > +static int of_to_struct(const void *blob, int node, int cfg__len, void *cfg); > +static int of_get_input_clks(const void *blob, int node, void *cfg); > +static int of_get_clk_cfg(const void *blob, struct mainpll_cfg *main_cfg, > + struct perpll_cfg *per_cfg, struct alteragrp_cfg *altrgrp_cfg); > +static unsigned int cm_calc_handoff_main_vco_clk_hz( > + struct mainpll_cfg *main_cfg); > +static unsigned int cm_calc_handoff_periph_vco_clk_hz( > + struct mainpll_cfg *main_cfg, struct perpll_cfg *per_cfg); > +static unsigned int cm_calc_handoff_mpu_clk_hz(struct mainpll_cfg *main_cfg, > + struct perpll_cfg *per_cfg); > +static unsigned int cm_calc_handoff_noc_clk_hz(struct mainpll_cfg *main_cfg, > + struct perpll_cfg *per_cfg); > +static int cm_is_pll_ramp_required(int main0periph1, > + struct mainpll_cfg *main_cfg, struct perpll_cfg *per_cfg); > +static unsigned int cm_calc_safe_pll_numer(int main0periph1, > + struct mainpll_cfg *main_cfg, struct perpll_cfg *per_cfg, > + unsigned int safe_hz); > +static void cm_pll_ramp_main(struct mainpll_cfg *main_cfg, > + struct perpll_cfg *per_cfg, unsigned int pll_ramp_main_hz); > +static void cm_pll_ramp_periph(struct mainpll_cfg *main_cfg, > + struct perpll_cfg *per_cfg, unsigned int pll_ramp_periph_hz); > +static int cm_full_cfg(struct mainpll_cfg *main_cfg, > + struct perpll_cfg *per_cfg); > + > +static const struct socfpga_clock_manager *clock_manager_base = > + (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS; > + > +void cm_use_intosc(void) > +{ > + setbits_le32(&clock_manager_base->ctrl, > + CLKMGR_CLKMGR_CTL_BOOTCLK_INTOSC_SET_MSK); > +} > + > +unsigned int cm_get_noc_clk_hz(void) > +{ > + unsigned int clk_src, dividor, nocclk, src_hz; > + > + nocclk = readl(&clock_manager_base->main_pll.nocclk); > + clk_src = (nocclk >> CLKMGR_MAINPLL_NOCCLK_SRC_LSB) & > + CLKMGR_MAINPLL_NOCCLK_SRC_MSK; > + > + dividor = 1 + (nocclk & CLKMGR_MAINPLL_NOCDIV_MSK); > + > + if (clk_src == CLKMGR_PERPLLGRP_SRC_MAIN) { > + src_hz = cm_get_main_vco_clk_hz(); > + src_hz /= 1 + > + (readl(SOCFPGA_CLKMGR_ADDRESS+CLKMGR_MAINPLL_NOC_CLK_OFFSET)& > + CLKMGR_MAINPLL_NOCCLK_CNT_MSK); > + } else if (clk_src == CLKMGR_PERPLLGRP_SRC_PERI) { > + src_hz = cm_get_per_vco_clk_hz(); > + src_hz /= 1 + > + ((readl(SOCFPGA_CLKMGR_ADDRESS+CLKMGR_MAINPLL_NOC_CLK_OFFSET)>> > + CLKMGR_MAINPLL_NOCCLK_PERICNT_LSB)& > + CLKMGR_MAINPLL_NOCCLK_CNT_MSK); > + } else if (clk_src == CLKMGR_PERPLLGRP_SRC_OSC1) { > + src_hz = eosc1_hz; > + } else if (clk_src == CLKMGR_PERPLLGRP_SRC_INTOSC) { > + src_hz = cb_intosc_hz; > + } else if (clk_src == CLKMGR_PERPLLGRP_SRC_FPGA) { > + src_hz = f2s_free_hz; > + } else { > + src_hz = 0; > + } > + return src_hz/dividor; > +} > + > +unsigned int cm_get_l4_noc_hz(unsigned int nocdivshift) > +{ > + unsigned int dividor2 = 1 << > + ((readl(&clock_manager_base->main_pll.nocdiv) >> > + nocdivshift) & CLKMGR_MAINPLL_NOCDIV_MSK); > + > + return cm_get_noc_clk_hz()/dividor2; > +} > + > +int of_to_struct(const void *blob, int node, int cfg_len, void *cfg) > +{ > + if (fdtdec_get_int_array(blob, node, "altr,of_reg_value", > + (u32*)cfg, cfg_len)) { > + /* could not find required property */ > + return 100; > + } > + > + return 0; > +} > + > +static int of_get_input_clks(const void *blob, int node, void *cfg) > +{ > + if (fdtdec_get_int_array(blob, node, "clock-frequency", > + (u32*)cfg, 1)) { > + /* could not find required property */ > + return 100; > + } > + > + return 0; > +} > + > +int of_get_clk_cfg(const void *blob, struct mainpll_cfg *main_cfg, > + struct perpll_cfg *per_cfg, struct alteragrp_cfg > *altrgrp_cfg) > +{ > + int node, child, len; > + const char *node_name; > + > + node = fdtdec_next_compatible(blob, 0, COMPAT_ALTERA_SOCFPGA_CLK); > + > + if (node < 0) > + return 1; > + > + child = fdt_first_subnode(blob, node); > + > + if (child < 0) > + return 2; > + > + child = fdt_first_subnode(blob, child); > + > + if (child < 0) > + return 3; > + > + node_name = fdt_get_name(blob, child, &len); > + > + while (node_name) { > + if (!strcmp(node_name, "osc1")) { > + if (of_get_input_clks(blob, child, &eosc1_hz)) > + return 101; > + } else if (!strcmp(node_name, "cb_intosc_ls_clk")) { > + if (of_get_input_clks(blob, child, &cb_intosc_hz)) > + return 102; > + } else if (!strcmp(node_name, "f2s_free_clk")) { > + if (of_get_input_clks(blob, child, &f2s_free_hz)) > + return 103; > + } else if (!strcmp(node_name, "main_pll")) { > + if (of_to_struct(blob, child, > sizeof(*main_cfg)/sizeof(uint32_t), > + main_cfg)) > + return 104; > + } else if (!strcmp(node_name, "periph_pll")) { > + if (of_to_struct(blob, child, > sizeof(*per_cfg)/sizeof(uint32_t), > + per_cfg)) > + return 105; > + } else if (!strcmp(node_name, "altera")) { > + if (of_to_struct(blob, child, > + sizeof(*altrgrp_cfg)/sizeof(uint32_t), > altrgrp_cfg)) > + return 106; > + > + main_cfg->mpuclk = altrgrp_cfg->mpuclk; > + main_cfg->nocclk = altrgrp_cfg->nocclk; > + } > + child = fdt_next_subnode(blob, child); > + > + if (child < 0) > + break; > + > + node_name = fdt_get_name(blob, child, &len); > + } > + > + return 0; > +} > + > +/* calculate the intended main VCO frequency based on handoff */ > +static unsigned int cm_calc_handoff_main_vco_clk_hz > + (struct mainpll_cfg *main_cfg) > +{ > + unsigned int clk_hz; > + > + /* Check main VCO clock source: eosc, intosc or f2s? */ > + switch (main_cfg->vco0_psrc) { > + case CLKMGR_MAINPLL_VCO0_PSRC_EOSC: > + clk_hz = eosc1_hz; > + break; > + case CLKMGR_MAINPLL_VCO0_PSRC_E_INTOSC: > + clk_hz = cb_intosc_hz; > + break; > + case CLKMGR_MAINPLL_VCO0_PSRC_F2S: > + clk_hz = f2s_free_hz; > + break; > + default: > + return 0; > + } > + > + /* calculate the VCO frequency */ > + clk_hz /= (1 + main_cfg->vco1_denom); > + clk_hz *= (1 + main_cfg->vco1_numer); > + > + return clk_hz; > +} > + > +/* calculate the intended periph VCO frequency based on handoff */ > +static unsigned int cm_calc_handoff_periph_vco_clk_hz > + (struct mainpll_cfg *main_cfg, struct perpll_cfg *per_cfg) > +{ > + unsigned int clk_hz; > + > + /* Check periph VCO clock source: eosc, intosc, f2s or mainpll? */ > + switch (per_cfg->vco0_psrc) { > + case CLKMGR_PERPLL_VCO0_PSRC_EOSC: > + clk_hz = eosc1_hz; > + break; > + case CLKMGR_PERPLL_VCO0_PSRC_E_INTOSC: > + clk_hz = cb_intosc_hz; > + break; > + case CLKMGR_PERPLL_VCO0_PSRC_F2S: > + clk_hz = f2s_free_hz; > + break; > + case CLKMGR_PERPLL_VCO0_PSRC_MAIN: > + clk_hz = cm_calc_handoff_main_vco_clk_hz(main_cfg); > + clk_hz /= main_cfg->cntr15clk_cnt; > + break; > + default: > + return 0; > + } > + > + /* calculate the VCO frequency */ > + clk_hz /= (1 + per_cfg->vco1_denom); > + clk_hz *= (1 + per_cfg->vco1_numer); > + > + return clk_hz; > +} > + > +/* calculate the intended MPU clock frequency based on handoff */ > +static unsigned int cm_calc_handoff_mpu_clk_hz(struct mainpll_cfg *main_cfg, > + struct perpll_cfg *per_cfg) > +{ > + unsigned int clk_hz; > + > + /* Check MPU clock source: main, periph, osc1, intosc or f2s? */ > + switch (main_cfg->mpuclk_src) { > + case CLKMGR_MAINPLL_MPUCLK_SRC_MAIN: > + clk_hz = cm_calc_handoff_main_vco_clk_hz(main_cfg); > + clk_hz /= ((main_cfg->mpuclk & CLKMGR_MAINPLL_MPUCLK_CNT_MSK) > + + 1); > + break; > + case CLKMGR_MAINPLL_MPUCLK_SRC_PERI: > + clk_hz = cm_calc_handoff_periph_vco_clk_hz(main_cfg, per_cfg); > + clk_hz /= (((main_cfg->mpuclk >> > + CLKMGR_MAINPLL_MPUCLK_PERICNT_LSB) & > + CLKMGR_MAINPLL_MPUCLK_CNT_MSK) + 1); > + break; > + case CLKMGR_MAINPLL_MPUCLK_SRC_OSC1: > + clk_hz = eosc1_hz; > + break; > + case CLKMGR_MAINPLL_MPUCLK_SRC_INTOSC: > + clk_hz = cb_intosc_hz; > + break; > + case CLKMGR_MAINPLL_MPUCLK_SRC_FPGA: > + clk_hz = f2s_free_hz; > + break; > + default: > + return 0; > + } > + > + clk_hz /= (main_cfg->mpuclk_cnt + 1); > + return clk_hz; > +} > + > +/* calculate the intended NOC clock frequency based on handoff */ > +static unsigned int cm_calc_handoff_noc_clk_hz(struct mainpll_cfg *main_cfg, > + struct perpll_cfg *per_cfg) > +{ > + unsigned int clk_hz; > + > + /* Check MPU clock source: main, periph, osc1, intosc or f2s? */ > + switch (main_cfg->nocclk_src) { > + case CLKMGR_MAINPLL_NOCCLK_SRC_MAIN: > + clk_hz = cm_calc_handoff_main_vco_clk_hz(main_cfg); > + clk_hz /= ((main_cfg->nocclk & CLKMGR_MAINPLL_NOCCLK_CNT_MSK) > + + 1); > + break; > + case CLKMGR_MAINPLL_NOCCLK_SRC_PERI: > + clk_hz = cm_calc_handoff_periph_vco_clk_hz(main_cfg, per_cfg); > + clk_hz /= (((main_cfg->nocclk >> > + CLKMGR_MAINPLL_NOCCLK_PERICNT_LSB) & > + CLKMGR_MAINPLL_NOCCLK_CNT_MSK) + 1); > + break; > + case CLKMGR_MAINPLL_NOCCLK_SRC_OSC1: > + clk_hz = eosc1_hz; > + break; > + case CLKMGR_MAINPLL_NOCCLK_SRC_INTOSC: > + clk_hz = cb_intosc_hz; > + break; > + case CLKMGR_MAINPLL_NOCCLK_SRC_FPGA: > + clk_hz = f2s_free_hz; > + break; > + default: > + return 0; > + } > + > + clk_hz /= (main_cfg->nocclk_cnt + 1); > + return clk_hz; > +} > + > +/* return 1 if PLL ramp is required */ > +static int cm_is_pll_ramp_required(int main0periph1, > + struct mainpll_cfg *main_cfg, > + struct perpll_cfg *per_cfg) > +{ > + > + /* Check for main PLL */ > + if (main0periph1 == 0) { > + /* > + * PLL ramp is not required if both MPU clock and NOC clock are > + * not sourced from main PLL > + */ > + if (main_cfg->mpuclk_src != CLKMGR_MAINPLL_MPUCLK_SRC_MAIN && > + main_cfg->nocclk_src != CLKMGR_MAINPLL_NOCCLK_SRC_MAIN) > + return 0; > + > + /* > + * PLL ramp is required if MPU clock is sourced from main PLL > + * and MPU clock is over 900MHz (as advised by HW team) > + */ > + if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_MAIN && > + (cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg) > > + CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ)) > + return 1; > + > + /* > + * PLL ramp is required if NOC clock is sourced from main PLL > + * and NOC clock is over 300MHz (as advised by HW team) > + */ > + if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_MAIN && > + (cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg) > > + CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ)) > + return 2; > + > + } else if (main0periph1 == 1) { > + /* > + * PLL ramp is not required if both MPU clock and NOC clock are > + * not sourced from periph PLL > + */ > + if (main_cfg->mpuclk_src != CLKMGR_MAINPLL_MPUCLK_SRC_PERI && > + main_cfg->nocclk_src != CLKMGR_MAINPLL_NOCCLK_SRC_PERI) > + return 0; > + > + /* > + * PLL ramp is required if MPU clock are source from periph PLL > + * and MPU clock is over 900MHz (as advised by HW team) > + */ > + if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_PERI && > + (cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg) > > + CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ)) > + return 1; > + > + /* > + * PLL ramp is required if NOC clock are source from periph PLL > + * and NOC clock is over 300MHz (as advised by HW team) > + */ > + if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_PERI && > + (cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg) > > + CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ)) > + return 2; > + } > + return 0; > +} > + > +/* > + * Calculate the new PLL numerator which is based on existing DTS hand off > and > + * intended safe frequency (safe_hz). Note that PLL ramp is only modifying > the > + * numerator while maintaining denominator as denominator will influence the > + * jitter condition. Please refer A10 HPS TRM for the jitter guide. Note > final > + * value for numerator is minus with 1 to cater our register value > + * representation. > + */ > +static unsigned int cm_calc_safe_pll_numer(int main0periph1, > + struct mainpll_cfg *main_cfg, > + struct perpll_cfg *per_cfg, > + unsigned int safe_hz) > +{ > + unsigned int clk_hz = 0; > + > + /* Check for main PLL */ > + if (main0periph1 == 0) { > + /* Check main VCO clock source: eosc, intosc or f2s? */ > + switch (main_cfg->vco0_psrc) { > + case CLKMGR_MAINPLL_VCO0_PSRC_EOSC: > + clk_hz = eosc1_hz; > + break; > + case CLKMGR_MAINPLL_VCO0_PSRC_E_INTOSC: > + clk_hz = cb_intosc_hz; > + break; > + case CLKMGR_MAINPLL_VCO0_PSRC_F2S: > + clk_hz = f2s_free_hz; > + break; > + default: > + return 0; > + } > + /* Applicable if MPU clock is from main PLL */ > + if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_MAIN) { > + /* calculate the safe numer value */ > + clk_hz = (safe_hz / clk_hz) * > + (main_cfg->mpuclk_cnt + 1) * > + ((main_cfg->mpuclk & > + CLKMGR_MAINPLL_MPUCLK_CNT_MSK) + 1) * > + (1 + main_cfg->vco1_denom) - 1; > + } > + /* Reach here if MPU clk not from main PLL but NOC clk is */ > + else if (main_cfg->nocclk_src == > + CLKMGR_MAINPLL_NOCCLK_SRC_MAIN) { > + /* calculate the safe numer value */ > + clk_hz = (safe_hz / clk_hz) * > + (main_cfg->nocclk_cnt + 1) * > + ((main_cfg->nocclk & > + CLKMGR_MAINPLL_NOCCLK_CNT_MSK) + 1) * > + (1 + main_cfg->vco1_denom) - 1; > + } else > + clk_hz = 0; > + > + } else if (main0periph1 == 1) { > + /* Check periph VCO clock source: eosc, intosc, f2s, mainpll */ > + switch (per_cfg->vco0_psrc) { > + case CLKMGR_PERPLL_VCO0_PSRC_EOSC: > + clk_hz = eosc1_hz; > + break; > + case CLKMGR_PERPLL_VCO0_PSRC_E_INTOSC: > + clk_hz = cb_intosc_hz; > + break; > + case CLKMGR_PERPLL_VCO0_PSRC_F2S: > + clk_hz = f2s_free_hz; > + break; > + case CLKMGR_PERPLL_VCO0_PSRC_MAIN: > + clk_hz = cm_calc_handoff_main_vco_clk_hz( > + main_cfg); > + clk_hz /= main_cfg->cntr15clk_cnt; > + break; > + default: > + return 0; > + } > + /* Applicable if MPU clock is from periph PLL */ > + if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_PERI) { > + /* calculate the safe numer value */ > + clk_hz = (safe_hz / clk_hz) * > + (main_cfg->mpuclk_cnt + 1) * > + (((main_cfg->mpuclk >> > + CLKMGR_MAINPLL_MPUCLK_PERICNT_LSB) & > + CLKMGR_MAINPLL_MPUCLK_CNT_MSK) + 1) * > + (1 + per_cfg->vco1_denom) - 1; > + } > + /* Reach here if MPU clk not from periph PLL but NOC clk is */ > + else if (main_cfg->nocclk_src == > + CLKMGR_MAINPLL_NOCCLK_SRC_PERI) { > + /* calculate the safe numer value */ > + clk_hz = (safe_hz / clk_hz) * > + (main_cfg->nocclk_cnt + 1) * > + (((main_cfg->nocclk >> > + CLKMGR_MAINPLL_NOCCLK_PERICNT_LSB) & > + CLKMGR_MAINPLL_NOCCLK_CNT_MSK) + 1) * > + (1 + per_cfg->vco1_denom) - 1; > + } else > + clk_hz = 0; > + } > + return clk_hz; > +} > + > +/* ramping the main PLL to final value */ > +static void cm_pll_ramp_main(struct mainpll_cfg *main_cfg, > + struct perpll_cfg *per_cfg, > + unsigned int pll_ramp_main_hz) > +{ > + unsigned int clk_hz = 0, clk_incr_hz = 0, clk_final_hz = 0; > + > + /* find out the increment value */ > + if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_MAIN) { > + clk_incr_hz = CLKMGR_PLL_RAMP_MPUCLK_INCREMENT_HZ; > + clk_final_hz = cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg); > + } else if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_MAIN) { > + clk_incr_hz = CLKMGR_PLL_RAMP_NOCCLK_INCREMENT_HZ; > + clk_final_hz = cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg); > + } > + /* execute the ramping here */ > + for (clk_hz = pll_ramp_main_hz + clk_incr_hz; > + clk_hz < clk_final_hz; clk_hz += clk_incr_hz) { > + writel((main_cfg->vco1_denom << > + CLKMGR_MAINPLL_VCO1_DENOM_LSB) | > + cm_calc_safe_pll_numer(0, main_cfg, per_cfg, clk_hz), > + &clock_manager_base->main_pll.vco1); > + udelay(1000); > + cm_wait_for_lock(LOCKED_MASK); > + } > + writel((main_cfg->vco1_denom << CLKMGR_MAINPLL_VCO1_DENOM_LSB) | > + main_cfg->vco1_numer, > + &clock_manager_base->main_pll.vco1); > + udelay(1000); > + cm_wait_for_lock(LOCKED_MASK); > +} > + > +/* ramping the periph PLL to final value */ > +static void cm_pll_ramp_periph(struct mainpll_cfg *main_cfg, > + struct perpll_cfg *per_cfg, > + unsigned int pll_ramp_periph_hz) > +{ > + unsigned int clk_hz = 0, clk_incr_hz = 0, clk_final_hz = 0; > + > + /* find out the increment value */ > + if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_PERI) { > + clk_incr_hz = CLKMGR_PLL_RAMP_MPUCLK_INCREMENT_HZ; > + clk_final_hz = cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg); > + } else if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_PERI) { > + clk_incr_hz = CLKMGR_PLL_RAMP_NOCCLK_INCREMENT_HZ; > + clk_final_hz = cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg); > + } > + /* execute the ramping here */ > + for (clk_hz = pll_ramp_periph_hz + clk_incr_hz; > + clk_hz < clk_final_hz; clk_hz += clk_incr_hz) { > + writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) | > + cm_calc_safe_pll_numer(1, main_cfg, per_cfg, clk_hz), > + &clock_manager_base->per_pll.vco1); > + udelay(1000); > + cm_wait_for_lock(LOCKED_MASK); > + } > + writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) | > + per_cfg->vco1_numer, > + &clock_manager_base->per_pll.vco1); > + udelay(1000); > + cm_wait_for_lock(LOCKED_MASK); > +} > + > +/* > + * Setup clocks while making no assumptions of the > + * previous state of the clocks. > + * > + * Start by being paranoid and gate all sw managed clocks > + * > + * Put all plls in bypass > + * > + * Put all plls VCO registers back to reset value (bgpwr dwn). > + * > + * Put peripheral and main pll src to reset value to avoid glitch. > + * > + * Delay 5 us. > + * > + * Deassert bg pwr dn and set numerator and denominator > + * > + * Start 7 us timer. > + * > + * set internal dividers > + * > + * Wait for 7 us timer. > + * > + * Enable plls > + * > + * Set external dividers while plls are locking > + * > + * Wait for pll lock > + * > + * Assert/deassert outreset all. > + * > + * Take all pll's out of bypass > + * > + * Clear safe mode > + * > + * set source main and peripheral clocks > + * > + * Ungate clocks > + */ > + > +static int cm_full_cfg(struct mainpll_cfg *main_cfg, struct perpll_cfg > *per_cfg) > +{ > + unsigned int pll_ramp_main_hz = 0, pll_ramp_periph_hz = 0, > + ramp_required; > + > + /* gate off all mainpll clock excpet HW managed clock */ > + writel(CLKMGR_MAINPLL_EN_S2FUSER0CLKEN_SET_MSK | > + CLKMGR_MAINPLL_EN_HMCPLLREFCLKEN_SET_MSK, > + &clock_manager_base->main_pll.enr); > + > + /* now we can gate off the rest of the peripheral clocks */ > + writel(0, &clock_manager_base->per_pll.en); > + > + /* Put all plls in external bypass */ > + writel(CLKMGR_MAINPLL_BYPASS_RESET, > + &clock_manager_base->main_pll.bypasss); > + writel(CLKMGR_PERPLL_BYPASS_RESET, > + &clock_manager_base->per_pll.bypasss); > + > + /* > + * Put all plls VCO registers back to reset value. > + * Some code might have messed with them. At same time set the > + * desired clock source > + */ > + writel(CLKMGR_MAINPLL_VCO0_RESET | > + CLKMGR_MAINPLL_VCO0_REGEXTSEL_SET_MSK | > + (main_cfg->vco0_psrc << > + CLKMGR_MAINPLL_VCO0_PSRC_LSB), > + &clock_manager_base->main_pll.vco0); > + > + writel(CLKMGR_PERPLL_VCO0_RESET | > + CLKMGR_PERPLL_VCO0_REGEXTSEL_SET_MSK | > + (per_cfg->vco0_psrc << > + CLKMGR_PERPLL_VCO0_PSRC_LSB), > + &clock_manager_base->per_pll.vco0); > + > + writel(CLKMGR_MAINPLL_VCO1_RESET, > + &clock_manager_base->main_pll.vco1); > + writel(CLKMGR_PERPLL_VCO1_RESET, > + &clock_manager_base->per_pll.vco1); > + > + /* clear the interrupt register status register */ > + writel(CLKMGR_CLKMGR_INTR_MAINPLLLOST_SET_MSK | > + CLKMGR_CLKMGR_INTR_PERPLLLOST_SET_MSK | > + CLKMGR_CLKMGR_INTR_MAINPLLRFSLIP_SET_MSK | > + CLKMGR_CLKMGR_INTR_PERPLLRFSLIP_SET_MSK | > + CLKMGR_CLKMGR_INTR_MAINPLLFBSLIP_SET_MSK | > + CLKMGR_CLKMGR_INTR_PERPLLFBSLIP_SET_MSK | > + CLKMGR_CLKMGR_INTR_MAINPLLACHIEVED_SET_MSK | > + CLKMGR_CLKMGR_INTR_PERPLLACHIEVED_SET_MSK, > + &clock_manager_base->intr); > + > + /* Program VCO �Numerator� and �Denominator� for main PLL */ > + ramp_required = cm_is_pll_ramp_required(0, main_cfg, per_cfg); > + if (ramp_required) { > + /* set main PLL to safe starting threshold frequency */ > + if (ramp_required == 1) > + pll_ramp_main_hz = CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ; > + else if (ramp_required == 2) > + pll_ramp_main_hz = CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ; > + > + writel((main_cfg->vco1_denom << CLKMGR_MAINPLL_VCO1_DENOM_LSB) | > + cm_calc_safe_pll_numer(0, main_cfg, per_cfg, > + pll_ramp_main_hz), > + &clock_manager_base->main_pll.vco1); > + } else > + writel((main_cfg->vco1_denom << CLKMGR_MAINPLL_VCO1_DENOM_LSB) | > + main_cfg->vco1_numer, > + &clock_manager_base->main_pll.vco1); > + > + /* Program VCO �Numerator� and �Denominator� for periph PLL */ > + ramp_required = cm_is_pll_ramp_required(1, main_cfg, per_cfg); > + if (ramp_required) { > + /* set periph PLL to safe starting threshold frequency */ > + if (ramp_required == 1) > + pll_ramp_periph_hz = > + CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ; > + else if (ramp_required == 2) > + pll_ramp_periph_hz = > + CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ; > + > + writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) | > + cm_calc_safe_pll_numer(1, main_cfg, per_cfg, > + pll_ramp_periph_hz), > + &clock_manager_base->per_pll.vco1); > + } else > + writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) | > + per_cfg->vco1_numer, > + &clock_manager_base->per_pll.vco1); > + > + /* Wait for at least 5 us */ > + udelay(5); > + > + /* Now deassert BGPWRDN and PWRDN */ > + clrbits_le32(&clock_manager_base->main_pll.vco0, > + CLKMGR_MAINPLL_VCO0_BGPWRDN_SET_MSK | > + CLKMGR_MAINPLL_VCO0_PWRDN_SET_MSK); > + clrbits_le32(&clock_manager_base->per_pll.vco0, > + CLKMGR_PERPLL_VCO0_BGPWRDN_SET_MSK | > + CLKMGR_PERPLL_VCO0_PWRDN_SET_MSK); > + > + /* Wait for at least 7 us */ > + udelay(7); > + > + /* enable the VCO and disable the external regulator to PLL */ > + writel((readl(&clock_manager_base->main_pll.vco0) & > + ~CLKMGR_MAINPLL_VCO0_REGEXTSEL_SET_MSK) | > + CLKMGR_MAINPLL_VCO0_EN_SET_MSK, > + &clock_manager_base->main_pll.vco0); > + writel((readl(&clock_manager_base->per_pll.vco0) & > + ~CLKMGR_PERPLL_VCO0_REGEXTSEL_SET_MSK) | > + CLKMGR_PERPLL_VCO0_EN_SET_MSK, > + &clock_manager_base->per_pll.vco0); > + > + /* setup all the main PLL counter and clock source */ > + writel(main_cfg->nocclk, > + SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLL_NOC_CLK_OFFSET); > + writel(main_cfg->mpuclk, > + SOCFPGA_CLKMGR_ADDRESS + CLKMGR_ALTERAGRP_MPU_CLK_OFFSET); > + > + /* main_emaca_clk divider */ > + writel(main_cfg->cntr2clk_cnt, > + &clock_manager_base->main_pll.cntr2clk); > + /* main_emacb_clk divider */ > + writel(main_cfg->cntr3clk_cnt, > + &clock_manager_base->main_pll.cntr3clk); > + /* main_emac_ptp_clk divider */ > + writel(main_cfg->cntr4clk_cnt, > + &clock_manager_base->main_pll.cntr4clk); > + /* main_gpio_db_clk divider */ > + writel(main_cfg->cntr5clk_cnt, > + &clock_manager_base->main_pll.cntr5clk); > + /* main_sdmmc_clk divider */ > + writel(main_cfg->cntr6clk_cnt, > + &clock_manager_base->main_pll.cntr6clk); > + /* main_s2f_user0_clk divider */ > + writel(main_cfg->cntr7clk_cnt | > + (main_cfg->cntr7clk_src << > + CLKMGR_MAINPLL_CNTR7CLK_SRC_LSB), > + &clock_manager_base->main_pll.cntr7clk); > + /* main_s2f_user1_clk divider */ > + writel(main_cfg->cntr8clk_cnt, > + &clock_manager_base->main_pll.cntr8clk); > + /* main_hmc_pll_clk divider */ > + writel(main_cfg->cntr9clk_cnt | > + (main_cfg->cntr9clk_src << > + CLKMGR_MAINPLL_CNTR9CLK_SRC_LSB), > + &clock_manager_base->main_pll.cntr9clk); > + /* main_periph_ref_clk divider */ > + writel(main_cfg->cntr15clk_cnt, > + &clock_manager_base->main_pll.cntr15clk); > + > + /* setup all the peripheral PLL counter and clock source */ > + /* peri_emaca_clk divider */ > + writel(per_cfg->cntr2clk_cnt | > + (per_cfg->cntr2clk_src << CLKMGR_PERPLL_CNTR2CLK_SRC_LSB), > + &clock_manager_base->per_pll.cntr2clk); > + /* peri_emacb_clk divider */ > + writel(per_cfg->cntr3clk_cnt | > + (per_cfg->cntr3clk_src << CLKMGR_PERPLL_CNTR3CLK_SRC_LSB), > + &clock_manager_base->per_pll.cntr3clk); > + /* peri_emac_ptp_clk divider */ > + writel(per_cfg->cntr4clk_cnt | > + (per_cfg->cntr4clk_src << CLKMGR_PERPLL_CNTR4CLK_SRC_LSB), > + &clock_manager_base->per_pll.cntr4clk); > + /* peri_gpio_db_clk divider */ > + writel(per_cfg->cntr5clk_cnt | > + (per_cfg->cntr5clk_src << CLKMGR_PERPLL_CNTR5CLK_SRC_LSB), > + &clock_manager_base->per_pll.cntr5clk); > + /* peri_sdmmc_clk divider */ > + writel(per_cfg->cntr6clk_cnt | > + (per_cfg->cntr6clk_src << CLKMGR_PERPLL_CNTR6CLK_SRC_LSB), > + &clock_manager_base->per_pll.cntr6clk); > + /* peri_s2f_user0_clk divider */ > + writel(per_cfg->cntr7clk_cnt, > + &clock_manager_base->per_pll.cntr7clk); > + /* peri_s2f_user1_clk divider */ > + writel(per_cfg->cntr8clk_cnt | > + (per_cfg->cntr8clk_src << CLKMGR_PERPLL_CNTR8CLK_SRC_LSB), > + &clock_manager_base->per_pll.cntr8clk); > + /* peri_hmc_pll_clk divider */ > + writel(per_cfg->cntr9clk_cnt, > + &clock_manager_base->per_pll.cntr9clk); > + > + /* setup all the external PLL counter */ > + /* mpu wrapper / external divider */ > + writel(main_cfg->mpuclk_cnt | > + (main_cfg->mpuclk_src << > + CLKMGR_MAINPLL_MPUCLK_SRC_LSB), > + &clock_manager_base->main_pll.mpuclk); > + /* NOC wrapper / external divider */ > + writel(main_cfg->nocclk_cnt | > + (main_cfg->nocclk_src << CLKMGR_MAINPLL_NOCCLK_SRC_LSB), > + &clock_manager_base->main_pll.nocclk); > + /* NOC subclock divider such as l4 */ > + writel(main_cfg->nocdiv_l4mainclk | > + (main_cfg->nocdiv_l4mpclk << > + CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB) | > + (main_cfg->nocdiv_l4spclk << > + CLKMGR_MAINPLL_NOCDIV_L4SPCLK_LSB) | > + (main_cfg->nocdiv_csatclk << > + CLKMGR_MAINPLL_NOCDIV_CSATCLK_LSB) | > + (main_cfg->nocdiv_cstraceclk << > + CLKMGR_MAINPLL_NOCDIV_CSTRACECLK_LSB) | > + (main_cfg->nocdiv_cspdbclk << > + CLKMGR_MAINPLL_NOCDIV_CSPDBGCLK_LSB), > + &clock_manager_base->main_pll.nocdiv); > + /* gpio_db external divider */ > + writel(per_cfg->gpiodiv_gpiodbclk, > + &clock_manager_base->per_pll.gpiodiv); > + > + /* setup the EMAC clock mux select */ > + writel((per_cfg->emacctl_emac0sel << > + CLKMGR_PERPLL_EMACCTL_EMAC0SEL_LSB) | > + (per_cfg->emacctl_emac1sel << > + CLKMGR_PERPLL_EMACCTL_EMAC1SEL_LSB) | > + (per_cfg->emacctl_emac2sel << > + CLKMGR_PERPLL_EMACCTL_EMAC2SEL_LSB), > + &clock_manager_base->per_pll.emacctl); > + > + /* at this stage, check for PLL lock status */ > + cm_wait_for_lock(LOCKED_MASK); > + > + /* > + * after locking, but before taking out of bypass, > + * assert/deassert outresetall > + */ > + /* assert mainpll outresetall */ > + setbits_le32(&clock_manager_base->main_pll.vco0, > + CLKMGR_MAINPLL_VCO0_OUTRSTALL_SET_MSK); > + /* assert perpll outresetall */ > + setbits_le32(&clock_manager_base->per_pll.vco0, > + CLKMGR_PERPLL_VCO0_OUTRSTALL_SET_MSK); > + /* de-assert mainpll outresetall */ > + clrbits_le32(&clock_manager_base->main_pll.vco0, > + CLKMGR_MAINPLL_VCO0_OUTRSTALL_SET_MSK); > + /* de-assert perpll outresetall */ > + clrbits_le32(&clock_manager_base->per_pll.vco0, > + CLKMGR_PERPLL_VCO0_OUTRSTALL_SET_MSK); > + > + /* Take all PLLs out of bypass when boot mode is cleared. */ > + /* release mainpll from bypass */ > + writel(CLKMGR_MAINPLL_BYPASS_RESET, > + &clock_manager_base->main_pll.bypassr); > + /* wait till Clock Manager is not busy */ > + cm_wait_for_fsm(); > + > + /* release perpll from bypass */ > + writel(CLKMGR_PERPLL_BYPASS_RESET, > + &clock_manager_base->per_pll.bypassr); > + /* wait till Clock Manager is not busy */ > + cm_wait_for_fsm(); > + > + /* clear boot mode */ > + clrbits_le32(&clock_manager_base->ctrl, > + CLKMGR_CLKMGR_CTL_BOOTMOD_SET_MSK); > + /* wait till Clock Manager is not busy */ > + cm_wait_for_fsm(); > + > + /* At here, we need to ramp to final value if needed */ > + if (pll_ramp_main_hz != 0) > + cm_pll_ramp_main(main_cfg, per_cfg, pll_ramp_main_hz); > + if (pll_ramp_periph_hz != 0) > + cm_pll_ramp_periph(main_cfg, per_cfg, pll_ramp_periph_hz); > + > + /* Now ungate non-hw-managed clocks */ > + writel(CLKMGR_MAINPLL_EN_S2FUSER0CLKEN_SET_MSK | > + CLKMGR_MAINPLL_EN_HMCPLLREFCLKEN_SET_MSK, > + &clock_manager_base->main_pll.ens); > + writel(CLKMGR_PERPLL_EN_RESET, > + &clock_manager_base->per_pll.ens); > + > + /* Clear the loss lock and slip bits as they might set during > + clock reconfiguration */ > + writel(CLKMGR_CLKMGR_INTR_MAINPLLLOST_SET_MSK | > + CLKMGR_CLKMGR_INTR_PERPLLLOST_SET_MSK | > + CLKMGR_CLKMGR_INTR_MAINPLLRFSLIP_SET_MSK | > + CLKMGR_CLKMGR_INTR_PERPLLRFSLIP_SET_MSK | > + CLKMGR_CLKMGR_INTR_MAINPLLFBSLIP_SET_MSK | > + CLKMGR_CLKMGR_INTR_PERPLLFBSLIP_SET_MSK, > + &clock_manager_base->intr); > + > + return 0; > +} > + > +int cm_basic_init(const void *blob) > +{ > + struct mainpll_cfg main_cfg; > + struct perpll_cfg per_cfg; > + struct alteragrp_cfg altrgrp_cfg; > + int rval; > + > + /* initialize to zero for use case of optional node */ > + memset(&main_cfg, 0, sizeof(main_cfg)); > + memset(&per_cfg, 0, sizeof(per_cfg)); > + memset(&altrgrp_cfg, 0, sizeof(altrgrp_cfg)); > + > + if (of_get_clk_cfg(blob, &main_cfg, &per_cfg, &altrgrp_cfg)) { > + return 1; > + } > + > + rval = cm_full_cfg(&main_cfg, &per_cfg); > + > + cm_l4_main_clk_hz = > + cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MAINCLK_LSB); > + > + cm_l4_mp_clk_hz = cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB); > + > + cm_l4_sp_clk_hz = cm_get_l4_sp_clk_hz(); > + > + cm_l4_sys_free_clk_hz = cm_get_noc_clk_hz()/4; > + > + return rval; > +} > diff --git a/arch/arm/mach-socfpga/clock_manager.c > b/arch/arm/mach-socfpga/clock_manager_gen5.c > similarity index 62% > copy from arch/arm/mach-socfpga/clock_manager.c > copy to arch/arm/mach-socfpga/clock_manager_gen5.c > index aa71636..f4bb02b 100644 > --- a/arch/arm/mach-socfpga/clock_manager.c > +++ b/arch/arm/mach-socfpga/clock_manager_gen5.c > @@ -1,7 +1,7 @@ > /* > - * Copyright (C) 2013 Altera Corporation <www.altera.com> > + * Copyright (C) 2016, Intel Corporation > * > - * SPDX-License-Identifier: GPL-2.0+ > + * SPDX-License-Identifier: GPL-2.0 > */ > > #include <common.h> > @@ -10,31 +10,19 @@ > > DECLARE_GLOBAL_DATA_PTR; > > +const unsigned int cm_get_osc_clk_hz(const int osc); > +const unsigned int cm_get_f2s_per_ref_clk_hz(void); > +const unsigned int cm_get_f2s_sdr_ref_clk_hz(void); > +static void cm_write_bypass(uint32_t val); > +static void cm_write_ctrl(uint32_t val); > +static void cm_write_with_phase(uint32_t value, > + uint32_t reg_address, uint32_t mask); > +unsigned long cm_get_sdram_clk_hz(void); > +int set_cpu_clk_info(void); > + > static const struct socfpga_clock_manager *clock_manager_base = > (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS; > > -static void cm_wait_for_lock(uint32_t mask) > -{ > - register uint32_t inter_val; > - uint32_t retry = 0; > - do { > - inter_val = readl(&clock_manager_base->inter) & mask; > - if (inter_val == mask) > - retry++; > - else > - retry = 0; > - if (retry >= 10) > - break; > - } while (1); > -} > - > -/* function to poll in the fsm busy bit */ > -static void cm_wait_for_fsm(void) > -{ > - while (readl(&clock_manager_base->stat) & CLKMGR_STAT_BUSY) > - ; > -} > - > /* > * function to write the bypass register which requires a poll of the > * busy bit > @@ -87,7 +75,6 @@ static void cm_write_with_phase(uint32_t value, > * set source main and peripheral clocks > * Ungate clocks > */ > - > void cm_basic_init(const struct cm_config * const cfg) > { > unsigned long end; > @@ -230,11 +217,6 @@ void cm_basic_init(const struct cm_config * const cfg) > > writel(cfg->gpiodiv, &clock_manager_base->per_pll.gpiodiv); > > -#define LOCKED_MASK \ > - (CLKMGR_INTER_SDRPLLLOCKED_MASK | \ > - CLKMGR_INTER_PERPLLLOCKED_MASK | \ > - CLKMGR_INTER_MAINPLLLOCKED_MASK) > - > cm_wait_for_lock(LOCKED_MASK); > > /* write the sdram clock counters before toggling outreset all */ > @@ -328,60 +310,6 @@ void cm_basic_init(const struct cm_config * const cfg) > &clock_manager_base->inter); > } > > -static unsigned int cm_get_main_vco_clk_hz(void) > -{ > - uint32_t reg, clock; > - > - /* get the main VCO clock */ > - reg = readl(&clock_manager_base->main_pll.vco); > - clock = cm_get_osc_clk_hz(1); > - clock /= ((reg & CLKMGR_MAINPLLGRP_VCO_DENOM_MASK) >> > - CLKMGR_MAINPLLGRP_VCO_DENOM_OFFSET) + 1; > - clock *= ((reg & CLKMGR_MAINPLLGRP_VCO_NUMER_MASK) >> > - CLKMGR_MAINPLLGRP_VCO_NUMER_OFFSET) + 1; > - > - return clock; > -} > - > -static unsigned int cm_get_per_vco_clk_hz(void) > -{ > - uint32_t reg, clock = 0; > - > - /* identify PER PLL clock source */ > - reg = readl(&clock_manager_base->per_pll.vco); > - reg = (reg & CLKMGR_PERPLLGRP_VCO_SSRC_MASK) >> > - CLKMGR_PERPLLGRP_VCO_SSRC_OFFSET; > - if (reg == CLKMGR_VCO_SSRC_EOSC1) > - clock = cm_get_osc_clk_hz(1); > - else if (reg == CLKMGR_VCO_SSRC_EOSC2) > - clock = cm_get_osc_clk_hz(2); > - else if (reg == CLKMGR_VCO_SSRC_F2S) > - clock = cm_get_f2s_per_ref_clk_hz(); > - > - /* get the PER VCO clock */ > - reg = readl(&clock_manager_base->per_pll.vco); > - clock /= ((reg & CLKMGR_PERPLLGRP_VCO_DENOM_MASK) >> > - CLKMGR_PERPLLGRP_VCO_DENOM_OFFSET) + 1; > - clock *= ((reg & CLKMGR_PERPLLGRP_VCO_NUMER_MASK) >> > - CLKMGR_PERPLLGRP_VCO_NUMER_OFFSET) + 1; > - > - return clock; > -} > - > -unsigned long cm_get_mpu_clk_hz(void) > -{ > - uint32_t reg, clock; > - > - clock = cm_get_main_vco_clk_hz(); > - > - /* get the MPU clock */ > - reg = readl(&clock_manager_base->altera.mpuclk); > - clock /= (reg + 1); > - reg = readl(&clock_manager_base->main_pll.mpuclk); > - clock /= (reg + 1); > - return clock; > -} > - > unsigned long cm_get_sdram_clk_hz(void) > { > uint32_t reg, clock = 0; > @@ -412,147 +340,3 @@ unsigned long cm_get_sdram_clk_hz(void) > > return clock; > } > - > -unsigned int cm_get_l4_sp_clk_hz(void) > -{ > - uint32_t reg, clock = 0; > - > - /* identify the source of L4 SP clock */ > - reg = readl(&clock_manager_base->main_pll.l4src); > - reg = (reg & CLKMGR_MAINPLLGRP_L4SRC_L4SP) >> > - CLKMGR_MAINPLLGRP_L4SRC_L4SP_OFFSET; > - > - if (reg == CLKMGR_L4_SP_CLK_SRC_MAINPLL) { > - clock = cm_get_main_vco_clk_hz(); > - > - /* get the clock prior L4 SP divider (main clk) */ > - reg = readl(&clock_manager_base->altera.mainclk); > - clock /= (reg + 1); > - reg = readl(&clock_manager_base->main_pll.mainclk); > - clock /= (reg + 1); > - } else if (reg == CLKMGR_L4_SP_CLK_SRC_PERPLL) { > - clock = cm_get_per_vco_clk_hz(); > - > - /* get the clock prior L4 SP divider (periph_base_clk) */ > - reg = readl(&clock_manager_base->per_pll.perbaseclk); > - clock /= (reg + 1); > - } > - > - /* get the L4 SP clock which supplied to UART */ > - reg = readl(&clock_manager_base->main_pll.maindiv); > - reg = (reg & CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_MASK) >> > - CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_OFFSET; > - clock = clock / (1 << reg); > - > - return clock; > -} > - > -unsigned int cm_get_mmc_controller_clk_hz(void) > -{ > - uint32_t reg, clock = 0; > - > - /* identify the source of MMC clock */ > - reg = readl(&clock_manager_base->per_pll.src); > - reg = (reg & CLKMGR_PERPLLGRP_SRC_SDMMC_MASK) >> > - CLKMGR_PERPLLGRP_SRC_SDMMC_OFFSET; > - > - if (reg == CLKMGR_SDMMC_CLK_SRC_F2S) { > - clock = cm_get_f2s_per_ref_clk_hz(); > - } else if (reg == CLKMGR_SDMMC_CLK_SRC_MAIN) { > - clock = cm_get_main_vco_clk_hz(); > - > - /* get the SDMMC clock */ > - reg = readl(&clock_manager_base->main_pll.mainnandsdmmcclk); > - clock /= (reg + 1); > - } else if (reg == CLKMGR_SDMMC_CLK_SRC_PER) { > - clock = cm_get_per_vco_clk_hz(); > - > - /* get the SDMMC clock */ > - reg = readl(&clock_manager_base->per_pll.pernandsdmmcclk); > - clock /= (reg + 1); > - } > - > - /* further divide by 4 as we have fixed divider at wrapper */ > - clock /= 4; > - return clock; > -} > - > -unsigned int cm_get_qspi_controller_clk_hz(void) > -{ > - uint32_t reg, clock = 0; > - > - /* identify the source of QSPI clock */ > - reg = readl(&clock_manager_base->per_pll.src); > - reg = (reg & CLKMGR_PERPLLGRP_SRC_QSPI_MASK) >> > - CLKMGR_PERPLLGRP_SRC_QSPI_OFFSET; > - > - if (reg == CLKMGR_QSPI_CLK_SRC_F2S) { > - clock = cm_get_f2s_per_ref_clk_hz(); > - } else if (reg == CLKMGR_QSPI_CLK_SRC_MAIN) { > - clock = cm_get_main_vco_clk_hz(); > - > - /* get the qspi clock */ > - reg = readl(&clock_manager_base->main_pll.mainqspiclk); > - clock /= (reg + 1); > - } else if (reg == CLKMGR_QSPI_CLK_SRC_PER) { > - clock = cm_get_per_vco_clk_hz(); > - > - /* get the qspi clock */ > - reg = readl(&clock_manager_base->per_pll.perqspiclk); > - clock /= (reg + 1); > - } > - > - return clock; > -} > - > -unsigned int cm_get_spi_controller_clk_hz(void) > -{ > - uint32_t reg, clock = 0; > - > - clock = cm_get_per_vco_clk_hz(); > - > - /* get the clock prior L4 SP divider (periph_base_clk) */ > - reg = readl(&clock_manager_base->per_pll.perbaseclk); > - clock /= (reg + 1); > - > - return clock; > -} > - > -static void cm_print_clock_quick_summary(void) > -{ > - printf("MPU %10ld kHz\n", cm_get_mpu_clk_hz() / 1000); > - printf("DDR %10ld kHz\n", cm_get_sdram_clk_hz() / 1000); > - printf("EOSC1 %8d kHz\n", cm_get_osc_clk_hz(1) / 1000); > - printf("EOSC2 %8d kHz\n", cm_get_osc_clk_hz(2) / 1000); > - printf("F2S_SDR_REF %8d kHz\n", cm_get_f2s_sdr_ref_clk_hz() / 1000); > - printf("F2S_PER_REF %8d kHz\n", cm_get_f2s_per_ref_clk_hz() / 1000); > - printf("MMC %8d kHz\n", cm_get_mmc_controller_clk_hz() / 1000); > - printf("QSPI %8d kHz\n", cm_get_qspi_controller_clk_hz() / 1000); > - printf("UART %8d kHz\n", cm_get_l4_sp_clk_hz() / 1000); > - printf("SPI %8d kHz\n", cm_get_spi_controller_clk_hz() / 1000); > -} > - > -int set_cpu_clk_info(void) > -{ > - /* Calculate the clock frequencies required for drivers */ > - cm_get_l4_sp_clk_hz(); > - cm_get_mmc_controller_clk_hz(); > - > - gd->bd->bi_arm_freq = cm_get_mpu_clk_hz() / 1000000; > - gd->bd->bi_dsp_freq = 0; > - gd->bd->bi_ddr_freq = cm_get_sdram_clk_hz() / 1000000; > - > - return 0; > -} > - > -int do_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) > -{ > - cm_print_clock_quick_summary(); > - return 0; > -} > - > -U_BOOT_CMD( > - clocks, CONFIG_SYS_MAXARGS, 1, do_showclocks, > - "display clocks", > - "" > -); > diff --git a/arch/arm/mach-socfpga/include/mach/clock_manager.h > b/arch/arm/mach-socfpga/include/mach/clock_manager.h > index 2675951..45943ea 100644 > --- a/arch/arm/mach-socfpga/include/mach/clock_manager.h > +++ b/arch/arm/mach-socfpga/include/mach/clock_manager.h > @@ -1,5 +1,5 @@ > /* > - * Copyright (C) 2013 Altera Corporation <www.altera.com> > + * Copyright (C) 2013-2016 Altera Corporation <www.altera.com> > * > * SPDX-License-Identifier: GPL-2.0+ > */ > @@ -8,21 +8,9 @@ > #define _CLOCK_MANAGER_H_ > > #ifndef __ASSEMBLER__ > -/* Clock speed accessors */ > -unsigned long cm_get_mpu_clk_hz(void); > -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_qspi_controller_clk_hz(void); > -unsigned int cm_get_spi_controller_clk_hz(void); > -const unsigned int cm_get_osc_clk_hz(const int osc); > -const unsigned int cm_get_f2s_per_ref_clk_hz(void); > -const unsigned int cm_get_f2s_sdr_ref_clk_hz(void); > - > -/* Clock configuration accessors */ > -const struct cm_config * const cm_get_default_config(void); > -#endif > +#include <linux/types.h> > > +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) > struct cm_config { > /* main group */ > uint32_t main_vco_base; > @@ -57,74 +45,196 @@ struct cm_config { > uint32_t s2fuser2clk; > }; > > +struct socfpga_clock_manager_sdr_pll { > + uint32_t vco; > + uint32_t ctrl; > + uint32_t ddrdqsclk; > + uint32_t ddr2xdqsclk; > + uint32_t ddrdqclk; > + uint32_t s2fuser2clk; > + uint32_t en; > + uint32_t stat; > +}; > +#endif > + > +/* Common prototypes */ > +unsigned int cm_get_l4_sp_clk_hz(void); > +unsigned int cm_get_qspi_controller_clk_hz(void); > +unsigned int cm_get_mmc_controller_clk_hz(void); > +unsigned int cm_get_spi_controller_clk_hz(void); > +void cm_use_intosc(void); > +void cm_wait_for_lock(uint32_t mask); > +void cm_wait_for_fsm(void); > +unsigned int cm_get_main_vco_clk_hz(void); > +unsigned int cm_get_per_vco_clk_hz(void); > +unsigned long cm_get_mpu_clk_hz(void); > +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) > +/* Clock speed accessors */ > +const unsigned int cm_get_osc_clk_hz(const int osc); > +const unsigned int cm_get_f2s_per_ref_clk_hz(void); > +const unsigned int cm_get_f2s_sdr_ref_clk_hz(void); > void cm_basic_init(const struct cm_config * const cfg); > +unsigned long cm_get_sdram_clk_hz(void); > +/* Clock configuration accessors */ > +const struct cm_config * const cm_get_default_config(void); > +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) > +unsigned int cm_get_noc_clk_hz(void); > +unsigned int cm_get_l4_noc_hz(unsigned int nocdivshift); > +int cm_basic_init(const void* blob); > +extern unsigned int cm_l4_main_clk_hz; > +extern unsigned int cm_l4_sp_clk_hz; > +extern unsigned int cm_l4_mp_clk_hz; > +extern unsigned int cm_l4_sys_free_clk_hz; > +extern uint32_t eosc1_hz; > +extern uint32_t cb_intosc_hz; > +extern uint32_t f2s_free_hz; > +#endif > +#endif > > struct socfpga_clock_manager_main_pll { > - u32 vco; > - u32 misc; > - u32 mpuclk; > - u32 mainclk; > - u32 dbgatclk; > - u32 mainqspiclk; > - u32 mainnandsdmmcclk; > - u32 cfgs2fuser0clk; > - u32 en; > - u32 maindiv; > - u32 dbgdiv; > - u32 tracediv; > - u32 l4src; > - u32 stat; > - u32 _pad_0x38_0x40[2]; > +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) > + uint32_t vco; > + uint32_t misc; > + uint32_t mpuclk; > + uint32_t mainclk; > + uint32_t dbgatclk; > + uint32_t mainqspiclk; > + uint32_t mainnandsdmmcclk; > + uint32_t cfgs2fuser0clk; > + uint32_t en; > + uint32_t maindiv; > + uint32_t dbgdiv; > + uint32_t tracediv; > + uint32_t l4src; > + uint32_t stat; > + uint32_t _pad_0x38_0x40[2]; > +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) > + uint32_t vco0; > + uint32_t vco1; > + uint32_t en; > + uint32_t ens; > + uint32_t enr; > + uint32_t bypass; > + uint32_t bypasss; > + uint32_t bypassr; > + uint32_t mpuclk; > + uint32_t nocclk; > + uint32_t cntr2clk; > + uint32_t cntr3clk; > + uint32_t cntr4clk; > + uint32_t cntr5clk; > + uint32_t cntr6clk; > + uint32_t cntr7clk; > + uint32_t cntr8clk; > + uint32_t cntr9clk; > + uint32_t pad_0x48_0x5b[5]; > + uint32_t cntr15clk; > + uint32_t outrst; > + uint32_t outrststat; > + uint32_t nocdiv; > + uint32_t pad_0x6c_0x80[5]; > +#endif > }; > > struct socfpga_clock_manager_per_pll { > - u32 vco; > - u32 misc; > - u32 emac0clk; > - u32 emac1clk; > - u32 perqspiclk; > - u32 pernandsdmmcclk; > - u32 perbaseclk; > - u32 s2fuser1clk; > - u32 en; > - u32 div; > - u32 gpiodiv; > - u32 src; > - u32 stat; > - u32 _pad_0x34_0x40[3]; > -}; > - > -struct socfpga_clock_manager_sdr_pll { > - u32 vco; > - u32 ctrl; > - u32 ddrdqsclk; > - u32 ddr2xdqsclk; > - u32 ddrdqclk; > - u32 s2fuser2clk; > - u32 en; > - u32 stat; > +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) > + uint32_t vco; > + uint32_t misc; > + uint32_t emac0clk; > + uint32_t emac1clk; > + uint32_t perqspiclk; > + uint32_t pernandsdmmcclk; > + uint32_t perbaseclk; > + uint32_t s2fuser1clk; > + uint32_t en; > + uint32_t div; > + uint32_t gpiodiv; > + uint32_t src; > + uint32_t stat; > + uint32_t _pad_0x34_0x40[3]; > +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) > + uint32_t vco0; > + uint32_t vco1; > + uint32_t en; > + uint32_t ens; > + uint32_t enr; > + uint32_t bypass; > + uint32_t bypasss; > + uint32_t bypassr; > + uint32_t pad_0x20_0x27[2]; > + uint32_t cntr2clk; > + uint32_t cntr3clk; > + uint32_t cntr4clk; > + uint32_t cntr5clk; > + uint32_t cntr6clk; > + uint32_t cntr7clk; > + uint32_t cntr8clk; > + uint32_t cntr9clk; > + uint32_t pad_0x48_0x5f[6]; > + uint32_t outrst; > + uint32_t outrststat; > + uint32_t emacctl; > + uint32_t gpiodiv; > + uint32_t pad_0x70_0x80[4]; > +#endif > }; > > struct socfpga_clock_manager_altera { > - u32 mpuclk; > - u32 mainclk; > + uint32_t mpuclk; > +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) > + uint32_t mainclk; > +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) > + uint32_t nocclk; > + uint32_t mainmisc0; > + uint32_t mainmisc1; > + uint32_t perimisc0; > + uint32_t perimisc1; > +#endif > }; > > struct socfpga_clock_manager { > - u32 ctrl; > - u32 bypass; > - u32 inter; > - u32 intren; > - u32 dbctrl; > - u32 stat; > - u32 _pad_0x18_0x3f[10]; > +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) > + uint32_t ctrl; > + uint32_t bypass; > + uint32_t inter; > + uint32_t intren; > + uint32_t dbctrl; > + uint32_t stat; > + uint32_t _pad_0x18_0x3f[10]; > struct socfpga_clock_manager_main_pll main_pll; > struct socfpga_clock_manager_per_pll per_pll; > struct socfpga_clock_manager_sdr_pll sdr_pll; > struct socfpga_clock_manager_altera altera; > - u32 _pad_0xe8_0x200[70]; > + uint32_t _pad_0xe8_0x200[70]; > +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) > + /* clkmgr */ > + uint32_t ctrl; > + uint32_t intr; > + uint32_t intrs; > + uint32_t intrr; > + uint32_t intren; > + uint32_t intrens; > + uint32_t intrenr; > + uint32_t stat; > + uint32_t testioctrl; > + uint32_t _pad_0x24_0x40[7]; > + /* mainpllgrp */ > + struct socfpga_clock_manager_main_pll main_pll; > + /* perpllgrp */ > + struct socfpga_clock_manager_per_pll per_pll; > + struct socfpga_clock_manager_altera altera; > +#endif > }; > > +/* Common mask */ > +#define CLKMGR_CLKMGR_STAT_BUSY_SET_MSK 0x00000001 > + > +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) > +#define LOCKED_MASK \ > + (CLKMGR_INTER_SDRPLLLOCKED_MASK | \ > + CLKMGR_INTER_PERPLLLOCKED_MASK | \ > + CLKMGR_INTER_MAINPLLLOCKED_MASK) > + > #define CLKMGR_CTRL_SAFEMODE (1 << 0) > #define CLKMGR_CTRL_SAFEMODE_OFFSET 0 > > @@ -310,5 +420,119 @@ struct socfpga_clock_manager { > #define CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_MASK 0x000001ff > #define CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_OFFSET 9 > #define CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_MASK 0x00000e00 > - > +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) > +#define CLKMGR_ALTERAGRP_MPU_CLK_OFFSET 0x140 > +#define CLKMGR_MAINPLL_NOC_CLK_OFFSET 0x144 > +#define LOCKED_MASK \ > + (CLKMGR_CLKMGR_STAT_MAINPLLLOCKED_SET_MSK | \ > + CLKMGR_CLKMGR_STAT_PERPLLLOCKED_SET_MSK) > + > +/* value */ > +#define CLKMGR_MAINPLL_BYPASS_RESET 0x0000003f > +#define CLKMGR_PERPLL_BYPASS_RESET 0x000000ff > +#define CLKMGR_MAINPLL_VCO0_RESET 0x00010053 > +#define CLKMGR_MAINPLL_VCO1_RESET 0x00010001 > +#define CLKMGR_PERPLL_VCO0_RESET 0x00010053 > +#define CLKMGR_PERPLL_VCO1_RESET 0x00010001 > +#define CLKMGR_MAINPLL_VCO0_PSRC_EOSC 0x0 > +#define CLKMGR_MAINPLL_VCO0_PSRC_E_INTOSC 0x1 > +#define CLKMGR_MAINPLL_VCO0_PSRC_F2S 0x2 > +#define CLKMGR_PERPLL_VCO0_PSRC_EOSC 0x0 > +#define CLKMGR_PERPLL_VCO0_PSRC_E_INTOSC 0x1 > +#define CLKMGR_PERPLL_VCO0_PSRC_F2S 0x2 > +#define CLKMGR_PERPLL_VCO0_PSRC_MAIN 0x3 > + > +/* mask */ > +#define CLKMGR_MAINPLL_EN_S2FUSER0CLKEN_SET_MSK 0x00000040 > +#define CLKMGR_MAINPLL_EN_HMCPLLREFCLKEN_SET_MSK 0x00000080 > +#define CLKMGR_CLKMGR_STAT_MAINPLLLOCKED_SET_MSK 0x00000100 > +#define CLKMGR_CLKMGR_STAT_PERPLLLOCKED_SET_MSK 0x00000200 > +#define CLKMGR_CLKMGR_STAT_BOOTCLKSRC_SET_MSK 0x00020000 > +#define CLKMGR_MAINPLL_VCO0_BGPWRDN_SET_MSK 0x00000001 > +#define CLKMGR_MAINPLL_VCO0_PWRDN_SET_MSK 0x00000002 > +#define CLKMGR_MAINPLL_VCO0_EN_SET_MSK 0x00000004 > +#define CLKMGR_MAINPLL_VCO0_OUTRSTALL_SET_MSK 0x00000008 > +#define CLKMGR_MAINPLL_VCO0_REGEXTSEL_SET_MSK 0x00000010 > +#define CLKMGR_PERPLL_VCO0_BGPWRDN_SET_MSK 0x00000001 > +#define CLKMGR_PERPLL_VCO0_PWRDN_SET_MSK 0x00000002 > +#define CLKMGR_PERPLL_VCO0_EN_SET_MSK 0x00000004 > +#define CLKMGR_PERPLL_VCO0_OUTRSTALL_SET_MSK 0x00000008 > +#define CLKMGR_PERPLL_VCO0_REGEXTSEL_SET_MSK 0x00000010 > +#define CLKMGR_CLKMGR_INTR_PERPLLFBSLIP_SET_MSK 0x00000800 > +#define CLKMGR_CLKMGR_INTR_MAINPLLFBSLIP_SET_MSK 0x00000400 > +#define CLKMGR_CLKMGR_INTR_PERPLLRFSLIP_SET_MSK 0x00000200 > +#define CLKMGR_CLKMGR_INTR_MAINPLLRFSLIP_SET_MSK 0x00000100 > +#define CLKMGR_CLKMGR_INTR_PERPLLLOST_SET_MSK 0x00000008 > +#define CLKMGR_CLKMGR_INTR_MAINPLLLOST_SET_MSK 0x00000004 > +#define CLKMGR_CLKMGR_INTR_MAINPLLACHIEVED_SET_MSK 0x00000001 > +#define CLKMGR_CLKMGR_INTR_PERPLLACHIEVED_SET_MSK 0x00000002 > +#define CLKMGR_CLKMGR_CTL_BOOTMOD_SET_MSK 0x00000001 > +#define CLKMGR_CLKMGR_CTL_BOOTCLK_INTOSC_SET_MSK 0x00000300 > +#define CLKMGR_PERPLL_EN_RESET 0x00000f7f > +#define CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK 0x00000020 > +#define CLKMGR_MAINPLL_VCO0_PSRC_MSK 0x00000003 > +#define CLKMGR_MAINPLL_VCO1_NUMER_MSK 0x00001fff > +#define CLKMGR_MAINPLL_VCO1_DENOM_MSK 0x0000003f > +#define CLKMGR_MAINPLL_CNTRCLK_MSK 0x000003ff > +#define CLKMGR_PERPLL_VCO0_PSRC_MSK 0x00000003 > +#define CLKMGR_PERPLL_VCO1_NUMER_MSK 0x00001fff > +#define CLKMGR_PERPLL_VCO1_DENOM_MSK 0x0000003f > +#define CLKMGR_PERPLL_CNTRCLK_MSK 0x000003ff > +#define CLKMGR_MAINPLL_MPUCLK_SRC_MSK 0x00000007 > +#define CLKMGR_MAINPLL_MPUCLK_CNT_MSK 0x000003ff > +#define CLKMGR_MAINPLL_MPUCLK_SRC_MAIN 0 > +#define CLKMGR_MAINPLL_MPUCLK_SRC_PERI 1 > +#define CLKMGR_MAINPLL_MPUCLK_SRC_OSC1 2 > +#define CLKMGR_MAINPLL_MPUCLK_SRC_INTOSC 3 > +#define CLKMGR_MAINPLL_MPUCLK_SRC_FPGA 4 > +#define CLKMGR_MAINPLL_NOCDIV_MSK 0x00000003 > +#define CLKMGR_MAINPLL_NOCCLK_CNT_MSK 0x000003ff > +#define CLKMGR_MAINPLL_NOCCLK_SRC_MSK 0x00000007 > +#define CLKMGR_MAINPLL_NOCCLK_SRC_MAIN 0 > +#define CLKMGR_MAINPLL_NOCCLK_SRC_PERI 1 > +#define CLKMGR_MAINPLL_NOCCLK_SRC_OSC1 2 > +#define CLKMGR_MAINPLL_NOCCLK_SRC_INTOSC 3 > +#define CLKMGR_MAINPLL_NOCCLK_SRC_FPGA 4 > + > +#define CLKMGR_PERPLLGRP_SRC_MSK 0x00000007 > +#define CLKMGR_PERPLLGRP_SRC_MAIN 0 > +#define CLKMGR_PERPLLGRP_SRC_PERI 1 > +#define CLKMGR_PERPLLGRP_SRC_OSC1 2 > +#define CLKMGR_PERPLLGRP_SRC_INTOSC 3 > +#define CLKMGR_PERPLLGRP_SRC_FPGA 4 > + > +/* bit shifting macro */ > +#define CLKMGR_MAINPLL_VCO0_PSRC_LSB 8 > +#define CLKMGR_PERPLL_VCO0_PSRC_LSB 8 > +#define CLKMGR_MAINPLL_VCO1_DENOM_LSB 16 > +#define CLKMGR_PERPLL_VCO1_DENOM_LSB 16 > +#define CLKMGR_MAINPLL_NOCCLK_PERICNT_LSB 16 > +#define CLKMGR_MAINPLL_NOCCLK_SRC_LSB 16 > +#define CLKMGR_MAINPLL_NOCDIV_L4MAINCLK_LSB 0 > +#define CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB 8 > +#define CLKMGR_MAINPLL_NOCDIV_L4SPCLK_LSB 16 > +#define CLKMGR_MAINPLL_NOCDIV_CSATCLK_LSB 24 > +#define CLKMGR_MAINPLL_NOCDIV_CSTRACECLK_LSB 26 > +#define CLKMGR_MAINPLL_NOCDIV_CSPDBGCLK_LSB 28 > +#define CLKMGR_MAINPLL_MPUCLK_SRC_LSB 16 > +#define CLKMGR_MAINPLL_MPUCLK_PERICNT_LSB 16 > +#define CLKMGR_MAINPLL_NOCCLK_SRC_LSB 16 > +#define CLKMGR_MAINPLL_CNTR7CLK_SRC_LSB 16 > +#define CLKMGR_MAINPLL_CNTR9CLK_SRC_LSB 16 > +#define CLKMGR_PERPLL_CNTR2CLK_SRC_LSB 16 > +#define CLKMGR_PERPLL_CNTR3CLK_SRC_LSB 16 > +#define CLKMGR_PERPLL_CNTR4CLK_SRC_LSB 16 > +#define CLKMGR_PERPLL_CNTR5CLK_SRC_LSB 16 > +#define CLKMGR_PERPLL_CNTR6CLK_SRC_LSB 16 > +#define CLKMGR_PERPLL_CNTR8CLK_SRC_LSB 16 > +#define CLKMGR_PERPLL_EMACCTL_EMAC0SEL_LSB 26 > +#define CLKMGR_PERPLL_EMACCTL_EMAC1SEL_LSB 27 > +#define CLKMGR_PERPLL_EMACCTL_EMAC2SEL_LSB 28 > + > +/* PLL ramping work around */ > +#define CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ 900000000 > +#define CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ 300000000 > +#define CLKMGR_PLL_RAMP_MPUCLK_INCREMENT_HZ 100000000 > +#define CLKMGR_PLL_RAMP_NOCCLK_INCREMENT_HZ 33000000 > +#endif > #endif /* _CLOCK_MANAGER_H_ */ > -- Best regards, Marek Vasut _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot