* [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up
@ 2010-01-19 23:35 Paul Walmsley
2010-01-19 23:35 ` [PATCH v2 01/18] OMAP3 clock: move OMAP3-specific DPLL functions to dpll3xxx.c Paul Walmsley
` (17 more replies)
0 siblings, 18 replies; 19+ messages in thread
From: Paul Walmsley @ 2010-01-19 23:35 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
This second version of this series improves the patch changelogs
and adds some code comments.
This patch series splits clock2xxx.c and clock34xx.c by
clock "type", e.g., DPLLs, APLLs, clksel clocks, etc. The point
is to make the code easier to read and easier to debug (by
restricting the scope of DEBUG defines). This also lays the
groundwork for further generalization of the clock code and prepares
for a multi-OMAP2/3/4 kernel.
The series also cleans up a few other minor aspects of the clock
code: the various struct omap2_clk_functions are combined; a
warning identified by sparse is resolved; unnecessary includes
have been trimmed; and some formerly-common code is now only
compiled for the chips that need it.
There are a few minor functional changes, documented in some of
the patch descriptions, but nothing significant.
Compile-tested with n8x0_defconfig, omap_2430sdp_defconfig, and
omap3_beagle_defconfig. Boot-tested on Beagle and N800.
Applies on the "for_2.6.34" branch of git://git.pwsan.com/linux-2.6
Thanks to Alexander Shishkin <virtuoso@slind.org> for his comments.
- Paul
---
size:
text data bss dec hex filename
2338183 126432 64056 2528671 26959f vmlinux.n8x0.orig
2338299 126432 64056 2528787 269613 vmlinux.n8x0.patched
3427989 179488 146848 3754325 394955 vmlinux.2430sdp.orig
3428069 179488 146848 3754405 3949a5 vmlinux.2430sdp.patched
3635559 199232 102984 3937775 3c15ef vmlinux.beagle.orig
3635443 199232 102984 3937659 3c157b vmlinux.beagle.patched
2038356 169664 65380 2273400 22b078 vmlinux.4430sdp.orig
2038448 169664 65380 2273492 22b0d4 vmlinux.4430sdp.patched
Paul Walmsley (18):
OMAP3 clock: move OMAP3-specific DPLL functions to dpll3xxx.c
OMAP2/3/4 clock: move DPLL clock functions into mach-omap2/clkt_dpll.c
OMAP2/3/4 clock: move clksel clock functions into mach-omap2/clkt_clksel.c
OMAP2 clock: move all static functions to the top of the file
OMAP2/3/4 clock: combine all omap2_clk_functions
OMAP2xxx clock: move the DPLL+CORE composite clock code into mach-omap2/clkt2xxx_dpllcore.c
OMAP2xxx clock: move the DVFS virtual clock code into mach-omap2/clkt2xxx_virt_prcm_set.c
OMAP2xxx clock: move the APLL clock code into mach-omap2/clkt2xxx_apll.c
OMAP2xxx clock: move osc_clk code into mach-omap2/clkt2xxx_osc.c
OMAP2xxx clock: move sys_clk code into mach-omap2/clkt2xxx_sys.c
OMAP2 clock: don't compile OMAP2430-only functions on non-2430 builds
OMAP3 clock: split out DPLL3 M2 divider functions into mach-omap2/clkt3xxx_dpll3m2.c
OMAP2/3 clock: clean up omap*_clk_arch_init()
OMAP2/3 clock: remove unnecessary includes and clean up header
OMAP2/3/4 clock: omap2_clk_prepare_for_reboot() is OMAP2xxx-only
OMAP3 DPLL: reorganize static functions
OMAP clock: resolve all remaining sparse warnings
OMAP2/3/4 clock: rename and clean the omap2_clk_init() functions
arch/arm/mach-omap2/Makefile | 18 -
arch/arm/mach-omap2/clkt2xxx_apll.c | 120 ++++
arch/arm/mach-omap2/clkt2xxx_dpllcore.c | 173 +++++
arch/arm/mach-omap2/clkt2xxx_osc.c | 62 ++
arch/arm/mach-omap2/clkt2xxx_sys.c | 50 ++
arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c | 254 ++++++++
arch/arm/mach-omap2/clkt3xxx_dpll3m2.c | 120 ++++
arch/arm/mach-omap2/clkt_clksel.c | 417 +++++++++++++
arch/arm/mach-omap2/clkt_dpll.c | 386 ++++++++++++
arch/arm/mach-omap2/clock.c | 825 ++------------------------
arch/arm/mach-omap2/clock.h | 11
arch/arm/mach-omap2/clock2xxx.c | 548 +----------------
arch/arm/mach-omap2/clock2xxx.h | 7
arch/arm/mach-omap2/clock2xxx_data.c | 6
arch/arm/mach-omap2/clock34xx.c | 154 -----
arch/arm/mach-omap2/clock34xx.h | 1
arch/arm/mach-omap2/clock34xx_data.c | 19 -
arch/arm/mach-omap2/clock44xx.c | 14
arch/arm/mach-omap2/clock44xx.h | 2
arch/arm/mach-omap2/clock44xx_data.c | 4
arch/arm/mach-omap2/dpll3xxx.c | 113 ++--
arch/arm/mach-omap2/io.c | 15
arch/arm/mach-omap2/prcm.c | 8
arch/arm/plat-omap/clock.c | 2
arch/arm/plat-omap/include/plat/clock.h | 2
25 files changed, 1788 insertions(+), 1543 deletions(-)
create mode 100644 arch/arm/mach-omap2/clkt2xxx_apll.c
create mode 100644 arch/arm/mach-omap2/clkt2xxx_dpllcore.c
create mode 100644 arch/arm/mach-omap2/clkt2xxx_osc.c
create mode 100644 arch/arm/mach-omap2/clkt2xxx_sys.c
create mode 100644 arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
create mode 100644 arch/arm/mach-omap2/clkt3xxx_dpll3m2.c
create mode 100644 arch/arm/mach-omap2/clkt_clksel.c
create mode 100644 arch/arm/mach-omap2/clkt_dpll.c
rename arch/arm/mach-omap2/{dpll.c => dpll3xxx.c} (98%)
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 01/18] OMAP3 clock: move OMAP3-specific DPLL functions to dpll3xxx.c
2010-01-19 23:35 [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up Paul Walmsley
@ 2010-01-19 23:35 ` Paul Walmsley
2010-01-19 23:35 ` [PATCH v2 02/18] OMAP2/3/4 clock: move DPLL clock functions into mach-omap2/clkt_dpll.c Paul Walmsley
` (16 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Paul Walmsley @ 2010-01-19 23:35 UTC (permalink / raw)
To: linux-arm-kernel
Mark the OMAP3-specific DPLL functions as being OMAP3-specific by moving
them from mach-omap2/dpll.c to mach-omap2/dpll3xxx.c.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Rajendra Nayak <rnayak@ti.com>
---
arch/arm/mach-omap2/Makefile | 2 +-
arch/arm/mach-omap2/dpll3xxx.c | 0
2 files changed, 1 insertions(+), 1 deletions(-)
rename arch/arm/mach-omap2/{dpll.c => dpll3xxx.c} (100%)
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 64de2fd..7d46fde 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -6,7 +6,7 @@
obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o
omap-2-3-common = irq.o sdrc.o omap_hwmod.o
-omap-3-4-common = dpll.o
+omap-3-4-common = dpll3xxx.o
prcm-common = prcm.o powerdomain.o
clock-common = clock.o clock_common_data.o clockdomain.o
diff --git a/arch/arm/mach-omap2/dpll.c b/arch/arm/mach-omap2/dpll3xxx.c
similarity index 100%
rename from arch/arm/mach-omap2/dpll.c
rename to arch/arm/mach-omap2/dpll3xxx.c
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 02/18] OMAP2/3/4 clock: move DPLL clock functions into mach-omap2/clkt_dpll.c
2010-01-19 23:35 [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up Paul Walmsley
2010-01-19 23:35 ` [PATCH v2 01/18] OMAP3 clock: move OMAP3-specific DPLL functions to dpll3xxx.c Paul Walmsley
@ 2010-01-19 23:35 ` Paul Walmsley
2010-01-19 23:35 ` [PATCH v2 03/18] OMAP2/3/4 clock: move clksel clock functions into mach-omap2/clkt_clksel.c Paul Walmsley
` (15 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Paul Walmsley @ 2010-01-19 23:35 UTC (permalink / raw)
To: linux-arm-kernel
Move all DPLL-related clock functions from mach-omap2/clock.c to
mach-omap2/clkt_dpll.c. This is intended to make the clock code
easier to understand, since all of the functions needed to manage
DPLLs 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 DPLLs alone. This should reduce unnecessary
console noise when debugging.
Also, if at some future point the mach-omap2/ directory is split
into OMAP2/3/4 variants, this clkt file can be moved to the plat-omap/
directory to be shared.
Thanks to Alexander Shishkin <virtuoso@slind.org> for his comments to
improve the patch description.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Alexander Shishkin <virtuoso@slind.org>
---
arch/arm/mach-omap2/Makefile | 3
arch/arm/mach-omap2/clkt_dpll.c | 386 +++++++++++++++++++++++++++++++++++++++
arch/arm/mach-omap2/clock.c | 355 ------------------------------------
3 files changed, 388 insertions(+), 356 deletions(-)
create mode 100644 arch/arm/mach-omap2/clkt_dpll.c
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 7d46fde..1a135c8 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -8,7 +8,8 @@ obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o
omap-2-3-common = irq.o sdrc.o omap_hwmod.o
omap-3-4-common = dpll3xxx.o
prcm-common = prcm.o powerdomain.o
-clock-common = clock.o clock_common_data.o clockdomain.o
+clock-common = clock.o clock_common_data.o \
+ clockdomain.o clkt_dpll.o
obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common)
obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c
new file mode 100644
index 0000000..9eee0e6
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt_dpll.c
@@ -0,0 +1,386 @@
+/*
+ * OMAP2/3/4 DPLL clock functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/div64.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "cm.h"
+#include "cm-regbits-24xx.h"
+#include "cm-regbits-34xx.h"
+
+/* DPLL rate rounding: minimum DPLL multiplier, divider values */
+#define DPLL_MIN_MULTIPLIER 1
+#define DPLL_MIN_DIVIDER 1
+
+/* Possible error results from _dpll_test_mult */
+#define DPLL_MULT_UNDERFLOW -1
+
+/*
+ * Scale factor to mitigate roundoff errors in DPLL rate rounding.
+ * The higher the scale factor, the greater the risk of arithmetic overflow,
+ * but the closer the rounded rate to the target rate. DPLL_SCALE_FACTOR
+ * must be a power of DPLL_SCALE_BASE.
+ */
+#define DPLL_SCALE_FACTOR 64
+#define DPLL_SCALE_BASE 2
+#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \
+ (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))
+
+/* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */
+#define DPLL_FINT_BAND1_MIN 750000
+#define DPLL_FINT_BAND1_MAX 2100000
+#define DPLL_FINT_BAND2_MIN 7500000
+#define DPLL_FINT_BAND2_MAX 21000000
+
+/* _dpll_test_fint() return codes */
+#define DPLL_FINT_UNDERFLOW -1
+#define DPLL_FINT_INVALID -2
+
+/* Private functions */
+
+/*
+ * _dpll_test_fint - test whether an Fint value is valid for the DPLL
+ * @clk: DPLL struct clk to test
+ * @n: divider value (N) to test
+ *
+ * Tests whether a particular divider @n will result in a valid DPLL
+ * internal clock frequency Fint. See the 34xx TRM 4.7.6.2 "DPLL Jitter
+ * Correction". Returns 0 if OK, -1 if the enclosing loop can terminate
+ * (assuming that it is counting N upwards), or -2 if the enclosing loop
+ * should skip to the next iteration (again assuming N is increasing).
+ */
+static int _dpll_test_fint(struct clk *clk, u8 n)
+{
+ struct dpll_data *dd;
+ long fint;
+ int ret = 0;
+
+ dd = clk->dpll_data;
+
+ /* DPLL divider must result in a valid jitter correction val */
+ fint = clk->parent->rate / (n + 1);
+ if (fint < DPLL_FINT_BAND1_MIN) {
+
+ pr_debug("rejecting n=%d due to Fint failure, "
+ "lowering max_divider\n", n);
+ dd->max_divider = n;
+ ret = DPLL_FINT_UNDERFLOW;
+
+ } else if (fint > DPLL_FINT_BAND1_MAX &&
+ fint < DPLL_FINT_BAND2_MIN) {
+
+ pr_debug("rejecting n=%d due to Fint failure\n", n);
+ ret = DPLL_FINT_INVALID;
+
+ } else if (fint > DPLL_FINT_BAND2_MAX) {
+
+ pr_debug("rejecting n=%d due to Fint failure, "
+ "boosting min_divider\n", n);
+ dd->min_divider = n;
+ ret = DPLL_FINT_INVALID;
+
+ }
+
+ return ret;
+}
+
+static unsigned long _dpll_compute_new_rate(unsigned long parent_rate,
+ unsigned int m, unsigned int n)
+{
+ unsigned long long num;
+
+ num = (unsigned long long)parent_rate * m;
+ do_div(num, n);
+ return num;
+}
+
+/*
+ * _dpll_test_mult - test a DPLL multiplier value
+ * @m: pointer to the DPLL m (multiplier) value under test
+ * @n: current DPLL n (divider) value under test
+ * @new_rate: pointer to storage for the resulting rounded rate
+ * @target_rate: the desired DPLL rate
+ * @parent_rate: the DPLL's parent clock rate
+ *
+ * This code tests a DPLL multiplier value, ensuring that the
+ * resulting rate will not be higher than the target_rate, and that
+ * the multiplier value itself is valid for the DPLL. Initially, the
+ * integer pointed to by the m argument should be prescaled by
+ * multiplying by DPLL_SCALE_FACTOR. The code will replace this with
+ * a non-scaled m upon return. This non-scaled m will result in a
+ * new_rate as close as possible to target_rate (but not greater than
+ * target_rate) given the current (parent_rate, n, prescaled m)
+ * triple. Returns DPLL_MULT_UNDERFLOW in the event that the
+ * non-scaled m attempted to underflow, which can allow the calling
+ * function to bail out early; or 0 upon success.
+ */
+static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
+ unsigned long target_rate,
+ unsigned long parent_rate)
+{
+ int r = 0, carry = 0;
+
+ /* Unscale m and round if necessary */
+ if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL)
+ carry = 1;
+ *m = (*m / DPLL_SCALE_FACTOR) + carry;
+
+ /*
+ * The new rate must be <= the target rate to avoid programming
+ * a rate that is impossible for the hardware to handle
+ */
+ *new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
+ if (*new_rate > target_rate) {
+ (*m)--;
+ *new_rate = 0;
+ }
+
+ /* Guard against m underflow */
+ if (*m < DPLL_MIN_MULTIPLIER) {
+ *m = DPLL_MIN_MULTIPLIER;
+ *new_rate = 0;
+ r = DPLL_MULT_UNDERFLOW;
+ }
+
+ if (*new_rate == 0)
+ *new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
+
+ return r;
+}
+
+/* Public functions */
+
+void omap2_init_dpll_parent(struct clk *clk)
+{
+ u32 v;
+ struct dpll_data *dd;
+
+ dd = clk->dpll_data;
+ if (!dd)
+ return;
+
+ /* Return bypass rate if DPLL is bypassed */
+ v = __raw_readl(dd->control_reg);
+ v &= dd->enable_mask;
+ v >>= __ffs(dd->enable_mask);
+
+ /* Reparent in case the dpll is in bypass */
+ if (cpu_is_omap24xx()) {
+ if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP2XXX_EN_DPLL_FRBYPASS)
+ clk_reparent(clk, dd->clk_bypass);
+ } else if (cpu_is_omap34xx()) {
+ if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP3XXX_EN_DPLL_FRBYPASS)
+ clk_reparent(clk, dd->clk_bypass);
+ } else if (cpu_is_omap44xx()) {
+ if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP4XXX_EN_DPLL_FRBYPASS ||
+ v == OMAP4XXX_EN_DPLL_MNBYPASS)
+ clk_reparent(clk, dd->clk_bypass);
+ }
+ return;
+}
+
+/**
+ * omap2_get_dpll_rate - returns the current DPLL CLKOUT rate
+ * @clk: struct clk * of a DPLL
+ *
+ * DPLLs can be locked or bypassed - basically, enabled or disabled.
+ * When locked, the DPLL output depends on the M and N values. When
+ * bypassed, on OMAP2xxx, the output rate is either the 32KiHz clock
+ * or sys_clk. Bypass rates on OMAP3 depend on the DPLL: DPLLs 1 and
+ * 2 are bypassed with dpll1_fclk and dpll2_fclk respectively
+ * (generated by DPLL3), while DPLL 3, 4, and 5 bypass rates are sys_clk.
+ * Returns the current DPLL CLKOUT rate (*not* CLKOUTX2) if the DPLL is
+ * locked, or the appropriate bypass rate if the DPLL is bypassed, or 0
+ * if the clock @clk is not a DPLL.
+ */
+u32 omap2_get_dpll_rate(struct clk *clk)
+{
+ long long dpll_clk;
+ u32 dpll_mult, dpll_div, v;
+ struct dpll_data *dd;
+
+ dd = clk->dpll_data;
+ if (!dd)
+ return 0;
+
+ /* Return bypass rate if DPLL is bypassed */
+ v = __raw_readl(dd->control_reg);
+ v &= dd->enable_mask;
+ v >>= __ffs(dd->enable_mask);
+
+ if (cpu_is_omap24xx()) {
+ if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP2XXX_EN_DPLL_FRBYPASS)
+ return dd->clk_bypass->rate;
+ } else if (cpu_is_omap34xx()) {
+ if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP3XXX_EN_DPLL_FRBYPASS)
+ return dd->clk_bypass->rate;
+ } else if (cpu_is_omap44xx()) {
+ if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP4XXX_EN_DPLL_FRBYPASS ||
+ v == OMAP4XXX_EN_DPLL_MNBYPASS)
+ return dd->clk_bypass->rate;
+ }
+
+ v = __raw_readl(dd->mult_div1_reg);
+ dpll_mult = v & dd->mult_mask;
+ dpll_mult >>= __ffs(dd->mult_mask);
+ dpll_div = v & dd->div1_mask;
+ dpll_div >>= __ffs(dd->div1_mask);
+
+ dpll_clk = (long long)dd->clk_ref->rate * dpll_mult;
+ do_div(dpll_clk, dpll_div + 1);
+
+ return dpll_clk;
+}
+
+/* DPLL rate rounding code */
+
+/**
+ * omap2_dpll_set_rate_tolerance: set the error tolerance during rate rounding
+ * @clk: struct clk * of the DPLL
+ * @tolerance: maximum rate error tolerance
+ *
+ * Set the maximum DPLL rate error tolerance for the rate rounding
+ * algorithm. The rate tolerance is an attempt to balance DPLL power
+ * saving (the least divider value "n") vs. rate fidelity (the least
+ * difference between the desired DPLL target rate and the rounded
+ * rate out of the algorithm). So, increasing the tolerance is likely
+ * to decrease DPLL power consumption and increase DPLL rate error.
+ * Returns -EINVAL if provided a null clock ptr or a clk that is not a
+ * DPLL; or 0 upon success.
+ */
+int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance)
+{
+ if (!clk || !clk->dpll_data)
+ return -EINVAL;
+
+ clk->dpll_data->rate_tolerance = tolerance;
+
+ return 0;
+}
+
+/**
+ * omap2_dpll_round_rate - round a target rate for an OMAP DPLL
+ * @clk: struct clk * for a DPLL
+ * @target_rate: desired DPLL clock rate
+ *
+ * Given a DPLL, a desired target rate, and a rate tolerance, round
+ * the target rate to a possible, programmable rate for this DPLL.
+ * Rate tolerance is assumed to be set by the caller before this
+ * function is called. Attempts to select the minimum possible n
+ * within the tolerance to reduce power consumption. Stores the
+ * computed (m, n) in the DPLL's dpll_data structure so set_rate()
+ * will not need to call this (expensive) function again. Returns ~0
+ * if the target rate cannot be rounded, either because the rate is
+ * too low or because the rate tolerance is set too tightly; or the
+ * rounded rate upon success.
+ */
+long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
+{
+ int m, n, r, e, scaled_max_m;
+ unsigned long scaled_rt_rp, new_rate;
+ int min_e = -1, min_e_m = -1, min_e_n = -1;
+ struct dpll_data *dd;
+
+ if (!clk || !clk->dpll_data)
+ return ~0;
+
+ dd = clk->dpll_data;
+
+ pr_debug("clock: starting DPLL round_rate for clock %s, target rate "
+ "%ld\n", clk->name, target_rate);
+
+ scaled_rt_rp = target_rate / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
+ scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
+
+ dd->last_rounded_rate = 0;
+
+ for (n = dd->min_divider; n <= dd->max_divider; n++) {
+
+ /* Is the (input clk, divider) pair valid for the DPLL? */
+ r = _dpll_test_fint(clk, n);
+ if (r == DPLL_FINT_UNDERFLOW)
+ break;
+ else if (r == DPLL_FINT_INVALID)
+ continue;
+
+ /* Compute the scaled DPLL multiplier, based on the divider */
+ m = scaled_rt_rp * n;
+
+ /*
+ * Since we're counting n up, a m overflow means we
+ * can bail out completely (since as n increases in
+ * the next iteration, there's no way that m can
+ * increase beyond the current m)
+ */
+ if (m > scaled_max_m)
+ break;
+
+ r = _dpll_test_mult(&m, n, &new_rate, target_rate,
+ dd->clk_ref->rate);
+
+ /* m can't be set low enough for this n - try with a larger n */
+ if (r == DPLL_MULT_UNDERFLOW)
+ continue;
+
+ e = target_rate - new_rate;
+ pr_debug("clock: n = %d: m = %d: rate error is %d "
+ "(new_rate = %ld)\n", n, m, e, new_rate);
+
+ if (min_e == -1 ||
+ min_e >= (int)(abs(e) - dd->rate_tolerance)) {
+ min_e = e;
+ min_e_m = m;
+ min_e_n = n;
+
+ pr_debug("clock: found new least error %d\n", min_e);
+
+ /* We found good settings -- bail out now */
+ if (min_e <= dd->rate_tolerance)
+ break;
+ }
+ }
+
+ if (min_e < 0) {
+ pr_debug("clock: error: target rate or tolerance too low\n");
+ return ~0;
+ }
+
+ dd->last_rounded_m = min_e_m;
+ dd->last_rounded_n = min_e_n;
+ dd->last_rounded_rate = _dpll_compute_new_rate(dd->clk_ref->rate,
+ min_e_m, min_e_n);
+
+ pr_debug("clock: final least error: e = %d, m = %d, n = %d\n",
+ min_e, min_e_m, min_e_n);
+ pr_debug("clock: final rate: %ld (target rate: %ld)\n",
+ dd->last_rounded_rate, target_rate);
+
+ return dd->last_rounded_rate;
+}
+
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index d88b255..9819628 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -28,10 +28,7 @@
#include <plat/clockdomain.h>
#include <plat/cpu.h>
#include <plat/prcm.h>
-#include <asm/div64.h>
-#include <plat/sdrc.h>
-#include "sdrc.h"
#include "clock.h"
#include "prm.h"
#include "prm-regbits-24xx.h"
@@ -39,72 +36,12 @@
#include "cm-regbits-24xx.h"
#include "cm-regbits-34xx.h"
-/* DPLL rate rounding: minimum DPLL multiplier, divider values */
-#define DPLL_MIN_MULTIPLIER 1
-#define DPLL_MIN_DIVIDER 1
-
-/* Possible error results from _dpll_test_mult */
-#define DPLL_MULT_UNDERFLOW -1
-
-/*
- * Scale factor to mitigate roundoff errors in DPLL rate rounding.
- * The higher the scale factor, the greater the risk of arithmetic overflow,
- * but the closer the rounded rate to the target rate. DPLL_SCALE_FACTOR
- * must be a power of DPLL_SCALE_BASE.
- */
-#define DPLL_SCALE_FACTOR 64
-#define DPLL_SCALE_BASE 2
-#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \
- (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))
-
-/* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */
-#define DPLL_FINT_BAND1_MIN 750000
-#define DPLL_FINT_BAND1_MAX 2100000
-#define DPLL_FINT_BAND2_MIN 7500000
-#define DPLL_FINT_BAND2_MAX 21000000
-
-/* _dpll_test_fint() return codes */
-#define DPLL_FINT_UNDERFLOW -1
-#define DPLL_FINT_INVALID -2
-
u8 cpu_mask;
/*-------------------------------------------------------------------------
* OMAP2/3/4 specific clock functions
*-------------------------------------------------------------------------*/
-void omap2_init_dpll_parent(struct clk *clk)
-{
- u32 v;
- struct dpll_data *dd;
-
- dd = clk->dpll_data;
- if (!dd)
- return;
-
- /* Return bypass rate if DPLL is bypassed */
- v = __raw_readl(dd->control_reg);
- v &= dd->enable_mask;
- v >>= __ffs(dd->enable_mask);
-
- /* Reparent in case the dpll is in bypass */
- if (cpu_is_omap24xx()) {
- if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
- v == OMAP2XXX_EN_DPLL_FRBYPASS)
- clk_reparent(clk, dd->clk_bypass);
- } else if (cpu_is_omap34xx()) {
- if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
- v == OMAP3XXX_EN_DPLL_FRBYPASS)
- clk_reparent(clk, dd->clk_bypass);
- } else if (cpu_is_omap44xx()) {
- if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
- v == OMAP4XXX_EN_DPLL_FRBYPASS ||
- v == OMAP4XXX_EN_DPLL_MNBYPASS)
- clk_reparent(clk, dd->clk_bypass);
- }
- return;
-}
-
/**
* _omap2xxx_clk_commit - commit clock parent/rate changes in hardware
* @clk: struct clk *
@@ -127,52 +64,6 @@ static void _omap2xxx_clk_commit(struct clk *clk)
prm_read_mod_reg(OMAP24XX_GR_MOD, OMAP2_PRCM_CLKCFG_CTRL_OFFSET);
}
-/*
- * _dpll_test_fint - test whether an Fint value is valid for the DPLL
- * @clk: DPLL struct clk to test
- * @n: divider value (N) to test
- *
- * Tests whether a particular divider @n will result in a valid DPLL
- * internal clock frequency Fint. See the 34xx TRM 4.7.6.2 "DPLL Jitter
- * Correction". Returns 0 if OK, -1 if the enclosing loop can terminate
- * (assuming that it is counting N upwards), or -2 if the enclosing loop
- * should skip to the next iteration (again assuming N is increasing).
- */
-static int _dpll_test_fint(struct clk *clk, u8 n)
-{
- struct dpll_data *dd;
- long fint;
- int ret = 0;
-
- dd = clk->dpll_data;
-
- /* DPLL divider must result in a valid jitter correction val */
- fint = clk->parent->rate / (n + 1);
- if (fint < DPLL_FINT_BAND1_MIN) {
-
- pr_debug("rejecting n=%d due to Fint failure, "
- "lowering max_divider\n", n);
- dd->max_divider = n;
- ret = DPLL_FINT_UNDERFLOW;
-
- } else if (fint > DPLL_FINT_BAND1_MAX &&
- fint < DPLL_FINT_BAND2_MIN) {
-
- pr_debug("rejecting n=%d due to Fint failure\n", n);
- ret = DPLL_FINT_INVALID;
-
- } else if (fint > DPLL_FINT_BAND2_MAX) {
-
- pr_debug("rejecting n=%d due to Fint failure, "
- "boosting min_divider\n", n);
- dd->min_divider = n;
- ret = DPLL_FINT_INVALID;
-
- }
-
- return ret;
-}
-
/**
* omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
* @clk: OMAP clock struct ptr to use
@@ -243,62 +134,6 @@ void omap2_init_clksel_parent(struct clk *clk)
}
/**
- * omap2_get_dpll_rate - returns the current DPLL CLKOUT rate
- * @clk: struct clk * of a DPLL
- *
- * DPLLs can be locked or bypassed - basically, enabled or disabled.
- * When locked, the DPLL output depends on the M and N values. When
- * bypassed, on OMAP2xxx, the output rate is either the 32KiHz clock
- * or sys_clk. Bypass rates on OMAP3 depend on the DPLL: DPLLs 1 and
- * 2 are bypassed with dpll1_fclk and dpll2_fclk respectively
- * (generated by DPLL3), while DPLL 3, 4, and 5 bypass rates are sys_clk.
- * Returns the current DPLL CLKOUT rate (*not* CLKOUTX2) if the DPLL is
- * locked, or the appropriate bypass rate if the DPLL is bypassed, or 0
- * if the clock @clk is not a DPLL.
- */
-u32 omap2_get_dpll_rate(struct clk *clk)
-{
- long long dpll_clk;
- u32 dpll_mult, dpll_div, v;
- struct dpll_data *dd;
-
- dd = clk->dpll_data;
- if (!dd)
- return 0;
-
- /* Return bypass rate if DPLL is bypassed */
- v = __raw_readl(dd->control_reg);
- v &= dd->enable_mask;
- v >>= __ffs(dd->enable_mask);
-
- if (cpu_is_omap24xx()) {
- if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
- v == OMAP2XXX_EN_DPLL_FRBYPASS)
- return dd->clk_bypass->rate;
- } else if (cpu_is_omap34xx()) {
- if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
- v == OMAP3XXX_EN_DPLL_FRBYPASS)
- return dd->clk_bypass->rate;
- } else if (cpu_is_omap44xx()) {
- if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
- v == OMAP4XXX_EN_DPLL_FRBYPASS ||
- v == OMAP4XXX_EN_DPLL_MNBYPASS)
- return dd->clk_bypass->rate;
- }
-
- v = __raw_readl(dd->mult_div1_reg);
- dpll_mult = v & dd->mult_mask;
- dpll_mult >>= __ffs(dd->mult_mask);
- dpll_div = v & dd->div1_mask;
- dpll_div >>= __ffs(dd->div1_mask);
-
- dpll_clk = (long long)dd->clk_ref->rate * dpll_mult;
- do_div(dpll_clk, dpll_div + 1);
-
- return dpll_clk;
-}
-
-/**
* omap2_clk_dflt_find_companion - find companion clock to @clk
* @clk: struct clk * to find the companion clock of
* @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in
@@ -858,196 +693,6 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
return 0;
}
-/* DPLL rate rounding code */
-
-/**
- * omap2_dpll_set_rate_tolerance: set the error tolerance during rate rounding
- * @clk: struct clk * of the DPLL
- * @tolerance: maximum rate error tolerance
- *
- * Set the maximum DPLL rate error tolerance for the rate rounding
- * algorithm. The rate tolerance is an attempt to balance DPLL power
- * saving (the least divider value "n") vs. rate fidelity (the least
- * difference between the desired DPLL target rate and the rounded
- * rate out of the algorithm). So, increasing the tolerance is likely
- * to decrease DPLL power consumption and increase DPLL rate error.
- * Returns -EINVAL if provided a null clock ptr or a clk that is not a
- * DPLL; or 0 upon success.
- */
-int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance)
-{
- if (!clk || !clk->dpll_data)
- return -EINVAL;
-
- clk->dpll_data->rate_tolerance = tolerance;
-
- return 0;
-}
-
-static unsigned long _dpll_compute_new_rate(unsigned long parent_rate,
- unsigned int m, unsigned int n)
-{
- unsigned long long num;
-
- num = (unsigned long long)parent_rate * m;
- do_div(num, n);
- return num;
-}
-
-/*
- * _dpll_test_mult - test a DPLL multiplier value
- * @m: pointer to the DPLL m (multiplier) value under test
- * @n: current DPLL n (divider) value under test
- * @new_rate: pointer to storage for the resulting rounded rate
- * @target_rate: the desired DPLL rate
- * @parent_rate: the DPLL's parent clock rate
- *
- * This code tests a DPLL multiplier value, ensuring that the
- * resulting rate will not be higher than the target_rate, and that
- * the multiplier value itself is valid for the DPLL. Initially, the
- * integer pointed to by the m argument should be prescaled by
- * multiplying by DPLL_SCALE_FACTOR. The code will replace this with
- * a non-scaled m upon return. This non-scaled m will result in a
- * new_rate as close as possible to target_rate (but not greater than
- * target_rate) given the current (parent_rate, n, prescaled m)
- * triple. Returns DPLL_MULT_UNDERFLOW in the event that the
- * non-scaled m attempted to underflow, which can allow the calling
- * function to bail out early; or 0 upon success.
- */
-static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
- unsigned long target_rate,
- unsigned long parent_rate)
-{
- int r = 0, carry = 0;
-
- /* Unscale m and round if necessary */
- if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL)
- carry = 1;
- *m = (*m / DPLL_SCALE_FACTOR) + carry;
-
- /*
- * The new rate must be <= the target rate to avoid programming
- * a rate that is impossible for the hardware to handle
- */
- *new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
- if (*new_rate > target_rate) {
- (*m)--;
- *new_rate = 0;
- }
-
- /* Guard against m underflow */
- if (*m < DPLL_MIN_MULTIPLIER) {
- *m = DPLL_MIN_MULTIPLIER;
- *new_rate = 0;
- r = DPLL_MULT_UNDERFLOW;
- }
-
- if (*new_rate == 0)
- *new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
-
- return r;
-}
-
-/**
- * omap2_dpll_round_rate - round a target rate for an OMAP DPLL
- * @clk: struct clk * for a DPLL
- * @target_rate: desired DPLL clock rate
- *
- * Given a DPLL, a desired target rate, and a rate tolerance, round
- * the target rate to a possible, programmable rate for this DPLL.
- * Rate tolerance is assumed to be set by the caller before this
- * function is called. Attempts to select the minimum possible n
- * within the tolerance to reduce power consumption. Stores the
- * computed (m, n) in the DPLL's dpll_data structure so set_rate()
- * will not need to call this (expensive) function again. Returns ~0
- * if the target rate cannot be rounded, either because the rate is
- * too low or because the rate tolerance is set too tightly; or the
- * rounded rate upon success.
- */
-long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
-{
- int m, n, r, e, scaled_max_m;
- unsigned long scaled_rt_rp, new_rate;
- int min_e = -1, min_e_m = -1, min_e_n = -1;
- struct dpll_data *dd;
-
- if (!clk || !clk->dpll_data)
- return ~0;
-
- dd = clk->dpll_data;
-
- pr_debug("clock: starting DPLL round_rate for clock %s, target rate "
- "%ld\n", clk->name, target_rate);
-
- scaled_rt_rp = target_rate / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
- scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
-
- dd->last_rounded_rate = 0;
-
- for (n = dd->min_divider; n <= dd->max_divider; n++) {
-
- /* Is the (input clk, divider) pair valid for the DPLL? */
- r = _dpll_test_fint(clk, n);
- if (r == DPLL_FINT_UNDERFLOW)
- break;
- else if (r == DPLL_FINT_INVALID)
- continue;
-
- /* Compute the scaled DPLL multiplier, based on the divider */
- m = scaled_rt_rp * n;
-
- /*
- * Since we're counting n up, a m overflow means we
- * can bail out completely (since as n increases in
- * the next iteration, there's no way that m can
- * increase beyond the current m)
- */
- if (m > scaled_max_m)
- break;
-
- r = _dpll_test_mult(&m, n, &new_rate, target_rate,
- dd->clk_ref->rate);
-
- /* m can't be set low enough for this n - try with a larger n */
- if (r == DPLL_MULT_UNDERFLOW)
- continue;
-
- e = target_rate - new_rate;
- pr_debug("clock: n = %d: m = %d: rate error is %d "
- "(new_rate = %ld)\n", n, m, e, new_rate);
-
- if (min_e == -1 ||
- min_e >= (int)(abs(e) - dd->rate_tolerance)) {
- min_e = e;
- min_e_m = m;
- min_e_n = n;
-
- pr_debug("clock: found new least error %d\n", min_e);
-
- /* We found good settings -- bail out now */
- if (min_e <= dd->rate_tolerance)
- break;
- }
- }
-
- if (min_e < 0) {
- pr_debug("clock: error: target rate or tolerance too low\n");
- return ~0;
- }
-
- dd->last_rounded_m = min_e_m;
- dd->last_rounded_n = min_e_n;
- dd->last_rounded_rate = _dpll_compute_new_rate(dd->clk_ref->rate,
- min_e_m, min_e_n);
-
- pr_debug("clock: final least error: e = %d, m = %d, n = %d\n",
- min_e, min_e_m, min_e_n);
- pr_debug("clock: final rate: %ld (target rate: %ld)\n",
- dd->last_rounded_rate, target_rate);
-
- return dd->last_rounded_rate;
-}
-
/*-------------------------------------------------------------------------
* Omap2 clock reset and init functions
*-------------------------------------------------------------------------*/
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 03/18] OMAP2/3/4 clock: move clksel clock functions into mach-omap2/clkt_clksel.c
2010-01-19 23:35 [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up Paul Walmsley
2010-01-19 23:35 ` [PATCH v2 01/18] OMAP3 clock: move OMAP3-specific DPLL functions to dpll3xxx.c Paul Walmsley
2010-01-19 23:35 ` [PATCH v2 02/18] OMAP2/3/4 clock: move DPLL clock functions into mach-omap2/clkt_dpll.c Paul Walmsley
@ 2010-01-19 23:35 ` Paul Walmsley
2010-01-19 23:35 ` [PATCH v2 04/18] OMAP2 clock: move all static functions to the top of the file Paul Walmsley
` (14 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Paul Walmsley @ 2010-01-19 23:35 UTC (permalink / raw)
To: linux-arm-kernel
Move all clksel-related clock functions from mach-omap2/clock.c to
mach-omap2/clkt_clksel.c. This is intended to make the clock code
easier to understand, since all of the functions needed to manage
clksel clocks 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 clksel clocks alon. This should reduce
unnecessary console noise when debugging.
Also, if at some future point the mach-omap2/ directory is split
into OMAP2/3/4 variants, this clkt file can be moved to the plat-omap/
directory to be shared.
Thanks to Alexander Shishkin <virtuoso@slind.org> for his comments to
improve the patch description.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Alexander Shishkin <virtuoso@slind.org>
---
arch/arm/mach-omap2/Makefile | 3
arch/arm/mach-omap2/clkt_clksel.c | 417 +++++++++++++++++++++++++++++++++++++
arch/arm/mach-omap2/clock.c | 377 ---------------------------------
arch/arm/mach-omap2/clock.h | 2
4 files changed, 424 insertions(+), 375 deletions(-)
create mode 100644 arch/arm/mach-omap2/clkt_clksel.c
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 1a135c8..9ecc58d 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -9,7 +9,8 @@ omap-2-3-common = irq.o sdrc.o omap_hwmod.o
omap-3-4-common = dpll3xxx.o
prcm-common = prcm.o powerdomain.o
clock-common = clock.o clock_common_data.o \
- clockdomain.o clkt_dpll.o
+ clockdomain.o clkt_dpll.o \
+ clkt_clksel.o
obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common)
obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
diff --git a/arch/arm/mach-omap2/clkt_clksel.c b/arch/arm/mach-omap2/clkt_clksel.c
new file mode 100644
index 0000000..25a2363
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt_clksel.c
@@ -0,0 +1,417 @@
+/*
+ * clkt_clksel.c - OMAP2/3/4 clksel clock functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX At some point these clksel clocks should be split into
+ * "divider" clocks and "mux" clocks to better match the hardware.
+ *
+ * XXX Currently these clocks are only used in the OMAP2/3/4 code, but
+ * many of the OMAP1 clocks should be convertible to use this
+ * mechanism.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "cm.h"
+#include "cm-regbits-24xx.h"
+#include "cm-regbits-34xx.h"
+
+/* Private functions */
+
+/**
+ * _omap2_get_clksel_by_parent - return clksel struct for a given clk & parent
+ * @clk: OMAP struct clk ptr to inspect
+ * @src_clk: OMAP struct clk ptr of the parent clk to search for
+ *
+ * Scan the struct clksel array associated with the clock to find
+ * the element associated with the supplied parent clock address.
+ * Returns a pointer to the struct clksel on success or NULL on error.
+ */
+static const struct clksel *_omap2_get_clksel_by_parent(struct clk *clk,
+ struct clk *src_clk)
+{
+ const struct clksel *clks;
+
+ if (!clk->clksel)
+ return NULL;
+
+ for (clks = clk->clksel; clks->parent; clks++) {
+ if (clks->parent == src_clk)
+ break; /* Found the requested parent */
+ }
+
+ if (!clks->parent) {
+ printk(KERN_ERR "clock: Could not find parent clock %s in "
+ "clksel array of clock %s\n", src_clk->name,
+ clk->name);
+ return NULL;
+ }
+
+ return clks;
+}
+
+/*
+ * Converts encoded control register address into a full address
+ * On error, the return value (parent_div) will be 0.
+ */
+static u32 _omap2_clksel_get_src_field(struct clk *src_clk, struct clk *clk,
+ u32 *field_val)
+{
+ const struct clksel *clks;
+ const struct clksel_rate *clkr;
+
+ clks = _omap2_get_clksel_by_parent(clk, src_clk);
+ if (!clks)
+ return 0;
+
+ for (clkr = clks->rates; clkr->div; clkr++) {
+ if (clkr->flags & cpu_mask && clkr->flags & DEFAULT_RATE)
+ break; /* Found the default rate for this platform */
+ }
+
+ if (!clkr->div) {
+ printk(KERN_ERR "clock: Could not find default rate for "
+ "clock %s parent %s\n", clk->name,
+ src_clk->parent->name);
+ return 0;
+ }
+
+ /* Should never happen. Add a clksel mask to the struct clk. */
+ WARN_ON(clk->clksel_mask == 0);
+
+ *field_val = clkr->val;
+
+ return clkr->div;
+}
+
+
+/* Public functions */
+
+/**
+ * omap2_init_clksel_parent - set a clksel clk's parent field from the hardware
+ * @clk: OMAP clock struct ptr to use
+ *
+ * Given a pointer to a source-selectable struct clk, read the hardware
+ * register and determine what its parent is currently set to. Update the
+ * clk->parent field with the appropriate clk ptr.
+ */
+void omap2_init_clksel_parent(struct clk *clk)
+{
+ const struct clksel *clks;
+ const struct clksel_rate *clkr;
+ u32 r, found = 0;
+
+ if (!clk->clksel)
+ return;
+
+ r = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
+ r >>= __ffs(clk->clksel_mask);
+
+ for (clks = clk->clksel; clks->parent && !found; clks++) {
+ for (clkr = clks->rates; clkr->div && !found; clkr++) {
+ if ((clkr->flags & cpu_mask) && (clkr->val == r)) {
+ if (clk->parent != clks->parent) {
+ pr_debug("clock: inited %s parent "
+ "to %s (was %s)\n",
+ clk->name, clks->parent->name,
+ ((clk->parent) ?
+ clk->parent->name : "NULL"));
+ clk_reparent(clk, clks->parent);
+ };
+ found = 1;
+ }
+ }
+ }
+
+ if (!found)
+ printk(KERN_ERR "clock: init parent: could not find "
+ "regval %0x for clock %s\n", r, clk->name);
+
+ return;
+}
+
+/*
+ * Used for clocks that are part of CLKSEL_xyz governed clocks.
+ * REVISIT: Maybe change to use clk->enable() functions like on omap1?
+ */
+unsigned long omap2_clksel_recalc(struct clk *clk)
+{
+ unsigned long rate;
+ u32 div = 0;
+
+ pr_debug("clock: recalc'ing clksel clk %s\n", clk->name);
+
+ div = omap2_clksel_get_divisor(clk);
+ if (div == 0)
+ return clk->rate;
+
+ rate = clk->parent->rate / div;
+
+ pr_debug("clock: new clock rate is %ld (div %d)\n", rate, div);
+
+ return rate;
+}
+
+/**
+ * omap2_clksel_round_rate_div - find divisor for the given clock and rate
+ * @clk: OMAP struct clk to use
+ * @target_rate: desired clock rate
+ * @new_div: ptr to where we should store the divisor
+ *
+ * Finds 'best' divider value in an array based on the source and target
+ * rates. The divider array must be sorted with smallest divider first.
+ * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
+ * they are only settable as part of virtual_prcm set.
+ *
+ * Returns the rounded clock rate or returns 0xffffffff on error.
+ */
+u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
+ u32 *new_div)
+{
+ unsigned long test_rate;
+ const struct clksel *clks;
+ const struct clksel_rate *clkr;
+ u32 last_div = 0;
+
+ pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n",
+ clk->name, target_rate);
+
+ *new_div = 1;
+
+ clks = _omap2_get_clksel_by_parent(clk, clk->parent);
+ if (!clks)
+ return ~0;
+
+ for (clkr = clks->rates; clkr->div; clkr++) {
+ if (!(clkr->flags & cpu_mask))
+ continue;
+
+ /* Sanity check */
+ if (clkr->div <= last_div)
+ pr_err("clock: clksel_rate table not sorted "
+ "for clock %s", clk->name);
+
+ last_div = clkr->div;
+
+ test_rate = clk->parent->rate / clkr->div;
+
+ if (test_rate <= target_rate)
+ break; /* found it */
+ }
+
+ if (!clkr->div) {
+ pr_err("clock: Could not find divisor for target "
+ "rate %ld for clock %s parent %s\n", target_rate,
+ clk->name, clk->parent->name);
+ return ~0;
+ }
+
+ *new_div = clkr->div;
+
+ pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div,
+ (clk->parent->rate / clkr->div));
+
+ return clk->parent->rate / clkr->div;
+}
+
+/**
+ * omap2_clksel_round_rate - find rounded rate for the given clock and rate
+ * @clk: OMAP struct clk to use
+ * @target_rate: desired clock rate
+ *
+ * Compatibility wrapper for OMAP clock framework
+ * Finds best target rate based on the source clock and possible dividers.
+ * rates. The divider array must be sorted with smallest divider first.
+ * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
+ * they are only settable as part of virtual_prcm set.
+ *
+ * Returns the rounded clock rate or returns 0xffffffff on error.
+ */
+long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
+{
+ u32 new_div;
+
+ return omap2_clksel_round_rate_div(clk, target_rate, &new_div);
+}
+
+
+/* Given a clock and a rate apply a clock specific rounding function */
+long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk->round_rate)
+ return clk->round_rate(clk, rate);
+
+ if (clk->flags & RATE_FIXED)
+ printk(KERN_ERR "clock: generic omap2_clk_round_rate called "
+ "on fixed-rate clock %s\n", clk->name);
+
+ return clk->rate;
+}
+
+/**
+ * omap2_clksel_to_divisor() - turn clksel field value into integer divider
+ * @clk: OMAP struct clk to use
+ * @field_val: register field value to find
+ *
+ * Given a struct clk of a rate-selectable clksel clock, and a register field
+ * value to search for, find the corresponding clock divisor. The register
+ * field value should be pre-masked and shifted down so the LSB is at bit 0
+ * before calling. Returns 0 on error
+ */
+u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val)
+{
+ const struct clksel *clks;
+ const struct clksel_rate *clkr;
+
+ clks = _omap2_get_clksel_by_parent(clk, clk->parent);
+ if (!clks)
+ return 0;
+
+ for (clkr = clks->rates; clkr->div; clkr++) {
+ if ((clkr->flags & cpu_mask) && (clkr->val == field_val))
+ break;
+ }
+
+ if (!clkr->div) {
+ printk(KERN_ERR "clock: Could not find fieldval %d for "
+ "clock %s parent %s\n", field_val, clk->name,
+ clk->parent->name);
+ return 0;
+ }
+
+ return clkr->div;
+}
+
+/**
+ * omap2_divisor_to_clksel() - turn clksel integer divisor into a field value
+ * @clk: OMAP struct clk to use
+ * @div: integer divisor to search for
+ *
+ * Given a struct clk of a rate-selectable clksel clock, and a clock divisor,
+ * find the corresponding register field value. The return register value is
+ * the value before left-shifting. Returns ~0 on error
+ */
+u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
+{
+ const struct clksel *clks;
+ const struct clksel_rate *clkr;
+
+ /* should never happen */
+ WARN_ON(div == 0);
+
+ clks = _omap2_get_clksel_by_parent(clk, clk->parent);
+ if (!clks)
+ return ~0;
+
+ for (clkr = clks->rates; clkr->div; clkr++) {
+ if ((clkr->flags & cpu_mask) && (clkr->div == div))
+ break;
+ }
+
+ if (!clkr->div) {
+ printk(KERN_ERR "clock: Could not find divisor %d for "
+ "clock %s parent %s\n", div, clk->name,
+ clk->parent->name);
+ return ~0;
+ }
+
+ return clkr->val;
+}
+
+/**
+ * omap2_clksel_get_divisor - get current divider applied to parent clock.
+ * @clk: OMAP struct clk to use.
+ *
+ * Returns the integer divisor upon success or 0 on error.
+ */
+u32 omap2_clksel_get_divisor(struct clk *clk)
+{
+ u32 v;
+
+ if (!clk->clksel_mask)
+ return 0;
+
+ v = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
+ v >>= __ffs(clk->clksel_mask);
+
+ return omap2_clksel_to_divisor(clk, v);
+}
+
+int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 v, field_val, validrate, new_div = 0;
+
+ if (!clk->clksel_mask)
+ return -EINVAL;
+
+ validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
+ if (validrate != rate)
+ return -EINVAL;
+
+ field_val = omap2_divisor_to_clksel(clk, new_div);
+ if (field_val == ~0)
+ return -EINVAL;
+
+ v = __raw_readl(clk->clksel_reg);
+ v &= ~clk->clksel_mask;
+ v |= field_val << __ffs(clk->clksel_mask);
+ __raw_writel(v, clk->clksel_reg);
+ v = __raw_readl(clk->clksel_reg); /* OCP barrier */
+
+ clk->rate = clk->parent->rate / new_div;
+
+ omap2xxx_clk_commit(clk);
+
+ return 0;
+}
+
+int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent)
+{
+ u32 field_val, v, parent_div;
+
+ if (!clk->clksel)
+ return -EINVAL;
+
+ parent_div = _omap2_clksel_get_src_field(new_parent, clk, &field_val);
+ if (!parent_div)
+ return -EINVAL;
+
+ /* Set new source value (previous dividers if any in effect) */
+ v = __raw_readl(clk->clksel_reg);
+ v &= ~clk->clksel_mask;
+ v |= field_val << __ffs(clk->clksel_mask);
+ __raw_writel(v, clk->clksel_reg);
+ v = __raw_readl(clk->clksel_reg); /* OCP barrier */
+
+ omap2xxx_clk_commit(clk);
+
+ clk_reparent(clk, new_parent);
+
+ /* CLKSEL clocks follow their parents' rates, divided by a divisor */
+ clk->rate = new_parent->rate;
+
+ if (parent_div > 0)
+ clk->rate /= parent_div;
+
+ pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
+ clk->name, clk->parent->name, clk->rate);
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 9819628..d3ebb74 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -43,14 +43,14 @@ u8 cpu_mask;
*-------------------------------------------------------------------------*/
/**
- * _omap2xxx_clk_commit - commit clock parent/rate changes in hardware
+ * omap2xxx_clk_commit - commit clock parent/rate changes in hardware
* @clk: struct clk *
*
* If @clk has the DELAYED_APP flag set, meaning that parent/rate changes
* don't take effect until the VALID_CONFIG bit is written, write the
* VALID_CONFIG bit and wait for the write to complete. No return value.
*/
-static void _omap2xxx_clk_commit(struct clk *clk)
+void omap2xxx_clk_commit(struct clk *clk)
{
if (!cpu_is_omap24xx())
return;
@@ -91,49 +91,6 @@ void omap2_init_clk_clkdm(struct clk *clk)
}
/**
- * omap2_init_clksel_parent - set a clksel clk's parent field from the hardware
- * @clk: OMAP clock struct ptr to use
- *
- * Given a pointer to a source-selectable struct clk, read the hardware
- * register and determine what its parent is currently set to. Update the
- * clk->parent field with the appropriate clk ptr.
- */
-void omap2_init_clksel_parent(struct clk *clk)
-{
- const struct clksel *clks;
- const struct clksel_rate *clkr;
- u32 r, found = 0;
-
- if (!clk->clksel)
- return;
-
- r = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
- r >>= __ffs(clk->clksel_mask);
-
- for (clks = clk->clksel; clks->parent && !found; clks++) {
- for (clkr = clks->rates; clkr->div && !found; clkr++) {
- if ((clkr->flags & cpu_mask) && (clkr->val == r)) {
- if (clk->parent != clks->parent) {
- pr_debug("clock: inited %s parent "
- "to %s (was %s)\n",
- clk->name, clks->parent->name,
- ((clk->parent) ?
- clk->parent->name : "NULL"));
- clk_reparent(clk, clks->parent);
- };
- found = 1;
- }
- }
- }
-
- if (!found)
- printk(KERN_ERR "clock: init parent: could not find "
- "regval %0x for clock %s\n", r, clk->name);
-
- return;
-}
-
-/**
* omap2_clk_dflt_find_companion - find companion clock to @clk
* @clk: struct clk * to find the companion clock of
* @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in
@@ -335,274 +292,6 @@ err:
return ret;
}
-/*
- * Used for clocks that are part of CLKSEL_xyz governed clocks.
- * REVISIT: Maybe change to use clk->enable() functions like on omap1?
- */
-unsigned long omap2_clksel_recalc(struct clk *clk)
-{
- unsigned long rate;
- u32 div = 0;
-
- pr_debug("clock: recalc'ing clksel clk %s\n", clk->name);
-
- div = omap2_clksel_get_divisor(clk);
- if (div == 0)
- return clk->rate;
-
- rate = clk->parent->rate / div;
-
- pr_debug("clock: new clock rate is %ld (div %d)\n", rate, div);
-
- return rate;
-}
-
-/**
- * omap2_get_clksel_by_parent - return clksel struct for a given clk & parent
- * @clk: OMAP struct clk ptr to inspect
- * @src_clk: OMAP struct clk ptr of the parent clk to search for
- *
- * Scan the struct clksel array associated with the clock to find
- * the element associated with the supplied parent clock address.
- * Returns a pointer to the struct clksel on success or NULL on error.
- */
-static const struct clksel *omap2_get_clksel_by_parent(struct clk *clk,
- struct clk *src_clk)
-{
- const struct clksel *clks;
-
- if (!clk->clksel)
- return NULL;
-
- for (clks = clk->clksel; clks->parent; clks++) {
- if (clks->parent == src_clk)
- break; /* Found the requested parent */
- }
-
- if (!clks->parent) {
- printk(KERN_ERR "clock: Could not find parent clock %s in "
- "clksel array of clock %s\n", src_clk->name,
- clk->name);
- return NULL;
- }
-
- return clks;
-}
-
-/**
- * omap2_clksel_round_rate_div - find divisor for the given clock and rate
- * @clk: OMAP struct clk to use
- * @target_rate: desired clock rate
- * @new_div: ptr to where we should store the divisor
- *
- * Finds 'best' divider value in an array based on the source and target
- * rates. The divider array must be sorted with smallest divider first.
- * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
- * they are only settable as part of virtual_prcm set.
- *
- * Returns the rounded clock rate or returns 0xffffffff on error.
- */
-u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
- u32 *new_div)
-{
- unsigned long test_rate;
- const struct clksel *clks;
- const struct clksel_rate *clkr;
- u32 last_div = 0;
-
- pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n",
- clk->name, target_rate);
-
- *new_div = 1;
-
- clks = omap2_get_clksel_by_parent(clk, clk->parent);
- if (!clks)
- return ~0;
-
- for (clkr = clks->rates; clkr->div; clkr++) {
- if (!(clkr->flags & cpu_mask))
- continue;
-
- /* Sanity check */
- if (clkr->div <= last_div)
- pr_err("clock: clksel_rate table not sorted "
- "for clock %s", clk->name);
-
- last_div = clkr->div;
-
- test_rate = clk->parent->rate / clkr->div;
-
- if (test_rate <= target_rate)
- break; /* found it */
- }
-
- if (!clkr->div) {
- pr_err("clock: Could not find divisor for target "
- "rate %ld for clock %s parent %s\n", target_rate,
- clk->name, clk->parent->name);
- return ~0;
- }
-
- *new_div = clkr->div;
-
- pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div,
- (clk->parent->rate / clkr->div));
-
- return (clk->parent->rate / clkr->div);
-}
-
-/**
- * omap2_clksel_round_rate - find rounded rate for the given clock and rate
- * @clk: OMAP struct clk to use
- * @target_rate: desired clock rate
- *
- * Compatibility wrapper for OMAP clock framework
- * Finds best target rate based on the source clock and possible dividers.
- * rates. The divider array must be sorted with smallest divider first.
- * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
- * they are only settable as part of virtual_prcm set.
- *
- * Returns the rounded clock rate or returns 0xffffffff on error.
- */
-long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
-{
- u32 new_div;
-
- return omap2_clksel_round_rate_div(clk, target_rate, &new_div);
-}
-
-
-/* Given a clock and a rate apply a clock specific rounding function */
-long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
-{
- if (clk->round_rate)
- return clk->round_rate(clk, rate);
-
- if (clk->flags & RATE_FIXED)
- printk(KERN_ERR "clock: generic omap2_clk_round_rate called "
- "on fixed-rate clock %s\n", clk->name);
-
- return clk->rate;
-}
-
-/**
- * omap2_clksel_to_divisor() - turn clksel field value into integer divider
- * @clk: OMAP struct clk to use
- * @field_val: register field value to find
- *
- * Given a struct clk of a rate-selectable clksel clock, and a register field
- * value to search for, find the corresponding clock divisor. The register
- * field value should be pre-masked and shifted down so the LSB is at bit 0
- * before calling. Returns 0 on error
- */
-u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val)
-{
- const struct clksel *clks;
- const struct clksel_rate *clkr;
-
- clks = omap2_get_clksel_by_parent(clk, clk->parent);
- if (!clks)
- return 0;
-
- for (clkr = clks->rates; clkr->div; clkr++) {
- if ((clkr->flags & cpu_mask) && (clkr->val == field_val))
- break;
- }
-
- if (!clkr->div) {
- printk(KERN_ERR "clock: Could not find fieldval %d for "
- "clock %s parent %s\n", field_val, clk->name,
- clk->parent->name);
- return 0;
- }
-
- return clkr->div;
-}
-
-/**
- * omap2_divisor_to_clksel() - turn clksel integer divisor into a field value
- * @clk: OMAP struct clk to use
- * @div: integer divisor to search for
- *
- * Given a struct clk of a rate-selectable clksel clock, and a clock divisor,
- * find the corresponding register field value. The return register value is
- * the value before left-shifting. Returns ~0 on error
- */
-u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
-{
- const struct clksel *clks;
- const struct clksel_rate *clkr;
-
- /* should never happen */
- WARN_ON(div == 0);
-
- clks = omap2_get_clksel_by_parent(clk, clk->parent);
- if (!clks)
- return ~0;
-
- for (clkr = clks->rates; clkr->div; clkr++) {
- if ((clkr->flags & cpu_mask) && (clkr->div == div))
- break;
- }
-
- if (!clkr->div) {
- printk(KERN_ERR "clock: Could not find divisor %d for "
- "clock %s parent %s\n", div, clk->name,
- clk->parent->name);
- return ~0;
- }
-
- return clkr->val;
-}
-
-/**
- * omap2_clksel_get_divisor - get current divider applied to parent clock.
- * @clk: OMAP struct clk to use.
- *
- * Returns the integer divisor upon success or 0 on error.
- */
-u32 omap2_clksel_get_divisor(struct clk *clk)
-{
- u32 v;
-
- if (!clk->clksel_mask)
- return 0;
-
- v = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
- v >>= __ffs(clk->clksel_mask);
-
- return omap2_clksel_to_divisor(clk, v);
-}
-
-int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 v, field_val, validrate, new_div = 0;
-
- if (!clk->clksel_mask)
- return -EINVAL;
-
- validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
- if (validrate != rate)
- return -EINVAL;
-
- field_val = omap2_divisor_to_clksel(clk, new_div);
- if (field_val == ~0)
- return -EINVAL;
-
- v = __raw_readl(clk->clksel_reg);
- v &= ~clk->clksel_mask;
- v |= field_val << __ffs(clk->clksel_mask);
- __raw_writel(v, clk->clksel_reg);
- v = __raw_readl(clk->clksel_reg); /* OCP barrier */
-
- clk->rate = clk->parent->rate / new_div;
-
- _omap2xxx_clk_commit(clk);
-
- return 0;
-}
-
-
/* Set the clock rate for a clock source */
int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
{
@@ -622,75 +311,15 @@ int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
return ret;
}
-/*
- * Converts encoded control register address into a full address
- * On error, the return value (parent_div) will be 0.
- */
-static u32 _omap2_clksel_get_src_field(struct clk *src_clk, struct clk *clk,
- u32 *field_val)
-{
- const struct clksel *clks;
- const struct clksel_rate *clkr;
-
- clks = omap2_get_clksel_by_parent(clk, src_clk);
- if (!clks)
- return 0;
-
- for (clkr = clks->rates; clkr->div; clkr++) {
- if (clkr->flags & cpu_mask && clkr->flags & DEFAULT_RATE)
- break; /* Found the default rate for this platform */
- }
-
- if (!clkr->div) {
- printk(KERN_ERR "clock: Could not find default rate for "
- "clock %s parent %s\n", clk->name,
- src_clk->parent->name);
- return 0;
- }
-
- /* Should never happen. Add a clksel mask to the struct clk. */
- WARN_ON(clk->clksel_mask == 0);
-
- *field_val = clkr->val;
-
- return clkr->div;
-}
-
int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
{
- u32 field_val, v, parent_div;
-
if (clk->flags & CONFIG_PARTICIPANT)
return -EINVAL;
if (!clk->clksel)
return -EINVAL;
- parent_div = _omap2_clksel_get_src_field(new_parent, clk, &field_val);
- if (!parent_div)
- return -EINVAL;
-
- /* Set new source value (previous dividers if any in effect) */
- v = __raw_readl(clk->clksel_reg);
- v &= ~clk->clksel_mask;
- v |= field_val << __ffs(clk->clksel_mask);
- __raw_writel(v, clk->clksel_reg);
- v = __raw_readl(clk->clksel_reg); /* OCP barrier */
-
- _omap2xxx_clk_commit(clk);
-
- clk_reparent(clk, new_parent);
-
- /* CLKSEL clocks follow their parents' rates, divided by a divisor */
- clk->rate = new_parent->rate;
-
- if (parent_div > 0)
- clk->rate /= parent_div;
-
- pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
- clk->name, clk->parent->name, clk->rate);
-
- return 0;
+ return omap2_clksel_set_parent(clk, new_parent);
}
/*-------------------------------------------------------------------------
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 0d70dc0..0d21702 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -80,6 +80,7 @@ u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val);
u32 omap2_divisor_to_clksel(struct clk *clk, u32 div);
long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate);
int omap2_clksel_set_rate(struct clk *clk, unsigned long rate);
+int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent);
u32 omap2_get_dpll_rate(struct clk *clk);
void omap2_init_dpll_parent(struct clk *clk);
int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name);
@@ -90,6 +91,7 @@ void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
u8 *other_bit);
void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
u8 *idlest_bit);
+void omap2xxx_clk_commit(struct clk *clk);
extern u8 cpu_mask;
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 04/18] OMAP2 clock: move all static functions to the top of the file
2010-01-19 23:35 [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up Paul Walmsley
` (2 preceding siblings ...)
2010-01-19 23:35 ` [PATCH v2 03/18] OMAP2/3/4 clock: move clksel clock functions into mach-omap2/clkt_clksel.c Paul Walmsley
@ 2010-01-19 23:35 ` Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 05/18] OMAP2/3/4 clock: combine all omap2_clk_functions Paul Walmsley
` (13 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Paul Walmsley @ 2010-01-19 23:35 UTC (permalink / raw)
To: linux-arm-kernel
Move static functions to the top of the file and ensure that their names
are prefixed with an underscore to conform with the practice in the newer
OMAP clock code files.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
arch/arm/mach-omap2/clock.c | 88 ++++++++++++++++++++++---------------------
1 files changed, 46 insertions(+), 42 deletions(-)
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index d3ebb74..0d54fde 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -42,6 +42,51 @@ u8 cpu_mask;
* OMAP2/3/4 specific clock functions
*-------------------------------------------------------------------------*/
+/* Private functions */
+
+/**
+ * _omap2_module_wait_ready - wait for an OMAP module to leave IDLE
+ * @clk: struct clk * belonging to the module
+ *
+ * If the necessary clocks for the OMAP hardware IP block that
+ * corresponds to clock @clk are enabled, then wait for the module to
+ * indicate readiness (i.e., to leave IDLE). This code does not
+ * belong in the clock code and will be moved in the medium term to
+ * module-dependent code. No return value.
+ */
+static void _omap2_module_wait_ready(struct clk *clk)
+{
+ void __iomem *companion_reg, *idlest_reg;
+ u8 other_bit, idlest_bit;
+
+ /* Not all modules have multiple clocks that their IDLEST depends on */
+ if (clk->ops->find_companion) {
+ clk->ops->find_companion(clk, &companion_reg, &other_bit);
+ if (!(__raw_readl(companion_reg) & (1 << other_bit)))
+ return;
+ }
+
+ clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit);
+
+ omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), clk->name);
+}
+
+/* Enables clock without considering parent dependencies or use count
+ * REVISIT: Maybe change this to use clk->enable like on omap1?
+ */
+static int _omap2_clk_enable(struct clk *clk)
+{
+ return clk->ops->enable(clk);
+}
+
+/* Disables clock without considering parent dependencies or use count */
+static void _omap2_clk_disable(struct clk *clk)
+{
+ clk->ops->disable(clk);
+}
+
+/* Public functions */
+
/**
* omap2xxx_clk_commit - commit clock parent/rate changes in hardware
* @clk: struct clk *
@@ -149,33 +194,6 @@ void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
*idlest_bit = clk->enable_bit;
}
-/**
- * omap2_module_wait_ready - wait for an OMAP module to leave IDLE
- * @clk: struct clk * belonging to the module
- *
- * If the necessary clocks for the OMAP hardware IP block that
- * corresponds to clock @clk are enabled, then wait for the module to
- * indicate readiness (i.e., to leave IDLE). This code does not
- * belong in the clock code and will be moved in the medium term to
- * module-dependent code. No return value.
- */
-static void omap2_module_wait_ready(struct clk *clk)
-{
- void __iomem *companion_reg, *idlest_reg;
- u8 other_bit, idlest_bit;
-
- /* Not all modules have multiple clocks that their IDLEST depends on */
- if (clk->ops->find_companion) {
- clk->ops->find_companion(clk, &companion_reg, &other_bit);
- if (!(__raw_readl(companion_reg) & (1 << other_bit)))
- return;
- }
-
- clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit);
-
- omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), clk->name);
-}
-
int omap2_dflt_clk_enable(struct clk *clk)
{
u32 v;
@@ -195,7 +213,7 @@ int omap2_dflt_clk_enable(struct clk *clk)
v = __raw_readl(clk->enable_reg); /* OCP barrier */
if (clk->ops->find_idlest)
- omap2_module_wait_ready(clk);
+ _omap2_module_wait_ready(clk);
return 0;
}
@@ -235,20 +253,6 @@ const struct clkops clkops_omap2_dflt = {
.disable = omap2_dflt_clk_disable,
};
-/* Enables clock without considering parent dependencies or use count
- * REVISIT: Maybe change this to use clk->enable like on omap1?
- */
-static int _omap2_clk_enable(struct clk *clk)
-{
- return clk->ops->enable(clk);
-}
-
-/* Disables clock without considering parent dependencies or use count */
-static void _omap2_clk_disable(struct clk *clk)
-{
- clk->ops->disable(clk);
-}
-
void omap2_clk_disable(struct clk *clk)
{
if (clk->usecount > 0 && !(--clk->usecount)) {
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 05/18] OMAP2/3/4 clock: combine all omap2_clk_functions
2010-01-19 23:35 [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up Paul Walmsley
` (3 preceding siblings ...)
2010-01-19 23:35 ` [PATCH v2 04/18] OMAP2 clock: move all static functions to the top of the file Paul Walmsley
@ 2010-01-19 23:36 ` Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 06/18] OMAP2xxx clock: move the DPLL+CORE composite clock code into mach-omap2/clkt2xxx_dpllcore.c Paul Walmsley
` (12 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Paul Walmsley @ 2010-01-19 23:36 UTC (permalink / raw)
To: linux-arm-kernel
The struct clk_functions for OMAP2, 3, and 4 are all essentially the
same, so combine them. This removes one multi-OMAP kernel impediment
and saves memory on multi-OMAP builds.
The stubs for omap2_clk_{init,exit}_cpufreq() code will removed once
the OPP layer code that's currently in Kevin's PM branch is merged.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/clock.c | 17 +++++++++++++++++
arch/arm/mach-omap2/clock.h | 7 +++++++
arch/arm/mach-omap2/clock2xxx.c | 23 ++++++++---------------
arch/arm/mach-omap2/clock34xx.c | 9 ---------
arch/arm/mach-omap2/clock44xx.c | 9 ---------
5 files changed, 32 insertions(+), 33 deletions(-)
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 0d54fde..999b91e 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -351,3 +351,20 @@ void omap2_clk_disable_unused(struct clk *clk)
pwrdm_clkdm_state_switch(clk->clkdm);
}
#endif
+
+/* Common data */
+
+struct clk_functions omap2_clk_functions = {
+ .clk_enable = omap2_clk_enable,
+ .clk_disable = omap2_clk_disable,
+ .clk_round_rate = omap2_clk_round_rate,
+ .clk_set_rate = omap2_clk_set_rate,
+ .clk_set_parent = omap2_clk_set_parent,
+ .clk_disable_unused = omap2_clk_disable_unused,
+#ifdef CONFIG_CPU_FREQ
+ /* These will be removed when the OPP code is integrated */
+ .clk_init_cpufreq_table = omap2_clk_init_cpufreq_table,
+ .clk_exit_cpufreq_table = omap2_clk_exit_cpufreq_table,
+#endif
+};
+
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 0d21702..dcd58cd 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -105,5 +105,12 @@ extern const struct clksel_rate gpt_32k_rates[];
extern const struct clksel_rate gpt_sys_rates[];
extern const struct clksel_rate gfx_l3_rates[];
+#if defined(CONFIG_ARCH_OMAP24XX) && defined(CONFIG_CPU_FREQ)
+extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
+extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
+#else
+#define omap2_clk_init_cpufreq_table 0
+#define omap2_clk_exit_cpufreq_table 0
+#endif
#endif
diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c
index 5420356..bef5574 100644
--- a/arch/arm/mach-omap2/clock2xxx.c
+++ b/arch/arm/mach-omap2/clock2xxx.c
@@ -453,13 +453,16 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate)
*/
static struct cpufreq_frequency_table *freq_table;
-void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
+void omap2xxx_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
{
const struct prcm_config *prcm;
long sys_ck_rate;
int i = 0;
int tbl_sz = 0;
+ if (!cpu_is_omap2xxx())
+ return;
+
sys_ck_rate = clk_get_rate(sclk);
for (prcm = rate_table; prcm->mpu_speed; prcm++) {
@@ -516,26 +519,16 @@ void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
*table = &freq_table[0];
}
-void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
+void omap2xxx_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
{
+ if (!cpu_is_omap2xxx())
+ return;
+
kfree(freq_table);
}
#endif
-struct clk_functions omap2_clk_functions = {
- .clk_enable = omap2_clk_enable,
- .clk_disable = omap2_clk_disable,
- .clk_round_rate = omap2_clk_round_rate,
- .clk_set_rate = omap2_clk_set_rate,
- .clk_set_parent = omap2_clk_set_parent,
- .clk_disable_unused = omap2_clk_disable_unused,
-#ifdef CONFIG_CPU_FREQ
- .clk_init_cpufreq_table = omap2_clk_init_cpufreq_table,
- .clk_exit_cpufreq_table = omap2_clk_exit_cpufreq_table,
-#endif
-};
-
static u32 omap2_get_apll_clkin(void)
{
u32 aplls, srate = 0;
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index d4217b9..4c4bb3c 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -258,15 +258,6 @@ int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
*/
#if defined(CONFIG_ARCH_OMAP3)
-struct clk_functions omap2_clk_functions = {
- .clk_enable = omap2_clk_enable,
- .clk_disable = omap2_clk_disable,
- .clk_round_rate = omap2_clk_round_rate,
- .clk_set_rate = omap2_clk_set_rate,
- .clk_set_parent = omap2_clk_set_parent,
- .clk_disable_unused = omap2_clk_disable_unused,
-};
-
/*
* Set clocks for bypass mode for reboot to work.
*/
diff --git a/arch/arm/mach-omap2/clock44xx.c b/arch/arm/mach-omap2/clock44xx.c
index e370868..08dd642 100644
--- a/arch/arm/mach-omap2/clock44xx.c
+++ b/arch/arm/mach-omap2/clock44xx.c
@@ -13,15 +13,6 @@
#include <linux/errno.h>
#include "clock.h"
-struct clk_functions omap2_clk_functions = {
- .clk_enable = omap2_clk_enable,
- .clk_disable = omap2_clk_disable,
- .clk_round_rate = omap2_clk_round_rate,
- .clk_set_rate = omap2_clk_set_rate,
- .clk_set_parent = omap2_clk_set_parent,
- .clk_disable_unused = omap2_clk_disable_unused,
-};
-
const struct clkops clkops_noncore_dpll_ops = {
.enable = &omap3_noncore_dpll_enable,
.disable = &omap3_noncore_dpll_disable,
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 06/18] OMAP2xxx clock: move the DPLL+CORE composite clock code into mach-omap2/clkt2xxx_dpllcore.c
2010-01-19 23:35 [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up Paul Walmsley
` (4 preceding siblings ...)
2010-01-19 23:36 ` [PATCH v2 05/18] OMAP2/3/4 clock: combine all omap2_clk_functions Paul Walmsley
@ 2010-01-19 23:36 ` Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 07/18] OMAP2xxx clock: move the DVFS virtual clock code into mach-omap2/clkt2xxx_virt_prcm_set.c Paul Walmsley
` (11 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Paul Walmsley @ 2010-01-19 23:36 UTC (permalink / raw)
To: linux-arm-kernel
Move the DPLL+CORE composite clock functions from clock2xxx.c to
mach-omap2/clkt2xxx_dpllcore.c. This is intended to make the clock
code easier to understand, since all of the functions needed to manage
the OMAP2 DPLL+CORE clock 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 DPLL+CORE clock alone. This
should reduce unnecessary console noise when debugging.
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-omap2xxx/
directory, rather than shared with other chip types that don't use this
clock type.
Thanks to Alexander Shishkin <virtuoso@slind.org> for his comments to
improve the patch description.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Richard Woodruff <r-woodruff2@ti.com>
Cc: Alexander Shishkin <virtuoso@slind.org>
---
arch/arm/mach-omap2/Makefile | 4 +
arch/arm/mach-omap2/clkt2xxx_dpllcore.c | 173 +++++++++++++++++++++++++++++++
arch/arm/mach-omap2/clock2xxx.c | 136 ------------------------
3 files changed, 176 insertions(+), 137 deletions(-)
create mode 100644 arch/arm/mach-omap2/clkt2xxx_dpllcore.c
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 9ecc58d..04ce372 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -11,8 +11,10 @@ prcm-common = prcm.o powerdomain.o
clock-common = clock.o clock_common_data.o \
clockdomain.o clkt_dpll.o \
clkt_clksel.o
+clock-omap2xxx = clkt2xxx_dpllcore.o
-obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common)
+obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
+ $(clock-omap2xxx)
obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
$(omap-3-4-common)
obj-$(CONFIG_ARCH_OMAP4) += $(omap-3-4-common) $(prcm-common) $(clock-common)
diff --git a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
new file mode 100644
index 0000000..0190484
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
@@ -0,0 +1,173 @@
+/*
+ * DPLL + CORE_CLK composite clock functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX The DPLL and CORE clocks should be split into two separate clock
+ * types.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/sdrc.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "opp2xxx.h"
+#include "cm.h"
+#include "cm-regbits-24xx.h"
+
+/* #define DOWN_VARIABLE_DPLL 1 */ /* Experimental */
+
+/**
+ * omap2xxx_clk_get_core_rate - return the CORE_CLK rate
+ * @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck")
+ *
+ * Returns the CORE_CLK rate. CORE_CLK can have one of three rate
+ * sources on OMAP2xxx: the DPLL CLKOUT rate, DPLL CLKOUTX2, or 32KHz
+ * (the latter is unusual). This currently should be called with
+ * struct clk *dpll_ck, which is a composite clock of dpll_ck and
+ * core_ck.
+ */
+unsigned long omap2xxx_clk_get_core_rate(struct clk *clk)
+{
+ long long core_clk;
+ u32 v;
+
+ core_clk = omap2_get_dpll_rate(clk);
+
+ v = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+ v &= OMAP24XX_CORE_CLK_SRC_MASK;
+
+ if (v == CORE_CLK_SRC_32K)
+ core_clk = 32768;
+ else
+ core_clk *= v;
+
+ return core_clk;
+}
+
+/*
+ * Uses the current prcm set to tell if a rate is valid.
+ * You can go slower, but not faster within a given rate set.
+ */
+static long omap2_dpllcore_round_rate(unsigned long target_rate)
+{
+ u32 high, low, core_clk_src;
+
+ core_clk_src = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+ core_clk_src &= OMAP24XX_CORE_CLK_SRC_MASK;
+
+ if (core_clk_src == CORE_CLK_SRC_DPLL) { /* DPLL clockout */
+ high = curr_prcm_set->dpll_speed * 2;
+ low = curr_prcm_set->dpll_speed;
+ } else { /* DPLL clockout x 2 */
+ high = curr_prcm_set->dpll_speed;
+ low = curr_prcm_set->dpll_speed / 2;
+ }
+
+#ifdef DOWN_VARIABLE_DPLL
+ if (target_rate > high)
+ return high;
+ else
+ return target_rate;
+#else
+ if (target_rate > low)
+ return high;
+ else
+ return low;
+#endif
+
+}
+
+unsigned long omap2_dpllcore_recalc(struct clk *clk)
+{
+ return omap2xxx_clk_get_core_rate(clk);
+}
+
+int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
+{
+ u32 cur_rate, low, mult, div, valid_rate, done_rate;
+ u32 bypass = 0;
+ struct prcm_config tmpset;
+ const struct dpll_data *dd;
+
+ cur_rate = omap2xxx_clk_get_core_rate(dclk);
+ mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+ mult &= OMAP24XX_CORE_CLK_SRC_MASK;
+
+ if ((rate == (cur_rate / 2)) && (mult == 2)) {
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
+ } else if ((rate == (cur_rate * 2)) && (mult == 1)) {
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+ } else if (rate != cur_rate) {
+ valid_rate = omap2_dpllcore_round_rate(rate);
+ if (valid_rate != rate)
+ return -EINVAL;
+
+ if (mult == 1)
+ low = curr_prcm_set->dpll_speed;
+ else
+ low = curr_prcm_set->dpll_speed / 2;
+
+ dd = clk->dpll_data;
+ if (!dd)
+ return -EINVAL;
+
+ tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg);
+ tmpset.cm_clksel1_pll &= ~(dd->mult_mask |
+ dd->div1_mask);
+ div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
+ tmpset.cm_clksel2_pll = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+ tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK;
+ if (rate > low) {
+ tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2;
+ mult = ((rate / 2) / 1000000);
+ done_rate = CORE_CLK_SRC_DPLL_X2;
+ } else {
+ tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL;
+ mult = (rate / 1000000);
+ done_rate = CORE_CLK_SRC_DPLL;
+ }
+ tmpset.cm_clksel1_pll |= (div << __ffs(dd->mult_mask));
+ tmpset.cm_clksel1_pll |= (mult << __ffs(dd->div1_mask));
+
+ /* Worst case */
+ tmpset.base_sdrc_rfr = SDRC_RFR_CTRL_BYPASS;
+
+ if (rate == curr_prcm_set->xtal_speed) /* If asking for 1-1 */
+ bypass = 1;
+
+ /* For omap2xxx_sdrc_init_params() */
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+
+ /* Force dll lock mode */
+ omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr,
+ bypass);
+
+ /* Errata: ret dll entry state */
+ omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
+ omap2xxx_sdrc_reprogram(done_rate, 0);
+ }
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c
index bef5574..419ae80 100644
--- a/arch/arm/mach-omap2/clock2xxx.c
+++ b/arch/arm/mach-omap2/clock2xxx.c
@@ -54,8 +54,6 @@
#define APLLS_CLKIN_13MHZ 2
#define APLLS_CLKIN_12MHZ 3
-/* #define DOWN_VARIABLE_DPLL 1 */ /* Experimental */
-
const struct prcm_config *curr_prcm_set;
const struct prcm_config *rate_table;
@@ -94,34 +92,6 @@ const struct clkops clkops_omap2430_i2chs_wait = {
.find_companion = omap2_clk_dflt_find_companion,
};
-/**
- * omap2xxx_clk_get_core_rate - return the CORE_CLK rate
- * @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck")
- *
- * Returns the CORE_CLK rate. CORE_CLK can have one of three rate
- * sources on OMAP2xxx: the DPLL CLKOUT rate, DPLL CLKOUTX2, or 32KHz
- * (the latter is unusual). This currently should be called with
- * struct clk *dpll_ck, which is a composite clock of dpll_ck and
- * core_ck.
- */
-unsigned long omap2xxx_clk_get_core_rate(struct clk *clk)
-{
- long long core_clk;
- u32 v;
-
- core_clk = omap2_get_dpll_rate(clk);
-
- v = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
- v &= OMAP24XX_CORE_CLK_SRC_MASK;
-
- if (v == CORE_CLK_SRC_32K)
- core_clk = 32768;
- else
- core_clk *= v;
-
- return core_clk;
-}
-
static int omap2_enable_osc_ck(struct clk *clk)
{
u32 pcc;
@@ -215,112 +185,6 @@ const struct clkops clkops_apll54 = {
.disable = omap2_clk_apll_disable,
};
-/*
- * Uses the current prcm set to tell if a rate is valid.
- * You can go slower, but not faster within a given rate set.
- */
-long omap2_dpllcore_round_rate(unsigned long target_rate)
-{
- u32 high, low, core_clk_src;
-
- core_clk_src = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
- core_clk_src &= OMAP24XX_CORE_CLK_SRC_MASK;
-
- if (core_clk_src == CORE_CLK_SRC_DPLL) { /* DPLL clockout */
- high = curr_prcm_set->dpll_speed * 2;
- low = curr_prcm_set->dpll_speed;
- } else { /* DPLL clockout x 2 */
- high = curr_prcm_set->dpll_speed;
- low = curr_prcm_set->dpll_speed / 2;
- }
-
-#ifdef DOWN_VARIABLE_DPLL
- if (target_rate > high)
- return high;
- else
- return target_rate;
-#else
- if (target_rate > low)
- return high;
- else
- return low;
-#endif
-
-}
-
-unsigned long omap2_dpllcore_recalc(struct clk *clk)
-{
- return omap2xxx_clk_get_core_rate(clk);
-}
-
-int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
-{
- u32 cur_rate, low, mult, div, valid_rate, done_rate;
- u32 bypass = 0;
- struct prcm_config tmpset;
- const struct dpll_data *dd;
-
- cur_rate = omap2xxx_clk_get_core_rate(dclk);
- mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
- mult &= OMAP24XX_CORE_CLK_SRC_MASK;
-
- if ((rate == (cur_rate / 2)) && (mult == 2)) {
- omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
- } else if ((rate == (cur_rate * 2)) && (mult == 1)) {
- omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
- } else if (rate != cur_rate) {
- valid_rate = omap2_dpllcore_round_rate(rate);
- if (valid_rate != rate)
- return -EINVAL;
-
- if (mult == 1)
- low = curr_prcm_set->dpll_speed;
- else
- low = curr_prcm_set->dpll_speed / 2;
-
- dd = clk->dpll_data;
- if (!dd)
- return -EINVAL;
-
- tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg);
- tmpset.cm_clksel1_pll &= ~(dd->mult_mask |
- dd->div1_mask);
- div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
- tmpset.cm_clksel2_pll = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
- tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK;
- if (rate > low) {
- tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2;
- mult = ((rate / 2) / 1000000);
- done_rate = CORE_CLK_SRC_DPLL_X2;
- } else {
- tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL;
- mult = (rate / 1000000);
- done_rate = CORE_CLK_SRC_DPLL;
- }
- tmpset.cm_clksel1_pll |= (div << __ffs(dd->mult_mask));
- tmpset.cm_clksel1_pll |= (mult << __ffs(dd->div1_mask));
-
- /* Worst case */
- tmpset.base_sdrc_rfr = SDRC_RFR_CTRL_BYPASS;
-
- if (rate == curr_prcm_set->xtal_speed) /* If asking for 1-1 */
- bypass = 1;
-
- /* For omap2xxx_sdrc_init_params() */
- omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
-
- /* Force dll lock mode */
- omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr,
- bypass);
-
- /* Errata: ret dll entry state */
- omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
- omap2xxx_sdrc_reprogram(done_rate, 0);
- }
-
- return 0;
-}
-
/**
* omap2_table_mpu_recalc - just return the MPU speed
* @clk: virt_prcm_set struct clk
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 07/18] OMAP2xxx clock: move the DVFS virtual clock code into mach-omap2/clkt2xxx_virt_prcm_set.c
2010-01-19 23:35 [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up Paul Walmsley
` (5 preceding siblings ...)
2010-01-19 23:36 ` [PATCH v2 06/18] OMAP2xxx clock: move the DPLL+CORE composite clock code into mach-omap2/clkt2xxx_dpllcore.c Paul Walmsley
@ 2010-01-19 23:36 ` Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 08/18] OMAP2xxx clock: move the APLL clock code into mach-omap2/clkt2xxx_apll.c Paul Walmsley
` (10 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Paul Walmsley @ 2010-01-19 23:36 UTC (permalink / raw)
To: linux-arm-kernel
Move the DVFS virtual clock functions from clock2xxx.c to
mach-omap2/clkt2xxx_virt_prcm_set.c. This is intended to make the
clock code easier to understand, since all of the functions needed to
manage the virt_prcm_set clock 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 virt_prcm_set clock alone. This should
reduce unnecessary console noise when debugging.
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-omap2xxx/
directory, rather than shared with other chip types that don't use
this clock type.
Thanks to Alexander Shishkin <virtuoso@slind.org> for his comments.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Richard Woodruff <r-woodruff2@ti.com>
Cc: Alexander Shishkin <virtuoso@slind.org>
---
arch/arm/mach-omap2/Makefile | 3
arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c | 254 ++++++++++++++++++++++++++
arch/arm/mach-omap2/clock2xxx.c | 211 ----------------------
3 files changed, 256 insertions(+), 212 deletions(-)
create mode 100644 arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 04ce372..2b58363 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -11,7 +11,8 @@ prcm-common = prcm.o powerdomain.o
clock-common = clock.o clock_common_data.o \
clockdomain.o clkt_dpll.o \
clkt_clksel.o
-clock-omap2xxx = clkt2xxx_dpllcore.o
+clock-omap2xxx = clkt2xxx_dpllcore.o \
+ clkt2xxx_virt_prcm_set.o
obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
$(clock-omap2xxx)
diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
new file mode 100644
index 0000000..7174d09
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
@@ -0,0 +1,254 @@
+/*
+ * OMAP2xxx DVFS virtual clock functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX Some of this code should be replaceable by the upcoming OPP layer
+ * code. However, some notion of "rate set" is probably still necessary
+ * for OMAP2xxx at least. Rate sets should be generalized so they can be
+ * used for any OMAP chip, not just OMAP2xxx. In particular, Richard Woodruff
+ * has in the past expressed a preference to use rate sets for OPP changes,
+ * rather than dynamically recalculating the clock tree, so if someone wants
+ * this badly enough to write the code to handle it, we should support it
+ * as an option.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/cpufreq.h>
+
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/sdrc.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "opp2xxx.h"
+#include "cm.h"
+#include "cm-regbits-24xx.h"
+
+const struct prcm_config *curr_prcm_set;
+const struct prcm_config *rate_table;
+
+/**
+ * omap2_table_mpu_recalc - just return the MPU speed
+ * @clk: virt_prcm_set struct clk
+ *
+ * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
+ */
+unsigned long omap2_table_mpu_recalc(struct clk *clk)
+{
+ return curr_prcm_set->mpu_speed;
+}
+
+/*
+ * Look for a rate equal or less than the target rate given a configuration set.
+ *
+ * What's not entirely clear is "which" field represents the key field.
+ * Some might argue L3-DDR, others ARM, others IVA. This code is simple and
+ * just uses the ARM rates.
+ */
+long omap2_round_to_table_rate(struct clk *clk, unsigned long rate)
+{
+ const struct prcm_config *ptr;
+ long highest_rate;
+ long sys_ck_rate;
+
+ sys_ck_rate = clk_get_rate(sclk);
+
+ highest_rate = -EINVAL;
+
+ for (ptr = rate_table; ptr->mpu_speed; ptr++) {
+ if (!(ptr->flags & cpu_mask))
+ continue;
+ if (ptr->xtal_speed != sys_ck_rate)
+ continue;
+
+ highest_rate = ptr->mpu_speed;
+
+ /* Can check only after xtal frequency check */
+ if (ptr->mpu_speed <= rate)
+ break;
+ }
+ return highest_rate;
+}
+
+/* Sets basic clocks based on the specified rate */
+int omap2_select_table_rate(struct clk *clk, unsigned long rate)
+{
+ u32 cur_rate, done_rate, bypass = 0, tmp;
+ const struct prcm_config *prcm;
+ unsigned long found_speed = 0;
+ unsigned long flags;
+ long sys_ck_rate;
+
+ sys_ck_rate = clk_get_rate(sclk);
+
+ for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+ if (!(prcm->flags & cpu_mask))
+ continue;
+
+ if (prcm->xtal_speed != sys_ck_rate)
+ continue;
+
+ if (prcm->mpu_speed <= rate) {
+ found_speed = prcm->mpu_speed;
+ break;
+ }
+ }
+
+ if (!found_speed) {
+ printk(KERN_INFO "Could not set MPU rate to %luMHz\n",
+ rate / 1000000);
+ return -EINVAL;
+ }
+
+ curr_prcm_set = prcm;
+ cur_rate = omap2xxx_clk_get_core_rate(dclk);
+
+ if (prcm->dpll_speed == cur_rate / 2) {
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
+ } else if (prcm->dpll_speed == cur_rate * 2) {
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+ } else if (prcm->dpll_speed != cur_rate) {
+ local_irq_save(flags);
+
+ if (prcm->dpll_speed == prcm->xtal_speed)
+ bypass = 1;
+
+ if ((prcm->cm_clksel2_pll & OMAP24XX_CORE_CLK_SRC_MASK) ==
+ CORE_CLK_SRC_DPLL_X2)
+ done_rate = CORE_CLK_SRC_DPLL_X2;
+ else
+ done_rate = CORE_CLK_SRC_DPLL;
+
+ /* MPU divider */
+ cm_write_mod_reg(prcm->cm_clksel_mpu, MPU_MOD, CM_CLKSEL);
+
+ /* dsp + iva1 div(2420), iva2.1(2430) */
+ cm_write_mod_reg(prcm->cm_clksel_dsp,
+ OMAP24XX_DSP_MOD, CM_CLKSEL);
+
+ cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL);
+
+ /* Major subsystem dividers */
+ tmp = cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK;
+ cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD,
+ CM_CLKSEL1);
+
+ if (cpu_is_omap2430())
+ cm_write_mod_reg(prcm->cm_clksel_mdm,
+ OMAP2430_MDM_MOD, CM_CLKSEL);
+
+ /* x2 to enter omap2xxx_sdrc_init_params() */
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+
+ omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr,
+ bypass);
+
+ omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
+ omap2xxx_sdrc_reprogram(done_rate, 0);
+
+ local_irq_restore(flags);
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_CPU_FREQ
+/*
+ * Walk PRCM rate table and fillout cpufreq freq_table
+ * XXX This should be replaced by an OPP layer in the near future
+ */
+static struct cpufreq_frequency_table *freq_table;
+
+void omap2xxx_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
+{
+ const struct prcm_config *prcm;
+ long sys_ck_rate;
+ int i = 0;
+ int tbl_sz = 0;
+
+ if (!cpu_is_omap2xxx())
+ return;
+
+ sys_ck_rate = clk_get_rate(sclk);
+
+ for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+ if (!(prcm->flags & cpu_mask))
+ continue;
+ if (prcm->xtal_speed != sys_ck_rate)
+ continue;
+
+ /* don't put bypass rates in table */
+ if (prcm->dpll_speed == prcm->xtal_speed)
+ continue;
+
+ tbl_sz++;
+ }
+
+ /*
+ * XXX Ensure that we're doing what CPUFreq expects for this error
+ * case and the following one
+ */
+ if (tbl_sz == 0) {
+ pr_warning("%s: no matching entries in rate_table\n",
+ __func__);
+ return;
+ }
+
+ /* Include the CPUFREQ_TABLE_END terminator entry */
+ tbl_sz++;
+
+ freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * tbl_sz,
+ GFP_ATOMIC);
+ if (!freq_table) {
+ pr_err("%s: could not kzalloc frequency table\n", __func__);
+ return;
+ }
+
+ for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+ if (!(prcm->flags & cpu_mask))
+ continue;
+ if (prcm->xtal_speed != sys_ck_rate)
+ continue;
+
+ /* don't put bypass rates in table */
+ if (prcm->dpll_speed == prcm->xtal_speed)
+ continue;
+
+ freq_table[i].index = i;
+ freq_table[i].frequency = prcm->mpu_speed / 1000;
+ i++;
+ }
+
+ freq_table[i].index = i;
+ freq_table[i].frequency = CPUFREQ_TABLE_END;
+
+ *table = &freq_table[0];
+}
+
+void omap2xxx_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
+{
+ if (!cpu_is_omap2xxx())
+ return;
+
+ kfree(freq_table);
+}
+
+#endif
diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c
index 419ae80..11d6edb 100644
--- a/arch/arm/mach-omap2/clock2xxx.c
+++ b/arch/arm/mach-omap2/clock2xxx.c
@@ -54,9 +54,6 @@
#define APLLS_CLKIN_13MHZ 2
#define APLLS_CLKIN_12MHZ 3
-const struct prcm_config *curr_prcm_set;
-const struct prcm_config *rate_table;
-
struct clk *vclk, *sclk, *dclk;
void __iomem *prcm_clksrc_ctrl;
@@ -185,214 +182,6 @@ const struct clkops clkops_apll54 = {
.disable = omap2_clk_apll_disable,
};
-/**
- * omap2_table_mpu_recalc - just return the MPU speed
- * @clk: virt_prcm_set struct clk
- *
- * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
- */
-unsigned long omap2_table_mpu_recalc(struct clk *clk)
-{
- return curr_prcm_set->mpu_speed;
-}
-
-/*
- * Look for a rate equal or less than the target rate given a configuration set.
- *
- * What's not entirely clear is "which" field represents the key field.
- * Some might argue L3-DDR, others ARM, others IVA. This code is simple and
- * just uses the ARM rates.
- */
-long omap2_round_to_table_rate(struct clk *clk, unsigned long rate)
-{
- const struct prcm_config *ptr;
- long highest_rate;
- long sys_ck_rate;
-
- sys_ck_rate = clk_get_rate(sclk);
-
- highest_rate = -EINVAL;
-
- for (ptr = rate_table; ptr->mpu_speed; ptr++) {
- if (!(ptr->flags & cpu_mask))
- continue;
- if (ptr->xtal_speed != sys_ck_rate)
- continue;
-
- highest_rate = ptr->mpu_speed;
-
- /* Can check only after xtal frequency check */
- if (ptr->mpu_speed <= rate)
- break;
- }
- return highest_rate;
-}
-
-/* Sets basic clocks based on the specified rate */
-int omap2_select_table_rate(struct clk *clk, unsigned long rate)
-{
- u32 cur_rate, done_rate, bypass = 0, tmp;
- const struct prcm_config *prcm;
- unsigned long found_speed = 0;
- unsigned long flags;
- long sys_ck_rate;
-
- sys_ck_rate = clk_get_rate(sclk);
-
- for (prcm = rate_table; prcm->mpu_speed; prcm++) {
- if (!(prcm->flags & cpu_mask))
- continue;
-
- if (prcm->xtal_speed != sys_ck_rate)
- continue;
-
- if (prcm->mpu_speed <= rate) {
- found_speed = prcm->mpu_speed;
- break;
- }
- }
-
- if (!found_speed) {
- printk(KERN_INFO "Could not set MPU rate to %luMHz\n",
- rate / 1000000);
- return -EINVAL;
- }
-
- curr_prcm_set = prcm;
- cur_rate = omap2xxx_clk_get_core_rate(dclk);
-
- if (prcm->dpll_speed == cur_rate / 2) {
- omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
- } else if (prcm->dpll_speed == cur_rate * 2) {
- omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
- } else if (prcm->dpll_speed != cur_rate) {
- local_irq_save(flags);
-
- if (prcm->dpll_speed == prcm->xtal_speed)
- bypass = 1;
-
- if ((prcm->cm_clksel2_pll & OMAP24XX_CORE_CLK_SRC_MASK) ==
- CORE_CLK_SRC_DPLL_X2)
- done_rate = CORE_CLK_SRC_DPLL_X2;
- else
- done_rate = CORE_CLK_SRC_DPLL;
-
- /* MPU divider */
- cm_write_mod_reg(prcm->cm_clksel_mpu, MPU_MOD, CM_CLKSEL);
-
- /* dsp + iva1 div(2420), iva2.1(2430) */
- cm_write_mod_reg(prcm->cm_clksel_dsp,
- OMAP24XX_DSP_MOD, CM_CLKSEL);
-
- cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL);
-
- /* Major subsystem dividers */
- tmp = cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK;
- cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD,
- CM_CLKSEL1);
-
- if (cpu_is_omap2430())
- cm_write_mod_reg(prcm->cm_clksel_mdm,
- OMAP2430_MDM_MOD, CM_CLKSEL);
-
- /* x2 to enter omap2xxx_sdrc_init_params() */
- omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
-
- omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr,
- bypass);
-
- omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
- omap2xxx_sdrc_reprogram(done_rate, 0);
-
- local_irq_restore(flags);
- }
-
- return 0;
-}
-
-#ifdef CONFIG_CPU_FREQ
-/*
- * Walk PRCM rate table and fillout cpufreq freq_table
- * XXX This should be replaced by an OPP layer in the near future
- */
-static struct cpufreq_frequency_table *freq_table;
-
-void omap2xxx_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
-{
- const struct prcm_config *prcm;
- long sys_ck_rate;
- int i = 0;
- int tbl_sz = 0;
-
- if (!cpu_is_omap2xxx())
- return;
-
- sys_ck_rate = clk_get_rate(sclk);
-
- for (prcm = rate_table; prcm->mpu_speed; prcm++) {
- if (!(prcm->flags & cpu_mask))
- continue;
- if (prcm->xtal_speed != sys_ck_rate)
- continue;
-
- /* don't put bypass rates in table */
- if (prcm->dpll_speed == prcm->xtal_speed)
- continue;
-
- tbl_sz++;
- }
-
- /*
- * XXX Ensure that we're doing what CPUFreq expects for this error
- * case and the following one
- */
- if (tbl_sz == 0) {
- pr_warning("%s: no matching entries in rate_table\n",
- __func__);
- return;
- }
-
- /* Include the CPUFREQ_TABLE_END terminator entry */
- tbl_sz++;
-
- freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * tbl_sz,
- GFP_ATOMIC);
- if (!freq_table) {
- pr_err("%s: could not kzalloc frequency table\n", __func__);
- return;
- }
-
- for (prcm = rate_table; prcm->mpu_speed; prcm++) {
- if (!(prcm->flags & cpu_mask))
- continue;
- if (prcm->xtal_speed != sys_ck_rate)
- continue;
-
- /* don't put bypass rates in table */
- if (prcm->dpll_speed == prcm->xtal_speed)
- continue;
-
- freq_table[i].index = i;
- freq_table[i].frequency = prcm->mpu_speed / 1000;
- i++;
- }
-
- freq_table[i].index = i;
- freq_table[i].frequency = CPUFREQ_TABLE_END;
-
- *table = &freq_table[0];
-}
-
-void omap2xxx_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
-{
- if (!cpu_is_omap2xxx())
- return;
-
- kfree(freq_table);
-}
-
-#endif
-
static u32 omap2_get_apll_clkin(void)
{
u32 aplls, srate = 0;
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 08/18] OMAP2xxx clock: move the APLL clock code into mach-omap2/clkt2xxx_apll.c
2010-01-19 23:35 [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up Paul Walmsley
` (6 preceding siblings ...)
2010-01-19 23:36 ` [PATCH v2 07/18] OMAP2xxx clock: move the DVFS virtual clock code into mach-omap2/clkt2xxx_virt_prcm_set.c Paul Walmsley
@ 2010-01-19 23:36 ` Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 09/18] OMAP2xxx clock: move osc_clk code into mach-omap2/clkt2xxx_osc.c Paul Walmsley
` (9 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Paul Walmsley @ 2010-01-19 23:36 UTC (permalink / raw)
To: linux-arm-kernel
Move the APLL-related clock functions from clock2xxx.c to
mach-omap2/clkt2xxx_apll.c. This is intended to make the clock code
easier to understand, since all of the functions needed to manage APLLs
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 APLL clocks alone. This
should reduce unnecessary console noise when debugging.
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-omap2xxx/
directory, rather than shared with other chip types that don't use this
clock type.
Thanks to Alexander Shishkin <virtuoso@slind.org> for his comments to
improve the patch description.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Richard Woodruff <r-woodruff2@ti.com>
Cc: Alexander Shishkin <virtuoso@slind.org>
---
arch/arm/mach-omap2/Makefile | 3 +
arch/arm/mach-omap2/clkt2xxx_apll.c | 120 +++++++++++++++++++++++++++++++++++
arch/arm/mach-omap2/clock2xxx.c | 86 -------------------------
arch/arm/mach-omap2/clock2xxx.h | 1
4 files changed, 124 insertions(+), 86 deletions(-)
create mode 100644 arch/arm/mach-omap2/clkt2xxx_apll.c
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 2b58363..825c303 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -12,7 +12,8 @@ clock-common = clock.o clock_common_data.o \
clockdomain.o clkt_dpll.o \
clkt_clksel.o
clock-omap2xxx = clkt2xxx_dpllcore.o \
- clkt2xxx_virt_prcm_set.o
+ clkt2xxx_virt_prcm_set.o \
+ clkt2xxx_apll.o
obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
$(clock-omap2xxx)
diff --git a/arch/arm/mach-omap2/clkt2xxx_apll.c b/arch/arm/mach-omap2/clkt2xxx_apll.c
new file mode 100644
index 0000000..fc32ff8
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_apll.c
@@ -0,0 +1,120 @@
+/*
+ * OMAP2xxx APLL clock control functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+#include <plat/prcm.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "cm.h"
+#include "cm-regbits-24xx.h"
+
+/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
+#define EN_APLL_STOPPED 0
+#define EN_APLL_LOCKED 3
+
+/* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */
+#define APLLS_CLKIN_19_2MHZ 0
+#define APLLS_CLKIN_13MHZ 2
+#define APLLS_CLKIN_12MHZ 3
+
+/* Private functions */
+
+/* Enable an APLL if off */
+static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask)
+{
+ u32 cval, apll_mask;
+
+ apll_mask = EN_APLL_LOCKED << clk->enable_bit;
+
+ cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+
+ if ((cval & apll_mask) == apll_mask)
+ return 0; /* apll already enabled */
+
+ cval &= ~apll_mask;
+ cval |= apll_mask;
+ cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
+
+ omap2_cm_wait_idlest(OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), status_mask,
+ clk->name);
+
+ /*
+ * REVISIT: Should we return an error code if omap2_wait_clock_ready()
+ * fails?
+ */
+ return 0;
+}
+
+static int omap2_clk_apll96_enable(struct clk *clk)
+{
+ return omap2_clk_apll_enable(clk, OMAP24XX_ST_96M_APLL);
+}
+
+static int omap2_clk_apll54_enable(struct clk *clk)
+{
+ return omap2_clk_apll_enable(clk, OMAP24XX_ST_54M_APLL);
+}
+
+/* Stop APLL */
+static void omap2_clk_apll_disable(struct clk *clk)
+{
+ u32 cval;
+
+ cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+ cval &= ~(EN_APLL_LOCKED << clk->enable_bit);
+ cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
+}
+
+/* Public data */
+
+const struct clkops clkops_apll96 = {
+ .enable = omap2_clk_apll96_enable,
+ .disable = omap2_clk_apll_disable,
+};
+
+const struct clkops clkops_apll54 = {
+ .enable = omap2_clk_apll54_enable,
+ .disable = omap2_clk_apll_disable,
+};
+
+/* Public functions */
+
+u32 omap2xxx_get_apll_clkin(void)
+{
+ u32 aplls, srate = 0;
+
+ aplls = cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
+ aplls &= OMAP24XX_APLLS_CLKIN_MASK;
+ aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;
+
+ if (aplls == APLLS_CLKIN_19_2MHZ)
+ srate = 19200000;
+ else if (aplls == APLLS_CLKIN_13MHZ)
+ srate = 13000000;
+ else if (aplls == APLLS_CLKIN_12MHZ)
+ srate = 12000000;
+
+ return srate;
+}
+
diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c
index 11d6edb..88077e7 100644
--- a/arch/arm/mach-omap2/clock2xxx.c
+++ b/arch/arm/mach-omap2/clock2xxx.c
@@ -44,16 +44,6 @@
#include "cm.h"
#include "cm-regbits-24xx.h"
-
-/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
-#define EN_APLL_STOPPED 0
-#define EN_APLL_LOCKED 3
-
-/* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */
-#define APLLS_CLKIN_19_2MHZ 0
-#define APLLS_CLKIN_13MHZ 2
-#define APLLS_CLKIN_12MHZ 3
-
struct clk *vclk, *sclk, *dclk;
void __iomem *prcm_clksrc_ctrl;
@@ -126,80 +116,6 @@ static void omap2_sys_clk_recalc(struct clk *clk)
}
#endif /* OLD_CK */
-/* Enable an APLL if off */
-static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask)
-{
- u32 cval, apll_mask;
-
- apll_mask = EN_APLL_LOCKED << clk->enable_bit;
-
- cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
-
- if ((cval & apll_mask) == apll_mask)
- return 0; /* apll already enabled */
-
- cval &= ~apll_mask;
- cval |= apll_mask;
- cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
-
- omap2_cm_wait_idlest(OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), status_mask,
- clk->name);
-
- /*
- * REVISIT: Should we return an error code if omap2_wait_clock_ready()
- * fails?
- */
- return 0;
-}
-
-static int omap2_clk_apll96_enable(struct clk *clk)
-{
- return omap2_clk_apll_enable(clk, OMAP24XX_ST_96M_APLL);
-}
-
-static int omap2_clk_apll54_enable(struct clk *clk)
-{
- return omap2_clk_apll_enable(clk, OMAP24XX_ST_54M_APLL);
-}
-
-/* Stop APLL */
-static void omap2_clk_apll_disable(struct clk *clk)
-{
- u32 cval;
-
- cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
- cval &= ~(EN_APLL_LOCKED << clk->enable_bit);
- cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
-}
-
-const struct clkops clkops_apll96 = {
- .enable = omap2_clk_apll96_enable,
- .disable = omap2_clk_apll_disable,
-};
-
-const struct clkops clkops_apll54 = {
- .enable = omap2_clk_apll54_enable,
- .disable = omap2_clk_apll_disable,
-};
-
-static u32 omap2_get_apll_clkin(void)
-{
- u32 aplls, srate = 0;
-
- aplls = cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
- aplls &= OMAP24XX_APLLS_CLKIN_MASK;
- aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;
-
- if (aplls == APLLS_CLKIN_19_2MHZ)
- srate = 19200000;
- else if (aplls == APLLS_CLKIN_13MHZ)
- srate = 13000000;
- else if (aplls == APLLS_CLKIN_12MHZ)
- srate = 12000000;
-
- return srate;
-}
-
static u32 omap2_get_sysclkdiv(void)
{
u32 div;
@@ -213,7 +129,7 @@ static u32 omap2_get_sysclkdiv(void)
unsigned long omap2_osc_clk_recalc(struct clk *clk)
{
- return omap2_get_apll_clkin() * omap2_get_sysclkdiv();
+ return omap2xxx_get_apll_clkin() * omap2_get_sysclkdiv();
}
unsigned long omap2_sys_clk_recalc(struct clk *clk)
diff --git a/arch/arm/mach-omap2/clock2xxx.h b/arch/arm/mach-omap2/clock2xxx.h
index e35efde..3f1672e 100644
--- a/arch/arm/mach-omap2/clock2xxx.h
+++ b/arch/arm/mach-omap2/clock2xxx.h
@@ -17,6 +17,7 @@ unsigned long omap2_sys_clk_recalc(struct clk *clk);
unsigned long omap2_dpllcore_recalc(struct clk *clk);
int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate);
unsigned long omap2xxx_clk_get_core_rate(struct clk *clk);
+u32 omap2xxx_get_apll_clkin(void);
/* REVISIT: These should be set dynamically for CONFIG_MULTI_OMAP2 */
#ifdef CONFIG_ARCH_OMAP2420
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 09/18] OMAP2xxx clock: move osc_clk code into mach-omap2/clkt2xxx_osc.c
2010-01-19 23:35 [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up Paul Walmsley
` (7 preceding siblings ...)
2010-01-19 23:36 ` [PATCH v2 08/18] OMAP2xxx clock: move the APLL clock code into mach-omap2/clkt2xxx_apll.c Paul Walmsley
@ 2010-01-19 23:36 ` Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 10/18] OMAP2xxx clock: move sys_clk code into mach-omap2/clkt2xxx_sys.c Paul Walmsley
` (8 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Paul Walmsley @ 2010-01-19 23:36 UTC (permalink / raw)
To: linux-arm-kernel
Move the osc_clk clock functions from clock2xxx.c to
mach-omap2/clkt2xxx_osc. This is intended to make the clock code
easier to understand, since all of the functions needed to manage the
osc_clk 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 osc_clk clocks alone. This
should reduce unnecessary console noise when debugging.
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-omap2xxx/
directory, rather than shared with other chip types that don't use this
clock type.
Thanks to Alexander Shishkin <virtuoso@slind.org> for his comments to
improve the patch description.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Alexander Shishkin <virtuoso@slind.org>
---
arch/arm/mach-omap2/Makefile | 2 +
arch/arm/mach-omap2/clkt2xxx_osc.c | 62 ++++++++++++++++++++++++++++++++++++
arch/arm/mach-omap2/clock2xxx.c | 34 +-------------------
arch/arm/mach-omap2/clock2xxx.h | 1 +
4 files changed, 66 insertions(+), 33 deletions(-)
create mode 100644 arch/arm/mach-omap2/clkt2xxx_osc.c
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 825c303..51178bf 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -13,7 +13,7 @@ clock-common = clock.o clock_common_data.o \
clkt_clksel.o
clock-omap2xxx = clkt2xxx_dpllcore.o \
clkt2xxx_virt_prcm_set.o \
- clkt2xxx_apll.o
+ clkt2xxx_apll.o clkt2xxx_osc.o
obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
$(clock-omap2xxx)
diff --git a/arch/arm/mach-omap2/clkt2xxx_osc.c b/arch/arm/mach-omap2/clkt2xxx_osc.c
new file mode 100644
index 0000000..2167be8
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_osc.c
@@ -0,0 +1,62 @@
+/*
+ * OMAP2xxx osc_clk-specific clock code
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "prm.h"
+#include "prm-regbits-24xx.h"
+
+static int omap2_enable_osc_ck(struct clk *clk)
+{
+ u32 pcc;
+
+ pcc = __raw_readl(prcm_clksrc_ctrl);
+
+ __raw_writel(pcc & ~OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
+
+ return 0;
+}
+
+static void omap2_disable_osc_ck(struct clk *clk)
+{
+ u32 pcc;
+
+ pcc = __raw_readl(prcm_clksrc_ctrl);
+
+ __raw_writel(pcc | OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
+}
+
+const struct clkops clkops_oscck = {
+ .enable = omap2_enable_osc_ck,
+ .disable = omap2_disable_osc_ck,
+};
+
+unsigned long omap2_osc_clk_recalc(struct clk *clk)
+{
+ return omap2xxx_get_apll_clkin() * omap2xxx_get_sysclkdiv();
+}
+
diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c
index 88077e7..62c3b02 100644
--- a/arch/arm/mach-omap2/clock2xxx.c
+++ b/arch/arm/mach-omap2/clock2xxx.c
@@ -79,31 +79,6 @@ const struct clkops clkops_omap2430_i2chs_wait = {
.find_companion = omap2_clk_dflt_find_companion,
};
-static int omap2_enable_osc_ck(struct clk *clk)
-{
- u32 pcc;
-
- pcc = __raw_readl(prcm_clksrc_ctrl);
-
- __raw_writel(pcc & ~OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
-
- return 0;
-}
-
-static void omap2_disable_osc_ck(struct clk *clk)
-{
- u32 pcc;
-
- pcc = __raw_readl(prcm_clksrc_ctrl);
-
- __raw_writel(pcc | OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
-}
-
-const struct clkops clkops_oscck = {
- .enable = omap2_enable_osc_ck,
- .disable = omap2_disable_osc_ck,
-};
-
#ifdef OLD_CK
/* Recalculate SYST_CLK */
static void omap2_sys_clk_recalc(struct clk *clk)
@@ -116,7 +91,7 @@ static void omap2_sys_clk_recalc(struct clk *clk)
}
#endif /* OLD_CK */
-static u32 omap2_get_sysclkdiv(void)
+u32 omap2xxx_get_sysclkdiv(void)
{
u32 div;
@@ -127,14 +102,9 @@ static u32 omap2_get_sysclkdiv(void)
return div;
}
-unsigned long omap2_osc_clk_recalc(struct clk *clk)
-{
- return omap2xxx_get_apll_clkin() * omap2_get_sysclkdiv();
-}
-
unsigned long omap2_sys_clk_recalc(struct clk *clk)
{
- return clk->parent->rate / omap2_get_sysclkdiv();
+ return clk->parent->rate / omap2xxx_get_sysclkdiv();
}
/*
diff --git a/arch/arm/mach-omap2/clock2xxx.h b/arch/arm/mach-omap2/clock2xxx.h
index 3f1672e..3b0610d 100644
--- a/arch/arm/mach-omap2/clock2xxx.h
+++ b/arch/arm/mach-omap2/clock2xxx.h
@@ -18,6 +18,7 @@ unsigned long omap2_dpllcore_recalc(struct clk *clk);
int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate);
unsigned long omap2xxx_clk_get_core_rate(struct clk *clk);
u32 omap2xxx_get_apll_clkin(void);
+u32 omap2xxx_get_sysclkdiv(void);
/* REVISIT: These should be set dynamically for CONFIG_MULTI_OMAP2 */
#ifdef CONFIG_ARCH_OMAP2420
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 10/18] OMAP2xxx clock: move sys_clk code into mach-omap2/clkt2xxx_sys.c
2010-01-19 23:35 [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up Paul Walmsley
` (8 preceding siblings ...)
2010-01-19 23:36 ` [PATCH v2 09/18] OMAP2xxx clock: move osc_clk code into mach-omap2/clkt2xxx_osc.c Paul Walmsley
@ 2010-01-19 23:36 ` Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 11/18] OMAP2 clock: don't compile OMAP2430-only functions on non-2430 builds Paul Walmsley
` (7 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Paul Walmsley @ 2010-01-19 23:36 UTC (permalink / raw)
To: linux-arm-kernel
Move the sys_clk clock functions from clock2xxx.c to
mach-omap2/clkt2xxx_sys.c. This is intended to make the clock code
easier to understand, since all of the functions needed to manage the
sys_clk 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 sys_clk clock alone. This
should reduce unnecessary console noise when debugging.
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-omap2xxx/
directory, rather than shared with other chip types that don't use
this clock type.
Thanks to Alexander Shishkin <virtuoso@slind.org> for his comments to
improve the patch description.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Alexander Shishkin <virtuoso@slind.org>
---
arch/arm/mach-omap2/Makefile | 3 +-
arch/arm/mach-omap2/clkt2xxx_sys.c | 50 ++++++++++++++++++++++++++++++++++
arch/arm/mach-omap2/clock2xxx.c | 30 --------------------
arch/arm/mach-omap2/clock2xxx.h | 3 +-
arch/arm/mach-omap2/clock2xxx_data.c | 4 +--
5 files changed, 55 insertions(+), 35 deletions(-)
create mode 100644 arch/arm/mach-omap2/clkt2xxx_sys.c
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 51178bf..7ce5fea 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -13,7 +13,8 @@ clock-common = clock.o clock_common_data.o \
clkt_clksel.o
clock-omap2xxx = clkt2xxx_dpllcore.o \
clkt2xxx_virt_prcm_set.o \
- clkt2xxx_apll.o clkt2xxx_osc.o
+ clkt2xxx_apll.o clkt2xxx_osc.o \
+ clkt2xxx_sys.o
obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
$(clock-omap2xxx)
diff --git a/arch/arm/mach-omap2/clkt2xxx_sys.c b/arch/arm/mach-omap2/clkt2xxx_sys.c
new file mode 100644
index 0000000..822b5a7
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_sys.c
@@ -0,0 +1,50 @@
+/*
+ * OMAP2xxx sys_clk-specific clock code
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "prm.h"
+#include "prm-regbits-24xx.h"
+
+void __iomem *prcm_clksrc_ctrl;
+
+u32 omap2xxx_get_sysclkdiv(void)
+{
+ u32 div;
+
+ div = __raw_readl(prcm_clksrc_ctrl);
+ div &= OMAP_SYSCLKDIV_MASK;
+ div >>= OMAP_SYSCLKDIV_SHIFT;
+
+ return div;
+}
+
+unsigned long omap2xxx_sys_clk_recalc(struct clk *clk)
+{
+ return clk->parent->rate / omap2xxx_get_sysclkdiv();
+}
+
+
diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c
index 62c3b02..b59cb1d 100644
--- a/arch/arm/mach-omap2/clock2xxx.c
+++ b/arch/arm/mach-omap2/clock2xxx.c
@@ -46,8 +46,6 @@
struct clk *vclk, *sclk, *dclk;
-void __iomem *prcm_clksrc_ctrl;
-
/*-------------------------------------------------------------------------
* Omap24xx specific clock functions
*-------------------------------------------------------------------------*/
@@ -79,34 +77,6 @@ const struct clkops clkops_omap2430_i2chs_wait = {
.find_companion = omap2_clk_dflt_find_companion,
};
-#ifdef OLD_CK
-/* Recalculate SYST_CLK */
-static void omap2_sys_clk_recalc(struct clk *clk)
-{
- u32 div = PRCM_CLKSRC_CTRL;
- div &= (1 << 7) | (1 << 6); /* Test if ext clk divided by 1 or 2 */
- div >>= clk->rate_offset;
- clk->rate = (clk->parent->rate / div);
- propagate_rate(clk);
-}
-#endif /* OLD_CK */
-
-u32 omap2xxx_get_sysclkdiv(void)
-{
- u32 div;
-
- div = __raw_readl(prcm_clksrc_ctrl);
- div &= OMAP_SYSCLKDIV_MASK;
- div >>= OMAP_SYSCLKDIV_SHIFT;
-
- return div;
-}
-
-unsigned long omap2_sys_clk_recalc(struct clk *clk)
-{
- return clk->parent->rate / omap2xxx_get_sysclkdiv();
-}
-
/*
* Set clocks for bypass mode for reboot to work.
*/
diff --git a/arch/arm/mach-omap2/clock2xxx.h b/arch/arm/mach-omap2/clock2xxx.h
index 3b0610d..c14061b 100644
--- a/arch/arm/mach-omap2/clock2xxx.h
+++ b/arch/arm/mach-omap2/clock2xxx.h
@@ -11,9 +11,8 @@
unsigned long omap2_table_mpu_recalc(struct clk *clk);
int omap2_select_table_rate(struct clk *clk, unsigned long rate);
long omap2_round_to_table_rate(struct clk *clk, unsigned long rate);
-unsigned long omap2_sys_clk_recalc(struct clk *clk);
+unsigned long omap2xxx_sys_clk_recalc(struct clk *clk);
unsigned long omap2_osc_clk_recalc(struct clk *clk);
-unsigned long omap2_sys_clk_recalc(struct clk *clk);
unsigned long omap2_dpllcore_recalc(struct clk *clk);
int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate);
unsigned long omap2xxx_clk_get_core_rate(struct clk *clk);
diff --git a/arch/arm/mach-omap2/clock2xxx_data.c b/arch/arm/mach-omap2/clock2xxx_data.c
index 402115f..3a435bb 100644
--- a/arch/arm/mach-omap2/clock2xxx_data.c
+++ b/arch/arm/mach-omap2/clock2xxx_data.c
@@ -79,7 +79,7 @@ static struct clk sys_ck = { /* (*12, *13, 19.2, 26, 38.4)MHz */
.ops = &clkops_null,
.parent = &osc_ck,
.clkdm_name = "wkup_clkdm",
- .recalc = &omap2_sys_clk_recalc,
+ .recalc = &omap2xxx_sys_clk_recalc,
};
static struct clk alt_ck = { /* Typical 54M or 48M, may not exist */
@@ -2264,7 +2264,7 @@ int __init omap2_clk_init(void)
osc_ck.rate = omap2_osc_clk_recalc(&osc_ck);
propagate_rate(&osc_ck);
- sys_ck.rate = omap2_sys_clk_recalc(&sys_ck);
+ sys_ck.rate = omap2xxx_sys_clk_recalc(&sys_ck);
propagate_rate(&sys_ck);
for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 11/18] OMAP2 clock: don't compile OMAP2430-only functions on non-2430 builds
2010-01-19 23:35 [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up Paul Walmsley
` (9 preceding siblings ...)
2010-01-19 23:36 ` [PATCH v2 10/18] OMAP2xxx clock: move sys_clk code into mach-omap2/clkt2xxx_sys.c Paul Walmsley
@ 2010-01-19 23:36 ` Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 12/18] OMAP3 clock: split out DPLL3 M2 divider functions into mach-omap2/clkt3xxx_dpll3m2.c Paul Walmsley
` (6 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Paul Walmsley @ 2010-01-19 23:36 UTC (permalink / raw)
To: linux-arm-kernel
omap2430_clk_i2chs_find_idlest() doesn't need to be compiled in on
non-2430 builds, so skip it in those cases to save memory.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
arch/arm/mach-omap2/clock2xxx.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c
index b59cb1d..e5b9851 100644
--- a/arch/arm/mach-omap2/clock2xxx.c
+++ b/arch/arm/mach-omap2/clock2xxx.c
@@ -50,6 +50,8 @@ struct clk *vclk, *sclk, *dclk;
* Omap24xx specific clock functions
*-------------------------------------------------------------------------*/
+#ifdef CONFIG_ARCH_OMAP2430
+
/**
* omap2430_clk_i2chs_find_idlest - return CM_IDLEST info for 2430 I2CHS
* @clk: struct clk * being enabled
@@ -69,6 +71,10 @@ static void omap2430_clk_i2chs_find_idlest(struct clk *clk,
*idlest_bit = clk->enable_bit;
}
+#else
+#define omap2430_clk_i2chs_find_idlest NULL
+#endif
+
/* 2430 I2CHS has non-standard IDLEST register */
const struct clkops clkops_omap2430_i2chs_wait = {
.enable = omap2_dflt_clk_enable,
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 12/18] OMAP3 clock: split out DPLL3 M2 divider functions into mach-omap2/clkt3xxx_dpll3m2.c
2010-01-19 23:35 [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up Paul Walmsley
` (10 preceding siblings ...)
2010-01-19 23:36 ` [PATCH v2 11/18] OMAP2 clock: don't compile OMAP2430-only functions on non-2430 builds Paul Walmsley
@ 2010-01-19 23:36 ` Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 13/18] OMAP2/3 clock: clean up omap*_clk_arch_init() Paul Walmsley
` (5 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Paul Walmsley @ 2010-01-19 23:36 UTC (permalink / raw)
To: linux-arm-kernel
Split the DPLL3 M2 divider clock functions out of clock34xx.c and move
them into mach-omap2/clkt3xxx_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>
---
arch/arm/mach-omap2/Makefile | 3 +
arch/arm/mach-omap2/clkt3xxx_dpll3m2.c | 120 ++++++++++++++++++++++++++++++++
arch/arm/mach-omap2/clock34xx.c | 90 ------------------------
3 files changed, 122 insertions(+), 91 deletions(-)
create mode 100644 arch/arm/mach-omap2/clkt3xxx_dpll3m2.c
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 7ce5fea..b002c81 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -15,11 +15,12 @@ clock-omap2xxx = clkt2xxx_dpllcore.o \
clkt2xxx_virt_prcm_set.o \
clkt2xxx_apll.o clkt2xxx_osc.o \
clkt2xxx_sys.o
+clock-omap3xxx = clkt3xxx_dpll3m2.o
obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
$(clock-omap2xxx)
obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
- $(omap-3-4-common)
+ $(omap-3-4-common) $(clock-omap3xxx)
obj-$(CONFIG_ARCH_OMAP4) += $(omap-3-4-common) $(prcm-common) $(clock-common)
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
diff --git a/arch/arm/mach-omap2/clkt3xxx_dpll3m2.c b/arch/arm/mach-omap2/clkt3xxx_dpll3m2.c
new file mode 100644
index 0000000..14f1a4b
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt3xxx_dpll3m2.c
@@ -0,0 +1,120 @@
+/*
+ * OMAP3 M2 divider clock code
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
+ *
+ * Paul Walmsley
+ * Jouni H?gander
+ *
+ * Parts of this code are based on code written by
+ * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/sdrc.h>
+
+#include "clock.h"
+#include "clock34xx.h"
+#include "sdrc.h"
+
+#define CYCLES_PER_MHZ 1000000
+
+/*
+ * CORE DPLL (DPLL3) M2 divider rate programming functions
+ *
+ * These call into SRAM code to do the actual CM writes, since the SDRAM
+ * is clocked from DPLL3.
+ */
+
+/**
+ * omap3_core_dpll_m2_set_rate - set CORE DPLL M2 divider
+ * @clk: struct clk * of DPLL to set
+ * @rate: rounded target rate
+ *
+ * Program the DPLL M2 divider with the rounded target rate. Returns
+ * -EINVAL upon error, or 0 upon success.
+ */
+int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 new_div = 0;
+ u32 unlock_dll = 0;
+ u32 c;
+ unsigned long validrate, sdrcrate, _mpurate;
+ struct omap_sdrc_params *sdrc_cs0;
+ struct omap_sdrc_params *sdrc_cs1;
+ int ret;
+
+ if (!clk || !rate)
+ return -EINVAL;
+
+ validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
+ if (validrate != rate)
+ return -EINVAL;
+
+ sdrcrate = sdrc_ick_p->rate;
+ if (rate > clk->rate)
+ sdrcrate <<= ((rate / clk->rate) >> 1);
+ else
+ sdrcrate >>= ((clk->rate / rate) >> 1);
+
+ ret = omap2_sdrc_get_params(sdrcrate, &sdrc_cs0, &sdrc_cs1);
+ if (ret)
+ return -EINVAL;
+
+ if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) {
+ pr_debug("clock: will unlock SDRC DLL\n");
+ unlock_dll = 1;
+ }
+
+ /*
+ * XXX This only needs to be done when the CPU frequency changes
+ */
+ _mpurate = arm_fck_p->rate / CYCLES_PER_MHZ;
+ c = (_mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT;
+ c += 1; /* for safety */
+ c *= SDRC_MPURATE_LOOPS;
+ c >>= SDRC_MPURATE_SCALE;
+ if (c == 0)
+ c = 1;
+
+ pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
+ validrate);
+ pr_debug("clock: SDRC CS0 timing params used:"
+ " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
+ sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
+ sdrc_cs0->actim_ctrlb, sdrc_cs0->mr);
+ if (sdrc_cs1)
+ pr_debug("clock: SDRC CS1 timing params used: "
+ " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
+ sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
+ sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
+
+ if (sdrc_cs1)
+ omap3_configure_core_dpll(
+ new_div, unlock_dll, c, rate > clk->rate,
+ sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
+ sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
+ sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
+ sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
+ else
+ omap3_configure_core_dpll(
+ new_div, unlock_dll, c, rate > clk->rate,
+ sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
+ sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
+ 0, 0, 0, 0);
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 4c4bb3c..552ad30 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -42,8 +42,6 @@
#include "cm.h"
#include "cm-regbits-34xx.h"
-#define CYCLES_PER_MHZ 1000000
-
/*
* DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
* 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)
return omap3_noncore_dpll_set_rate(clk, rate);
}
-
-/*
- * CORE DPLL (DPLL3) rate programming functions
- *
- * These call into SRAM code to do the actual CM writes, since the SDRAM
- * is clocked from DPLL3.
- */
-
-/**
- * omap3_core_dpll_m2_set_rate - set CORE DPLL M2 divider
- * @clk: struct clk * of DPLL to set
- * @rate: rounded target rate
- *
- * Program the DPLL M2 divider with the rounded target rate. Returns
- * -EINVAL upon error, or 0 upon success.
- */
-int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 new_div = 0;
- u32 unlock_dll = 0;
- u32 c;
- unsigned long validrate, sdrcrate, _mpurate;
- struct omap_sdrc_params *sdrc_cs0;
- struct omap_sdrc_params *sdrc_cs1;
- int ret;
-
- if (!clk || !rate)
- return -EINVAL;
-
- validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
- if (validrate != rate)
- return -EINVAL;
-
- sdrcrate = sdrc_ick_p->rate;
- if (rate > clk->rate)
- sdrcrate <<= ((rate / clk->rate) >> 1);
- else
- sdrcrate >>= ((clk->rate / rate) >> 1);
-
- ret = omap2_sdrc_get_params(sdrcrate, &sdrc_cs0, &sdrc_cs1);
- if (ret)
- return -EINVAL;
-
- if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) {
- pr_debug("clock: will unlock SDRC DLL\n");
- unlock_dll = 1;
- }
-
- /*
- * XXX This only needs to be done when the CPU frequency changes
- */
- _mpurate = arm_fck_p->rate / CYCLES_PER_MHZ;
- c = (_mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT;
- c += 1; /* for safety */
- c *= SDRC_MPURATE_LOOPS;
- c >>= SDRC_MPURATE_SCALE;
- if (c == 0)
- c = 1;
-
- pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
- validrate);
- pr_debug("clock: SDRC CS0 timing params used:"
- " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
- sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
- sdrc_cs0->actim_ctrlb, sdrc_cs0->mr);
- if (sdrc_cs1)
- pr_debug("clock: SDRC CS1 timing params used: "
- " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
- sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
- sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
-
- if (sdrc_cs1)
- omap3_configure_core_dpll(
- new_div, unlock_dll, c, rate > clk->rate,
- sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
- sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
- sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
- sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
- else
- omap3_configure_core_dpll(
- new_div, unlock_dll, c, rate > clk->rate,
- sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
- sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
- 0, 0, 0, 0);
-
- return 0;
-}
-
/* Common clock code */
/*
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 13/18] OMAP2/3 clock: clean up omap*_clk_arch_init()
2010-01-19 23:35 [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up Paul Walmsley
` (11 preceding siblings ...)
2010-01-19 23:36 ` [PATCH v2 12/18] OMAP3 clock: split out DPLL3 M2 divider functions into mach-omap2/clkt3xxx_dpll3m2.c Paul Walmsley
@ 2010-01-19 23:36 ` Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 14/18] OMAP2/3 clock: remove unnecessary includes and clean up header Paul Walmsley
` (4 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Paul Walmsley @ 2010-01-19 23:36 UTC (permalink / raw)
To: linux-arm-kernel
In the OMAP3xxx clock code, remove the #ifdef CONFIG_ARCH_OMAP3 in
clock34xx.c, since this file is only compiled for OMAP3xxx builds. Also,
rename omap2_clk_arch_init in this file to omap3xxx_clk_arch_init() to
pave the way for multi-OMAP kernels. Ensure that it is not executed
on non-OMAP3xxx systems.
In the OMAP2xxx clock code, rename omap2_clk_arch_init in this file to
omap2xxx_clk_arch_init() to pave the way for multi-OMAP kernels.
Ensure that it is not executed on non-OMAP2xxx systems.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
arch/arm/mach-omap2/clock2xxx.c | 7 +++++--
arch/arm/mach-omap2/clock34xx.c | 16 +++++-----------
2 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c
index e5b9851..b7e81ec 100644
--- a/arch/arm/mach-omap2/clock2xxx.c
+++ b/arch/arm/mach-omap2/clock2xxx.c
@@ -101,11 +101,14 @@ void omap2_clk_prepare_for_reboot(void)
* Switch the MPU rate if specified on cmdline.
* We cannot do this early until cmdline is parsed.
*/
-static int __init omap2_clk_arch_init(void)
+static int __init omap2xxx_clk_arch_init(void)
{
struct clk *virt_prcm_set, *sys_ck, *dpll_ck, *mpu_ck;
unsigned long sys_ck_rate;
+ if (!cpu_is_omap24xx())
+ return 0;
+
if (!mpurate)
return -EINVAL;
@@ -129,6 +132,6 @@ static int __init omap2_clk_arch_init(void)
return 0;
}
-arch_initcall(omap2_clk_arch_init);
+arch_initcall(omap2xxx_clk_arch_init);
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 552ad30..d38ad44 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -163,12 +163,6 @@ int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
/* Common clock code */
/*
- * As it is structured now, this will prevent an OMAP2/3 multiboot
- * kernel from compiling. This will need further attention.
- */
-#if defined(CONFIG_ARCH_OMAP3)
-
-/*
* Set clocks for bypass mode for reboot to work.
*/
void omap2_clk_prepare_for_reboot(void)
@@ -213,11 +207,14 @@ void omap3_clk_lock_dpll5(void)
* Switch the MPU rate if specified on cmdline.
* We cannot do this early until cmdline is parsed.
*/
-static int __init omap2_clk_arch_init(void)
+static int __init omap3xxx_clk_arch_init(void)
{
struct clk *osc_sys_ck, *dpll1_ck, *arm_fck, *core_ck;
unsigned long osc_sys_rate;
+ if (!cpu_is_omap34xx())
+ return 0;
+
if (!mpurate)
return -EINVAL;
@@ -246,9 +243,6 @@ static int __init omap2_clk_arch_init(void)
return 0;
}
-arch_initcall(omap2_clk_arch_init);
-
-
-#endif
+arch_initcall(omap3xxx_clk_arch_init);
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 14/18] OMAP2/3 clock: remove unnecessary includes and clean up header
2010-01-19 23:35 [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up Paul Walmsley
` (12 preceding siblings ...)
2010-01-19 23:36 ` [PATCH v2 13/18] OMAP2/3 clock: clean up omap*_clk_arch_init() Paul Walmsley
@ 2010-01-19 23:36 ` Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 15/18] OMAP2/3/4 clock: omap2_clk_prepare_for_reboot() is OMAP2xxx-only Paul Walmsley
` (3 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Paul Walmsley @ 2010-01-19 23:36 UTC (permalink / raw)
To: linux-arm-kernel
Now that almost all of the code has been removed from clock2xxx.c and
clock34xx.c, many of the includes are now unnecessary and can be removed.
While we're here, standardize the initial comment blocks.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Richard Woodruff <r-woodruff2@ti.com>
Cc: Jouni H?gander <jouni.hogander@nokia.com>
---
arch/arm/mach-omap2/clock2xxx.c | 35 ++++++++++-------------------------
arch/arm/mach-omap2/clock34xx.c | 16 +++-------------
2 files changed, 13 insertions(+), 38 deletions(-)
diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c
index b7e81ec..e98f48b 100644
--- a/arch/arm/mach-omap2/clock2xxx.c
+++ b/arch/arm/mach-omap2/clock2xxx.c
@@ -1,15 +1,15 @@
/*
- * linux/arch/arm/mach-omap2/clock.c
+ * clock2xxx.c - OMAP2xxx-specific clock integration code
*
- * Copyright (C) 2005-2008 Texas Instruments, Inc.
- * Copyright (C) 2004-2008 Nokia Corporation
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
*
- * Contacts:
- * Richard Woodruff <r-woodruff2@ti.com>
- * Paul Walmsley
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
*
- * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
- * Gordon McNutt and RidgeRun, Inc.
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -17,38 +17,23 @@
*/
#undef DEBUG
-#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/list.h>
#include <linux/errno.h>
-#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/io.h>
-#include <linux/cpufreq.h>
-#include <linux/bitops.h>
#include <plat/clock.h>
-#include <plat/sram.h>
-#include <plat/prcm.h>
-#include <plat/clkdev_omap.h>
-#include <asm/div64.h>
-#include <asm/clkdev.h>
-#include <plat/sdrc.h>
#include "clock.h"
#include "clock2xxx.h"
-#include "opp2xxx.h"
-#include "prm.h"
-#include "prm-regbits-24xx.h"
#include "cm.h"
#include "cm-regbits-24xx.h"
struct clk *vclk, *sclk, *dclk;
-/*-------------------------------------------------------------------------
+/*
* Omap24xx specific clock functions
- *-------------------------------------------------------------------------*/
+ */
#ifdef CONFIG_ARCH_OMAP2430
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index d38ad44..8a7db7a 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -2,10 +2,10 @@
* OMAP3-specific clock framework functions
*
* Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2009 Nokia Corporation
+ * Copyright (C) 2007-2010 Nokia Corporation
*
- * Written by Paul Walmsley
- * Testing and integration fixes by Jouni H?gander
+ * Paul Walmsley
+ * Jouni H?gander
*
* Parts of this code are based on code written by
* Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
@@ -16,27 +16,17 @@
*/
#undef DEBUG
-#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/list.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/io.h>
-#include <linux/limits.h>
-#include <linux/bitops.h>
#include <plat/cpu.h>
#include <plat/clock.h>
-#include <plat/sram.h>
-#include <plat/sdrc.h>
-#include <asm/div64.h>
-#include <asm/clkdev.h>
#include "clock.h"
#include "clock34xx.h"
-#include "sdrc.h"
#include "prm.h"
#include "prm-regbits-34xx.h"
#include "cm.h"
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 15/18] OMAP2/3/4 clock: omap2_clk_prepare_for_reboot() is OMAP2xxx-only
2010-01-19 23:35 [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up Paul Walmsley
` (13 preceding siblings ...)
2010-01-19 23:36 ` [PATCH v2 14/18] OMAP2/3 clock: remove unnecessary includes and clean up header Paul Walmsley
@ 2010-01-19 23:36 ` Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 16/18] OMAP3 DPLL: reorganize static functions Paul Walmsley
` (2 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Paul Walmsley @ 2010-01-19 23:36 UTC (permalink / raw)
To: linux-arm-kernel
omap2_clk_prepare_for_reboot() is only applicable to OMAP2xxx chips,
so rename it to omap2xxx_clk_prepare_for_reboot() and only call it when
running on OMAP2xxx chips. Remove the old stub in the OMAP3 clock code.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
arch/arm/mach-omap2/clock.h | 1 -
arch/arm/mach-omap2/clock2xxx.c | 2 +-
arch/arm/mach-omap2/clock2xxx.h | 1 +
arch/arm/mach-omap2/clock34xx.c | 21 ++-------------------
arch/arm/mach-omap2/clock44xx.c | 5 -----
arch/arm/mach-omap2/prcm.c | 8 +++++---
6 files changed, 9 insertions(+), 29 deletions(-)
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index dcd58cd..be5a55f 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -84,7 +84,6 @@ int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent);
u32 omap2_get_dpll_rate(struct clk *clk);
void omap2_init_dpll_parent(struct clk *clk);
int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name);
-void omap2_clk_prepare_for_reboot(void);
int omap2_dflt_clk_enable(struct clk *clk);
void omap2_dflt_clk_disable(struct clk *clk);
void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c
index e98f48b..a48b01a 100644
--- a/arch/arm/mach-omap2/clock2xxx.c
+++ b/arch/arm/mach-omap2/clock2xxx.c
@@ -71,7 +71,7 @@ const struct clkops clkops_omap2430_i2chs_wait = {
/*
* Set clocks for bypass mode for reboot to work.
*/
-void omap2_clk_prepare_for_reboot(void)
+void omap2xxx_clk_prepare_for_reboot(void)
{
u32 rate;
diff --git a/arch/arm/mach-omap2/clock2xxx.h b/arch/arm/mach-omap2/clock2xxx.h
index c14061b..bed294a 100644
--- a/arch/arm/mach-omap2/clock2xxx.h
+++ b/arch/arm/mach-omap2/clock2xxx.h
@@ -18,6 +18,7 @@ int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate);
unsigned long omap2xxx_clk_get_core_rate(struct clk *clk);
u32 omap2xxx_get_apll_clkin(void);
u32 omap2xxx_get_sysclkdiv(void);
+void omap2xxx_clk_prepare_for_reboot(void);
/* REVISIT: These should be set dynamically for CONFIG_MULTI_OMAP2 */
#ifdef CONFIG_ARCH_OMAP2420
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 8a7db7a..34d3950 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -150,25 +150,6 @@ int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
return omap3_noncore_dpll_set_rate(clk, rate);
}
-/* Common clock code */
-
-/*
- * Set clocks for bypass mode for reboot to work.
- */
-void omap2_clk_prepare_for_reboot(void)
-{
- /* REVISIT: Not ready for 343x */
-#if 0
- u32 rate;
-
- if (vclk == NULL || sclk == NULL)
- return;
-
- rate = clk_get_rate(sclk);
- clk_set_rate(vclk, rate);
-#endif
-}
-
void omap3_clk_lock_dpll5(void)
{
struct clk *dpll5_clk;
@@ -191,6 +172,8 @@ void omap3_clk_lock_dpll5(void)
return;
}
+/* Common clock code */
+
/* REVISIT: Move this init stuff out into clock.c */
/*
diff --git a/arch/arm/mach-omap2/clock44xx.c b/arch/arm/mach-omap2/clock44xx.c
index 08dd642..c238717 100644
--- a/arch/arm/mach-omap2/clock44xx.c
+++ b/arch/arm/mach-omap2/clock44xx.c
@@ -17,8 +17,3 @@ const struct clkops clkops_noncore_dpll_ops = {
.enable = &omap3_noncore_dpll_enable,
.disable = &omap3_noncore_dpll_disable,
};
-
-void omap2_clk_prepare_for_reboot(void)
-{
- return;
-}
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
index 63330d2..814376a 100644
--- a/arch/arm/mach-omap2/prcm.c
+++ b/arch/arm/mach-omap2/prcm.c
@@ -29,6 +29,7 @@
#include <plat/control.h>
#include "clock.h"
+#include "clock2xxx.h"
#include "cm.h"
#include "prm.h"
#include "prm-regbits-24xx.h"
@@ -136,11 +137,12 @@ EXPORT_SYMBOL(omap_prcm_get_reset_sources);
void omap_prcm_arch_reset(char mode)
{
s16 prcm_offs;
- omap2_clk_prepare_for_reboot();
- if (cpu_is_omap24xx())
+ if (cpu_is_omap24xx()) {
+ omap2xxx_clk_prepare_for_reboot();
+
prcm_offs = WKUP_MOD;
- else if (cpu_is_omap34xx()) {
+ } else if (cpu_is_omap34xx()) {
u32 l;
prcm_offs = OMAP3430_GR_MOD;
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 16/18] OMAP3 DPLL: reorganize static functions
2010-01-19 23:35 [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up Paul Walmsley
` (14 preceding siblings ...)
2010-01-19 23:36 ` [PATCH v2 15/18] OMAP2/3/4 clock: omap2_clk_prepare_for_reboot() is OMAP2xxx-only Paul Walmsley
@ 2010-01-19 23:36 ` Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 17/18] OMAP clock: resolve all remaining sparse warnings Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 18/18] OMAP2/3/4 clock: rename and clean the omap2_clk_init() functions Paul Walmsley
17 siblings, 0 replies; 19+ messages in thread
From: Paul Walmsley @ 2010-01-19 23:36 UTC (permalink / raw)
To: linux-arm-kernel
Move all static functions up to the top of the file to match the
practice in other OMAP clock code. Make omap3_noncore_dpll_program()
static (noted by sparse) and prepend an underscore to the function
name to mark that it is file-local.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
arch/arm/mach-omap2/dpll3xxx.c | 113 +++++++++++++++++++++-------------------
1 files changed, 58 insertions(+), 55 deletions(-)
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
index f6055b4..2b559fc 100644
--- a/arch/arm/mach-omap2/dpll3xxx.c
+++ b/arch/arm/mach-omap2/dpll3xxx.c
@@ -44,17 +44,7 @@
#define MAX_DPLL_WAIT_TRIES 1000000
-
-/**
- * omap3_dpll_recalc - recalculate DPLL rate
- * @clk: DPLL struct clk
- *
- * Recalculate and propagate the DPLL rate.
- */
-unsigned long omap3_dpll_recalc(struct clk *clk)
-{
- return omap2_get_dpll_rate(clk);
-}
+/* Private functions */
/* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */
static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits)
@@ -136,8 +126,6 @@ static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
return f;
}
-/* Non-CORE DPLL (e.g., DPLLs that do not control SDRC) clock functions */
-
/*
* _omap3_noncore_dpll_lock - instruct a DPLL to lock and wait for readiness
* @clk: pointer to a DPLL struct clk
@@ -237,6 +225,63 @@ static int _omap3_noncore_dpll_stop(struct clk *clk)
return 0;
}
+/*
+ * _omap3_noncore_dpll_program - set non-core DPLL M,N values directly
+ * @clk: struct clk * of DPLL to set
+ * @m: DPLL multiplier to set
+ * @n: DPLL divider to set
+ * @freqsel: FREQSEL value to set
+ *
+ * Program the DPLL with the supplied M, N values, and wait for the DPLL to
+ * lock.. Returns -EINVAL upon error, or 0 upon success.
+ */
+static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
+{
+ struct dpll_data *dd = clk->dpll_data;
+ u32 v;
+
+ /* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */
+ _omap3_noncore_dpll_bypass(clk);
+
+ /* Set jitter correction */
+ if (!cpu_is_omap44xx()) {
+ v = __raw_readl(dd->control_reg);
+ v &= ~dd->freqsel_mask;
+ v |= freqsel << __ffs(dd->freqsel_mask);
+ __raw_writel(v, dd->control_reg);
+ }
+
+ /* Set DPLL multiplier, divider */
+ v = __raw_readl(dd->mult_div1_reg);
+ v &= ~(dd->mult_mask | dd->div1_mask);
+ v |= m << __ffs(dd->mult_mask);
+ v |= (n - 1) << __ffs(dd->div1_mask);
+ __raw_writel(v, dd->mult_div1_reg);
+
+ /* We let the clock framework set the other output dividers later */
+
+ /* REVISIT: Set ramp-up delay? */
+
+ _omap3_noncore_dpll_lock(clk);
+
+ return 0;
+}
+
+/* Public functions */
+
+/**
+ * omap3_dpll_recalc - recalculate DPLL rate
+ * @clk: DPLL struct clk
+ *
+ * Recalculate and propagate the DPLL rate.
+ */
+unsigned long omap3_dpll_recalc(struct clk *clk)
+{
+ return omap2_get_dpll_rate(clk);
+}
+
+/* Non-CORE DPLL (e.g., DPLLs that do not control SDRC) clock functions */
+
/**
* omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode
* @clk: pointer to a DPLL struct clk
@@ -292,48 +337,6 @@ void omap3_noncore_dpll_disable(struct clk *clk)
/* Non-CORE DPLL rate set code */
-/*
- * omap3_noncore_dpll_program - set non-core DPLL M,N values directly
- * @clk: struct clk * of DPLL to set
- * @m: DPLL multiplier to set
- * @n: DPLL divider to set
- * @freqsel: FREQSEL value to set
- *
- * Program the DPLL with the supplied M, N values, and wait for the DPLL to
- * lock.. Returns -EINVAL upon error, or 0 upon success.
- */
-int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
-{
- struct dpll_data *dd = clk->dpll_data;
- u32 v;
-
- /* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */
- _omap3_noncore_dpll_bypass(clk);
-
- /* Set jitter correction */
- if (!cpu_is_omap44xx()) {
- v = __raw_readl(dd->control_reg);
- v &= ~dd->freqsel_mask;
- v |= freqsel << __ffs(dd->freqsel_mask);
- __raw_writel(v, dd->control_reg);
- }
-
- /* Set DPLL multiplier, divider */
- v = __raw_readl(dd->mult_div1_reg);
- v &= ~(dd->mult_mask | dd->div1_mask);
- v |= m << __ffs(dd->mult_mask);
- v |= (n - 1) << __ffs(dd->div1_mask);
- __raw_writel(v, dd->mult_div1_reg);
-
- /* We let the clock framework set the other output dividers later */
-
- /* REVISIT: Set ramp-up delay? */
-
- _omap3_noncore_dpll_lock(clk);
-
- return 0;
-}
-
/**
* omap3_noncore_dpll_set_rate - set non-core DPLL rate
* @clk: struct clk * of DPLL to set
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 17/18] OMAP clock: resolve all remaining sparse warnings
2010-01-19 23:35 [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up Paul Walmsley
` (15 preceding siblings ...)
2010-01-19 23:36 ` [PATCH v2 16/18] OMAP3 DPLL: reorganize static functions Paul Walmsley
@ 2010-01-19 23:36 ` Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 18/18] OMAP2/3/4 clock: rename and clean the omap2_clk_init() functions Paul Walmsley
17 siblings, 0 replies; 19+ messages in thread
From: Paul Walmsley @ 2010-01-19 23:36 UTC (permalink / raw)
To: linux-arm-kernel
Resolve all remaining sparse warnings in the OMAP clock code.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
arch/arm/plat-omap/clock.c | 2 +-
arch/arm/plat-omap/include/plat/clock.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index e0f72f4..0ae2753 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -173,7 +173,7 @@ EXPORT_SYMBOL(clk_get_parent);
* OMAP specific clock functions shared between omap1 and omap2
*-------------------------------------------------------------------------*/
-unsigned int __initdata mpurate;
+int __initdata mpurate;
/*
* By default we use the rate set by the bootloader.
diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h
index 896cedc..e413132 100644
--- a/arch/arm/plat-omap/include/plat/clock.h
+++ b/arch/arm/plat-omap/include/plat/clock.h
@@ -123,7 +123,7 @@ struct clk_functions {
#endif
};
-extern unsigned int mpurate;
+extern int mpurate;
extern int clk_init(struct clk_functions *custom_clocks);
extern void clk_preinit(struct clk *clk);
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 18/18] OMAP2/3/4 clock: rename and clean the omap2_clk_init() functions
2010-01-19 23:35 [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up Paul Walmsley
` (16 preceding siblings ...)
2010-01-19 23:36 ` [PATCH v2 17/18] OMAP clock: resolve all remaining sparse warnings Paul Walmsley
@ 2010-01-19 23:36 ` Paul Walmsley
17 siblings, 0 replies; 19+ messages in thread
From: Paul Walmsley @ 2010-01-19 23:36 UTC (permalink / raw)
To: linux-arm-kernel
Rename the omap2_clk_init() in the OMAP2, 3, and 4 clock code to be
omap2xxx_clk_init(), omap3xxx_clk_init(), etc. Remove all traces of
the (commented) old virt_prcm_set code from omap3xxx_clk_init() and
omap4xxx_clk_init(), since this will be handled with the OPP code that
is cooking in the PM branch.
After this patch, there should be very little else in the clock code
that blocks a multi-OMAP 2+3 kernel. (OMAP2420+OMAP2430 still has some
outstanding issues that need to be resolved; this is pending on some
additions to the hwmod data.)
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
arch/arm/mach-omap2/clock.h | 1 -
arch/arm/mach-omap2/clock2xxx.h | 1 +
arch/arm/mach-omap2/clock2xxx_data.c | 2 +-
arch/arm/mach-omap2/clock34xx.c | 2 +-
arch/arm/mach-omap2/clock34xx.h | 1 +
arch/arm/mach-omap2/clock34xx_data.c | 19 +------------------
arch/arm/mach-omap2/clock44xx.h | 2 ++
arch/arm/mach-omap2/clock44xx_data.c | 4 +---
arch/arm/mach-omap2/io.c | 15 +++++++++++++--
9 files changed, 21 insertions(+), 26 deletions(-)
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index be5a55f..7bc344b 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -47,7 +47,6 @@
#define DPLL_LOW_POWER_BYPASS 0x5
#define DPLL_LOCKED 0x7
-int omap2_clk_init(void);
int omap2_clk_enable(struct clk *clk);
void omap2_clk_disable(struct clk *clk);
long omap2_clk_round_rate(struct clk *clk, unsigned long rate);
diff --git a/arch/arm/mach-omap2/clock2xxx.h b/arch/arm/mach-omap2/clock2xxx.h
index bed294a..32f3d0a 100644
--- a/arch/arm/mach-omap2/clock2xxx.h
+++ b/arch/arm/mach-omap2/clock2xxx.h
@@ -19,6 +19,7 @@ unsigned long omap2xxx_clk_get_core_rate(struct clk *clk);
u32 omap2xxx_get_apll_clkin(void);
u32 omap2xxx_get_sysclkdiv(void);
void omap2xxx_clk_prepare_for_reboot(void);
+int omap2xxx_clk_init(void);
/* REVISIT: These should be set dynamically for CONFIG_MULTI_OMAP2 */
#ifdef CONFIG_ARCH_OMAP2420
diff --git a/arch/arm/mach-omap2/clock2xxx_data.c b/arch/arm/mach-omap2/clock2xxx_data.c
index 3a435bb..52c7a6c 100644
--- a/arch/arm/mach-omap2/clock2xxx_data.c
+++ b/arch/arm/mach-omap2/clock2xxx_data.c
@@ -2238,7 +2238,7 @@ static struct omap_clk omap24xx_clks[] = {
* init code
*/
-int __init omap2_clk_init(void)
+int __init omap2xxx_clk_init(void)
{
const struct prcm_config *prcm;
struct omap_clk *c;
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 34d3950..1f1b5a6 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -150,7 +150,7 @@ int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
return omap3_noncore_dpll_set_rate(clk, rate);
}
-void omap3_clk_lock_dpll5(void)
+void __init omap3_clk_lock_dpll5(void)
{
struct clk *dpll5_clk;
struct clk *dpll5_m2_clk;
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
index 9a2c07e..73f2109 100644
--- a/arch/arm/mach-omap2/clock34xx.h
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -8,6 +8,7 @@
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_34XX_H
#define __ARCH_ARM_MACH_OMAP2_CLOCK_34XX_H
+int omap3xxx_clk_init(void);
int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate);
int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate);
void omap3_clk_lock_dpll5(void);
diff --git a/arch/arm/mach-omap2/clock34xx_data.c b/arch/arm/mach-omap2/clock34xx_data.c
index 9e7f68a..0d04f92 100644
--- a/arch/arm/mach-omap2/clock34xx_data.c
+++ b/arch/arm/mach-omap2/clock34xx_data.c
@@ -3212,11 +3212,9 @@ static struct omap_clk omap3xxx_clks[] = {
};
-int __init omap2_clk_init(void)
+int __init omap3xxx_clk_init(void)
{
- /* struct prcm_config *prcm; */
struct omap_clk *c;
- /* u32 clkrate; */
u32 cpu_clkflg = CK_3XXX;
if (cpu_is_omap3517()) {
@@ -3254,21 +3252,6 @@ int __init omap2_clk_init(void)
omap2_init_clk_clkdm(c->lk.clk);
}
- /* REVISIT: Not yet ready for OMAP3 */
-#if 0
- /* Check the MPU rate set by bootloader */
- clkrate = omap2_get_dpll_rate_24xx(&dpll_ck);
- for (prcm = rate_table; prcm->mpu_speed; prcm++) {
- if (!(prcm->flags & cpu_mask))
- continue;
- if (prcm->xtal_speed != sys_ck.rate)
- continue;
- if (prcm->dpll_speed <= clkrate)
- break;
- }
- curr_prcm_set = prcm;
-#endif
-
recalculate_root_clocks();
printk(KERN_INFO "Clocking rate (Crystal/Core/MPU): "
diff --git a/arch/arm/mach-omap2/clock44xx.h b/arch/arm/mach-omap2/clock44xx.h
index 59b9ced..1f55b6b 100644
--- a/arch/arm/mach-omap2/clock44xx.h
+++ b/arch/arm/mach-omap2/clock44xx.h
@@ -10,6 +10,8 @@
#define OMAP4430_MAX_DPLL_MULT 2048
#define OMAP4430_MAX_DPLL_DIV 128
+int omap4xxx_clk_init(void);
+
extern const struct clkops clkops_noncore_dpll_ops;
#endif
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index ae9649f..35ffe63 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -2726,11 +2726,9 @@ static struct omap_clk omap44xx_clks[] = {
CLK(NULL, "utmi_p2_gfclk_ck", &utmi_p2_gfclk_ck, CK_443X),
};
-int __init omap2_clk_init(void)
+int __init omap4xxx_clk_init(void)
{
- /* struct prcm_config *prcm; */
struct omap_clk *c;
- /* u32 clkrate; */
u32 cpu_clkflg;
if (cpu_is_omap44xx()) {
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 8c58699..01ef2ae 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -35,7 +35,9 @@
#include <plat/serial.h>
#include <plat/vram.h>
-#include "clock.h"
+#include "clock2xxx.h"
+#include "clock34xx.h"
+#include "clock44xx.h"
#include <plat/omap-pm.h>
#include <plat/powerdomain.h>
@@ -320,7 +322,16 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
omap2_mux_init();
omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps);
#endif
- omap2_clk_init();
+
+ if (cpu_is_omap24xx())
+ omap2xxx_clk_init();
+ else if (cpu_is_omap34xx())
+ omap3xxx_clk_init();
+ else if (cpu_is_omap44xx())
+ omap4xxx_clk_init();
+ else
+ pr_err("Could not init clock framework - unknown CPU\n");
+
omap_serial_early_init();
#ifndef CONFIG_ARCH_OMAP4
omap_hwmod_late_init();
^ permalink raw reply related [flat|nested] 19+ messages in thread
end of thread, other threads:[~2010-01-19 23:36 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-19 23:35 [PATCH v2 00/18] OMAP2/3/4 clock: split out code for clock types and clean up Paul Walmsley
2010-01-19 23:35 ` [PATCH v2 01/18] OMAP3 clock: move OMAP3-specific DPLL functions to dpll3xxx.c Paul Walmsley
2010-01-19 23:35 ` [PATCH v2 02/18] OMAP2/3/4 clock: move DPLL clock functions into mach-omap2/clkt_dpll.c Paul Walmsley
2010-01-19 23:35 ` [PATCH v2 03/18] OMAP2/3/4 clock: move clksel clock functions into mach-omap2/clkt_clksel.c Paul Walmsley
2010-01-19 23:35 ` [PATCH v2 04/18] OMAP2 clock: move all static functions to the top of the file Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 05/18] OMAP2/3/4 clock: combine all omap2_clk_functions Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 06/18] OMAP2xxx clock: move the DPLL+CORE composite clock code into mach-omap2/clkt2xxx_dpllcore.c Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 07/18] OMAP2xxx clock: move the DVFS virtual clock code into mach-omap2/clkt2xxx_virt_prcm_set.c Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 08/18] OMAP2xxx clock: move the APLL clock code into mach-omap2/clkt2xxx_apll.c Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 09/18] OMAP2xxx clock: move osc_clk code into mach-omap2/clkt2xxx_osc.c Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 10/18] OMAP2xxx clock: move sys_clk code into mach-omap2/clkt2xxx_sys.c Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 11/18] OMAP2 clock: don't compile OMAP2430-only functions on non-2430 builds Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 12/18] OMAP3 clock: split out DPLL3 M2 divider functions into mach-omap2/clkt3xxx_dpll3m2.c Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 13/18] OMAP2/3 clock: clean up omap*_clk_arch_init() Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 14/18] OMAP2/3 clock: remove unnecessary includes and clean up header Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 15/18] OMAP2/3/4 clock: omap2_clk_prepare_for_reboot() is OMAP2xxx-only Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 16/18] OMAP3 DPLL: reorganize static functions Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 17/18] OMAP clock: resolve all remaining sparse warnings Paul Walmsley
2010-01-19 23:36 ` [PATCH v2 18/18] OMAP2/3/4 clock: rename and clean the omap2_clk_init() functions Paul Walmsley
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).