/****************************************************************************** * 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); }
/****************************************************************************** * 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); }