summaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-omap2/clkt_dpll.c28
-rw-r--r--arch/arm/mach-omap2/control.c6
-rw-r--r--arch/arm/mach-omap2/dpll3xxx.c13
3 files changed, 35 insertions, 12 deletions
diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c
index b2ff6cd7ca9f..f251a14cbf16 100644
--- a/arch/arm/mach-omap2/clkt_dpll.c
+++ b/arch/arm/mach-omap2/clkt_dpll.c
@@ -285,10 +285,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)
@@ -334,23 +337,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/control.c b/arch/arm/mach-omap2/control.c
index f4796c002070..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)
@@ -309,7 +310,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
@@ -463,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)
@@ -521,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)
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
index cd5f3a0b97bd..ac3d789ac3cd 100644
--- a/arch/arm/mach-omap2/dpll3xxx.c
+++ b/arch/arm/mach-omap2/dpll3xxx.c
@@ -475,6 +475,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;
@@ -502,8 +503,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;