int cm_basic_init(const cm_config_t *cfg) { uint32_t start, timeout; /* 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. */ DEBUG_MEMORY writel(~CLKMGR_PERPLLGRP_EN_NANDCLK_MASK & readl(SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_EN_ADDRESS), (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_EN_ADDRESS)); /* 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, SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_EN_ADDRESS); writel(0, SOCFPGA_CLKMGR_ADDRESS + CLKMGR_SDRPLLGRP_EN_ADDRESS); /* now we can gate off the rest of the peripheral clocks */ DEBUG_MEMORY writel(0, SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_EN_ADDRESS); /* Put all plls in bypass */ DEBUG_MEMORY cm_write_bypass( CLKMGR_BYPASS_PERPLLSRC_SET( CLKMGR_BYPASS_PERPLLSRC_ENUM_SELECT_EOSC1) | CLKMGR_BYPASS_SDRPLLSRC_SET( CLKMGR_BYPASS_SDRPLLSRC_ENUM_SELECT_EOSC1) | CLKMGR_BYPASS_PERPLL_SET(CLKMGR_BYPASS_ENUM_ENABLE) | CLKMGR_BYPASS_SDRPLL_SET(CLKMGR_BYPASS_ENUM_ENABLE) | CLKMGR_BYPASS_MAINPLL_SET(CLKMGR_BYPASS_ENUM_ENABLE)); /* Put all plls VCO registers back to reset value */ DEBUG_MEMORY writel((CLKMGR_MAINPLLGRP_VCO_RESET_VALUE & ~CLKMGR_MAINPLLGRP_VCO_REGEXTSEL_MASK), SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_VCO_ADDRESS); writel((CLKMGR_PERPLLGRP_VCO_RESET_VALUE & ~CLKMGR_PERPLLGRP_VCO_REGEXTSEL_MASK), SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_VCO_ADDRESS); writel((CLKMGR_SDRPLLGRP_VCO_RESET_VALUE & ~CLKMGR_SDRPLLGRP_VCO_REGEXTSEL_MASK), SOCFPGA_CLKMGR_ADDRESS + CLKMGR_SDRPLLGRP_VCO_ADDRESS); /* * 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, SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_SRC_ADDRESS); writel(CLKMGR_MAINPLLGRP_L4SRC_RESET_VALUE, SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_L4SRC_ADDRESS); /* read back for the required 5 us delay. */ readl(SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_VCO_ADDRESS); readl(SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_VCO_ADDRESS); readl(SOCFPGA_CLKMGR_ADDRESS + CLKMGR_SDRPLLGRP_VCO_ADDRESS); /* * We made sure bgpwr down was assert for 5 us. Now deassert BG PWR DN * with numerator and denominator. */ DEBUG_MEMORY writel(cfg->main_vco_base | CLEAR_BGP_EN_PWRDN, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_VCO_ADDRESS)); writel(cfg->peri_vco_base | CLEAR_BGP_EN_PWRDN, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_VCO_ADDRESS)); writel(CLKMGR_SDRPLLGRP_VCO_OUTRESET_SET(0) | CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(0) | cfg->sdram_vco_base | CLEAR_BGP_EN_PWRDN, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_SDRPLLGRP_VCO_ADDRESS)); /* * Time starts here * must wait 7 us from BGPWRDN_SET(0) to VCO_ENABLE_SET(1) */ reset_timer(); start = get_timer(0); /* timeout in unit of us as CONFIG_SYS_HZ = 1000*1000 */ timeout = 7; /* main mpu */ DEBUG_MEMORY writel(cfg->mpuclk, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_MPUCLK_ADDRESS)); /* main main clock */ writel(cfg->mainclk, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_MAINCLK_ADDRESS)); #ifdef CONFIG_HPS_ALTERAGRP_MPUCLK /* re-configuring the fixed divider for faster MPU clock */ writel(CONFIG_HPS_ALTERAGRP_MPUCLK, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_ALTERAGRP_MPUCLK)); #endif /* main for dbg */ writel(cfg->dbgatclk, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_DBGATCLK_ADDRESS)); #ifdef CONFIG_HPS_ALTERAGRP_MAINCLK /* re-configuring the fixed divider due to different main VCO */ writel(CONFIG_HPS_ALTERAGRP_MAINCLK, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_ALTERAGRP_MAINCLK)); #endif /* main for cfgs2fuser0clk */ writel(cfg->cfg2fuser0clk, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_CFGS2FUSER0CLK_ADDRESS)); /* Peri emac0 50 MHz default to RMII */ writel(cfg->emac0clk, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_EMAC0CLK_ADDRESS)); /* Peri emac1 50 MHz default to RMII */ writel(cfg->emac1clk, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_EMAC1CLK_ADDRESS)); /* Peri QSPI */ writel(cfg->mainqspiclk, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_MAINQSPICLK_ADDRESS)); writel(cfg->perqspiclk, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_PERQSPICLK_ADDRESS)); /* Peri pernandsdmmcclk */ writel(cfg->mainnandsdmmcclk, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_MAINNANDSDMMCCLK_ADDRESS)); writel(cfg->pernandsdmmcclk, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_ADDRESS)); /* Peri perbaseclk */ writel(cfg->perbaseclk, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_PERBASECLK_ADDRESS)); /* Peri s2fuser1clk */ writel(cfg->s2fuser1clk, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_S2FUSER1CLK_ADDRESS)); /* 7 us must have elapsed before we can enable the VCO */ for ( ; get_timer(start) < timeout ; ) ; /* Enable vco */ DEBUG_MEMORY /* main pll vco */ writel(cfg->main_vco_base | VCO_EN_BASE, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_VCO_ADDRESS)); /* periferal pll */ writel(cfg->peri_vco_base | VCO_EN_BASE, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_VCO_ADDRESS)); /* sdram pll vco */ writel(CLKMGR_SDRPLLGRP_VCO_OUTRESET_SET(0) | CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(0) | cfg->sdram_vco_base | VCO_EN_BASE, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_SDRPLLGRP_VCO_ADDRESS)); /* setup dividers while plls are locking */ DEBUG_MEMORY /* L3 MP and L3 SP */ writel(cfg->maindiv, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_MAINDIV_ADDRESS)); writel(cfg->dbgdiv, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_DBGDIV_ADDRESS)); writel(cfg->tracediv, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_TRACEDIV_ADDRESS)); /* L4 MP, L4 SP, can0, and can1 */ writel(cfg->perdiv, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_DIV_ADDRESS)); writel(cfg->gpiodiv, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_GPIODIV_ADDRESS)); #define LOCKED_MASK \ (CLKMGR_INTER_SDRPLLLOCKED_MASK | \ CLKMGR_INTER_PERPLLLOCKED_MASK | \ CLKMGR_INTER_MAINPLLLOCKED_MASK) DEBUG_MEMORY cm_wait_for_lock(LOCKED_MASK); /* write the sdram clock counters before toggling outreset all */ DEBUG_MEMORY writel(cfg->ddrdqsclk & CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK, SOCFPGA_CLKMGR_ADDRESS + CLKMGR_SDRPLLGRP_DDRDQSCLK_ADDRESS); writel(cfg->ddr2xdqsclk & CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_MASK, SOCFPGA_CLKMGR_ADDRESS + CLKMGR_SDRPLLGRP_DDR2XDQSCLK_ADDRESS); writel(cfg->ddrdqclk & CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_MASK, SOCFPGA_CLKMGR_ADDRESS + CLKMGR_SDRPLLGRP_DDRDQCLK_ADDRESS); writel(cfg->s2fuser2clk & CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_MASK, SOCFPGA_CLKMGR_ADDRESS + CLKMGR_SDRPLLGRP_S2FUSER2CLK_ADDRESS); /* * after locking, but before taking out of bypass * assert/deassert outresetall */ DEBUG_MEMORY uint32_t mainvco = readl(SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_VCO_ADDRESS); /* assert main outresetall */ writel(mainvco | CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_VCO_ADDRESS)); uint32_t periphvco = readl(SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_VCO_ADDRESS); /* assert pheriph outresetall */ writel(periphvco | CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_VCO_ADDRESS)); /* assert sdram outresetall */ writel(cfg->sdram_vco_base | VCO_EN_BASE| CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(1), SOCFPGA_CLKMGR_ADDRESS + CLKMGR_SDRPLLGRP_VCO_ADDRESS); /* deassert main outresetall */ writel(mainvco & ~CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_VCO_ADDRESS)); /* deassert pheriph outresetall */ writel(periphvco & ~CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_VCO_ADDRESS)); /* deassert sdram outresetall */ writel(CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(0) | cfg->sdram_vco_base | VCO_EN_BASE, SOCFPGA_CLKMGR_ADDRESS + CLKMGR_SDRPLLGRP_VCO_ADDRESS); /* * now that we've toggled outreset all, all the clocks * are aligned nicely; so we can change any phase. */ DEBUG_MEMORY cm_write_with_phase(cfg->ddrdqsclk, SOCFPGA_CLKMGR_ADDRESS + CLKMGR_SDRPLLGRP_DDRDQSCLK_ADDRESS, CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_MASK); /* SDRAM DDR2XDQSCLK */ cm_write_with_phase(cfg->ddr2xdqsclk, SOCFPGA_CLKMGR_ADDRESS + CLKMGR_SDRPLLGRP_DDR2XDQSCLK_ADDRESS, CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_MASK); cm_write_with_phase(cfg->ddrdqclk, SOCFPGA_CLKMGR_ADDRESS + CLKMGR_SDRPLLGRP_DDRDQCLK_ADDRESS, CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_MASK); cm_write_with_phase(cfg->s2fuser2clk, SOCFPGA_CLKMGR_ADDRESS + CLKMGR_SDRPLLGRP_S2FUSER2CLK_ADDRESS, CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_MASK); /* Take all three PLLs out of bypass when safe mode is cleared. */ DEBUG_MEMORY cm_write_bypass( CLKMGR_BYPASS_PERPLLSRC_SET( CLKMGR_BYPASS_PERPLLSRC_ENUM_SELECT_EOSC1) | CLKMGR_BYPASS_SDRPLLSRC_SET( CLKMGR_BYPASS_SDRPLLSRC_ENUM_SELECT_EOSC1) | CLKMGR_BYPASS_PERPLL_SET(CLKMGR_BYPASS_ENUM_DISABLE) | CLKMGR_BYPASS_SDRPLL_SET(CLKMGR_BYPASS_ENUM_DISABLE) | CLKMGR_BYPASS_MAINPLL_SET(CLKMGR_BYPASS_ENUM_DISABLE)); /* clear safe mode */ DEBUG_MEMORY cm_write_ctrl( readl(SOCFPGA_CLKMGR_ADDRESS + CLKMGR_CTRL_ADDRESS) | CLKMGR_CTRL_SAFEMODE_SET(CLKMGR_CTRL_SAFEMODE_MASK)); /* * 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, SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_SRC_ADDRESS); writel(cfg->l4src, SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_L4SRC_ADDRESS); /* Now ungate non-hw-managed clocks */ DEBUG_MEMORY writel(~0, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_EN_ADDRESS)); writel(~0, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_EN_ADDRESS)); writel(~0, (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_SDRPLLGRP_EN_ADDRESS)); /* Clear the loss of lock bits (write 1 to clear) */ writel((CLKMGR_INTER_SDRPLLLOST_MASK | CLKMGR_INTER_PERPLLLOST_MASK | CLKMGR_INTER_MAINPLLLOST_MASK), (SOCFPGA_CLKMGR_ADDRESS + CLKMGR_INTER_ADDRESS)); return 0; }
void cm_basic_init(const cm_config_t *cfg) { uint32_t start, timeout; /* 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_PERPLLSRC_SET( CLKMGR_BYPASS_PERPLLSRC_SELECT_EOSC1) | CLKMGR_BYPASS_SDRPLLSRC_SET( CLKMGR_BYPASS_SDRPLLSRC_SELECT_EOSC1) | CLKMGR_BYPASS_PERPLL_SET(CLKMGR_BYPASS_ENABLE) | CLKMGR_BYPASS_SDRPLL_SET(CLKMGR_BYPASS_ENABLE) | CLKMGR_BYPASS_MAINPLL_SET(CLKMGR_BYPASS_ENABLE)); /* * Put all plls VCO registers back to reset value. * Some code might have messed with them. */ writel(CLKMGR_MAINPLLGRP_VCO_RESET_VALUE, &clock_manager_base->main_pll_vco); writel(CLKMGR_PERPLLGRP_VCO_RESET_VALUE, &clock_manager_base->per_pll_vco); writel(CLKMGR_SDRPLLGRP_VCO_RESET_VALUE, &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 | CLEAR_BGP_EN_PWRDN | CLKMGR_MAINPLLGRP_VCO_REGEXTSEL_MASK, &clock_manager_base->main_pll_vco); writel(cfg->peri_vco_base | CLEAR_BGP_EN_PWRDN | CLKMGR_PERPLLGRP_VCO_REGEXTSEL_MASK, &clock_manager_base->per_pll_vco); writel(CLKMGR_SDRPLLGRP_VCO_OUTRESET_SET(0) | CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(0) | cfg->sdram_vco_base | CLEAR_BGP_EN_PWRDN | CLKMGR_SDRPLLGRP_VCO_REGEXTSEL_MASK, &clock_manager_base->sdr_pll_vco); /* * Time starts here * must wait 7 us from BGPWRDN_SET(0) to VCO_ENABLE_SET(1) */ reset_timer(); start = get_timer(0); /* timeout in unit of us as CONFIG_SYS_HZ = 1000*1000 */ timeout = 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->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 (get_timer(start) < timeout) ; /* Enable vco */ /* main pll vco */ writel(cfg->main_vco_base | VCO_EN_BASE, &clock_manager_base->main_pll_vco); /* periferal pll */ writel(cfg->peri_vco_base | VCO_EN_BASE, &clock_manager_base->per_pll_vco); /* sdram pll vco */ writel(CLKMGR_SDRPLLGRP_VCO_OUTRESET_SET(0) | CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(0) | cfg->sdram_vco_base | VCO_EN_BASE, &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); writel(cfg->ddr2xdqsclk & CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_MASK, &clock_manager_base->sdr_pll_ddr2xdqsclk); writel(cfg->ddrdqclk & CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_MASK, &clock_manager_base->sdr_pll_ddrdqclk); writel(cfg->s2fuser2clk & CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_MASK, &clock_manager_base->sdr_pll_s2fuser2clk); /* * after locking, but before taking out of bypass * assert/deassert outresetall */ uint32_t mainvco = readl(&clock_manager_base->main_pll_vco); /* assert main outresetall */ writel(mainvco | CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK, &clock_manager_base->main_pll_vco); uint32_t periphvco = readl(&clock_manager_base->per_pll_vco); /* assert pheriph outresetall */ writel(periphvco | CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK, &clock_manager_base->per_pll_vco); /* assert sdram outresetall */ writel(cfg->sdram_vco_base | VCO_EN_BASE| CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(1), &clock_manager_base->sdr_pll_vco); /* deassert main outresetall */ writel(mainvco & ~CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK, &clock_manager_base->main_pll_vco); /* deassert pheriph outresetall */ writel(periphvco & ~CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK, &clock_manager_base->per_pll_vco); /* deassert sdram outresetall */ writel(CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(0) | cfg->sdram_vco_base | VCO_EN_BASE, &clock_manager_base->sdr_pll_vco); /* * 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); /* SDRAM DDR2XDQSCLK */ cm_write_with_phase(cfg->ddr2xdqsclk, (uint32_t)&clock_manager_base->sdr_pll_ddr2xdqsclk, CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_MASK); cm_write_with_phase(cfg->ddrdqclk, (uint32_t)&clock_manager_base->sdr_pll_ddrdqclk, CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_MASK); cm_write_with_phase(cfg->s2fuser2clk, (uint32_t)&clock_manager_base->sdr_pll_s2fuser2clk, CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_MASK); /* Take all three PLLs out of bypass when safe mode is cleared. */ cm_write_bypass( CLKMGR_BYPASS_PERPLLSRC_SET( CLKMGR_BYPASS_PERPLLSRC_SELECT_EOSC1) | CLKMGR_BYPASS_SDRPLLSRC_SET( CLKMGR_BYPASS_SDRPLLSRC_SELECT_EOSC1) | CLKMGR_BYPASS_PERPLL_SET(CLKMGR_BYPASS_DISABLE) | CLKMGR_BYPASS_SDRPLL_SET(CLKMGR_BYPASS_DISABLE) | CLKMGR_BYPASS_MAINPLL_SET(CLKMGR_BYPASS_DISABLE)); /* clear safe mode */ cm_write_ctrl(readl(&clock_manager_base->ctrl) | CLKMGR_CTRL_SAFEMODE_SET(CLKMGR_CTRL_SAFEMODE_MASK)); /* * 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); /* 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); }