/****************************************************************************** * prcm_init() - inits clocks for PRCM as defined in clocks.h * called from SRAM, or Flash (using temp SRAM stack). *****************************************************************************/ void prcm_init(void) { u32 osc_clk = 0, sys_clkin_sel; u32 clk_index, sil_index = 0; struct prm *prm_base = (struct prm *)PRM_BASE; struct prcm *prcm_base = (struct prcm *)PRCM_BASE; /* * Gauge the input clock speed and find out the sys_clkin_sel * value corresponding to the input clock. */ osc_clk = get_osc_clk_speed(); get_sys_clkin_sel(osc_clk, &sys_clkin_sel); /* set input crystal speed */ sr32(&prm_base->clksel, 0, 3, sys_clkin_sel); /* If the input clock is greater than 19.2M always divide/2 */ if (sys_clkin_sel > 2) { /* input clock divider */ sr32(&prm_base->clksrc_ctrl, 6, 2, 2); clk_index = sys_clkin_sel / 2; } else { /* input clock divider */ sr32(&prm_base->clksrc_ctrl, 6, 2, 1); clk_index = sys_clkin_sel; } if (get_cpu_family() == CPU_OMAP36XX) { /* Unlock MPU DPLL (slows things down, and needed later) */ sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOW_POWER_BYPASS); wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu, LDELAY); dpll3_init_36xx(0, clk_index); dpll4_init_36xx(0, clk_index); dpll5_init_34xx(0, clk_index); iva_init_36xx(0, clk_index); mpu_init_36xx(0, clk_index); /* Lock MPU DPLL to set frequency */ sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOCK); wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu, LDELAY); } else { /* * The DPLL tables are defined according to sysclk value and * silicon revision. The clk_index value will be used to get * the values for that input sysclk from the DPLL param table * and sil_index will get the values for that SysClk for the * appropriate silicon rev. */ if (((get_cpu_family() == CPU_OMAP34XX) && (get_cpu_rev() >= CPU_3XX_ES20)) || (get_cpu_family() == CPU_AM35XX)) sil_index = 1; /* Unlock MPU DPLL (slows things down, and needed later) */ sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOW_POWER_BYPASS); wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu, LDELAY); dpll3_init_34xx(sil_index, clk_index); dpll4_init_34xx(sil_index, clk_index); dpll5_init_34xx(sil_index, clk_index); if (get_cpu_family() != CPU_AM35XX) iva_init_34xx(sil_index, clk_index); mpu_init_34xx(sil_index, clk_index); /* Lock MPU DPLL to set frequency */ sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOCK); wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu, LDELAY); } /* Set up GPTimers to sys_clk source only */ sr32(&prcm_base->clksel_per, 0, 8, 0xff); sr32(&prcm_base->clksel_wkup, 0, 1, 1); sdelay(5000); }
void cpu_clock_info(void) { u32 osc_clk, clk_index; int sil_index; dpll_param *core, *mpu, *iva; dpll_per_param *per; osc_clk = get_osc_clk_speed(); get_sys_clkin_sel(osc_clk, &clk_index); sil_index = get_silindex(); printf("OSC CLK %d\n", osc_clk); printf("Clock index %d Silicon Index %d\n", clk_index, sil_index); core = _get_core_dpll(clk_index, sil_index); print_dpll_param(core, "core params"); per = _get_per_dpll(clk_index); print_dpll_per_param(per, "per params "); mpu = _get_mpu_dpll(clk_index, sil_index); print_dpll_param(mpu, "mpu params "); iva = _get_iva_dpll(clk_index, sil_index); print_dpll_param(iva, "iva params "); /* Now verify */ { /* System clk */ u32 sys_clk; u32 sys_clk_div; u32 sys_clk_calc; /* PER / DPLL 4 clk */ u32 per_m, per_n; u32 per_m2; u32 clk_96m_calc, per_clk_calc; u32 per_m3; u32 per_m4; u32 per_m5; u32 per_m6; #ifdef CONFIG_OMAP36XX u32 per_clk_div; u32 per_dco_sel; u32 per_sd_div; u32 per_m2_div; #else u32 per_fsel; #endif /* MPU clk */ u32 mpu_m, mpu_n, mpu_m2; #ifndef CONFIG_OMAP36XX u32 mpu_fsel; #endif /* IVA clk */ u32 iva_m, iva_n, iva_m2; #ifndef CONFIG_OMAP36XX u32 iva_fsel; #endif printf("Verifying from hardware registers..\n"); /* Sys clk */ sys_clk = readl(PRM_CLKSEL); sys_clk >>= 0; sys_clk &= ((1 << 3) - 1); sys_clk_calc = 0; sys_clk_div = readl(PRM_CLKSRC_CTRL); sys_clk_div >>= 6; sys_clk_div &= ((1 << 2) - 1); if (4 == sys_clk) sys_clk_calc = 38400000; else if (3 == sys_clk) sys_clk_calc = 26000000; else if (2 == sys_clk) sys_clk_calc = 19200000; else if (1 == sys_clk) sys_clk_calc = 13000000; else if (0 == sys_clk) sys_clk_calc = 12000000; if (sys_clk_div) sys_clk_calc /= sys_clk_div; else sys_clk_calc = 0; printf("sys_clk %d sys_clk_div %d\n", sys_clk, sys_clk_div); printf("calculated system clock %d\n", sys_clk_calc); per_clk_calc = sys_clk_calc; /* Per clk */ per_m = readl(CM_CLKSEL2_PLL); per_m >>= 8; per_m &= ((1 << PER_M_BITS) - 1); per_n = readl(CM_CLKSEL2_PLL); per_n >>= 0; per_n &= ((1 << 7) - 1); printf("per m %d n %d ", per_m, per_n); #ifndef CONFIG_OMAP36XX per_fsel = readl(CM_CLKEN_PLL); per_fsel >>= 20; per_fsel &= ((1 << 4) - 1); printf("fsel %d ", per_fsel); #endif per_m2 = readl(CM_CLKSEL3_PLL); per_m2 >>= 0; per_m2 &= ((1 << PER_M2_BITS) - 1); per_m3 = readl(CM_CLKSEL_DSS); per_m3 >>= 8; per_m3 &= ((1 << PER_M3_BITS) - 1); per_m4 = readl(CM_CLKSEL_DSS); per_m4 >>= 0; per_m4 &= ((1 << PER_M4_BITS) - 1); per_m5 = readl(CM_CLKSEL_CAM); per_m5 >>= 0; per_m5 &= ((1 << PER_M5_BITS) - 1); per_m6 = readl(CM_CLKSEL1_EMU); per_m6 >>= 24; per_m6 &= ((1 << PER_M6_BITS) - 1); #ifdef CONFIG_OMAP36XX per_clk_div = readl(PRM_CLKSRC_CTRL); per_clk_div >>= 8; per_clk_div &= 1; per_dco_sel = readl(CM_CLKSEL2_PLL); per_dco_sel >>= 21; per_dco_sel &= ((1 << 3) - 1); per_sd_div = readl(CM_CLKSEL2_PLL); per_sd_div >>= 24; per_sd_div &= ((1 << 7) - 1); /* Div by 6.5 */ if (per_clk_div) { per_clk_calc *= 2; per_clk_calc /= ((per_n + 1) * 13); } else { per_clk_calc /= (per_n + 1); } /* M2 div */ per_m2_div = readl(CM_CLKSEL_CORE); per_m2_div >>= 12; per_m2_div &= 3; per_m2 *= per_m2_div; printf("clkdiv %d dco_sel %d sd_div %d m2_div %d ", per_clk_div, per_dco_sel, per_sd_div, per_m2_div); #else per_clk_calc /= (per_n + 1); #endif printf("m2 %d m3 %d m4 %d m5 %d m6 %d", per_m2, per_m3, per_m4, per_m5, per_m6); per_clk_calc *= per_m; if (per_m2) clk_96m_calc = per_clk_calc / per_m2; else clk_96m_calc = 0; printf("\n"); if (!(per_clk_calc % 1000000)) printf("dpll4 base clk %d MHz\n", per_clk_calc / 1000000); else if (!(per_clk_calc % 1000)) printf("dpll4 base clk %d KHz\n", per_clk_calc / 1000); else printf("dpll4 base clk %d Hz\n", per_clk_calc); if (!(clk_96m_calc % 1000000)) printf("\t96M clk %d MHz\n", clk_96m_calc / 1000000); else if (!(clk_96m_calc % 1000)) printf("\t96M clk %d KHz\n", clk_96m_calc / 1000); else printf("\t96M clk %d Hz\n", clk_96m_calc); /* MPU */ mpu_m = readl(CM_CLKSEL1_PLL_MPU); mpu_m >>= 8; mpu_m &= ((1 << 11) - 1); mpu_n = readl(CM_CLKSEL1_PLL_MPU); mpu_n >>= 0; mpu_n &= ((1 << 5) - 1); printf("mpu m %d n %d ", mpu_m, mpu_n); #ifndef CONFIG_OMAP36XX mpu_fsel = readl(CM_CLKEN_PLL_MPU); mpu_fsel >>= 4; mpu_fsel &= ((1 << 4) - 1); printf("fsel %d ", mpu_fsel); #endif mpu_m2 = readl(CM_CLKSEL2_PLL_MPU); mpu_m2 >>= 0; mpu_m2 &= ((1 << 5) - 1); printf("m2 %d\n", mpu_m2); /* IVA */ iva_m = readl(CM_CLKSEL1_PLL_IVA2); iva_m >>= 8; iva_m &= ((1 << 11) - 1); iva_n = readl(CM_CLKSEL1_PLL_IVA2); iva_n >>= 0; iva_n &= ((1 << 7) - 1); printf("iva m %d n %d ", iva_m, iva_n); #ifndef CONFIG_OMAP36XX iva_fsel = readl(CM_CLKEN_PLL_IVA2); iva_fsel >>= 4; iva_fsel &= ((1 << 4) - 1); printf("fsel %d ", iva_fsel); #endif iva_m2 = readl(CM_CLKSEL2_PLL_IVA2); iva_m2 >>= 0; iva_m2 &= ((1 << 5) - 1); printf("m2 %d\n", iva_m2); } }
/****************************************************************************** * prcm_init() - inits clocks for PRCM as defined in clocks.h * called from SRAM, or Flash (using temp SRAM stack). *****************************************************************************/ void prcm_init(void) { u32 osc_clk = 0, sys_clkin_sel; u32 clk_index, sil_index = 0; struct prm *prm_base = (struct prm *)PRM_BASE; struct prcm *prcm_base = (struct prcm *)PRCM_BASE; /* * Gauge the input clock speed and find out the sys_clkin_sel * value corresponding to the input clock. */ osc_clk = get_osc_clk_speed(); get_sys_clkin_sel(osc_clk, &sys_clkin_sel); /* set input crystal speed */ clrsetbits_le32(&prm_base->clksel, 0x00000007, sys_clkin_sel); /* If the input clock is greater than 19.2M always divide/2 */ if (sys_clkin_sel > 2) { /* input clock divider */ clrsetbits_le32(&prm_base->clksrc_ctrl, 0x000000C0, 2 << 6); clk_index = sys_clkin_sel / 2; } else { /* input clock divider */ clrsetbits_le32(&prm_base->clksrc_ctrl, 0x000000C0, 1 << 6); clk_index = sys_clkin_sel; } if (get_cpu_family() == CPU_OMAP36XX) { /* * In warm reset conditions on OMAP36xx/AM/DM37xx * the rom code incorrectly sets the DPLL4 clock * input divider to /6.5. Section 3.5.3.3.3.2.1 of * the AM/DM37x TRM explains that the /6.5 divider * is used only when the input clock is 13MHz. * * If the part is in this cpu family *and* the input * clock *is not* 13 MHz, then reset the DPLL4 clock * input divider to /1 as it should never set to /6.5 * in this case. */ if (sys_clkin_sel != 1) { /* 13 MHz */ /* Bit 8: DPLL4_CLKINP_DIV */ clrbits_le32(&prm_base->clksrc_ctrl, 0x00000100); } /* Unlock MPU DPLL (slows things down, and needed later) */ clrsetbits_le32(&prcm_base->clken_pll_mpu, 0x00000007, PLL_LOW_POWER_BYPASS); wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu, LDELAY); dpll3_init_36xx(0, clk_index); dpll4_init_36xx(0, clk_index); dpll5_init_36xx(0, clk_index); iva_init_36xx(0, clk_index); mpu_init_36xx(0, clk_index); /* Lock MPU DPLL to set frequency */ clrsetbits_le32(&prcm_base->clken_pll_mpu, 0x00000007, PLL_LOCK); wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu, LDELAY); } else { /* * The DPLL tables are defined according to sysclk value and * silicon revision. The clk_index value will be used to get * the values for that input sysclk from the DPLL param table * and sil_index will get the values for that SysClk for the * appropriate silicon rev. */ if (((get_cpu_family() == CPU_OMAP34XX) && (get_cpu_rev() >= CPU_3XX_ES20)) || (get_cpu_family() == CPU_AM35XX)) sil_index = 1; /* Unlock MPU DPLL (slows things down, and needed later) */ clrsetbits_le32(&prcm_base->clken_pll_mpu, 0x00000007, PLL_LOW_POWER_BYPASS); wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu, LDELAY); dpll3_init_34xx(sil_index, clk_index); dpll4_init_34xx(sil_index, clk_index); dpll5_init_34xx(sil_index, clk_index); if (get_cpu_family() != CPU_AM35XX) iva_init_34xx(sil_index, clk_index); mpu_init_34xx(sil_index, clk_index); /* Lock MPU DPLL to set frequency */ clrsetbits_le32(&prcm_base->clken_pll_mpu, 0x00000007, PLL_LOCK); wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu, LDELAY); } /* Set up GPTimers to sys_clk source only */ setbits_le32(&prcm_base->clksel_per, 0x000000FF); setbits_le32(&prcm_base->clksel_wkup, 1); sdelay(5000); }
/****************************************************************************** * prcm_init() - inits clocks for PRCM as defined in clocks.h * -- called from SRAM, or Flash (using temp SRAM stack). *****************************************************************************/ void prcm_init(void) { void (*f_lock_pll) (u32, u32, u32, u32); int xip_safe, p0, p1, p2, p3; u32 osc_clk=0, sys_clkin_sel; extern void *_end_vect, *_start; u32 clk_index, sil_index=1; dpll_param *dpll_param_p; f_lock_pll = (void *)((u32) & _end_vect - (u32) & _start + SRAM_VECT_CODE); xip_safe = running_in_sram(); #ifdef CONFIG_3430VIRTIO xip_safe = 1; #endif /* Gauge the input clock speed and find out the sys_clkin_sel * value corresponding to the input clock. */ osc_clk = get_osc_clk_speed(); get_sys_clkin_sel(osc_clk, &sys_clkin_sel); sr32(PRM_CLKSEL, 0, 3, sys_clkin_sel); /* set input crystal speed */ sr32(PRM_CLKSRC_CTRL, 6, 2, 1);/* input clock divider */ clk_index = sys_clkin_sel; sr32(PRM_CLKSRC_CTRL, 0, 2, 0);/* Bypass mode: T2 inputs a square clock */ sil_index = get_silindex(); /* Unlock MPU DPLL (slows things down, and needed later) */ sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOW_POWER_BYPASS); wait_on_value(BIT0, 0, CM_IDLEST_PLL_MPU, LDELAY); /* Getting the base address of Core DPLL param table*/ dpll_param_p = (dpll_param *)get_core_dpll_param(); /* Moving it to the right sysclk and ES rev base */ dpll_param_p = dpll_param_p + MAX_SIL_INDEX*clk_index + sil_index; if(xip_safe){ /* CORE DPLL */ /* sr32(CM_CLKSEL2_EMU) set override to work when asleep */ sr32(CM_CLKEN_PLL, 0, 3, PLL_FAST_RELOCK_BYPASS); wait_on_value(BIT0, 0, CM_IDLEST_CKGEN, LDELAY); /* For 3430 ES1.0 Errata 1.50, default value directly doesnt work. write another value and then default value. */ sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2 + 1); /* m3x2 */ sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2); /* m3x2 */ sr32(CM_CLKSEL1_PLL, 27, 2, dpll_param_p->m2); /* Set M2 */ sr32(CM_CLKSEL1_PLL, 16, 11, dpll_param_p->m); /* Set M */ sr32(CM_CLKSEL1_PLL, 8, 7, dpll_param_p->n); /* Set N */ sr32(CM_CLKSEL1_PLL, 6, 1, 0); /* 96M Src */ sr32(CM_CLKSEL_CORE, 8, 4, CORE_SSI_DIV); /* ssi */ sr32(CM_CLKSEL_CORE, 4, 2, CORE_FUSB_DIV); /* fsusb ES1 only */ sr32(CM_CLKSEL_CORE, 2, 2, CORE_L4_DIV); /* l4 */ sr32(CM_CLKSEL_CORE, 0, 2, CORE_L3_DIV); /* l3 */ sr32(CM_CLKSEL_GFX, 0, 3, GFX_DIV); /* gfx */ sr32(CM_CLKSEL_WKUP, 1, 2, WKUP_RSM); /* reset mgr */ #ifndef CONFIG_OMAP36XX sr32(CM_CLKEN_PLL, 4, 4, dpll_param_p->fsel); /* FREQSEL */ #endif sr32(CM_CLKEN_PLL, 0, 3, PLL_LOCK); /* lock mode */ wait_on_value(BIT0, 1, CM_IDLEST_CKGEN, LDELAY); } else if(running_in_flash()){ /* if running from flash, jump to small relocated code area in SRAM.*/ p0 = __raw_readl(CM_CLKEN_PLL); sr32((u32)&p0, 0, 3, PLL_FAST_RELOCK_BYPASS); #ifndef CONFIG_OMAP36XX sr32((u32)&p0, 4, 4, dpll_param_p->fsel); /* FREQSEL */ #endif p1 = __raw_readl(CM_CLKSEL1_PLL); sr32((u32)&p1, 27, 2, dpll_param_p->m2); /* Set M2 */ sr32((u32)&p1, 16, 11, dpll_param_p->m); /* Set M */ sr32((u32)&p1, 8, 7, dpll_param_p->n); /* Set N */ sr32((u32)&p1, 6, 1, 0); /* set source for 96M */ p2 = __raw_readl(CM_CLKSEL_CORE); sr32((u32)&p2, 8, 4, CORE_SSI_DIV); /* ssi */ sr32((u32)&p2, 4, 2, CORE_FUSB_DIV); /* fsusb ES1 only*/ sr32((u32)&p2, 2, 2, CORE_L4_DIV); /* l4 */ sr32((u32)&p2, 0, 2, CORE_L3_DIV); /* l3 */ p3 = CM_IDLEST_CKGEN; (*f_lock_pll) (p0, p1, p2, p3); } #ifdef CONFIG_OMAP36XX per_dpll_init_36XX(clk_index); iva_dpll_init_36XX(clk_index, sil_index); mpu_dpll_init_36XX(clk_index, sil_index); #else per_dpll_init_34XX(clk_index); iva_dpll_init_34XX(clk_index, sil_index); mpu_dpll_init_34XX(clk_index, sil_index); #endif /* Set up GPTimers to sys_clk source only */ sr32(CM_CLKSEL_PER, 0, 8, 0xff); sr32(CM_CLKSEL_WKUP, 0, 1, 1); sdelay(5000); }