aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/dpll44xx.c
diff options
context:
space:
mode:
authorJon Hunter <jon-hunter@ti.com>2012-12-15 03:35:46 -0500
committerPaul Walmsley <paul@pwsan.com>2012-12-15 03:35:46 -0500
commit3ff51ed8287d3d2c7899f18f0487348e3448afb5 (patch)
treef0e7d354eb490bba562e2a5ee2ea5334cca2a9cb /arch/arm/mach-omap2/dpll44xx.c
parent9b4fcc86941ec0c12b27fefa39dc85e32244dc64 (diff)
ARM: OMAP4: Enhance support for DPLLs with 4X multiplier
On OMAP4 devices, the ABE DPLL has an internal 4X multiplier that can be enabled or disabled in addition to the standard configurable multiplier (M) for OMAP DPLLs. When configuring the ABE DPLL the 4X multiplier is accounted for by checking to see whether it is enabled or not. However, when calculating a new rate we only check to see if the rate can be achieved with the current setting for the 4X multiplier. Enhance the round_rate() function for such DPLLs to see if the rate can be achieved with the 4X multiplier if it cannot be achieved without the 4X multiplier. This change is necessary, because when using the 32kHz clock as the source clock for the ABE DPLL, the default DPLL frequency for the ABE DPLL cannot be achieved without enabling the 4X multiplier. When using the 32kHz clock as the source clock for the ABE DPLL and attempting to lock the DPLL to 98.304MHz (default frequency), it was found that the DPLL would fail to lock if the low-power mode for the DPLL was not enabled. From reviewing boot-loader settings that configure the ABE DPLL it was found that the low-power mode is enabled when using the 32kHz clock source, however, the documentation for OMAP does not state that this is a requirement. Therefore, introduce a new function for OMAP4 devices to see if low-power mode can be enabled when calculating a new rate to ensure the DPLL will lock. New variables for the last calculated 4X multiplier and low-power setting have been added to the dpll data structure as well as variables defining the bit mask for enabling these features via the DPLL's control_reg. It is possible that we could eliminate these bit masks from the dpll data structure as these bit masks are not unique to OMAP4, if it is preferred. The function omap3_noncore_program_dpll() has been updated to avoid passing the calculated values for the multiplier (M) and divider (N) as these are stored in the clk structure. Signed-off-by: Jon Hunter <jon-hunter@ti.com> Signed-off-by: Paul Walmsley <paul@pwsan.com>
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}