aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/clkt2xxx_dpllcore.c')
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_dpllcore.c62
1 files changed, 42 insertions, 20 deletions
diff --git a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
index 4ae43922208..59cf310bc1e 100644
--- a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
+++ b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
@@ -25,21 +25,25 @@
#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 "cm2xxx_3xxx.h"
+#include "cm2xxx.h"
#include "cm-regbits-24xx.h"
+#include "sdrc.h"
+#include "sram.h"
/* #define DOWN_VARIABLE_DPLL 1 */ /* Experimental */
+/*
+ * dpll_core_ck: pointer to the combined dpll_ck + core_ck on OMAP2xxx
+ * (currently defined as "dpll_ck" in the OMAP2xxx clock tree). Set
+ * during dpll_ck init and used later by omap2xxx_clk_get_core_rate().
+ */
+static struct clk_hw_omap *dpll_core_ck;
+
/**
* 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
@@ -47,15 +51,16 @@
* 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)
+unsigned long omap2xxx_clk_get_core_rate(void)
{
long long core_clk;
u32 v;
- core_clk = omap2_get_dpll_rate(clk);
+ WARN_ON(!dpll_core_ck);
+
+ core_clk = omap2_get_dpll_rate(dpll_core_ck);
- v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
- v &= OMAP24XX_CORE_CLK_SRC_MASK;
+ v = omap2xxx_cm_get_core_clk_src();
if (v == CORE_CLK_SRC_32K)
core_clk = 32768;
@@ -73,8 +78,7 @@ static long omap2_dpllcore_round_rate(unsigned long target_rate)
{
u32 high, low, core_clk_src;
- core_clk_src = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
- core_clk_src &= OMAP24XX_CORE_CLK_SRC_MASK;
+ core_clk_src = omap2xxx_cm_get_core_clk_src();
if (core_clk_src == CORE_CLK_SRC_DPLL) { /* DPLL clockout */
high = curr_prcm_set->dpll_speed * 2;
@@ -98,21 +102,23 @@ static long omap2_dpllcore_round_rate(unsigned long target_rate)
}
-unsigned long omap2_dpllcore_recalc(struct clk *clk)
+unsigned long omap2_dpllcore_recalc(struct clk_hw *hw,
+ unsigned long parent_rate)
{
- return omap2xxx_clk_get_core_rate(clk);
+ return omap2xxx_clk_get_core_rate();
}
-int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
+int omap2_reprogram_dpllcore(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
{
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
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 = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
- mult &= OMAP24XX_CORE_CLK_SRC_MASK;
+ cur_rate = omap2xxx_clk_get_core_rate();
+ mult = omap2xxx_cm_get_core_clk_src();
if ((rate == (cur_rate / 2)) && (mult == 2)) {
omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
@@ -132,11 +138,11 @@ int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
if (!dd)
return -EINVAL;
- tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg);
+ tmpset.cm_clksel1_pll = readl_relaxed(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 = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+ tmpset.cm_clksel2_pll = omap2xxx_cm_get_core_pll_config();
tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK;
if (rate > low) {
tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2;
@@ -171,3 +177,19 @@ int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
return 0;
}
+/**
+ * omap2xxx_clkt_dpllcore_init - clk init function for dpll_ck
+ * @clk: struct clk *dpll_ck
+ *
+ * Store a local copy of @clk in dpll_core_ck so other code can query
+ * the core rate without having to clk_get(), which can sleep. Must
+ * only be called once. No return value. XXX If the clock
+ * registration process is ever changed such that dpll_ck is no longer
+ * statically defined, this code may need to change to increment some
+ * kind of use count on dpll_ck.
+ */
+void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw)
+{
+ WARN(dpll_core_ck, "dpll_core_ck already set - should never happen");
+ dpll_core_ck = to_clk_hw_omap(hw);
+}