Commit 12706c54 authored by Paul Walmsley's avatar Paul Walmsley

OMAP2+: clock: allow per-SoC clock init code to prevent clockdomain calls from clock code

The OMAP2/3 clock code was written to notify the clockdomain code when
the first clock in a clockdomain is enabled and when the last enabled
clock in a clockdomain is disabled.  OMAP4 requires a different
approach: the hwmod code needs to signal the clockdomain code when to
force-enable and auto-idle a clockdomain during the IP block enable
process.  The current conjecture is that once that hwmod sequence is
implemented, it will no longer be necessary for the clock code to call
into the clockdomain code for "optional clocks" on OMAP4.

Add a static flag to the OMAP2+ clock code, clkdm_control, that by
default preserves the OMAP2/3 behavior.  Also add a function,
omap2_clk_disable_clkdm_control(), intended to be called from OMAP4
and beyond clock initcalls, that disables the old behavior.

Part of this patch was originally based on a patch by Rajendra Nayak
<rnayak@ti.com>.
Signed-off-by: default avatarPaul Walmsley <paul@pwsan.com>
Cc: Benoît Cousson <b-cousson@ti.com>
Cc: Rajendra Nayak <rnayak@ti.com>

parent 555e74ea
...@@ -37,6 +37,14 @@ ...@@ -37,6 +37,14 @@
u8 cpu_mask; u8 cpu_mask;
/*
* clkdm_control: if true, then when a clock is enabled in the
* hardware, its clockdomain will first be enabled; and when a clock
* is disabled in the hardware, its clockdomain will be disabled
* afterwards.
*/
static bool clkdm_control = true;
/* /*
* OMAP2+ specific clock functions * OMAP2+ specific clock functions
*/ */
...@@ -99,6 +107,19 @@ void omap2_init_clk_clkdm(struct clk *clk) ...@@ -99,6 +107,19 @@ void omap2_init_clk_clkdm(struct clk *clk)
} }
} }
/**
* omap2_clk_disable_clkdm_control - disable clkdm control on clk enable/disable
*
* Prevent the OMAP clock code from calling into the clockdomain code
* when a hardware clock in that clockdomain is enabled or disabled.
* Intended to be called at init time from omap*_clk_init(). No
* return value.
*/
void __init omap2_clk_disable_clkdm_control(void)
{
clkdm_control = false;
}
/** /**
* omap2_clk_dflt_find_companion - find companion clock to @clk * omap2_clk_dflt_find_companion - find companion clock to @clk
* @clk: struct clk * to find the companion clock of * @clk: struct clk * to find the companion clock of
...@@ -268,7 +289,7 @@ void omap2_clk_disable(struct clk *clk) ...@@ -268,7 +289,7 @@ void omap2_clk_disable(struct clk *clk)
clk->ops->disable(clk); clk->ops->disable(clk);
} }
if (clk->clkdm) if (clkdm_control && clk->clkdm)
clkdm_clk_disable(clk->clkdm, clk); clkdm_clk_disable(clk->clkdm, clk);
if (clk->parent) if (clk->parent)
...@@ -308,7 +329,7 @@ int omap2_clk_enable(struct clk *clk) ...@@ -308,7 +329,7 @@ int omap2_clk_enable(struct clk *clk)
} }
} }
if (clk->clkdm) { if (clkdm_control && clk->clkdm) {
ret = clkdm_clk_enable(clk->clkdm, clk); ret = clkdm_clk_enable(clk->clkdm, clk);
if (ret) { if (ret) {
WARN(1, "clock: %s: could not enable clockdomain %s: " WARN(1, "clock: %s: could not enable clockdomain %s: "
...@@ -330,7 +351,7 @@ int omap2_clk_enable(struct clk *clk) ...@@ -330,7 +351,7 @@ int omap2_clk_enable(struct clk *clk)
return 0; return 0;
oce_err3: oce_err3:
if (clk->clkdm) if (clkdm_control && clk->clkdm)
clkdm_clk_disable(clk->clkdm, clk); clkdm_clk_disable(clk->clkdm, clk);
oce_err2: oce_err2:
if (clk->parent) if (clk->parent)
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_H #ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_H
#define __ARCH_ARM_MACH_OMAP2_CLOCK_H #define __ARCH_ARM_MACH_OMAP2_CLOCK_H
#include <linux/kernel.h>
#include <plat/clock.h> #include <plat/clock.h>
/* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */ /* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */
...@@ -72,6 +74,7 @@ void omap2_clk_disable_unused(struct clk *clk); ...@@ -72,6 +74,7 @@ void omap2_clk_disable_unused(struct clk *clk);
#endif #endif
void omap2_init_clk_clkdm(struct clk *clk); void omap2_init_clk_clkdm(struct clk *clk);
void __init omap2_clk_disable_clkdm_control(void);
/* clkt_clksel.c public functions */ /* clkt_clksel.c public functions */
u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate, u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment