mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-29 16:10:58 +00:00
ARMV7: OMAP3: Add clock setup for OMAP36XX/37XX
This patch configures clocks properly when a 36XX/37XX processor is detected. Signed-off-by: Steve Sakoman <steve@sakoman.com> Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com>
This commit is contained in:
parent
b2b9169f0b
commit
7c281c985c
4 changed files with 541 additions and 173 deletions
|
@ -50,12 +50,7 @@ u32 get_osc_clk_speed(void)
|
|||
|
||||
if (val & SYSCLKDIV_2)
|
||||
cdiv = 2;
|
||||
else if (val & SYSCLKDIV_1)
|
||||
cdiv = 1;
|
||||
else
|
||||
/*
|
||||
* Should never reach here! (Assume divider as 1)
|
||||
*/
|
||||
cdiv = 1;
|
||||
|
||||
/* enable timer2 */
|
||||
|
@ -89,11 +84,7 @@ u32 get_osc_clk_speed(void)
|
|||
while (readl(&s32k_base->s32k_cr) < (start + 20)) ;
|
||||
cend = readl(&gpt1_base->tcrr); /* get end sys_clk count */
|
||||
cdiff = cend - cstart; /* get elapsed ticks */
|
||||
|
||||
if (cdiv == 2)
|
||||
{
|
||||
cdiff *= 2;
|
||||
}
|
||||
cdiff *= cdiv;
|
||||
|
||||
/* based on number of ticks assign speed */
|
||||
if (cdiff > 19000)
|
||||
|
@ -135,24 +126,410 @@ void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* OMAP34XX/35XX specific functions
|
||||
*/
|
||||
|
||||
static void dpll3_init_34xx(u32 sil_index, u32 clk_index)
|
||||
{
|
||||
struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
|
||||
dpll_param *ptr = (dpll_param *) get_core_dpll_param();
|
||||
void (*f_lock_pll) (u32, u32, u32, u32);
|
||||
int xip_safe, p0, p1, p2, p3;
|
||||
|
||||
xip_safe = is_running_in_sram();
|
||||
|
||||
/* Moving to the right sysclk and ES rev base */
|
||||
ptr = ptr + (3 * clk_index) + sil_index;
|
||||
|
||||
if (xip_safe) {
|
||||
/*
|
||||
* CORE DPLL
|
||||
* sr32(CM_CLKSEL2_EMU) set override to work when asleep
|
||||
*/
|
||||
sr32(&prcm_base->clken_pll, 0, 3, PLL_FAST_RELOCK_BYPASS);
|
||||
wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen,
|
||||
LDELAY);
|
||||
|
||||
/*
|
||||
* For OMAP3 ES1.0 Errata 1.50, default value directly doesn't
|
||||
* work. write another value and then default value.
|
||||
*/
|
||||
|
||||
/* CM_CLKSEL1_EMU[DIV_DPLL3] */
|
||||
sr32(&prcm_base->clksel1_emu, 16, 5, (CORE_M3X2 + 1)) ;
|
||||
sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2);
|
||||
|
||||
/* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
|
||||
sr32(&prcm_base->clksel1_pll, 27, 5, ptr->m2);
|
||||
|
||||
/* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
|
||||
sr32(&prcm_base->clksel1_pll, 16, 11, ptr->m);
|
||||
|
||||
/* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
|
||||
sr32(&prcm_base->clksel1_pll, 8, 7, ptr->n);
|
||||
|
||||
/* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
|
||||
sr32(&prcm_base->clksel1_pll, 6, 1, 0);
|
||||
|
||||
/* SSI */
|
||||
sr32(&prcm_base->clksel_core, 8, 4, CORE_SSI_DIV);
|
||||
/* FSUSB */
|
||||
sr32(&prcm_base->clksel_core, 4, 2, CORE_FUSB_DIV);
|
||||
/* L4 */
|
||||
sr32(&prcm_base->clksel_core, 2, 2, CORE_L4_DIV);
|
||||
/* L3 */
|
||||
sr32(&prcm_base->clksel_core, 0, 2, CORE_L3_DIV);
|
||||
/* GFX */
|
||||
sr32(&prcm_base->clksel_gfx, 0, 3, GFX_DIV);
|
||||
/* RESET MGR */
|
||||
sr32(&prcm_base->clksel_wkup, 1, 2, WKUP_RSM);
|
||||
/* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
|
||||
sr32(&prcm_base->clken_pll, 4, 4, ptr->fsel);
|
||||
/* LOCK MODE */
|
||||
sr32(&prcm_base->clken_pll, 0, 3, PLL_LOCK);
|
||||
|
||||
wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen,
|
||||
LDELAY);
|
||||
} else if (is_running_in_flash()) {
|
||||
/*
|
||||
* if running from flash, jump to small relocated code
|
||||
* area in SRAM.
|
||||
*/
|
||||
f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start +
|
||||
SRAM_VECT_CODE);
|
||||
|
||||
p0 = readl(&prcm_base->clken_pll);
|
||||
sr32(&p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
|
||||
/* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
|
||||
sr32(&p0, 4, 4, ptr->fsel);
|
||||
|
||||
p1 = readl(&prcm_base->clksel1_pll);
|
||||
/* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
|
||||
sr32(&p1, 27, 5, ptr->m2);
|
||||
/* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
|
||||
sr32(&p1, 16, 11, ptr->m);
|
||||
/* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
|
||||
sr32(&p1, 8, 7, ptr->n);
|
||||
/* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
|
||||
sr32(&p1, 6, 1, 0);
|
||||
|
||||
p2 = readl(&prcm_base->clksel_core);
|
||||
/* SSI */
|
||||
sr32(&p2, 8, 4, CORE_SSI_DIV);
|
||||
/* FSUSB */
|
||||
sr32(&p2, 4, 2, CORE_FUSB_DIV);
|
||||
/* L4 */
|
||||
sr32(&p2, 2, 2, CORE_L4_DIV);
|
||||
/* L3 */
|
||||
sr32(&p2, 0, 2, CORE_L3_DIV);
|
||||
|
||||
p3 = (u32)&prcm_base->idlest_ckgen;
|
||||
|
||||
(*f_lock_pll) (p0, p1, p2, p3);
|
||||
}
|
||||
}
|
||||
|
||||
static void dpll4_init_34xx(u32 sil_index, u32 clk_index)
|
||||
{
|
||||
struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
|
||||
dpll_param *ptr = (dpll_param *) get_per_dpll_param();
|
||||
|
||||
/* Moving it to the right sysclk base */
|
||||
ptr = ptr + clk_index;
|
||||
|
||||
/* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */
|
||||
sr32(&prcm_base->clken_pll, 16, 3, PLL_STOP);
|
||||
wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY);
|
||||
|
||||
/*
|
||||
* Errata 1.50 Workaround for OMAP3 ES1.0 only
|
||||
* If using default divisors, write default divisor + 1
|
||||
* and then the actual divisor value
|
||||
*/
|
||||
/* M6 */
|
||||
sr32(&prcm_base->clksel1_emu, 24, 5, (PER_M6X2 + 1));
|
||||
sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2);
|
||||
/* M5 */
|
||||
sr32(&prcm_base->clksel_cam, 0, 5, (PER_M5X2 + 1));
|
||||
sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2);
|
||||
/* M4 */
|
||||
sr32(&prcm_base->clksel_dss, 0, 5, (PER_M4X2 + 1));
|
||||
sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2);
|
||||
/* M3 */
|
||||
sr32(&prcm_base->clksel_dss, 8, 5, (PER_M3X2 + 1));
|
||||
sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2);
|
||||
/* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */
|
||||
sr32(&prcm_base->clksel3_pll, 0, 5, (ptr->m2 + 1));
|
||||
sr32(&prcm_base->clksel3_pll, 0, 5, ptr->m2);
|
||||
/* Workaround end */
|
||||
|
||||
/* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:18] */
|
||||
sr32(&prcm_base->clksel2_pll, 8, 11, ptr->m);
|
||||
|
||||
/* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */
|
||||
sr32(&prcm_base->clksel2_pll, 0, 7, ptr->n);
|
||||
|
||||
/* FREQSEL (PERIPH_DPLL_FREQSEL): CM_CLKEN_PLL[20:23] */
|
||||
sr32(&prcm_base->clken_pll, 20, 4, ptr->fsel);
|
||||
|
||||
/* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */
|
||||
sr32(&prcm_base->clken_pll, 16, 3, PLL_LOCK);
|
||||
wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY);
|
||||
}
|
||||
|
||||
static void mpu_init_34xx(u32 sil_index, u32 clk_index)
|
||||
{
|
||||
struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
|
||||
dpll_param *ptr = (dpll_param *) get_mpu_dpll_param();
|
||||
|
||||
/* Moving to the right sysclk and ES rev base */
|
||||
ptr = ptr + (3 * clk_index) + sil_index;
|
||||
|
||||
/* MPU DPLL (unlocked already) */
|
||||
|
||||
/* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */
|
||||
sr32(&prcm_base->clksel2_pll_mpu, 0, 5, ptr->m2);
|
||||
|
||||
/* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */
|
||||
sr32(&prcm_base->clksel1_pll_mpu, 8, 11, ptr->m);
|
||||
|
||||
/* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */
|
||||
sr32(&prcm_base->clksel1_pll_mpu, 0, 7, ptr->n);
|
||||
|
||||
/* FREQSEL (MPU_DPLL_FREQSEL) : CM_CLKEN_PLL_MPU[4:7] */
|
||||
sr32(&prcm_base->clken_pll_mpu, 4, 4, ptr->fsel);
|
||||
}
|
||||
|
||||
static void iva_init_34xx(u32 sil_index, u32 clk_index)
|
||||
{
|
||||
struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
|
||||
dpll_param *ptr = (dpll_param *) get_iva_dpll_param();
|
||||
|
||||
/* Moving to the right sysclk and ES rev base */
|
||||
ptr = ptr + (3 * clk_index) + sil_index;
|
||||
|
||||
/* IVA DPLL */
|
||||
/* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */
|
||||
sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_STOP);
|
||||
wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY);
|
||||
|
||||
/* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */
|
||||
sr32(&prcm_base->clksel2_pll_iva2, 0, 5, ptr->m2);
|
||||
|
||||
/* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */
|
||||
sr32(&prcm_base->clksel1_pll_iva2, 8, 11, ptr->m);
|
||||
|
||||
/* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */
|
||||
sr32(&prcm_base->clksel1_pll_iva2, 0, 7, ptr->n);
|
||||
|
||||
/* FREQSEL (IVA2_DPLL_FREQSEL) : CM_CLKEN_PLL_IVA2[4:7] */
|
||||
sr32(&prcm_base->clken_pll_iva2, 4, 4, ptr->fsel);
|
||||
|
||||
/* LOCK MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */
|
||||
sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_LOCK);
|
||||
|
||||
wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY);
|
||||
}
|
||||
|
||||
/*
|
||||
* OMAP3630 specific functions
|
||||
*/
|
||||
|
||||
static void dpll3_init_36xx(u32 sil_index, u32 clk_index)
|
||||
{
|
||||
struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
|
||||
dpll_param *ptr = (dpll_param *) get_36x_core_dpll_param();
|
||||
void (*f_lock_pll) (u32, u32, u32, u32);
|
||||
int xip_safe, p0, p1, p2, p3;
|
||||
|
||||
xip_safe = is_running_in_sram();
|
||||
|
||||
/* Moving it to the right sysclk base */
|
||||
ptr += clk_index;
|
||||
|
||||
if (xip_safe) {
|
||||
/* CORE DPLL */
|
||||
|
||||
/* Select relock bypass: CM_CLKEN_PLL[0:2] */
|
||||
sr32(&prcm_base->clken_pll, 0, 3, PLL_FAST_RELOCK_BYPASS);
|
||||
wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen,
|
||||
LDELAY);
|
||||
|
||||
/* CM_CLKSEL1_EMU[DIV_DPLL3] */
|
||||
sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2);
|
||||
|
||||
/* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
|
||||
sr32(&prcm_base->clksel1_pll, 27, 5, ptr->m2);
|
||||
|
||||
/* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
|
||||
sr32(&prcm_base->clksel1_pll, 16, 11, ptr->m);
|
||||
|
||||
/* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
|
||||
sr32(&prcm_base->clksel1_pll, 8, 7, ptr->n);
|
||||
|
||||
/* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
|
||||
sr32(&prcm_base->clksel1_pll, 6, 1, 0);
|
||||
|
||||
/* SSI */
|
||||
sr32(&prcm_base->clksel_core, 8, 4, CORE_SSI_DIV);
|
||||
/* FSUSB */
|
||||
sr32(&prcm_base->clksel_core, 4, 2, CORE_FUSB_DIV);
|
||||
/* L4 */
|
||||
sr32(&prcm_base->clksel_core, 2, 2, CORE_L4_DIV);
|
||||
/* L3 */
|
||||
sr32(&prcm_base->clksel_core, 0, 2, CORE_L3_DIV);
|
||||
/* GFX */
|
||||
sr32(&prcm_base->clksel_gfx, 0, 3, GFX_DIV);
|
||||
/* RESET MGR */
|
||||
sr32(&prcm_base->clksel_wkup, 1, 2, WKUP_RSM);
|
||||
/* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
|
||||
sr32(&prcm_base->clken_pll, 4, 4, ptr->fsel);
|
||||
/* LOCK MODE */
|
||||
sr32(&prcm_base->clken_pll, 0, 3, PLL_LOCK);
|
||||
|
||||
wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen,
|
||||
LDELAY);
|
||||
} else if (is_running_in_flash()) {
|
||||
/*
|
||||
* if running from flash, jump to small relocated code
|
||||
* area in SRAM.
|
||||
*/
|
||||
f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start +
|
||||
SRAM_VECT_CODE);
|
||||
|
||||
p0 = readl(&prcm_base->clken_pll);
|
||||
sr32(&p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
|
||||
/* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
|
||||
sr32(&p0, 4, 4, ptr->fsel);
|
||||
|
||||
p1 = readl(&prcm_base->clksel1_pll);
|
||||
/* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
|
||||
sr32(&p1, 27, 5, ptr->m2);
|
||||
/* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
|
||||
sr32(&p1, 16, 11, ptr->m);
|
||||
/* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
|
||||
sr32(&p1, 8, 7, ptr->n);
|
||||
/* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
|
||||
sr32(&p1, 6, 1, 0);
|
||||
|
||||
p2 = readl(&prcm_base->clksel_core);
|
||||
/* SSI */
|
||||
sr32(&p2, 8, 4, CORE_SSI_DIV);
|
||||
/* FSUSB */
|
||||
sr32(&p2, 4, 2, CORE_FUSB_DIV);
|
||||
/* L4 */
|
||||
sr32(&p2, 2, 2, CORE_L4_DIV);
|
||||
/* L3 */
|
||||
sr32(&p2, 0, 2, CORE_L3_DIV);
|
||||
|
||||
p3 = (u32)&prcm_base->idlest_ckgen;
|
||||
|
||||
(*f_lock_pll) (p0, p1, p2, p3);
|
||||
}
|
||||
}
|
||||
|
||||
static void dpll4_init_36xx(u32 sil_index, u32 clk_index)
|
||||
{
|
||||
struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
|
||||
struct dpll_per_36x_param *ptr;
|
||||
|
||||
ptr = (struct dpll_per_36x_param *)get_36x_per_dpll_param();
|
||||
|
||||
/* Moving it to the right sysclk base */
|
||||
ptr += clk_index;
|
||||
|
||||
/* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */
|
||||
sr32(&prcm_base->clken_pll, 16, 3, PLL_STOP);
|
||||
wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY);
|
||||
|
||||
/* M6 (DIV_DPLL4): CM_CLKSEL1_EMU[24:29] */
|
||||
sr32(&prcm_base->clksel1_emu, 24, 6, ptr->m6);
|
||||
|
||||
/* M5 (CLKSEL_CAM): CM_CLKSEL1_EMU[0:5] */
|
||||
sr32(&prcm_base->clksel_cam, 0, 6, ptr->m5);
|
||||
|
||||
/* M4 (CLKSEL_DSS1): CM_CLKSEL_DSS[0:5] */
|
||||
sr32(&prcm_base->clksel_dss, 0, 6, ptr->m4);
|
||||
|
||||
/* M3 (CLKSEL_DSS1): CM_CLKSEL_DSS[8:13] */
|
||||
sr32(&prcm_base->clksel_dss, 8, 6, ptr->m3);
|
||||
|
||||
/* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */
|
||||
sr32(&prcm_base->clksel3_pll, 0, 5, ptr->m2);
|
||||
|
||||
/* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:19] */
|
||||
sr32(&prcm_base->clksel2_pll, 8, 12, ptr->m);
|
||||
|
||||
/* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */
|
||||
sr32(&prcm_base->clksel2_pll, 0, 7, ptr->n);
|
||||
|
||||
/* M2DIV (CLKSEL_96M): CM_CLKSEL_CORE[12:13] */
|
||||
sr32(&prcm_base->clksel_core, 12, 2, ptr->m2div);
|
||||
|
||||
/* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */
|
||||
sr32(&prcm_base->clken_pll, 16, 3, PLL_LOCK);
|
||||
wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY);
|
||||
}
|
||||
|
||||
static void mpu_init_36xx(u32 sil_index, u32 clk_index)
|
||||
{
|
||||
struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
|
||||
dpll_param *ptr = (dpll_param *) get_36x_mpu_dpll_param();
|
||||
|
||||
/* Moving to the right sysclk */
|
||||
ptr += clk_index;
|
||||
|
||||
/* MPU DPLL (unlocked already */
|
||||
|
||||
/* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */
|
||||
sr32(&prcm_base->clksel2_pll_mpu, 0, 5, ptr->m2);
|
||||
|
||||
/* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */
|
||||
sr32(&prcm_base->clksel1_pll_mpu, 8, 11, ptr->m);
|
||||
|
||||
/* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */
|
||||
sr32(&prcm_base->clksel1_pll_mpu, 0, 7, ptr->n);
|
||||
}
|
||||
|
||||
static void iva_init_36xx(u32 sil_index, u32 clk_index)
|
||||
{
|
||||
struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
|
||||
dpll_param *ptr = (dpll_param *)get_36x_iva_dpll_param();
|
||||
|
||||
/* Moving to the right sysclk */
|
||||
ptr += clk_index;
|
||||
|
||||
/* IVA DPLL */
|
||||
/* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */
|
||||
sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_STOP);
|
||||
wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY);
|
||||
|
||||
/* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */
|
||||
sr32(&prcm_base->clksel2_pll_iva2, 0, 5, ptr->m2);
|
||||
|
||||
/* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */
|
||||
sr32(&prcm_base->clksel1_pll_iva2, 8, 11, ptr->m);
|
||||
|
||||
/* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */
|
||||
sr32(&prcm_base->clksel1_pll_iva2, 0, 7, ptr->n);
|
||||
|
||||
/* LOCK (MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */
|
||||
sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_LOCK);
|
||||
|
||||
wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* 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;
|
||||
u32 clk_index, sil_index = 0;
|
||||
struct prm *prm_base = (struct prm *)PRM_BASE;
|
||||
struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
|
||||
dpll_param *dpll_param_p;
|
||||
|
||||
f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start +
|
||||
SRAM_VECT_CODE);
|
||||
|
||||
xip_safe = is_running_in_sram();
|
||||
|
||||
/*
|
||||
* Gauge the input clock speed and find out the sys_clkin_sel
|
||||
|
@ -175,6 +552,22 @@ void prcm_init(void)
|
|||
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);
|
||||
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
|
||||
|
@ -182,164 +575,26 @@ void prcm_init(void)
|
|||
* and sil_index will get the values for that SysClk for the
|
||||
* appropriate silicon rev.
|
||||
*/
|
||||
if (get_cpu_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);
|
||||
|
||||
/* 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 + 3 * clk_index + sil_index;
|
||||
if (xip_safe) {
|
||||
/*
|
||||
* CORE DPLL
|
||||
* sr32(CM_CLKSEL2_EMU) set override to work when asleep
|
||||
*/
|
||||
sr32(&prcm_base->clken_pll, 0, 3, PLL_FAST_RELOCK_BYPASS);
|
||||
wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen,
|
||||
wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu,
|
||||
LDELAY);
|
||||
|
||||
/*
|
||||
* For OMAP3 ES1.0 Errata 1.50, default value directly doesn't
|
||||
* work. write another value and then default value.
|
||||
*/
|
||||
dpll3_init_34xx(sil_index, clk_index);
|
||||
dpll4_init_34xx(sil_index, clk_index);
|
||||
iva_init_34xx(sil_index, clk_index);
|
||||
mpu_init_34xx(sil_index, clk_index);
|
||||
|
||||
/* m3x2 */
|
||||
sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2 + 1);
|
||||
/* m3x2 */
|
||||
sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2);
|
||||
/* Set M2 */
|
||||
sr32(&prcm_base->clksel1_pll, 27, 2, dpll_param_p->m2);
|
||||
/* Set M */
|
||||
sr32(&prcm_base->clksel1_pll, 16, 11, dpll_param_p->m);
|
||||
/* Set N */
|
||||
sr32(&prcm_base->clksel1_pll, 8, 7, dpll_param_p->n);
|
||||
/* 96M Src */
|
||||
sr32(&prcm_base->clksel1_pll, 6, 1, 0);
|
||||
/* ssi */
|
||||
sr32(&prcm_base->clksel_core, 8, 4, CORE_SSI_DIV);
|
||||
/* fsusb */
|
||||
sr32(&prcm_base->clksel_core, 4, 2, CORE_FUSB_DIV);
|
||||
/* l4 */
|
||||
sr32(&prcm_base->clksel_core, 2, 2, CORE_L4_DIV);
|
||||
/* l3 */
|
||||
sr32(&prcm_base->clksel_core, 0, 2, CORE_L3_DIV);
|
||||
/* gfx */
|
||||
sr32(&prcm_base->clksel_gfx, 0, 3, GFX_DIV);
|
||||
/* reset mgr */
|
||||
sr32(&prcm_base->clksel_wkup, 1, 2, WKUP_RSM);
|
||||
/* FREQSEL */
|
||||
sr32(&prcm_base->clken_pll, 4, 4, dpll_param_p->fsel);
|
||||
/* lock mode */
|
||||
sr32(&prcm_base->clken_pll, 0, 3, PLL_LOCK);
|
||||
|
||||
wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen,
|
||||
LDELAY);
|
||||
} else if (is_running_in_flash()) {
|
||||
/*
|
||||
* if running from flash, jump to small relocated code
|
||||
* area in SRAM.
|
||||
*/
|
||||
p0 = readl(&prcm_base->clken_pll);
|
||||
sr32(&p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
|
||||
sr32(&p0, 4, 4, dpll_param_p->fsel); /* FREQSEL */
|
||||
|
||||
p1 = readl(&prcm_base->clksel1_pll);
|
||||
sr32(&p1, 27, 2, dpll_param_p->m2); /* Set M2 */
|
||||
sr32(&p1, 16, 11, dpll_param_p->m); /* Set M */
|
||||
sr32(&p1, 8, 7, dpll_param_p->n); /* Set N */
|
||||
sr32(&p1, 6, 1, 0); /* set source for 96M */
|
||||
|
||||
p2 = readl(&prcm_base->clksel_core);
|
||||
sr32(&p2, 8, 4, CORE_SSI_DIV); /* ssi */
|
||||
sr32(&p2, 4, 2, CORE_FUSB_DIV); /* fsusb */
|
||||
sr32(&p2, 2, 2, CORE_L4_DIV); /* l4 */
|
||||
sr32(&p2, 0, 2, CORE_L3_DIV); /* l3 */
|
||||
|
||||
p3 = (u32)&prcm_base->idlest_ckgen;
|
||||
|
||||
(*f_lock_pll) (p0, p1, p2, p3);
|
||||
}
|
||||
|
||||
/* PER DPLL */
|
||||
sr32(&prcm_base->clken_pll, 16, 3, PLL_STOP);
|
||||
wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY);
|
||||
|
||||
/* Getting the base address to PER DPLL param table */
|
||||
|
||||
/* Set N */
|
||||
dpll_param_p = (dpll_param *) get_per_dpll_param();
|
||||
|
||||
/* Moving it to the right sysclk base */
|
||||
dpll_param_p = dpll_param_p + clk_index;
|
||||
|
||||
/*
|
||||
* Errata 1.50 Workaround for OMAP3 ES1.0 only
|
||||
* If using default divisors, write default divisor + 1
|
||||
* and then the actual divisor value
|
||||
*/
|
||||
sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2 + 1); /* set M6 */
|
||||
sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2); /* set M6 */
|
||||
sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2 + 1); /* set M5 */
|
||||
sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2); /* set M5 */
|
||||
sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2 + 1); /* set M4 */
|
||||
sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2); /* set M4 */
|
||||
sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2 + 1); /* set M3 */
|
||||
sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2); /* set M3 */
|
||||
sr32(&prcm_base->clksel3_pll, 0, 5, dpll_param_p->m2 + 1); /* set M2 */
|
||||
sr32(&prcm_base->clksel3_pll, 0, 5, dpll_param_p->m2); /* set M2 */
|
||||
/* Workaround end */
|
||||
|
||||
sr32(&prcm_base->clksel2_pll, 8, 11, dpll_param_p->m); /* set m */
|
||||
sr32(&prcm_base->clksel2_pll, 0, 7, dpll_param_p->n); /* set n */
|
||||
sr32(&prcm_base->clken_pll, 20, 4, dpll_param_p->fsel); /* FREQSEL */
|
||||
sr32(&prcm_base->clken_pll, 16, 3, PLL_LOCK); /* lock mode */
|
||||
wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY);
|
||||
|
||||
/* Getting the base address to MPU DPLL param table */
|
||||
dpll_param_p = (dpll_param *) get_mpu_dpll_param();
|
||||
|
||||
/* Moving it to the right sysclk and ES rev base */
|
||||
dpll_param_p = dpll_param_p + 3 * clk_index + sil_index;
|
||||
|
||||
/* MPU DPLL (unlocked already) */
|
||||
|
||||
/* Set M2 */
|
||||
sr32(&prcm_base->clksel2_pll_mpu, 0, 5, dpll_param_p->m2);
|
||||
/* Set M */
|
||||
sr32(&prcm_base->clksel1_pll_mpu, 8, 11, dpll_param_p->m);
|
||||
/* Set N */
|
||||
sr32(&prcm_base->clksel1_pll_mpu, 0, 7, dpll_param_p->n);
|
||||
/* FREQSEL */
|
||||
sr32(&prcm_base->clken_pll_mpu, 4, 4, dpll_param_p->fsel);
|
||||
/* lock mode */
|
||||
/* 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);
|
||||
|
||||
/* Getting the base address to IVA DPLL param table */
|
||||
dpll_param_p = (dpll_param *) get_iva_dpll_param();
|
||||
|
||||
/* Moving it to the right sysclk and ES rev base */
|
||||
dpll_param_p = dpll_param_p + 3 * clk_index + sil_index;
|
||||
|
||||
/* IVA DPLL (set to 12*20=240MHz) */
|
||||
sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_STOP);
|
||||
wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY);
|
||||
/* set M2 */
|
||||
sr32(&prcm_base->clksel2_pll_iva2, 0, 5, dpll_param_p->m2);
|
||||
/* set M */
|
||||
sr32(&prcm_base->clksel1_pll_iva2, 8, 11, dpll_param_p->m);
|
||||
/* set N */
|
||||
sr32(&prcm_base->clksel1_pll_iva2, 0, 7, dpll_param_p->n);
|
||||
/* FREQSEL */
|
||||
sr32(&prcm_base->clken_pll_iva2, 4, 4, dpll_param_p->fsel);
|
||||
/* lock mode */
|
||||
sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_LOCK);
|
||||
wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY);
|
||||
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);
|
||||
|
|
|
@ -359,3 +359,72 @@ per_dpll_param:
|
|||
get_per_dpll_param:
|
||||
adr r0, per_dpll_param
|
||||
mov pc, lr
|
||||
|
||||
/*
|
||||
* Tables for 36XX/37XX devices
|
||||
*
|
||||
*/
|
||||
mpu_36x_dpll_param:
|
||||
/* 12MHz */
|
||||
.word 50, 0, 0, 1
|
||||
/* 13MHz */
|
||||
.word 600, 12, 0, 1
|
||||
/* 19.2MHz */
|
||||
.word 125, 3, 0, 1
|
||||
/* 26MHz */
|
||||
.word 300, 12, 0, 1
|
||||
/* 38.4MHz */
|
||||
.word 125, 7, 0, 1
|
||||
|
||||
iva_36x_dpll_param:
|
||||
/* 12MHz */
|
||||
.word 130, 2, 0, 1
|
||||
/* 13MHz */
|
||||
.word 20, 0, 0, 1
|
||||
/* 19.2MHz */
|
||||
.word 325, 11, 0, 1
|
||||
/* 26MHz */
|
||||
.word 10, 0, 0, 1
|
||||
/* 38.4MHz */
|
||||
.word 325, 23, 0, 1
|
||||
|
||||
core_36x_dpll_param:
|
||||
/* 12MHz */
|
||||
.word 100, 2, 0, 1
|
||||
/* 13MHz */
|
||||
.word 400, 12, 0, 1
|
||||
/* 19.2MHz */
|
||||
.word 375, 17, 0, 1
|
||||
/* 26MHz */
|
||||
.word 200, 12, 0, 1
|
||||
/* 38.4MHz */
|
||||
.word 375, 35, 0, 1
|
||||
|
||||
per_36x_dpll_param:
|
||||
/* SYSCLK M N M2 M3 M4 M5 M6 m2DIV */
|
||||
.word 12000, 360, 4, 9, 16, 5, 4, 3, 1
|
||||
.word 13000, 864, 12, 9, 16, 9, 4, 3, 1
|
||||
.word 19200, 360, 7, 9, 16, 5, 4, 3, 1
|
||||
.word 26000, 432, 12, 9, 16, 9, 4, 3, 1
|
||||
.word 38400, 360, 15, 9, 16, 5, 4, 3, 1
|
||||
|
||||
.globl get_36x_mpu_dpll_param
|
||||
get_36x_mpu_dpll_param:
|
||||
adr r0, mpu_36x_dpll_param
|
||||
mov pc, lr
|
||||
|
||||
.globl get_36x_iva_dpll_param
|
||||
get_36x_iva_dpll_param:
|
||||
adr r0, iva_36x_dpll_param
|
||||
mov pc, lr
|
||||
|
||||
.globl get_36x_core_dpll_param
|
||||
get_36x_core_dpll_param:
|
||||
adr r0, core_36x_dpll_param
|
||||
mov pc, lr
|
||||
|
||||
.globl get_36x_per_dpll_param
|
||||
get_36x_per_dpll_param:
|
||||
adr r0, per_36x_dpll_param
|
||||
mov pc, lr
|
||||
|
||||
|
|
|
@ -51,12 +51,29 @@ typedef struct {
|
|||
unsigned int m2;
|
||||
} dpll_param;
|
||||
|
||||
struct dpll_per_36x_param {
|
||||
unsigned int sys_clk;
|
||||
unsigned int m;
|
||||
unsigned int n;
|
||||
unsigned int m2;
|
||||
unsigned int m3;
|
||||
unsigned int m4;
|
||||
unsigned int m5;
|
||||
unsigned int m6;
|
||||
unsigned int m2div;
|
||||
};
|
||||
|
||||
/* Following functions are exported from lowlevel_init.S */
|
||||
extern dpll_param *get_mpu_dpll_param(void);
|
||||
extern dpll_param *get_iva_dpll_param(void);
|
||||
extern dpll_param *get_core_dpll_param(void);
|
||||
extern dpll_param *get_per_dpll_param(void);
|
||||
|
||||
extern dpll_param *get_36x_mpu_dpll_param(void);
|
||||
extern dpll_param *get_36x_iva_dpll_param(void);
|
||||
extern dpll_param *get_36x_core_dpll_param(void);
|
||||
extern dpll_param *get_36x_per_dpll_param(void);
|
||||
|
||||
extern void *_end_vect, *_start;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -282,4 +282,31 @@
|
|||
#define PER_FSEL_38P4 0x07
|
||||
#define PER_M2_38P4 0x09
|
||||
|
||||
/* 36XX PER DPLL */
|
||||
|
||||
#define PER_36XX_M_12 0x1B0
|
||||
#define PER_36XX_N_12 0x05
|
||||
#define PER_36XX_FSEL_12 0x07
|
||||
#define PER_36XX_M2_12 0x09
|
||||
|
||||
#define PER_36XX_M_13 0x360
|
||||
#define PER_36XX_N_13 0x0C
|
||||
#define PER_36XX_FSEL_13 0x03
|
||||
#define PER_36XX_M2_13 0x09
|
||||
|
||||
#define PER_36XX_M_19P2 0x1C2
|
||||
#define PER_36XX_N_19P2 0x09
|
||||
#define PER_36XX_FSEL_19P2 0x07
|
||||
#define PER_36XX_M2_19P2 0x09
|
||||
|
||||
#define PER_36XX_M_26 0x1B0
|
||||
#define PER_36XX_N_26 0x0C
|
||||
#define PER_36XX_FSEL_26 0x07
|
||||
#define PER_36XX_M2_26 0x09
|
||||
|
||||
#define PER_36XX_M_38P4 0x1C2
|
||||
#define PER_36XX_N_38P4 0x13
|
||||
#define PER_36XX_FSEL_38P4 0x07
|
||||
#define PER_36XX_M2_38P4 0x09
|
||||
|
||||
#endif /* endif _CLOCKS_OMAP3_H_ */
|
||||
|
|
Loading…
Reference in a new issue