|
@@ -115,17 +115,46 @@ static inline void wait_for_lock(u32 *const base)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+inline u32 check_for_lock(u32 *const base)
|
|
|
|
+{
|
|
|
|
+ struct dpll_regs *const dpll_regs = (struct dpll_regs *)base;
|
|
|
|
+ u32 lock = readl(&dpll_regs->cm_idlest_dpll) & ST_DPLL_CLK_MASK;
|
|
|
|
+
|
|
|
|
+ return lock;
|
|
|
|
+}
|
|
|
|
+
|
|
static void do_setup_dpll(u32 *const base, const struct dpll_params *params,
|
|
static void do_setup_dpll(u32 *const base, const struct dpll_params *params,
|
|
- u8 lock)
|
|
|
|
|
|
+ u8 lock, char *dpll)
|
|
{
|
|
{
|
|
- u32 temp;
|
|
|
|
|
|
+ u32 temp, M, N;
|
|
struct dpll_regs *const dpll_regs = (struct dpll_regs *)base;
|
|
struct dpll_regs *const dpll_regs = (struct dpll_regs *)base;
|
|
|
|
|
|
|
|
+ temp = readl(&dpll_regs->cm_clksel_dpll);
|
|
|
|
+
|
|
|
|
+ if (check_for_lock(base)) {
|
|
|
|
+ /*
|
|
|
|
+ * The Dpll has already been locked by rom code using CH.
|
|
|
|
+ * Check if M,N are matching with Ideal nominal opp values.
|
|
|
|
+ * If matches, skip the rest otherwise relock.
|
|
|
|
+ */
|
|
|
|
+ M = (temp & CM_CLKSEL_DPLL_M_MASK) >> CM_CLKSEL_DPLL_M_SHIFT;
|
|
|
|
+ N = (temp & CM_CLKSEL_DPLL_N_MASK) >> CM_CLKSEL_DPLL_N_SHIFT;
|
|
|
|
+ if ((M != (params->m)) || (N != (params->n))) {
|
|
|
|
+ debug("\n %s Dpll locked, but not for ideal M = %d,"
|
|
|
|
+ "N = %d values, current values are M = %d,"
|
|
|
|
+ "N= %d" , dpll, params->m, params->n,
|
|
|
|
+ M, N);
|
|
|
|
+ } else {
|
|
|
|
+ /* Dpll locked with ideal values for nominal opps. */
|
|
|
|
+ debug("\n %s Dpll already locked with ideal"
|
|
|
|
+ "nominal opp values", dpll);
|
|
|
|
+ goto setup_post_dividers;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
bypass_dpll(base);
|
|
bypass_dpll(base);
|
|
|
|
|
|
/* Set M & N */
|
|
/* Set M & N */
|
|
- temp = readl(&dpll_regs->cm_clksel_dpll);
|
|
|
|
-
|
|
|
|
temp &= ~CM_CLKSEL_DPLL_M_MASK;
|
|
temp &= ~CM_CLKSEL_DPLL_M_MASK;
|
|
temp |= (params->m << CM_CLKSEL_DPLL_M_SHIFT) & CM_CLKSEL_DPLL_M_MASK;
|
|
temp |= (params->m << CM_CLKSEL_DPLL_M_SHIFT) & CM_CLKSEL_DPLL_M_MASK;
|
|
|
|
|
|
@@ -138,6 +167,7 @@ static void do_setup_dpll(u32 *const base, const struct dpll_params *params,
|
|
if (lock)
|
|
if (lock)
|
|
do_lock_dpll(base);
|
|
do_lock_dpll(base);
|
|
|
|
|
|
|
|
+setup_post_dividers:
|
|
setup_post_dividers(base, params);
|
|
setup_post_dividers(base, params);
|
|
|
|
|
|
/* Wait till the DPLL locks */
|
|
/* Wait till the DPLL locks */
|
|
@@ -216,7 +246,8 @@ void configure_mpu_dpll(void)
|
|
}
|
|
}
|
|
|
|
|
|
params = get_mpu_dpll_params();
|
|
params = get_mpu_dpll_params();
|
|
- do_setup_dpll(&prcm->cm_clkmode_dpll_mpu, params, DPLL_LOCK);
|
|
|
|
|
|
+
|
|
|
|
+ do_setup_dpll(&prcm->cm_clkmode_dpll_mpu, params, DPLL_LOCK, "mpu");
|
|
debug("MPU DPLL locked\n");
|
|
debug("MPU DPLL locked\n");
|
|
}
|
|
}
|
|
|
|
|
|
@@ -235,7 +266,8 @@ static void setup_dplls(void)
|
|
* Core DPLL will be locked after setting up EMIF
|
|
* Core DPLL will be locked after setting up EMIF
|
|
* using the FREQ_UPDATE method(freq_update_core())
|
|
* using the FREQ_UPDATE method(freq_update_core())
|
|
*/
|
|
*/
|
|
- do_setup_dpll(&prcm->cm_clkmode_dpll_core, params, DPLL_NO_LOCK);
|
|
|
|
|
|
+ do_setup_dpll(&prcm->cm_clkmode_dpll_core, params, DPLL_NO_LOCK,
|
|
|
|
+ "core");
|
|
/* Set the ratios for CORE_CLK, L3_CLK, L4_CLK */
|
|
/* Set the ratios for CORE_CLK, L3_CLK, L4_CLK */
|
|
temp = (CLKSEL_CORE_X2_DIV_1 << CLKSEL_CORE_SHIFT) |
|
|
temp = (CLKSEL_CORE_X2_DIV_1 << CLKSEL_CORE_SHIFT) |
|
|
(CLKSEL_L3_CORE_DIV_2 << CLKSEL_L3_SHIFT) |
|
|
(CLKSEL_L3_CORE_DIV_2 << CLKSEL_L3_SHIFT) |
|
|
@@ -246,13 +278,14 @@ static void setup_dplls(void)
|
|
/* lock PER dpll */
|
|
/* lock PER dpll */
|
|
params = get_per_dpll_params();
|
|
params = get_per_dpll_params();
|
|
do_setup_dpll(&prcm->cm_clkmode_dpll_per,
|
|
do_setup_dpll(&prcm->cm_clkmode_dpll_per,
|
|
- params, DPLL_LOCK);
|
|
|
|
|
|
+ params, DPLL_LOCK, "per");
|
|
debug("PER DPLL locked\n");
|
|
debug("PER DPLL locked\n");
|
|
|
|
|
|
/* MPU dpll */
|
|
/* MPU dpll */
|
|
configure_mpu_dpll();
|
|
configure_mpu_dpll();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#ifdef CONFIG_SYS_CLOCKS_ENABLE_ALL
|
|
static void setup_non_essential_dplls(void)
|
|
static void setup_non_essential_dplls(void)
|
|
{
|
|
{
|
|
u32 sys_clk_khz, abe_ref_clk;
|
|
u32 sys_clk_khz, abe_ref_clk;
|
|
@@ -267,7 +300,7 @@ static void setup_non_essential_dplls(void)
|
|
CM_BYPCLK_DPLL_IVA_CLKSEL_MASK, DPLL_IVA_CLKSEL_CORE_X2_DIV_2);
|
|
CM_BYPCLK_DPLL_IVA_CLKSEL_MASK, DPLL_IVA_CLKSEL_CORE_X2_DIV_2);
|
|
|
|
|
|
params = get_iva_dpll_params();
|
|
params = get_iva_dpll_params();
|
|
- do_setup_dpll(&prcm->cm_clkmode_dpll_iva, params, DPLL_LOCK);
|
|
|
|
|
|
+ do_setup_dpll(&prcm->cm_clkmode_dpll_iva, params, DPLL_LOCK, "iva");
|
|
|
|
|
|
/*
|
|
/*
|
|
* USB:
|
|
* USB:
|
|
@@ -287,7 +320,7 @@ static void setup_non_essential_dplls(void)
|
|
sd_div << CM_CLKSEL_DPLL_DPLL_SD_DIV_SHIFT);
|
|
sd_div << CM_CLKSEL_DPLL_DPLL_SD_DIV_SHIFT);
|
|
|
|
|
|
/* Now setup the dpll with the regular function */
|
|
/* Now setup the dpll with the regular function */
|
|
- do_setup_dpll(&prcm->cm_clkmode_dpll_usb, params, DPLL_LOCK);
|
|
|
|
|
|
+ do_setup_dpll(&prcm->cm_clkmode_dpll_usb, params, DPLL_LOCK, "usb");
|
|
|
|
|
|
/* Configure ABE dpll */
|
|
/* Configure ABE dpll */
|
|
params = get_abe_dpll_params();
|
|
params = get_abe_dpll_params();
|
|
@@ -315,8 +348,9 @@ static void setup_non_essential_dplls(void)
|
|
CM_ABE_PLL_REF_CLKSEL_CLKSEL_MASK,
|
|
CM_ABE_PLL_REF_CLKSEL_CLKSEL_MASK,
|
|
abe_ref_clk << CM_ABE_PLL_REF_CLKSEL_CLKSEL_SHIFT);
|
|
abe_ref_clk << CM_ABE_PLL_REF_CLKSEL_CLKSEL_SHIFT);
|
|
/* Lock the dpll */
|
|
/* Lock the dpll */
|
|
- do_setup_dpll(&prcm->cm_clkmode_dpll_abe, params, DPLL_LOCK);
|
|
|
|
|
|
+ do_setup_dpll(&prcm->cm_clkmode_dpll_abe, params, DPLL_LOCK, "abe");
|
|
}
|
|
}
|
|
|
|
+#endif
|
|
|
|
|
|
void do_scale_tps62361(u32 reg, u32 volt_mv)
|
|
void do_scale_tps62361(u32 reg, u32 volt_mv)
|
|
{
|
|
{
|
|
@@ -561,10 +595,15 @@ void prcm_init(void)
|
|
enable_basic_clocks();
|
|
enable_basic_clocks();
|
|
scale_vcores();
|
|
scale_vcores();
|
|
setup_dplls();
|
|
setup_dplls();
|
|
|
|
+#ifdef CONFIG_SYS_CLOCKS_ENABLE_ALL
|
|
setup_non_essential_dplls();
|
|
setup_non_essential_dplls();
|
|
enable_non_essential_clocks();
|
|
enable_non_essential_clocks();
|
|
|
|
+#endif
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (OMAP_INIT_CONTEXT_SPL != omap_hw_init_context())
|
|
|
|
+ enable_basic_uboot_clocks();
|
|
}
|
|
}
|