diff options
Diffstat (limited to 'recipes/u-boot/u-boot-git/beagleboard/0019-OMAP3-clocks-update-clock-setup-for-36XX-37XX.patch')
-rw-r--r-- | recipes/u-boot/u-boot-git/beagleboard/0019-OMAP3-clocks-update-clock-setup-for-36XX-37XX.patch | 826 |
1 files changed, 826 insertions, 0 deletions
diff --git a/recipes/u-boot/u-boot-git/beagleboard/0019-OMAP3-clocks-update-clock-setup-for-36XX-37XX.patch b/recipes/u-boot/u-boot-git/beagleboard/0019-OMAP3-clocks-update-clock-setup-for-36XX-37XX.patch new file mode 100644 index 0000000000..03da8ce662 --- /dev/null +++ b/recipes/u-boot/u-boot-git/beagleboard/0019-OMAP3-clocks-update-clock-setup-for-36XX-37XX.patch @@ -0,0 +1,826 @@ +From 0bf419a0faa8c9dc73d7a84f93d7fcb89be3ea21 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman <steve@sakoman.com> +Date: Tue, 23 Mar 2010 09:20:56 -0700 +Subject: [PATCH 19/37] OMAP3: clocks: update clock setup for 36XX/37XX + +--- + cpu/arm_cortexa8/omap3/clock.c | 559 +++++++++++++++++++++-------- + cpu/arm_cortexa8/omap3/lowlevel_init.S | 69 ++++ + include/asm-arm/arch-omap3/clocks.h | 17 + + include/asm-arm/arch-omap3/clocks_omap3.h | 27 ++ + 4 files changed, 525 insertions(+), 147 deletions(-) + +diff --git a/cpu/arm_cortexa8/omap3/clock.c b/cpu/arm_cortexa8/omap3/clock.c +index 6330c9e..538a183 100644 +--- a/cpu/arm_cortexa8/omap3/clock.c ++++ b/cpu/arm_cortexa8/omap3/clock.c +@@ -47,17 +47,12 @@ u32 get_osc_clk_speed(void) + struct s32ktimer *s32k_base = (struct s32ktimer *)SYNC_32KTIMER_BASE; + + val = readl(&prm_base->clksrc_ctrl); +- + 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 */ + val = readl(&prcm_base->clksel_wkup) | CLKSEL_GPT1; + +@@ -67,7 +62,6 @@ u32 get_osc_clk_speed(void) + /* Enable I and F Clocks for GPT1 */ + val = readl(&prcm_base->iclken_wkup) | EN_GPT1 | EN_32KSYNC; + writel(val, &prcm_base->iclken_wkup); +- + val = readl(&prcm_base->fclken_wkup) | EN_GPT1; + writel(val, &prcm_base->fclken_wkup); + +@@ -87,13 +81,10 @@ u32 get_osc_clk_speed(void) + + /* wait for 40 cycles */ + 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,65 +126,25 @@ void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel) + } + } + ++/* ++ * OMAP3530 specific functions ++ */ ++ + /****************************************************************************** +- * prcm_init() - inits clocks for PRCM as defined in clocks.h +- * called from SRAM, or Flash (using temp SRAM stack). ++ * Initialize CORE DPLL for OMAP34x/35x + *****************************************************************************/ +-void prcm_init(void) ++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; +- 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 +- * value corresponding to the input clock. +- */ +- osc_clk = get_osc_clk_speed(); +- get_sys_clkin_sel(osc_clk, &sys_clkin_sel); ++ /* Moving to the right sysclk and ES rev base */ ++ ptr = ptr + (3 * clk_index) + sil_index; + +- /* 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; +- } +- +- /* +- * 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_rev()) +- 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 +@@ -208,34 +159,38 @@ void prcm_init(void) + * work. write another value and then default value. + */ + +- /* m3x2 */ +- sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2 + 1); +- /* m3x2 */ ++ /* CM_CLKSEL1_EMU[DIV_DPLL3] */ ++ sr32(&prcm_base->clksel1_emu, 16, 5, (CORE_M3X2 + 1)) ; + 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 */ ++ ++ /* 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 */ ++ ++ /* SSI */ + sr32(&prcm_base->clksel_core, 8, 4, CORE_SSI_DIV); +- /* fsusb */ ++ /* FSUSB */ + sr32(&prcm_base->clksel_core, 4, 2, CORE_FUSB_DIV); +- /* l4 */ ++ /* L4 */ + sr32(&prcm_base->clksel_core, 2, 2, CORE_L4_DIV); +- /* l3 */ ++ /* L3 */ + sr32(&prcm_base->clksel_core, 0, 2, CORE_L3_DIV); +- /* gfx */ +- sr32(&prcm_base->clksel_gfx, 0, 3, GFX_DIV); +- /* reset mgr */ ++ /* 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); ++ /* 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); +@@ -244,102 +199,411 @@ void prcm_init(void) + * 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); +- sr32(&p0, 4, 4, dpll_param_p->fsel); /* FREQSEL */ ++ /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */ ++ sr32(&p0, 4, 4, ptr->fsel); + + 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 */ ++ /* 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); +- 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 */ ++ /* 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); + } ++} + +- /* 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(); ++/****************************************************************************** ++ * Initialize PER DPLL for OMAP34x/35x ++ *****************************************************************************/ ++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 */ +- dpll_param_p = dpll_param_p + clk_index; ++ 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 + */ +- 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 */ ++ /* 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 */ + +- 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 */ ++ /* 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); ++} + +- /* Getting the base address to MPU DPLL param table */ +- dpll_param_p = (dpll_param *) get_mpu_dpll_param(); ++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 it to the right sysclk and ES rev base */ +- dpll_param_p = dpll_param_p + 3 * clk_index + sil_index; ++ /* Moving to the right sysclk and ES rev base */ ++ ptr = ptr + (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 */ +- 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) */ ++ /* 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); +- /* 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 */ ++ ++ /* 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 ++ */ ++ ++/****************************************************************************** ++ * Initialize PER DPLL for OMAP36x/37x ++ *****************************************************************************/ ++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) ++{ ++ 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); ++ 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); ++ 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); +@@ -414,3 +678,4 @@ void per_clocks_enable(void) + + sdelay(1000); + } ++ +diff --git a/cpu/arm_cortexa8/omap3/lowlevel_init.S b/cpu/arm_cortexa8/omap3/lowlevel_init.S +index 73063ec..2045e4e 100644 +--- a/cpu/arm_cortexa8/omap3/lowlevel_init.S ++++ b/cpu/arm_cortexa8/omap3/lowlevel_init.S +@@ -359,3 +359,72 @@ per_dpll_param: + get_per_dpll_param: + adr r0, per_dpll_param + mov pc, lr ++ ++/* ++ * Tables for 36x/37x 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 40, 0, 0, 1 ++/* 19.2MHz */ ++.word 325, 11, 0, 1 ++/* 26MHz */ ++.word 20, 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, 1728, 12, 9, 32, 18, 8, 6, 2 ++.word 19200, 360, 7, 9, 16, 5, 4, 3, 1 ++.word 26000, 1728, 12, 9, 32, 18, 8, 6, 2 ++.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 ++ +diff --git a/include/asm-arm/arch-omap3/clocks.h b/include/asm-arm/arch-omap3/clocks.h +index 71a0cb6..a5f2d08 100644 +--- a/include/asm-arm/arch-omap3/clocks.h ++++ b/include/asm-arm/arch-omap3/clocks.h +@@ -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 +diff --git a/include/asm-arm/arch-omap3/clocks_omap3.h b/include/asm-arm/arch-omap3/clocks_omap3.h +index 661407b..30ef690 100644 +--- a/include/asm-arm/arch-omap3/clocks_omap3.h ++++ b/include/asm-arm/arch-omap3/clocks_omap3.h +@@ -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_ */ +-- +1.6.6.1 + |