From 0a26344440b5f9940c99112fdc3804f073b1f5a7 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Fri, 25 Jul 2014 06:11:15 -0600 Subject: [PATCH 1/3] ARM: OMAP2+: clock: allow omap2_dpll_round_rate() to round to next-lowest rate Change the behavior of omap2_dpll_round_rate() to round to either the exact rate requested, or the next lowest rate that the clock is able to provide. This is not an ideal fix, but is intended to provide a relatively safe way for drivers to set PLL rates, until a better solution can be implemented. For the time being, omap3_noncore_dpll_set_rate() is still allowed to set its rate to something other than what the caller requested; but will warn when this occurs. Cc: Tomi Valkeinen Cc: Mike Turquette Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/clkt_dpll.c | 28 +++++++++++++++++++++------- arch/arm/mach-omap2/dpll3xxx.c | 13 +++++++++++-- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c index 332af927f4d3..85701142c5fc 100644 --- a/arch/arm/mach-omap2/clkt_dpll.c +++ b/arch/arm/mach-omap2/clkt_dpll.c @@ -293,10 +293,13 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, { struct clk_hw_omap *clk = to_clk_hw_omap(hw); int m, n, r, scaled_max_m; + int min_delta_m = INT_MAX, min_delta_n = INT_MAX; unsigned long scaled_rt_rp; unsigned long new_rate = 0; struct dpll_data *dd; unsigned long ref_rate; + long delta; + long prev_min_delta = LONG_MAX; const char *clk_name; if (!clk || !clk->dpll_data) @@ -342,23 +345,34 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, if (r == DPLL_MULT_UNDERFLOW) continue; + /* skip rates above our target rate */ + delta = target_rate - new_rate; + if (delta < 0) + continue; + + if (delta < prev_min_delta) { + prev_min_delta = delta; + min_delta_m = m; + min_delta_n = n; + } + pr_debug("clock: %s: m = %d: n = %d: new_rate = %lu\n", clk_name, m, n, new_rate); - if (target_rate == new_rate) { - dd->last_rounded_m = m; - dd->last_rounded_n = n; - dd->last_rounded_rate = target_rate; + if (delta == 0) break; - } } - if (target_rate != new_rate) { + if (prev_min_delta == LONG_MAX) { pr_debug("clock: %s: cannot round to rate %lu\n", clk_name, target_rate); return ~0; } - return target_rate; + dd->last_rounded_m = min_delta_m; + dd->last_rounded_n = min_delta_n; + dd->last_rounded_rate = target_rate - prev_min_delta; + + return dd->last_rounded_rate; } diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index 6d7ba37e2257..b6860bfb05b3 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c @@ -478,6 +478,7 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, { struct clk_hw_omap *clk = to_clk_hw_omap(hw); struct clk *new_parent = NULL; + unsigned long rrate; u16 freqsel = 0; struct dpll_data *dd; int ret; @@ -505,8 +506,16 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, __clk_prepare(dd->clk_ref); clk_enable(dd->clk_ref); - if (dd->last_rounded_rate != rate) - rate = __clk_round_rate(hw->clk, rate); + /* XXX this check is probably pointless in the CCF context */ + if (dd->last_rounded_rate != rate) { + rrate = __clk_round_rate(hw->clk, rate); + if (rrate != rate) { + pr_warn("%s: %s: final rate %lu does not match desired rate %lu\n", + __func__, __clk_get_name(hw->clk), + rrate, rate); + rate = rrate; + } + } if (dd->last_rounded_rate == 0) return -EINVAL; From 9b5f7428f8b16bd8980213f2b70baf1dd0b9e36c Mon Sep 17 00:00:00 2001 From: Jeremy Vial Date: Thu, 31 Jul 2014 15:10:33 +0200 Subject: [PATCH 2/3] ARM: OMAP3: Fix choice of omap3_restore_es function in OMAP34XX rev3.1.2 case. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the comment “restore_es3: applies to 34xx >= ES3.0" in "arch/arm/mach-omap2/sleep34xx.S”, omap3_restore_es3 should be used if the revision of an OMAP34xx is ES3.1.2. Signed-off-by: Jeremy Vial Cc: stable@vger.kernel.org Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/control.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c index f4796c002070..e84e3b4bfde1 100644 --- a/arch/arm/mach-omap2/control.c +++ b/arch/arm/mach-omap2/control.c @@ -309,7 +309,8 @@ void omap3_save_scratchpad_contents(void) scratchpad_contents.public_restore_ptr = virt_to_phys(omap3_restore_3630); else if (omap_rev() != OMAP3430_REV_ES3_0 && - omap_rev() != OMAP3430_REV_ES3_1) + omap_rev() != OMAP3430_REV_ES3_1 && + omap_rev() != OMAP3430_REV_ES3_1_2) scratchpad_contents.public_restore_ptr = virt_to_phys(omap3_restore); else From ae21e6180a03c147514c606b4e649690e0cbd40e Mon Sep 17 00:00:00 2001 From: Jeremy Vial Date: Thu, 31 Jul 2014 15:10:34 +0200 Subject: [PATCH 3/3] ARM: OMAP3: Fix coding style problems in arch/arm/mach-omap2/control.c Fix coding style problems in arch/arm/mach-omap2/control.c. Signed-off-by: Jeremy Vial Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/control.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c index e84e3b4bfde1..da041b4ab29c 100644 --- a/arch/arm/mach-omap2/control.c +++ b/arch/arm/mach-omap2/control.c @@ -280,6 +280,7 @@ void omap3_clear_scratchpad_contents(void) u32 max_offset = OMAP343X_SCRATCHPAD_ROM_OFFSET; void __iomem *v_addr; u32 offset = 0; + v_addr = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD_ROM); if (omap3xxx_prm_clear_global_cold_reset()) { for ( ; offset <= max_offset; offset += 0x4) @@ -464,7 +465,6 @@ void omap3_control_save_context(void) control_context.csi = omap_ctrl_readl(OMAP343X_CONTROL_CSI); control_context.padconf_sys_nirq = omap_ctrl_readl(OMAP343X_CONTROL_PADCONF_SYSNIRQ); - return; } void omap3_control_restore_context(void) @@ -522,7 +522,6 @@ void omap3_control_restore_context(void) omap_ctrl_writel(control_context.csi, OMAP343X_CONTROL_CSI); omap_ctrl_writel(control_context.padconf_sys_nirq, OMAP343X_CONTROL_PADCONF_SYSNIRQ); - return; } void omap3630_ctrl_disable_rta(void)