aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2010-01-26 22:13:09 -0500
committerPaul Walmsley <paul@pwsan.com>2010-01-28 20:13:50 -0500
commit35e424e2c0229aa1e32776fac23902150bd0ab9a (patch)
tree5d686ee74ae8774afadb0bb6af10563d6c4be0f2 /arch/arm
parent6ebe0d88f5fead21d6e1ac328acc683c173d26fc (diff)
OMAP3 clock: split out DPLL3 M2 divider functions into mach-omap2/clkt34xx_dpll3m2.c
Split the DPLL3 M2 divider clock functions out of clock34xx.c and move them into mach-omap2/clkt34xx_dpll3m2.c. This is intended to make the clock code easier to understand, since all of the functions needed to manage the OMAP3 DPLL3 M2 divider are now located in their own file, rather than being mixed with other, unrelated functions. Clock debugging is also now more finely-grained, since the DEBUG macro can now be defined for the DPLL3 M2 clock alone. This should reduce unnecessary console noise when debugging DVFS. Also, if at some future point the mach-omap2/ directory is split into OMAP2/3/4 variants, this clkt file can be placed in the mach-omap34xx/ directory, rather than shared with other chip types that don't use this clock type. This patch also lays the groundwork to skip compilation of this code on OMAP3 chips that don't support DVFS (e.g., AM35xx) via the Makefile, rather than via #ifdefs. Thanks to Alexander Shishkin <virtuoso@slind.org> for his comments to improve the patch description. Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Jouni Högander <jouni.hogander@nokia.com> Cc: Alexander Shishkin <virtuoso@slind.org>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-omap2/Makefile3
-rw-r--r--arch/arm/mach-omap2/clkt34xx_dpll3m2.c120
-rw-r--r--arch/arm/mach-omap2/clock34xx.c90
3 files changed, 122 insertions, 91 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 7ce5fea7f2b..34c2867e0f6 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -15,11 +15,12 @@ clock-omap2xxx = clkt2xxx_dpllcore.o \
15 clkt2xxx_virt_prcm_set.o \ 15 clkt2xxx_virt_prcm_set.o \
16 clkt2xxx_apll.o clkt2xxx_osc.o \ 16 clkt2xxx_apll.o clkt2xxx_osc.o \
17 clkt2xxx_sys.o 17 clkt2xxx_sys.o
18clock-omap3xxx = clkt34xx_dpll3m2.o
18 19
19obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common) \ 20obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
20 $(clock-omap2xxx) 21 $(clock-omap2xxx)
21obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(clock-common) \ 22obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
22 $(omap-3-4-common) 23 $(omap-3-4-common) $(clock-omap3xxx)
23obj-$(CONFIG_ARCH_OMAP4) += $(omap-3-4-common) $(prcm-common) $(clock-common) 24obj-$(CONFIG_ARCH_OMAP4) += $(omap-3-4-common) $(prcm-common) $(clock-common)
24 25
25obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o 26obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
diff --git a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
new file mode 100644
index 00000000000..8716a01d1f5
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
@@ -0,0 +1,120 @@
1/*
2 * OMAP34xx M2 divider clock code
3 *
4 * Copyright (C) 2007-2008 Texas Instruments, Inc.
5 * Copyright (C) 2007-2010 Nokia Corporation
6 *
7 * Paul Walmsley
8 * Jouni Högander
9 *
10 * Parts of this code are based on code written by
11 * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17#undef DEBUG
18
19#include <linux/kernel.h>
20#include <linux/errno.h>
21#include <linux/clk.h>
22#include <linux/io.h>
23
24#include <plat/clock.h>
25#include <plat/sram.h>
26#include <plat/sdrc.h>
27
28#include "clock.h"
29#include "clock34xx.h"
30#include "sdrc.h"
31
32#define CYCLES_PER_MHZ 1000000
33
34/*
35 * CORE DPLL (DPLL3) M2 divider rate programming functions
36 *
37 * These call into SRAM code to do the actual CM writes, since the SDRAM
38 * is clocked from DPLL3.
39 */
40
41/**
42 * omap3_core_dpll_m2_set_rate - set CORE DPLL M2 divider
43 * @clk: struct clk * of DPLL to set
44 * @rate: rounded target rate
45 *
46 * Program the DPLL M2 divider with the rounded target rate. Returns
47 * -EINVAL upon error, or 0 upon success.
48 */
49int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
50{
51 u32 new_div = 0;
52 u32 unlock_dll = 0;
53 u32 c;
54 unsigned long validrate, sdrcrate, _mpurate;
55 struct omap_sdrc_params *sdrc_cs0;
56 struct omap_sdrc_params *sdrc_cs1;
57 int ret;
58
59 if (!clk || !rate)
60 return -EINVAL;
61
62 validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
63 if (validrate != rate)
64 return -EINVAL;
65
66 sdrcrate = sdrc_ick_p->rate;
67 if (rate > clk->rate)
68 sdrcrate <<= ((rate / clk->rate) >> 1);
69 else
70 sdrcrate >>= ((clk->rate / rate) >> 1);
71
72 ret = omap2_sdrc_get_params(sdrcrate, &sdrc_cs0, &sdrc_cs1);
73 if (ret)
74 return -EINVAL;
75
76 if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) {
77 pr_debug("clock: will unlock SDRC DLL\n");
78 unlock_dll = 1;
79 }
80
81 /*
82 * XXX This only needs to be done when the CPU frequency changes
83 */
84 _mpurate = arm_fck_p->rate / CYCLES_PER_MHZ;
85 c = (_mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT;
86 c += 1; /* for safety */
87 c *= SDRC_MPURATE_LOOPS;
88 c >>= SDRC_MPURATE_SCALE;
89 if (c == 0)
90 c = 1;
91
92 pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
93 validrate);
94 pr_debug("clock: SDRC CS0 timing params used:"
95 " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
96 sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
97 sdrc_cs0->actim_ctrlb, sdrc_cs0->mr);
98 if (sdrc_cs1)
99 pr_debug("clock: SDRC CS1 timing params used: "
100 " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
101 sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
102 sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
103
104 if (sdrc_cs1)
105 omap3_configure_core_dpll(
106 new_div, unlock_dll, c, rate > clk->rate,
107 sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
108 sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
109 sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
110 sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
111 else
112 omap3_configure_core_dpll(
113 new_div, unlock_dll, c, rate > clk->rate,
114 sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
115 sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
116 0, 0, 0, 0);
117
118 return 0;
119}
120
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 4c4bb3cb79e..552ad300bb0 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -42,8 +42,6 @@
42#include "cm.h" 42#include "cm.h"
43#include "cm-regbits-34xx.h" 43#include "cm-regbits-34xx.h"
44 44
45#define CYCLES_PER_MHZ 1000000
46
47/* 45/*
48 * DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks 46 * DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
49 * that are sourced by DPLL5, and both of these require this clock 47 * that are sourced by DPLL5, and both of these require this clock
@@ -162,94 +160,6 @@ int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
162 return omap3_noncore_dpll_set_rate(clk, rate); 160 return omap3_noncore_dpll_set_rate(clk, rate);
163} 161}
164 162
165
166/*
167 * CORE DPLL (DPLL3) rate programming functions
168 *
169 * These call into SRAM code to do the actual CM writes, since the SDRAM
170 * is clocked from DPLL3.
171 */
172
173/**
174 * omap3_core_dpll_m2_set_rate - set CORE DPLL M2 divider
175 * @clk: struct clk * of DPLL to set
176 * @rate: rounded target rate
177 *
178 * Program the DPLL M2 divider with the rounded target rate. Returns
179 * -EINVAL upon error, or 0 upon success.
180 */
181int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
182{
183 u32 new_div = 0;
184 u32 unlock_dll = 0;
185 u32 c;
186 unsigned long validrate, sdrcrate, _mpurate;
187 struct omap_sdrc_params *sdrc_cs0;
188 struct omap_sdrc_params *sdrc_cs1;
189 int ret;
190
191 if (!clk || !rate)
192 return -EINVAL;
193
194 validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
195 if (validrate != rate)
196 return -EINVAL;
197
198 sdrcrate = sdrc_ick_p->rate;
199 if (rate > clk->rate)
200 sdrcrate <<= ((rate / clk->rate) >> 1);
201 else
202 sdrcrate >>= ((clk->rate / rate) >> 1);
203
204 ret = omap2_sdrc_get_params(sdrcrate, &sdrc_cs0, &sdrc_cs1);
205 if (ret)
206 return -EINVAL;
207
208 if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) {
209 pr_debug("clock: will unlock SDRC DLL\n");
210 unlock_dll = 1;
211 }
212
213 /*
214 * XXX This only needs to be done when the CPU frequency changes
215 */
216 _mpurate = arm_fck_p->rate / CYCLES_PER_MHZ;
217 c = (_mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT;
218 c += 1; /* for safety */
219 c *= SDRC_MPURATE_LOOPS;
220 c >>= SDRC_MPURATE_SCALE;
221 if (c == 0)
222 c = 1;
223
224 pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
225 validrate);
226 pr_debug("clock: SDRC CS0 timing params used:"
227 " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
228 sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
229 sdrc_cs0->actim_ctrlb, sdrc_cs0->mr);
230 if (sdrc_cs1)
231 pr_debug("clock: SDRC CS1 timing params used: "
232 " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
233 sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
234 sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
235
236 if (sdrc_cs1)
237 omap3_configure_core_dpll(
238 new_div, unlock_dll, c, rate > clk->rate,
239 sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
240 sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
241 sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
242 sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
243 else
244 omap3_configure_core_dpll(
245 new_div, unlock_dll, c, rate > clk->rate,
246 sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
247 sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
248 0, 0, 0, 0);
249
250 return 0;
251}
252
253/* Common clock code */ 163/* Common clock code */
254 164
255/* 165/*