From: Paul Walmsley <paul@xxxxxxxxx> According to the 34xx TRM Rev. K section 11.2.4.4.11.1 "Purpose of the DLL/CDL Module," the SDRC delay-locked-loop can be locked at any SDRC clock frequency from 83MHz to 166MHz. CDP code unconditionally unlocked the DLL whenever shifting to a lower SDRC speed, but this seems unnecessary and error-prone, as the DLL is no longer able to compensate for process, voltage, and temperature variations. Instead, only unlock the DLL when the SDRC clock rate would be less than 83MHz. In situations where the DLL is unlocked, we should probably be changing the FIXEDDELAY field, but currently we have no information on how to calculate it. Signed-off-by: Paul Walmsley <paul@xxxxxxxxx> --- arch/arm/mach-omap2/clock34xx.c | 10 +++++++++- arch/arm/mach-omap2/sram34xx.S | 13 +++++++------ arch/arm/plat-omap/include/mach/sram.h | 6 ++++-- arch/arm/plat-omap/sram.c | 7 ++++--- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index 55981dd..2e9ed66 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c @@ -74,6 +74,8 @@ static unsigned long compute_lpj(unsigned long ref, u_int div, u_int mult) } #endif +#define MIN_SDRC_DLL_LOCK_FREQ 83000000 + /** * omap3_dpll_recalc - recalculate DPLL rate * @clk: DPLL struct clk @@ -485,6 +487,7 @@ static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate) static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate) { u32 new_div = 0; + u32 unlock_dll = 0; unsigned long validrate, sdrcrate; struct omap_sdrc_params *sp; @@ -511,6 +514,11 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate) if (!sp) return -EINVAL; + if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) { + pr_debug("clock: will unlock SDRC DLL\n"); + unlock_dll = 1; + } + pr_info("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate, validrate); pr_info("clock: SDRC timing params used: %08x %08x %08x\n", @@ -521,7 +529,7 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate) /* REVISIT: Add SDRC_MR changing to this code also */ omap3_configure_core_dpll(sp->rfr_ctrl, sp->actim_ctrla, - sp->actim_ctrlb, new_div); + sp->actim_ctrlb, new_div, unlock_dll); return 0; } diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S index 35131e5..c080c82 100644 --- a/arch/arm/mach-omap2/sram34xx.S +++ b/arch/arm/mach-omap2/sram34xx.S @@ -40,22 +40,23 @@ /* * Change frequency of core dpll * r0 = sdrc_rfr_ctrl r1 = sdrc_actim_ctrla r2 = sdrc_actim_ctrlb r3 = M2 + * r4 = Unlock SDRC DLL? (1 = yes, 0 = no) -- only unlock DLL for + * SDRC rates < 83MHz */ ENTRY(omap3_sram_configure_core_dpll) stmfd sp!, {r1-r12, lr} @ store regs to stack + ldr r4, [sp, #52] @ pull extra args off the stack dsb @ flush buffered writes to interconnect cmp r3, #0x2 blne configure_sdrc - cmp r3, #0x2 + cmp r4, #0x1 + bleq unlock_dll blne lock_dll - cmp r3, #0x1 - blne unlock_dll bl sdram_in_selfrefresh @ put the SDRAM in self refresh bl configure_core_dpll bl enable_sdrc - cmp r3, #0x1 - blne wait_dll_unlock - cmp r3, #0x2 + cmp r4, #0x1 + bleq wait_dll_unlock blne wait_dll_lock cmp r3, #0x1 blne configure_sdrc diff --git a/arch/arm/plat-omap/include/mach/sram.h b/arch/arm/plat-omap/include/mach/sram.h index 0c0b45f..3f0711f 100644 --- a/arch/arm/plat-omap/include/mach/sram.h +++ b/arch/arm/plat-omap/include/mach/sram.h @@ -23,7 +23,8 @@ extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass); extern u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla, - u32 sdrc_actim_ctrlb, u32 m2); + u32 sdrc_actim_ctrlb, u32 m2, + u32 unlock_dll); extern void omap3_sram_restore_context(void); /* Do not use these */ @@ -61,7 +62,8 @@ extern unsigned long omap243x_sram_reprogram_sdrc_sz; extern u32 omap3_sram_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla, - u32 sdrc_actim_ctrlb, u32 m2); + u32 sdrc_actim_ctrlb, u32 m2, + u32 unlock_dll); extern unsigned long omap3_sram_configure_core_dpll_sz; #ifdef CONFIG_PM diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 5c0d463..6ecda40 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -371,16 +371,17 @@ static inline int omap243x_sram_init(void) static u32 (*_omap3_sram_configure_core_dpll)(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla, u32 sdrc_actim_ctrlb, - u32 m2); + u32 m2, u32 unlock_dll); u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla, - u32 sdrc_actim_ctrlb, u32 m2) + u32 sdrc_actim_ctrlb, u32 m2, u32 unlock_dll) { if (!_omap3_sram_configure_core_dpll) omap_sram_error(); return _omap3_sram_configure_core_dpll(sdrc_rfr_ctrl, sdrc_actim_ctrla, - sdrc_actim_ctrlb, m2); + sdrc_actim_ctrlb, m2, + unlock_dll); } #ifdef CONFIG_PM -- 1.5.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html