
On 01/10/2017 06:20 AM, Chee Tien Fong wrote:
From: Tien Fong Chee tien.fong.chee@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.chee@intel.com Cc: Marek Vasut marex@denx.de Cc: Dinh Nguyen dingnuyen@kernel.org Cc: Ching Liang See chin.liang.see@intel.com Cc: Tien Fong skywindctf@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_ */