aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/dpll44xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/dpll44xx.c')
-rw-r--r--arch/arm/mach-omap2/dpll44xx.c64
1 files changed, 55 insertions, 9 deletions
diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c
index d3326c474fdc..d28b0f726715 100644
--- a/arch/arm/mach-omap2/dpll44xx.c
+++ b/arch/arm/mach-omap2/dpll44xx.c
@@ -20,6 +20,15 @@
20#include "clock44xx.h" 20#include "clock44xx.h"
21#include "cm-regbits-44xx.h" 21#include "cm-regbits-44xx.h"
22 22
23/*
24 * Maximum DPLL input frequency (FINT) and output frequency (FOUT) that
25 * can supported when using the DPLL low-power mode. Frequencies are
26 * defined in OMAP4430/60 Public TRM section 3.6.3.3.2 "Enable Control,
27 * Status, and Low-Power Operation Mode".
28 */
29#define OMAP4_DPLL_LP_FINT_MAX 1000000
30#define OMAP4_DPLL_LP_FOUT_MAX 100000000
31
23/* Supported only on OMAP4 */ 32/* Supported only on OMAP4 */
24int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk) 33int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk)
25{ 34{
@@ -82,6 +91,31 @@ const struct clk_hw_omap_ops clkhwops_omap4_dpllmx = {
82}; 91};
83 92
84/** 93/**
94 * omap4_dpll_lpmode_recalc - compute DPLL low-power setting
95 * @dd: pointer to the dpll data structure
96 *
97 * Calculates if low-power mode can be enabled based upon the last
98 * multiplier and divider values calculated. If low-power mode can be
99 * enabled, then the bit to enable low-power mode is stored in the
100 * last_rounded_lpmode variable. This implementation is based upon the
101 * criteria for enabling low-power mode as described in the OMAP4430/60
102 * Public TRM section 3.6.3.3.2 "Enable Control, Status, and Low-Power
103 * Operation Mode".
104 */
105static void omap4_dpll_lpmode_recalc(struct dpll_data *dd)
106{
107 long fint, fout;
108
109 fint = __clk_get_rate(dd->clk_ref) / (dd->last_rounded_n + 1);
110 fout = fint * dd->last_rounded_m;
111
112 if ((fint < OMAP4_DPLL_LP_FINT_MAX) && (fout < OMAP4_DPLL_LP_FOUT_MAX))
113 dd->last_rounded_lpmode = 1;
114 else
115 dd->last_rounded_lpmode = 0;
116}
117
118/**
85 * omap4_dpll_regm4xen_recalc - compute DPLL rate, considering REGM4XEN bit 119 * omap4_dpll_regm4xen_recalc - compute DPLL rate, considering REGM4XEN bit
86 * @clk: struct clk * of the DPLL to compute the rate for 120 * @clk: struct clk * of the DPLL to compute the rate for
87 * 121 *
@@ -130,7 +164,6 @@ long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
130 unsigned long *parent_rate) 164 unsigned long *parent_rate)
131{ 165{
132 struct clk_hw_omap *clk = to_clk_hw_omap(hw); 166 struct clk_hw_omap *clk = to_clk_hw_omap(hw);
133 u32 v;
134 struct dpll_data *dd; 167 struct dpll_data *dd;
135 long r; 168 long r;
136 169
@@ -139,18 +172,31 @@ long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
139 172
140 dd = clk->dpll_data; 173 dd = clk->dpll_data;
141 174
142 /* regm4xen adds a multiplier of 4 to DPLL calculations */ 175 dd->last_rounded_m4xen = 0;
143 v = __raw_readl(dd->control_reg) & OMAP4430_DPLL_REGM4XEN_MASK;
144
145 if (v)
146 target_rate = target_rate / OMAP4430_REGM4XEN_MULT;
147 176
177 /*
178 * First try to compute the DPLL configuration for
179 * target rate without using the 4X multiplier.
180 */
148 r = omap2_dpll_round_rate(hw, target_rate, NULL); 181 r = omap2_dpll_round_rate(hw, target_rate, NULL);
182 if (r != ~0)
183 goto out;
184
185 /*
186 * If we did not find a valid DPLL configuration, try again, but
187 * this time see if using the 4X multiplier can help. Enabling the
188 * 4X multiplier is equivalent to dividing the target rate by 4.
189 */
190 r = omap2_dpll_round_rate(hw, target_rate / OMAP4430_REGM4XEN_MULT,
191 NULL);
149 if (r == ~0) 192 if (r == ~0)
150 return r; 193 return r;
151 194
152 if (v) 195 dd->last_rounded_rate *= OMAP4430_REGM4XEN_MULT;
153 clk->dpll_data->last_rounded_rate *= OMAP4430_REGM4XEN_MULT; 196 dd->last_rounded_m4xen = 1;
197
198out:
199 omap4_dpll_lpmode_recalc(dd);
154 200
155 return clk->dpll_data->last_rounded_rate; 201 return dd->last_rounded_rate;
156} 202}