diff options
Diffstat (limited to 'arch')
50 files changed, 2209 insertions, 1064 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 8ef8711..534d89a 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -102,25 +102,31 @@ obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common) \ # PRCM clockdomain control obj-$(CONFIG_ARCH_OMAP2) += clockdomain.o \ + clockdomain2xxx_3xxx.o \ clockdomains2xxx_3xxx_data.o obj-$(CONFIG_ARCH_OMAP3) += clockdomain.o \ + clockdomain2xxx_3xxx.o \ clockdomains2xxx_3xxx_data.o obj-$(CONFIG_ARCH_OMAP4) += clockdomain.o \ + clockdomain44xx.o \ clockdomains44xx_data.o + # Clock framework obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o \ clkt2xxx_sys.o \ clkt2xxx_dpllcore.o \ clkt2xxx_virt_prcm_set.o \ - clkt2xxx_apll.o clkt2xxx_osc.o + clkt2xxx_apll.o clkt2xxx_osc.o \ + clkt2xxx_dpll.o clkt_iclk.o obj-$(CONFIG_SOC_OMAP2420) += clock2420_data.o obj-$(CONFIG_SOC_OMAP2430) += clock2430.o clock2430_data.o obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o \ clock34xx.o clkt34xx_dpll3m2.o \ clock3517.o clock36xx.o \ - dpll3xxx.o clock3xxx_data.o + dpll3xxx.o clock3xxx_data.o \ + clkt_iclk.o obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) clock44xx_data.o \ - dpll3xxx.o + dpll3xxx.o dpll44xx.o # OMAP2 clock rate set data (old "OPP" data) obj-$(CONFIG_SOC_OMAP2420) += opp2420_data.o diff --git a/arch/arm/mach-omap2/clkt2xxx_apll.c b/arch/arm/mach-omap2/clkt2xxx_apll.c index f51cffd..b19a1f7 100644 --- a/arch/arm/mach-omap2/clkt2xxx_apll.c +++ b/arch/arm/mach-omap2/clkt2xxx_apll.c @@ -78,6 +78,26 @@ static int omap2_clk_apll54_enable(struct clk *clk) return omap2_clk_apll_enable(clk, OMAP24XX_ST_54M_APLL_MASK); } +static void _apll96_allow_idle(struct clk *clk) +{ + omap2xxx_cm_set_apll96_auto_low_power_stop(); +} + +static void _apll96_deny_idle(struct clk *clk) +{ + omap2xxx_cm_set_apll96_disable_autoidle(); +} + +static void _apll54_allow_idle(struct clk *clk) +{ + omap2xxx_cm_set_apll54_auto_low_power_stop(); +} + +static void _apll54_deny_idle(struct clk *clk) +{ + omap2xxx_cm_set_apll54_disable_autoidle(); +} + /* Stop APLL */ static void omap2_clk_apll_disable(struct clk *clk) { @@ -93,11 +113,15 @@ static void omap2_clk_apll_disable(struct clk *clk) const struct clkops clkops_apll96 = { .enable = omap2_clk_apll96_enable, .disable = omap2_clk_apll_disable, + .allow_idle = _apll96_allow_idle, + .deny_idle = _apll96_deny_idle, }; const struct clkops clkops_apll54 = { .enable = omap2_clk_apll54_enable, .disable = omap2_clk_apll_disable, + .allow_idle = _apll54_allow_idle, + .deny_idle = _apll54_deny_idle, }; /* Public functions */ diff --git a/arch/arm/mach-omap2/clkt2xxx_dpll.c b/arch/arm/mach-omap2/clkt2xxx_dpll.c new file mode 100644 index 0000000..1502a7b --- /dev/null +++ b/arch/arm/mach-omap2/clkt2xxx_dpll.c @@ -0,0 +1,63 @@ +/* + * OMAP2-specific DPLL control functions + * + * Copyright (C) 2011 Nokia Corporation + * 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. + */ + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/clk.h> +#include <linux/io.h> + +#include <plat/clock.h> + +#include "clock.h" +#include "cm2xxx_3xxx.h" +#include "cm-regbits-24xx.h" + +/* Private functions */ + +/** + * _allow_idle - enable DPLL autoidle bits + * @clk: struct clk * of the DPLL to operate on + * + * Enable DPLL automatic idle control. The DPLL will enter low-power + * stop when its downstream clocks are gated. No return value. + * REVISIT: DPLL can optionally enter low-power bypass by writing 0x1 + * instead. Add some mechanism to optionally enter this mode. + */ +static void _allow_idle(struct clk *clk) +{ + if (!clk || !clk->dpll_data) + return; + + omap2xxx_cm_set_dpll_auto_low_power_stop(); +} + +/** + * _deny_idle - prevent DPLL from automatically idling + * @clk: struct clk * of the DPLL to operate on + * + * Disable DPLL automatic idle control. No return value. + */ +static void _deny_idle(struct clk *clk) +{ + if (!clk || !clk->dpll_data) + return; + + omap2xxx_cm_set_dpll_disable_autoidle(); +} + + +/* Public data */ + +const struct clkops clkops_omap2xxx_dpll_ops = { + .allow_idle = _allow_idle, + .deny_idle = _deny_idle, +}; + diff --git a/arch/arm/mach-omap2/clkt2xxx_osc.c b/arch/arm/mach-omap2/clkt2xxx_osc.c index df7b805..c346092 100644 --- a/arch/arm/mach-omap2/clkt2xxx_osc.c +++ b/arch/arm/mach-omap2/clkt2xxx_osc.c @@ -30,6 +30,13 @@ #include "prm2xxx_3xxx.h" #include "prm-regbits-24xx.h" +/* + * XXX This does not actually enable the osc_ck, since the osc_ck must + * be running for this function to be called. Instead, this function + * is used to disable an autoidle mode on the osc_ck. The existing + * clk_enable/clk_disable()-based usecounting for osc_ck should be + * replaced with autoidle-based usecounting. + */ static int omap2_enable_osc_ck(struct clk *clk) { u32 pcc; @@ -41,6 +48,13 @@ static int omap2_enable_osc_ck(struct clk *clk) return 0; } +/* + * XXX This does not actually disable the osc_ck, since doing so would + * immediately halt the system. Instead, this function is used to + * enable an autoidle mode on the osc_ck. The existing + * clk_enable/clk_disable()-based usecounting for osc_ck should be + * replaced with autoidle-based usecounting. + */ static void omap2_disable_osc_ck(struct clk *clk) { u32 pcc; diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c index acb7ae5..bcffee0 100644 --- a/arch/arm/mach-omap2/clkt_dpll.c +++ b/arch/arm/mach-omap2/clkt_dpll.c @@ -178,12 +178,11 @@ void omap2_init_dpll_parent(struct clk *clk) 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 */ + /* Reparent the struct clk in case the dpll is in bypass */ if (cpu_is_omap24xx()) { if (v == OMAP2XXX_EN_DPLL_LPBYPASS || v == OMAP2XXX_EN_DPLL_FRBYPASS) @@ -260,50 +259,22 @@ u32 omap2_get_dpll_rate(struct clk *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. + * Given a DPLL and a desired target rate, round the target rate to a + * possible, programmable rate for this DPLL. Attempts to select the + * minimum possible n. 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, 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; + int m, n, r, scaled_max_m; + unsigned long scaled_rt_rp; + unsigned long new_rate = 0; struct dpll_data *dd; if (!clk || !clk->dpll_data) @@ -311,8 +282,8 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate) dd = clk->dpll_data; - pr_debug("clock: starting DPLL round_rate for clock %s, target rate " - "%ld\n", clk->name, target_rate); + pr_debug("clock: %s: starting DPLL round_rate, 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; @@ -347,39 +318,23 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate) 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); + pr_debug("clock: %s: m = %d: n = %d: new_rate = %ld\n", + clk->name, m, n, new_rate); - /* We found good settings -- bail out now */ - if (min_e <= dd->rate_tolerance) - break; + if (target_rate == new_rate) { + dd->last_rounded_m = m; + dd->last_rounded_n = n; + dd->last_rounded_rate = target_rate; + break; } } - if (min_e < 0) { - pr_debug("clock: error: target rate or tolerance too low\n"); + if (target_rate != new_rate) { + pr_debug("clock: %s: cannot round to rate %ld\n", clk->name, + target_rate); 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; + return target_rate; } diff --git a/arch/arm/mach-omap2/clkt_iclk.c b/arch/arm/mach-omap2/clkt_iclk.c new file mode 100644 index 0000000..3d43fba --- /dev/null +++ b/arch/arm/mach-omap2/clkt_iclk.c @@ -0,0 +1,82 @@ +/* + * OMAP2/3 interface clock control + * + * Copyright (C) 2011 Nokia Corporation + * 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/clk.h> +#include <linux/io.h> + +#include <plat/clock.h> +#include <plat/prcm.h> + +#include "clock.h" +#include "clock2xxx.h" +#include "cm2xxx_3xxx.h" +#include "cm-regbits-24xx.h" + +/* Private functions */ + +/* XXX */ +void omap2_clkt_iclk_allow_idle(struct clk *clk) +{ + u32 v, r; + + r = ((__force u32)clk->enable_reg ^ (CM_AUTOIDLE ^ CM_ICLKEN)); + + v = __raw_readl((__force void __iomem *)r); + v |= (1 << clk->enable_bit); + __raw_writel(v, (__force void __iomem *)r); +} + +/* XXX */ +void omap2_clkt_iclk_deny_idle(struct clk *clk) +{ + u32 v, r; + + r = ((__force u32)clk->enable_reg ^ (CM_AUTOIDLE ^ CM_ICLKEN)); + + v = __raw_readl((__force void __iomem *)r); + v &= ~(1 << clk->enable_bit); + __raw_writel(v, (__force void __iomem *)r); +} + +/* Public data */ + +const struct clkops clkops_omap2_iclk_dflt_wait = { + .enable = omap2_dflt_clk_enable, + .disable = omap2_dflt_clk_disable, + .find_companion = omap2_clk_dflt_find_companion, + .find_idlest = omap2_clk_dflt_find_idlest, + .allow_idle = omap2_clkt_iclk_allow_idle, + .deny_idle = omap2_clkt_iclk_deny_idle, +}; + +const struct clkops clkops_omap2_iclk_dflt = { + .enable = omap2_dflt_clk_enable, + .disable = omap2_dflt_clk_disable, + .allow_idle = omap2_clkt_iclk_allow_idle, + .deny_idle = omap2_clkt_iclk_deny_idle, +}; + +const struct clkops clkops_omap2_iclk_idle_only = { + .allow_idle = omap2_clkt_iclk_allow_idle, + .deny_idle = omap2_clkt_iclk_deny_idle, +}; + +const struct clkops clkops_omap2_mdmclk_dflt_wait = { + .enable = omap2_dflt_clk_enable, + .disable = omap2_dflt_clk_disable, + .find_companion = omap2_clk_dflt_find_companion, + .find_idlest = omap2_clk_dflt_find_idlest, + .allow_idle = omap2_clkt_iclk_allow_idle, + .deny_idle = omap2_clkt_iclk_deny_idle, +}; + diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 2a2f152..46d03cc 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -261,10 +261,11 @@ void omap2_clk_disable(struct clk *clk) pr_debug("clock: %s: disabling in hardware\n", clk->name); - clk->ops->disable(clk); + if (clk->ops && clk->ops->disable) + clk->ops->disable(clk); if (clk->clkdm) - omap2_clkdm_clk_disable(clk->clkdm, clk); + clkdm_clk_disable(clk->clkdm, clk); if (clk->parent) omap2_clk_disable(clk->parent); @@ -304,7 +305,7 @@ int omap2_clk_enable(struct clk *clk) } if (clk->clkdm) { - ret = omap2_clkdm_clk_enable(clk->clkdm, clk); + ret = clkdm_clk_enable(clk->clkdm, clk); if (ret) { WARN(1, "clock: %s: could not enable clockdomain %s: " "%d\n", clk->name, clk->clkdm->name, ret); @@ -312,17 +313,20 @@ int omap2_clk_enable(struct clk *clk) } } - ret = clk->ops->enable(clk); - if (ret) { - WARN(1, "clock: %s: could not enable: %d\n", clk->name, ret); - goto oce_err3; + if (clk->ops && clk->ops->enable) { + ret = clk->ops->enable(clk); + if (ret) { + WARN(1, "clock: %s: could not enable: %d\n", + clk->name, ret); + goto oce_err3; + } } return 0; oce_err3: if (clk->clkdm) - omap2_clkdm_clk_disable(clk->clkdm, clk); + clkdm_clk_disable(clk->clkdm, clk); oce_err2: if (clk->parent) omap2_clk_disable(clk->parent); @@ -373,10 +377,16 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) const struct clkops clkops_omap3_noncore_dpll_ops = { .enable = omap3_noncore_dpll_enable, .disable = omap3_noncore_dpll_disable, + .allow_idle = omap3_dpll_allow_idle, + .deny_idle = omap3_dpll_deny_idle, }; -#endif +const struct clkops clkops_omap3_core_dpll_ops = { + .allow_idle = omap3_dpll_allow_idle, + .deny_idle = omap3_dpll_deny_idle, +}; +#endif /* * OMAP2+ clock reset and init functions diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 896584e..e10ff2b 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -2,7 +2,7 @@ * linux/arch/arm/mach-omap2/clock.h * * Copyright (C) 2005-2009 Texas Instruments, Inc. - * Copyright (C) 2004-2009 Nokia Corporation + * Copyright (C) 2004-2011 Nokia Corporation * * Contacts: * Richard Woodruff <r-woodruff2@ti.com> @@ -18,9 +18,6 @@ #include <plat/clock.h> -/* The maximum error between a target DPLL rate and the rounded rate in Hz */ -#define DEFAULT_DPLL_RATE_TOLERANCE 50000 - /* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */ #define CORE_CLK_SRC_32K 0x0 #define CORE_CLK_SRC_DPLL 0x1 @@ -55,7 +52,6 @@ void omap2_clk_disable(struct clk *clk); long omap2_clk_round_rate(struct clk *clk, unsigned long rate); int omap2_clk_set_rate(struct clk *clk, unsigned long rate); int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent); -int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance); long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate); unsigned long omap3_dpll_recalc(struct clk *clk); unsigned long omap3_clkoutx2_recalc(struct clk *clk); @@ -65,6 +61,9 @@ u32 omap3_dpll_autoidle_read(struct clk *clk); int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate); int omap3_noncore_dpll_enable(struct clk *clk); void omap3_noncore_dpll_disable(struct clk *clk); +int omap4_dpllmx_gatectrl_read(struct clk *clk); +void omap4_dpllmx_allow_gatectrl(struct clk *clk); +void omap4_dpllmx_deny_gatectrl(struct clk *clk); #ifdef CONFIG_OMAP_RESET_CLOCKS void omap2_clk_disable_unused(struct clk *clk); @@ -83,6 +82,10 @@ 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); +/* clkt_iclk.c public functions */ +extern void omap2_clkt_iclk_allow_idle(struct clk *clk); +extern void omap2_clkt_iclk_deny_idle(struct clk *clk); + u32 omap2_get_dpll_rate(struct clk *clk); void omap2_init_dpll_parent(struct clk *clk); @@ -136,6 +139,7 @@ extern struct clk *vclk, *sclk; extern const struct clksel_rate gpt_32k_rates[]; extern const struct clksel_rate gpt_sys_rates[]; extern const struct clksel_rate gfx_l3_rates[]; +extern const struct clksel_rate dsp_ick_rates[]; #if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_CPU_FREQ) extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table); @@ -145,6 +149,13 @@ extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table) #define omap2_clk_exit_cpufreq_table 0 #endif +extern const struct clkops clkops_omap2_iclk_dflt_wait; +extern const struct clkops clkops_omap2_iclk_dflt; +extern const struct clkops clkops_omap2_iclk_idle_only; +extern const struct clkops clkops_omap2_mdmclk_dflt_wait; +extern const struct clkops clkops_omap2xxx_dpll_ops; extern const struct clkops clkops_omap3_noncore_dpll_ops; +extern const struct clkops clkops_omap3_core_dpll_ops; +extern const struct clkops clkops_omap4_dpllmx_ops; #endif diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c index 0a992bc..b6f65d4 100644 --- a/arch/arm/mach-omap2/clock2420_data.c +++ b/arch/arm/mach-omap2/clock2420_data.c @@ -1,12 +1,12 @@ /* - * linux/arch/arm/mach-omap2/clock2420_data.c + * OMAP2420 clock data * - * Copyright (C) 2005-2009 Texas Instruments, Inc. - * Copyright (C) 2004-2010 Nokia Corporation + * Copyright (C) 2005-2009 Texas Instruments, Inc. + * Copyright (C) 2004-2011 Nokia Corporation * - * Contacts: - * Richard Woodruff <r-woodruff2@ti.com> - * Paul Walmsley + * 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 @@ -34,18 +34,15 @@ /* * 2420 clock tree. * - * NOTE:In many cases here we are assigning a 'default' parent. In many - * cases the parent is selectable. The get/set parent calls will also - * switch sources. - * - * Many some clocks say always_enabled, but they can be auto idled for - * power savings. They will always be available upon clock request. + * NOTE:In many cases here we are assigning a 'default' parent. In + * many cases the parent is selectable. The set parent calls will + * also switch sources. * * Several sources are given initial rates which may be wrong, this will * be fixed up in the init func. * * Things are broadly separated below by clock domains. It is - * noteworthy that most periferals have dependencies on multiple clock + * noteworthy that most peripherals have dependencies on multiple clock * domains. Many get their interface clocks from the L4 domain, but get * functional clocks from fixed sources or other core domain derived * clocks. @@ -55,7 +52,7 @@ static struct clk func_32k_ck = { .name = "func_32k_ck", .ops = &clkops_null, - .rate = 32000, + .rate = 32768, .clkdm_name = "wkup_clkdm", }; @@ -116,7 +113,6 @@ static struct dpll_data dpll_dd = { .max_multiplier = 1023, .min_divider = 1, .max_divider = 16, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; /* @@ -125,7 +121,7 @@ static struct dpll_data dpll_dd = { */ static struct clk dpll_ck = { .name = "dpll_ck", - .ops = &clkops_null, + .ops = &clkops_omap2xxx_dpll_ops, .parent = &sys_ck, /* Can be func_32k also */ .dpll_data = &dpll_dd, .clkdm_name = "wkup_clkdm", @@ -455,36 +451,22 @@ static struct clk dsp_fck = { .recalc = &omap2_clksel_recalc, }; -/* DSP interface clock */ -static const struct clksel_rate dsp_irate_ick_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX }, - { .div = 2, .val = 2, .flags = RATE_IN_24XX }, - { .div = 0 }, -}; - -static const struct clksel dsp_irate_ick_clksel[] = { - { .parent = &dsp_fck, .rates = dsp_irate_ick_rates }, +static const struct clksel dsp_ick_clksel[] = { + { .parent = &dsp_fck, .rates = dsp_ick_rates }, { .parent = NULL } }; -/* This clock does not exist as such in the TRM. */ -static struct clk dsp_irate_ick = { - .name = "dsp_irate_ick", - .ops = &clkops_null, - .parent = &dsp_fck, - .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL), - .clksel_mask = OMAP24XX_CLKSEL_DSP_IF_MASK, - .clksel = dsp_irate_ick_clksel, - .recalc = &omap2_clksel_recalc, -}; - -/* 2420 only */ static struct clk dsp_ick = { .name = "dsp_ick", /* apparently ipi and isp */ - .ops = &clkops_omap2_dflt_wait, - .parent = &dsp_irate_ick, + .ops = &clkops_omap2_iclk_dflt_wait, + .parent = &dsp_fck, + .clkdm_name = "dsp_clkdm", .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_ICLKEN), .enable_bit = OMAP2420_EN_DSP_IPI_SHIFT, /* for ipi */ + .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL), + .clksel_mask = OMAP24XX_CLKSEL_DSP_IF_MASK, + .clksel = dsp_ick_clksel, + .recalc = &omap2_clksel_recalc, }; /* @@ -579,7 +561,7 @@ static const struct clksel usb_l4_ick_clksel[] = { /* It is unclear from TRM whether usb_l4_ick is really in L3 or L4 clkdm */ static struct clk usb_l4_ick = { /* FS-USB interface clock */ .name = "usb_l4_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l3_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), @@ -661,7 +643,7 @@ static struct clk ssi_ssr_sst_fck = { */ static struct clk ssi_l4_ick = { .name = "ssi_l4_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), @@ -716,6 +698,7 @@ static struct clk gfx_2d_fck = { .recalc = &omap2_clksel_recalc, }; +/* This interface clock does not have a CM_AUTOIDLE bit */ static struct clk gfx_ick = { .name = "gfx_ick", /* From l3 */ .ops = &clkops_omap2_dflt_wait, @@ -763,7 +746,7 @@ static const struct clksel dss1_fck_clksel[] = { static struct clk dss_ick = { /* Enables both L3,L4 ICLK's */ .name = "dss_ick", - .ops = &clkops_omap2_dflt, + .ops = &clkops_omap2_iclk_dflt, .parent = &l4_ck, /* really both l3 and l4 */ .clkdm_name = "dss_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -825,6 +808,14 @@ static struct clk dss_54m_fck = { /* Alt clk used in power management */ .recalc = &followparent_recalc, }; +static struct clk wu_l4_ick = { + .name = "wu_l4_ick", + .ops = &clkops_null, + .parent = &sys_ck, + .clkdm_name = "wkup_clkdm", + .recalc = &followparent_recalc, +}; + /* * CORE power domain ICLK & FCLK defines. * Many of the these can have more than one possible parent. Entries @@ -845,9 +836,9 @@ static const struct clksel omap24xx_gpt_clksel[] = { static struct clk gpt1_ick = { .name = "gpt1_ick", - .ops = &clkops_omap2_dflt_wait, - .parent = &l4_ck, - .clkdm_name = "core_l4_clkdm", + .ops = &clkops_omap2_iclk_dflt_wait, + .parent = &wu_l4_ick, + .clkdm_name = "wkup_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP24XX_EN_GPT1_SHIFT, .recalc = &followparent_recalc, @@ -871,7 +862,7 @@ static struct clk gpt1_fck = { static struct clk gpt2_ick = { .name = "gpt2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -895,7 +886,7 @@ static struct clk gpt2_fck = { static struct clk gpt3_ick = { .name = "gpt3_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -919,7 +910,7 @@ static struct clk gpt3_fck = { static struct clk gpt4_ick = { .name = "gpt4_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -943,7 +934,7 @@ static struct clk gpt4_fck = { static struct clk gpt5_ick = { .name = "gpt5_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -967,7 +958,7 @@ static struct clk gpt5_fck = { static struct clk gpt6_ick = { .name = "gpt6_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -991,8 +982,9 @@ static struct clk gpt6_fck = { static struct clk gpt7_ick = { .name = "gpt7_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, + .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_GPT7_SHIFT, .recalc = &followparent_recalc, @@ -1014,7 +1006,7 @@ static struct clk gpt7_fck = { static struct clk gpt8_ick = { .name = "gpt8_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1038,7 +1030,7 @@ static struct clk gpt8_fck = { static struct clk gpt9_ick = { .name = "gpt9_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1062,7 +1054,7 @@ static struct clk gpt9_fck = { static struct clk gpt10_ick = { .name = "gpt10_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1086,7 +1078,7 @@ static struct clk gpt10_fck = { static struct clk gpt11_ick = { .name = "gpt11_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1110,7 +1102,7 @@ static struct clk gpt11_fck = { static struct clk gpt12_ick = { .name = "gpt12_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1134,7 +1126,7 @@ static struct clk gpt12_fck = { static struct clk mcbsp1_ick = { .name = "mcbsp1_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1174,7 +1166,7 @@ static struct clk mcbsp1_fck = { static struct clk mcbsp2_ick = { .name = "mcbsp2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1198,7 +1190,7 @@ static struct clk mcbsp2_fck = { static struct clk mcspi1_ick = { .name = "mcspi1_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1218,7 +1210,7 @@ static struct clk mcspi1_fck = { static struct clk mcspi2_ick = { .name = "mcspi2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1238,7 +1230,7 @@ static struct clk mcspi2_fck = { static struct clk uart1_ick = { .name = "uart1_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1258,7 +1250,7 @@ static struct clk uart1_fck = { static struct clk uart2_ick = { .name = "uart2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1278,7 +1270,7 @@ static struct clk uart2_fck = { static struct clk uart3_ick = { .name = "uart3_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), @@ -1298,9 +1290,9 @@ static struct clk uart3_fck = { static struct clk gpios_ick = { .name = "gpios_ick", - .ops = &clkops_omap2_dflt_wait, - .parent = &l4_ck, - .clkdm_name = "core_l4_clkdm", + .ops = &clkops_omap2_iclk_dflt_wait, + .parent = &wu_l4_ick, + .clkdm_name = "wkup_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP24XX_EN_GPIOS_SHIFT, .recalc = &followparent_recalc, @@ -1318,9 +1310,9 @@ static struct clk gpios_fck = { static struct clk mpu_wdt_ick = { .name = "mpu_wdt_ick", - .ops = &clkops_omap2_dflt_wait, - .parent = &l4_ck, - .clkdm_name = "core_l4_clkdm", + .ops = &clkops_omap2_iclk_dflt_wait, + .parent = &wu_l4_ick, + .clkdm_name = "wkup_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP24XX_EN_MPU_WDT_SHIFT, .recalc = &followparent_recalc, @@ -1338,10 +1330,10 @@ static struct clk mpu_wdt_fck = { static struct clk sync_32k_ick = { .name = "sync_32k_ick", - .ops = &clkops_omap2_dflt_wait, - .parent = &l4_ck, + .ops = &clkops_omap2_iclk_dflt_wait, + .parent = &wu_l4_ick, + .clkdm_name = "wkup_clkdm", .flags = ENABLE_ON_INIT, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP24XX_EN_32KSYNC_SHIFT, .recalc = &followparent_recalc, @@ -1349,9 +1341,9 @@ static struct clk sync_32k_ick = { static struct clk wdt1_ick = { .name = "wdt1_ick", - .ops = &clkops_omap2_dflt_wait, - .parent = &l4_ck, - .clkdm_name = "core_l4_clkdm", + .ops = &clkops_omap2_iclk_dflt_wait, + .parent = &wu_l4_ick, + .clkdm_name = "wkup_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP24XX_EN_WDT1_SHIFT, .recalc = &followparent_recalc, @@ -1359,10 +1351,10 @@ static struct clk wdt1_ick = { static struct clk omapctrl_ick = { .name = "omapctrl_ick", - .ops = &clkops_omap2_dflt_wait, - .parent = &l4_ck, + .ops = &clkops_omap2_iclk_dflt_wait, + .parent = &wu_l4_ick, + .clkdm_name = "wkup_clkdm", .flags = ENABLE_ON_INIT, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP24XX_EN_OMAPCTRL_SHIFT, .recalc = &followparent_recalc, @@ -1370,7 +1362,7 @@ static struct clk omapctrl_ick = { static struct clk cam_ick = { .name = "cam_ick", - .ops = &clkops_omap2_dflt, + .ops = &clkops_omap2_iclk_dflt, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1395,7 +1387,7 @@ static struct clk cam_fck = { static struct clk mailboxes_ick = { .name = "mailboxes_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1405,7 +1397,7 @@ static struct clk mailboxes_ick = { static struct clk wdt4_ick = { .name = "wdt4_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1425,7 +1417,7 @@ static struct clk wdt4_fck = { static struct clk wdt3_ick = { .name = "wdt3_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1445,7 +1437,7 @@ static struct clk wdt3_fck = { static struct clk mspro_ick = { .name = "mspro_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1465,7 +1457,7 @@ static struct clk mspro_fck = { static struct clk mmc_ick = { .name = "mmc_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1485,7 +1477,7 @@ static struct clk mmc_fck = { static struct clk fac_ick = { .name = "fac_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1505,7 +1497,7 @@ static struct clk fac_fck = { static struct clk eac_ick = { .name = "eac_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1525,7 +1517,7 @@ static struct clk eac_fck = { static struct clk hdq_ick = { .name = "hdq_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1545,7 +1537,7 @@ static struct clk hdq_fck = { static struct clk i2c2_ick = { .name = "i2c2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1565,7 +1557,7 @@ static struct clk i2c2_fck = { static struct clk i2c1_ick = { .name = "i2c1_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1583,12 +1575,18 @@ static struct clk i2c1_fck = { .recalc = &followparent_recalc, }; +/* + * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE + * accesses derived from this data. + */ static struct clk gpmc_fck = { .name = "gpmc_fck", - .ops = &clkops_null, /* RMK: missing? */ + .ops = &clkops_omap2_iclk_idle_only, .parent = &core_l3_ck, .flags = ENABLE_ON_INIT, .clkdm_name = "core_l3_clkdm", + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), + .enable_bit = OMAP24XX_AUTO_GPMC_SHIFT, .recalc = &followparent_recalc, }; @@ -1600,17 +1598,38 @@ static struct clk sdma_fck = { .recalc = &followparent_recalc, }; +/* + * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE + * accesses derived from this data. + */ static struct clk sdma_ick = { .name = "sdma_ick", - .ops = &clkops_null, /* RMK: missing? */ - .parent = &l4_ck, + .ops = &clkops_omap2_iclk_idle_only, + .parent = &core_l3_ck, + .clkdm_name = "core_l3_clkdm", + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), + .enable_bit = OMAP24XX_AUTO_SDMA_SHIFT, + .recalc = &followparent_recalc, +}; + +/* + * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE + * accesses derived from this data. + */ +static struct clk sdrc_ick = { + .name = "sdrc_ick", + .ops = &clkops_omap2_iclk_idle_only, + .parent = &core_l3_ck, + .flags = ENABLE_ON_INIT, .clkdm_name = "core_l3_clkdm", + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), + .enable_bit = OMAP24XX_AUTO_SDRC_SHIFT, .recalc = &followparent_recalc, }; static struct clk vlynq_ick = { .name = "vlynq_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l3_ck, .clkdm_name = "core_l3_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1659,7 +1678,7 @@ static struct clk vlynq_fck = { static struct clk des_ick = { .name = "des_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), @@ -1669,7 +1688,7 @@ static struct clk des_ick = { static struct clk sha_ick = { .name = "sha_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), @@ -1679,7 +1698,7 @@ static struct clk sha_ick = { static struct clk rng_ick = { .name = "rng_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), @@ -1689,7 +1708,7 @@ static struct clk rng_ick = { static struct clk aes_ick = { .name = "aes_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), @@ -1699,7 +1718,7 @@ static struct clk aes_ick = { static struct clk pka_ick = { .name = "pka_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), @@ -1777,7 +1796,6 @@ static struct omap_clk omap2420_clks[] = { CLK(NULL, "mpu_ck", &mpu_ck, CK_242X), /* dsp domain clocks */ CLK(NULL, "dsp_fck", &dsp_fck, CK_242X), - CLK(NULL, "dsp_irate_ick", &dsp_irate_ick, CK_242X), CLK(NULL, "dsp_ick", &dsp_ick, CK_242X), CLK(NULL, "iva1_ifck", &iva1_ifck, CK_242X), CLK(NULL, "iva1_mpu_int_ifck", &iva1_mpu_int_ifck, CK_242X), @@ -1797,6 +1815,7 @@ static struct omap_clk omap2420_clks[] = { /* L4 domain clocks */ CLK(NULL, "l4_ck", &l4_ck, CK_242X), CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_242X), + CLK(NULL, "wu_l4_ick", &wu_l4_ick, CK_242X), /* virtual meta-group clock */ CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_242X), /* general l4 interface ck, multi-parent functional clk */ @@ -1869,6 +1888,7 @@ static struct omap_clk omap2420_clks[] = { CLK(NULL, "gpmc_fck", &gpmc_fck, CK_242X), CLK(NULL, "sdma_fck", &sdma_fck, CK_242X), CLK(NULL, "sdma_ick", &sdma_ick, CK_242X), + CLK(NULL, "sdrc_ick", &sdrc_ick, CK_242X), CLK(NULL, "vlynq_ick", &vlynq_ick, CK_242X), CLK(NULL, "vlynq_fck", &vlynq_fck, CK_242X), CLK(NULL, "des_ick", &des_ick, CK_242X), @@ -1913,6 +1933,9 @@ int __init omap2420_clk_init(void) omap2_init_clk_clkdm(c->lk.clk); } + /* Disable autoidle on all clocks; let the PM code enable it later */ + omap_clk_disable_autoidle_all(); + /* Check the MPU rate set by bootloader */ clkrate = omap2xxx_clk_get_core_rate(&dpll_ck); for (prcm = rate_table; prcm->mpu_speed; prcm++) { diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c index 5c647ce..bba0183 100644 --- a/arch/arm/mach-omap2/clock2430_data.c +++ b/arch/arm/mach-omap2/clock2430_data.c @@ -1,12 +1,12 @@ /* - * linux/arch/arm/mach-omap2/clock2430_data.c + * OMAP2430 clock data * - * Copyright (C) 2005-2009 Texas Instruments, Inc. - * Copyright (C) 2004-2010 Nokia Corporation + * Copyright (C) 2005-2009 Texas Instruments, Inc. + * Copyright (C) 2004-2011 Nokia Corporation * - * Contacts: - * Richard Woodruff <r-woodruff2@ti.com> - * Paul Walmsley + * 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 @@ -34,18 +34,15 @@ /* * 2430 clock tree. * - * NOTE:In many cases here we are assigning a 'default' parent. In many - * cases the parent is selectable. The get/set parent calls will also - * switch sources. - * - * Many some clocks say always_enabled, but they can be auto idled for - * power savings. They will always be available upon clock request. + * NOTE:In many cases here we are assigning a 'default' parent. In + * many cases the parent is selectable. The set parent calls will + * also switch sources. * * Several sources are given initial rates which may be wrong, this will * be fixed up in the init func. * * Things are broadly separated below by clock domains. It is - * noteworthy that most periferals have dependencies on multiple clock + * noteworthy that most peripherals have dependencies on multiple clock * domains. Many get their interface clocks from the L4 domain, but get * functional clocks from fixed sources or other core domain derived * clocks. @@ -55,7 +52,7 @@ static struct clk func_32k_ck = { .name = "func_32k_ck", .ops = &clkops_null, - .rate = 32000, + .rate = 32768, .clkdm_name = "wkup_clkdm", }; @@ -116,7 +113,6 @@ static struct dpll_data dpll_dd = { .max_multiplier = 1023, .min_divider = 1, .max_divider = 16, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; /* @@ -125,7 +121,7 @@ static struct dpll_data dpll_dd = { */ static struct clk dpll_ck = { .name = "dpll_ck", - .ops = &clkops_null, + .ops = &clkops_omap2xxx_dpll_ops, .parent = &sys_ck, /* Can be func_32k also */ .dpll_data = &dpll_dd, .clkdm_name = "wkup_clkdm", @@ -434,37 +430,23 @@ static struct clk dsp_fck = { .recalc = &omap2_clksel_recalc, }; -/* DSP interface clock */ -static const struct clksel_rate dsp_irate_ick_rates[] = { - { .div = 1, .val = 1, .flags = RATE_IN_24XX }, - { .div = 2, .val = 2, .flags = RATE_IN_24XX }, - { .div = 3, .val = 3, .flags = RATE_IN_243X }, - { .div = 0 }, -}; - -static const struct clksel dsp_irate_ick_clksel[] = { - { .parent = &dsp_fck, .rates = dsp_irate_ick_rates }, +static const struct clksel dsp_ick_clksel[] = { + { .parent = &dsp_fck, .rates = dsp_ick_rates }, { .parent = NULL } }; -/* This clock does not exist as such in the TRM. */ -static struct clk dsp_irate_ick = { - .name = "dsp_irate_ick", - .ops = &clkops_null, - .parent = &dsp_fck, - .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL), - .clksel_mask = OMAP24XX_CLKSEL_DSP_IF_MASK, - .clksel = dsp_irate_ick_clksel, - .recalc = &omap2_clksel_recalc, -}; - /* 2430 only - EN_DSP controls both dsp fclk and iclk on 2430 */ static struct clk iva2_1_ick = { .name = "iva2_1_ick", .ops = &clkops_omap2_dflt_wait, - .parent = &dsp_irate_ick, + .parent = &dsp_fck, + .clkdm_name = "dsp_clkdm", .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN), .enable_bit = OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT, + .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL), + .clksel_mask = OMAP24XX_CLKSEL_DSP_IF_MASK, + .clksel = dsp_ick_clksel, + .recalc = &omap2_clksel_recalc, }; /* @@ -525,7 +507,7 @@ static const struct clksel usb_l4_ick_clksel[] = { /* It is unclear from TRM whether usb_l4_ick is really in L3 or L4 clkdm */ static struct clk usb_l4_ick = { /* FS-USB interface clock */ .name = "usb_l4_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l3_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), @@ -606,7 +588,7 @@ static struct clk ssi_ssr_sst_fck = { */ static struct clk ssi_l4_ick = { .name = "ssi_l4_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), @@ -661,6 +643,7 @@ static struct clk gfx_2d_fck = { .recalc = &omap2_clksel_recalc, }; +/* This interface clock does not have a CM_AUTOIDLE bit */ static struct clk gfx_ick = { .name = "gfx_ick", /* From l3 */ .ops = &clkops_omap2_dflt_wait, @@ -693,7 +676,7 @@ static const struct clksel mdm_ick_clksel[] = { static struct clk mdm_ick = { /* used both as a ick and fck */ .name = "mdm_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_ck, .clkdm_name = "mdm_clkdm", .enable_reg = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_ICLKEN), @@ -706,7 +689,7 @@ static struct clk mdm_ick = { /* used both as a ick and fck */ static struct clk mdm_osc_ck = { .name = "mdm_osc_ck", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_mdmclk_dflt_wait, .parent = &osc_ck, .clkdm_name = "mdm_clkdm", .enable_reg = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_FCLKEN), @@ -751,7 +734,7 @@ static const struct clksel dss1_fck_clksel[] = { static struct clk dss_ick = { /* Enables both L3,L4 ICLK's */ .name = "dss_ick", - .ops = &clkops_omap2_dflt, + .ops = &clkops_omap2_iclk_dflt, .parent = &l4_ck, /* really both l3 and l4 */ .clkdm_name = "dss_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -813,6 +796,14 @@ static struct clk dss_54m_fck = { /* Alt clk used in power management */ .recalc = &followparent_recalc, }; +static struct clk wu_l4_ick = { + .name = "wu_l4_ick", + .ops = &clkops_null, + .parent = &sys_ck, + .clkdm_name = "wkup_clkdm", + .recalc = &followparent_recalc, +}; + /* * CORE power domain ICLK & FCLK defines. * Many of the these can have more than one possible parent. Entries @@ -833,9 +824,9 @@ static const struct clksel omap24xx_gpt_clksel[] = { static struct clk gpt1_ick = { .name = "gpt1_ick", - .ops = &clkops_omap2_dflt_wait, - .parent = &l4_ck, - .clkdm_name = "core_l4_clkdm", + .ops = &clkops_omap2_iclk_dflt_wait, + .parent = &wu_l4_ick, + .clkdm_name = "wkup_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP24XX_EN_GPT1_SHIFT, .recalc = &followparent_recalc, @@ -859,7 +850,7 @@ static struct clk gpt1_fck = { static struct clk gpt2_ick = { .name = "gpt2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -883,7 +874,7 @@ static struct clk gpt2_fck = { static struct clk gpt3_ick = { .name = "gpt3_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -907,7 +898,7 @@ static struct clk gpt3_fck = { static struct clk gpt4_ick = { .name = "gpt4_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -931,7 +922,7 @@ static struct clk gpt4_fck = { static struct clk gpt5_ick = { .name = "gpt5_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -955,7 +946,7 @@ static struct clk gpt5_fck = { static struct clk gpt6_ick = { .name = "gpt6_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -979,8 +970,9 @@ static struct clk gpt6_fck = { static struct clk gpt7_ick = { .name = "gpt7_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, + .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP24XX_EN_GPT7_SHIFT, .recalc = &followparent_recalc, @@ -1002,7 +994,7 @@ static struct clk gpt7_fck = { static struct clk gpt8_ick = { .name = "gpt8_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1026,7 +1018,7 @@ static struct clk gpt8_fck = { static struct clk gpt9_ick = { .name = "gpt9_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1050,7 +1042,7 @@ static struct clk gpt9_fck = { static struct clk gpt10_ick = { .name = "gpt10_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1074,7 +1066,7 @@ static struct clk gpt10_fck = { static struct clk gpt11_ick = { .name = "gpt11_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1098,7 +1090,7 @@ static struct clk gpt11_fck = { static struct clk gpt12_ick = { .name = "gpt12_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1122,7 +1114,7 @@ static struct clk gpt12_fck = { static struct clk mcbsp1_ick = { .name = "mcbsp1_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1162,7 +1154,7 @@ static struct clk mcbsp1_fck = { static struct clk mcbsp2_ick = { .name = "mcbsp2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1186,7 +1178,7 @@ static struct clk mcbsp2_fck = { static struct clk mcbsp3_ick = { .name = "mcbsp3_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), @@ -1210,7 +1202,7 @@ static struct clk mcbsp3_fck = { static struct clk mcbsp4_ick = { .name = "mcbsp4_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), @@ -1234,7 +1226,7 @@ static struct clk mcbsp4_fck = { static struct clk mcbsp5_ick = { .name = "mcbsp5_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), @@ -1258,7 +1250,7 @@ static struct clk mcbsp5_fck = { static struct clk mcspi1_ick = { .name = "mcspi1_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1278,7 +1270,7 @@ static struct clk mcspi1_fck = { static struct clk mcspi2_ick = { .name = "mcspi2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1298,7 +1290,7 @@ static struct clk mcspi2_fck = { static struct clk mcspi3_ick = { .name = "mcspi3_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), @@ -1318,7 +1310,7 @@ static struct clk mcspi3_fck = { static struct clk uart1_ick = { .name = "uart1_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1338,7 +1330,7 @@ static struct clk uart1_fck = { static struct clk uart2_ick = { .name = "uart2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1358,7 +1350,7 @@ static struct clk uart2_fck = { static struct clk uart3_ick = { .name = "uart3_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), @@ -1378,9 +1370,9 @@ static struct clk uart3_fck = { static struct clk gpios_ick = { .name = "gpios_ick", - .ops = &clkops_omap2_dflt_wait, - .parent = &l4_ck, - .clkdm_name = "core_l4_clkdm", + .ops = &clkops_omap2_iclk_dflt_wait, + .parent = &wu_l4_ick, + .clkdm_name = "wkup_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP24XX_EN_GPIOS_SHIFT, .recalc = &followparent_recalc, @@ -1398,9 +1390,9 @@ static struct clk gpios_fck = { static struct clk mpu_wdt_ick = { .name = "mpu_wdt_ick", - .ops = &clkops_omap2_dflt_wait, - .parent = &l4_ck, - .clkdm_name = "core_l4_clkdm", + .ops = &clkops_omap2_iclk_dflt_wait, + .parent = &wu_l4_ick, + .clkdm_name = "wkup_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP24XX_EN_MPU_WDT_SHIFT, .recalc = &followparent_recalc, @@ -1418,10 +1410,10 @@ static struct clk mpu_wdt_fck = { static struct clk sync_32k_ick = { .name = "sync_32k_ick", - .ops = &clkops_omap2_dflt_wait, - .parent = &l4_ck, + .ops = &clkops_omap2_iclk_dflt_wait, .flags = ENABLE_ON_INIT, - .clkdm_name = "core_l4_clkdm", + .parent = &wu_l4_ick, + .clkdm_name = "wkup_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP24XX_EN_32KSYNC_SHIFT, .recalc = &followparent_recalc, @@ -1429,9 +1421,9 @@ static struct clk sync_32k_ick = { static struct clk wdt1_ick = { .name = "wdt1_ick", - .ops = &clkops_omap2_dflt_wait, - .parent = &l4_ck, - .clkdm_name = "core_l4_clkdm", + .ops = &clkops_omap2_iclk_dflt_wait, + .parent = &wu_l4_ick, + .clkdm_name = "wkup_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP24XX_EN_WDT1_SHIFT, .recalc = &followparent_recalc, @@ -1439,10 +1431,10 @@ static struct clk wdt1_ick = { static struct clk omapctrl_ick = { .name = "omapctrl_ick", - .ops = &clkops_omap2_dflt_wait, - .parent = &l4_ck, + .ops = &clkops_omap2_iclk_dflt_wait, .flags = ENABLE_ON_INIT, - .clkdm_name = "core_l4_clkdm", + .parent = &wu_l4_ick, + .clkdm_name = "wkup_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP24XX_EN_OMAPCTRL_SHIFT, .recalc = &followparent_recalc, @@ -1450,9 +1442,9 @@ static struct clk omapctrl_ick = { static struct clk icr_ick = { .name = "icr_ick", - .ops = &clkops_omap2_dflt_wait, - .parent = &l4_ck, - .clkdm_name = "core_l4_clkdm", + .ops = &clkops_omap2_iclk_dflt_wait, + .parent = &wu_l4_ick, + .clkdm_name = "wkup_clkdm", .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP2430_EN_ICR_SHIFT, .recalc = &followparent_recalc, @@ -1460,7 +1452,7 @@ static struct clk icr_ick = { static struct clk cam_ick = { .name = "cam_ick", - .ops = &clkops_omap2_dflt, + .ops = &clkops_omap2_iclk_dflt, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1485,7 +1477,7 @@ static struct clk cam_fck = { static struct clk mailboxes_ick = { .name = "mailboxes_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1495,7 +1487,7 @@ static struct clk mailboxes_ick = { static struct clk wdt4_ick = { .name = "wdt4_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1515,7 +1507,7 @@ static struct clk wdt4_fck = { static struct clk mspro_ick = { .name = "mspro_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1535,7 +1527,7 @@ static struct clk mspro_fck = { static struct clk fac_ick = { .name = "fac_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1555,7 +1547,7 @@ static struct clk fac_fck = { static struct clk hdq_ick = { .name = "hdq_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1579,7 +1571,7 @@ static struct clk hdq_fck = { */ static struct clk i2c2_ick = { .name = "i2c2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1603,7 +1595,7 @@ static struct clk i2chs2_fck = { */ static struct clk i2c1_ick = { .name = "i2c1_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1621,12 +1613,18 @@ static struct clk i2chs1_fck = { .recalc = &followparent_recalc, }; +/* + * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE + * accesses derived from this data. + */ static struct clk gpmc_fck = { .name = "gpmc_fck", - .ops = &clkops_null, /* RMK: missing? */ + .ops = &clkops_omap2_iclk_idle_only, .parent = &core_l3_ck, .flags = ENABLE_ON_INIT, .clkdm_name = "core_l3_clkdm", + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), + .enable_bit = OMAP24XX_AUTO_GPMC_SHIFT, .recalc = &followparent_recalc, }; @@ -1638,20 +1636,26 @@ static struct clk sdma_fck = { .recalc = &followparent_recalc, }; +/* + * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE + * accesses derived from this data. + */ static struct clk sdma_ick = { .name = "sdma_ick", - .ops = &clkops_null, /* RMK: missing? */ - .parent = &l4_ck, + .ops = &clkops_omap2_iclk_idle_only, + .parent = &core_l3_ck, .clkdm_name = "core_l3_clkdm", + .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), + .enable_bit = OMAP24XX_AUTO_SDMA_SHIFT, .recalc = &followparent_recalc, }; static struct clk sdrc_ick = { .name = "sdrc_ick", - .ops = &clkops_omap2_dflt_wait, - .parent = &l4_ck, + .ops = &clkops_omap2_iclk_idle_only, + .parent = &core_l3_ck, .flags = ENABLE_ON_INIT, - .clkdm_name = "core_l4_clkdm", + .clkdm_name = "core_l3_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), .enable_bit = OMAP2430_EN_SDRC_SHIFT, .recalc = &followparent_recalc, @@ -1659,7 +1663,7 @@ static struct clk sdrc_ick = { static struct clk des_ick = { .name = "des_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), @@ -1669,7 +1673,7 @@ static struct clk des_ick = { static struct clk sha_ick = { .name = "sha_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), @@ -1679,7 +1683,7 @@ static struct clk sha_ick = { static struct clk rng_ick = { .name = "rng_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), @@ -1689,7 +1693,7 @@ static struct clk rng_ick = { static struct clk aes_ick = { .name = "aes_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), @@ -1699,7 +1703,7 @@ static struct clk aes_ick = { static struct clk pka_ick = { .name = "pka_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4), @@ -1719,7 +1723,7 @@ static struct clk usb_fck = { static struct clk usbhs_ick = { .name = "usbhs_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l3_ck, .clkdm_name = "core_l3_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), @@ -1729,7 +1733,7 @@ static struct clk usbhs_ick = { static struct clk mmchs1_ick = { .name = "mmchs1_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), @@ -1741,7 +1745,7 @@ static struct clk mmchs1_fck = { .name = "mmchs1_fck", .ops = &clkops_omap2_dflt_wait, .parent = &func_96m_ck, - .clkdm_name = "core_l3_clkdm", + .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), .enable_bit = OMAP2430_EN_MMCHS1_SHIFT, .recalc = &followparent_recalc, @@ -1749,7 +1753,7 @@ static struct clk mmchs1_fck = { static struct clk mmchs2_ick = { .name = "mmchs2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), @@ -1761,6 +1765,7 @@ static struct clk mmchs2_fck = { .name = "mmchs2_fck", .ops = &clkops_omap2_dflt_wait, .parent = &func_96m_ck, + .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), .enable_bit = OMAP2430_EN_MMCHS2_SHIFT, .recalc = &followparent_recalc, @@ -1768,7 +1773,7 @@ static struct clk mmchs2_fck = { static struct clk gpio5_ick = { .name = "gpio5_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), @@ -1788,7 +1793,7 @@ static struct clk gpio5_fck = { static struct clk mdm_intc_ick = { .name = "mdm_intc_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ck, .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), @@ -1880,7 +1885,6 @@ static struct omap_clk omap2430_clks[] = { CLK(NULL, "mpu_ck", &mpu_ck, CK_243X), /* dsp domain clocks */ CLK(NULL, "dsp_fck", &dsp_fck, CK_243X), - CLK(NULL, "dsp_irate_ick", &dsp_irate_ick, CK_243X), CLK(NULL, "iva2_1_ick", &iva2_1_ick, CK_243X), /* GFX domain clocks */ CLK(NULL, "gfx_3d_fck", &gfx_3d_fck, CK_243X), @@ -1901,6 +1905,7 @@ static struct omap_clk omap2430_clks[] = { /* L4 domain clocks */ CLK(NULL, "l4_ck", &l4_ck, CK_243X), CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_243X), + CLK(NULL, "wu_l4_ick", &wu_l4_ick, CK_243X), /* virtual meta-group clock */ CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_243X), /* general l4 interface ck, multi-parent functional clk */ @@ -2028,6 +2033,9 @@ int __init omap2430_clk_init(void) omap2_init_clk_clkdm(c->lk.clk); } + /* Disable autoidle on all clocks; let the PM code enable it later */ + omap_clk_disable_autoidle_all(); + /* Check the MPU rate set by bootloader */ clkrate = omap2xxx_clk_get_core_rate(&dpll_ck); for (prcm = rate_table; prcm->mpu_speed; prcm++) { diff --git a/arch/arm/mach-omap2/clock2xxx.h b/arch/arm/mach-omap2/clock2xxx.h index cc5c8d4..cb6df8c 100644 --- a/arch/arm/mach-omap2/clock2xxx.h +++ b/arch/arm/mach-omap2/clock2xxx.h @@ -23,13 +23,13 @@ void omap2xxx_clk_prepare_for_reboot(void); #ifdef CONFIG_SOC_OMAP2420 int omap2420_clk_init(void); #else -#define omap2420_clk_init() 0 +#define omap2420_clk_init() do { } while(0) #endif #ifdef CONFIG_SOC_OMAP2430 int omap2430_clk_init(void); #else -#define omap2430_clk_init() 0 +#define omap2430_clk_init() do { } while(0) #endif extern void __iomem *prcm_clksrc_ctrl, *cm_idlest_pll; diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index 287abc4..1fc96b9 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c @@ -2,7 +2,7 @@ * OMAP3-specific clock framework functions * * Copyright (C) 2007-2008 Texas Instruments, Inc. - * Copyright (C) 2007-2010 Nokia Corporation + * Copyright (C) 2007-2011 Nokia Corporation * * Paul Walmsley * Jouni Högander @@ -59,6 +59,15 @@ const struct clkops clkops_omap3430es2_ssi_wait = { .find_companion = omap2_clk_dflt_find_companion, }; +const struct clkops clkops_omap3430es2_iclk_ssi_wait = { + .enable = omap2_dflt_clk_enable, + .disable = omap2_dflt_clk_disable, + .find_idlest = omap3430es2_clk_ssi_find_idlest, + .find_companion = omap2_clk_dflt_find_companion, + .allow_idle = omap2_clkt_iclk_allow_idle, + .deny_idle = omap2_clkt_iclk_deny_idle, +}; + /** * omap3430es2_clk_dss_usbhost_find_idlest - CM_IDLEST info for DSS, USBHOST * @clk: struct clk * being enabled @@ -94,6 +103,15 @@ const struct clkops clkops_omap3430es2_dss_usbhost_wait = { .find_companion = omap2_clk_dflt_find_companion, }; +const struct clkops clkops_omap3430es2_iclk_dss_usbhost_wait = { + .enable = omap2_dflt_clk_enable, + .disable = omap2_dflt_clk_disable, + .find_idlest = omap3430es2_clk_dss_usbhost_find_idlest, + .find_companion = omap2_clk_dflt_find_companion, + .allow_idle = omap2_clkt_iclk_allow_idle, + .deny_idle = omap2_clkt_iclk_deny_idle, +}; + /** * omap3430es2_clk_hsotgusb_find_idlest - return CM_IDLEST info for HSOTGUSB * @clk: struct clk * being enabled @@ -124,3 +142,12 @@ const struct clkops clkops_omap3430es2_hsotgusb_wait = { .find_idlest = omap3430es2_clk_hsotgusb_find_idlest, .find_companion = omap2_clk_dflt_find_companion, }; + +const struct clkops clkops_omap3430es2_iclk_hsotgusb_wait = { + .enable = omap2_dflt_clk_enable, + .disable = omap2_dflt_clk_disable, + .find_idlest = omap3430es2_clk_hsotgusb_find_idlest, + .find_companion = omap2_clk_dflt_find_companion, + .allow_idle = omap2_clkt_iclk_allow_idle, + .deny_idle = omap2_clkt_iclk_deny_idle, +}; diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h index 628e8de..084ba71 100644 --- a/arch/arm/mach-omap2/clock34xx.h +++ b/arch/arm/mach-omap2/clock34xx.h @@ -2,14 +2,17 @@ * OMAP34xx clock function prototypes and macros * * Copyright (C) 2007-2010 Texas Instruments, Inc. - * Copyright (C) 2007-2010 Nokia Corporation + * Copyright (C) 2007-2011 Nokia Corporation */ #ifndef __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H #define __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H extern const struct clkops clkops_omap3430es2_ssi_wait; +extern const struct clkops clkops_omap3430es2_iclk_ssi_wait; extern const struct clkops clkops_omap3430es2_hsotgusb_wait; +extern const struct clkops clkops_omap3430es2_iclk_hsotgusb_wait; extern const struct clkops clkops_omap3430es2_dss_usbhost_wait; +extern const struct clkops clkops_omap3430es2_iclk_dss_usbhost_wait; #endif diff --git a/arch/arm/mach-omap2/clock3517.c b/arch/arm/mach-omap2/clock3517.c index 74116a3..2e97d08 100644 --- a/arch/arm/mach-omap2/clock3517.c +++ b/arch/arm/mach-omap2/clock3517.c @@ -2,7 +2,7 @@ * OMAP3517/3505-specific clock framework functions * * Copyright (C) 2010 Texas Instruments, Inc. - * Copyright (C) 2010 Nokia Corporation + * Copyright (C) 2011 Nokia Corporation * * Ranjith Lohithakshan * Paul Walmsley @@ -119,6 +119,8 @@ const struct clkops clkops_am35xx_ipss_wait = { .disable = omap2_dflt_clk_disable, .find_idlest = am35xx_clk_ipss_find_idlest, .find_companion = omap2_clk_dflt_find_companion, + .allow_idle = omap2_clkt_iclk_allow_idle, + .deny_idle = omap2_clkt_iclk_deny_idle, }; diff --git a/arch/arm/mach-omap2/clock3xxx.c b/arch/arm/mach-omap2/clock3xxx.c index e9f66b6..952c3e0 100644 --- a/arch/arm/mach-omap2/clock3xxx.c +++ b/arch/arm/mach-omap2/clock3xxx.c @@ -65,9 +65,6 @@ void __init omap3_clk_lock_dpll5(void) clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST); clk_enable(dpll5_clk); - /* Enable autoidle to allow it to enter low power bypass */ - omap3_dpll_allow_idle(dpll5_clk); - /* Program dpll5_m2_clk divider for no division */ dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck"); clk_enable(dpll5_m2_clk); diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 052ac32..d905ecc 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -2,7 +2,7 @@ * OMAP3 clock data * * Copyright (C) 2007-2010 Texas Instruments, Inc. - * Copyright (C) 2007-2010 Nokia Corporation + * Copyright (C) 2007-2011 Nokia Corporation * * Written by Paul Walmsley * With many device clock fixes by Kevin Hilman and Jouni Högander @@ -291,12 +291,11 @@ static struct dpll_data dpll1_dd = { .max_multiplier = OMAP3_MAX_DPLL_MULT, .min_divider = 1, .max_divider = OMAP3_MAX_DPLL_DIV, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; static struct clk dpll1_ck = { .name = "dpll1_ck", - .ops = &clkops_null, + .ops = &clkops_omap3_noncore_dpll_ops, .parent = &sys_ck, .dpll_data = &dpll1_dd, .round_rate = &omap2_dpll_round_rate, @@ -364,7 +363,6 @@ static struct dpll_data dpll2_dd = { .max_multiplier = OMAP3_MAX_DPLL_MULT, .min_divider = 1, .max_divider = OMAP3_MAX_DPLL_DIV, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; static struct clk dpll2_ck = { @@ -424,12 +422,11 @@ static struct dpll_data dpll3_dd = { .max_multiplier = OMAP3_MAX_DPLL_MULT, .min_divider = 1, .max_divider = OMAP3_MAX_DPLL_DIV, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; static struct clk dpll3_ck = { .name = "dpll3_ck", - .ops = &clkops_null, + .ops = &clkops_omap3_core_dpll_ops, .parent = &sys_ck, .dpll_data = &dpll3_dd, .round_rate = &omap2_dpll_round_rate, @@ -583,7 +580,6 @@ static struct dpll_data dpll4_dd_34xx __initdata = { .max_multiplier = OMAP3_MAX_DPLL_MULT, .min_divider = 1, .max_divider = OMAP3_MAX_DPLL_DIV, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; static struct dpll_data dpll4_dd_3630 __initdata = { @@ -607,7 +603,6 @@ static struct dpll_data dpll4_dd_3630 __initdata = { .max_multiplier = OMAP3630_MAX_JTYPE_DPLL_MULT, .min_divider = 1, .max_divider = OMAP3_MAX_DPLL_DIV, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE, .flags = DPLL_J_TYPE }; @@ -939,7 +934,6 @@ static struct dpll_data dpll5_dd = { .max_multiplier = OMAP3_MAX_DPLL_MULT, .min_divider = 1, .max_divider = OMAP3_MAX_DPLL_DIV, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; static struct clk dpll5_ck = { @@ -1205,7 +1199,10 @@ static const struct clksel gfx_l3_clksel[] = { { .parent = NULL } }; -/* Virtual parent clock for gfx_l3_ick and gfx_l3_fck */ +/* + * Virtual parent clock for gfx_l3_ick and gfx_l3_fck + * This interface clock does not have a CM_AUTOIDLE bit + */ static struct clk gfx_l3_ck = { .name = "gfx_l3_ck", .ops = &clkops_omap2_dflt_wait, @@ -1304,6 +1301,7 @@ static struct clk sgx_fck = { .round_rate = &omap2_clksel_round_rate }; +/* This interface clock does not have a CM_AUTOIDLE bit */ static struct clk sgx_ick = { .name = "sgx_ick", .ops = &clkops_omap2_dflt_wait, @@ -1328,7 +1326,7 @@ static struct clk d2d_26m_fck = { static struct clk modem_fck = { .name = "modem_fck", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_mdmclk_dflt_wait, .parent = &sys_ck, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430_EN_MODEM_SHIFT, @@ -1338,7 +1336,7 @@ static struct clk modem_fck = { static struct clk sad2d_ick = { .name = "sad2d_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l3_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_SAD2D_SHIFT, @@ -1348,7 +1346,7 @@ static struct clk sad2d_ick = { static struct clk mad2d_ick = { .name = "mad2d_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l3_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), .enable_bit = OMAP3430_EN_MAD2D_SHIFT, @@ -1718,7 +1716,7 @@ static struct clk core_l3_ick = { static struct clk hsotgusb_ick_3430es1 = { .name = "hsotgusb_ick", - .ops = &clkops_omap2_dflt, + .ops = &clkops_omap2_iclk_dflt, .parent = &core_l3_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_HSOTGUSB_SHIFT, @@ -1728,7 +1726,7 @@ static struct clk hsotgusb_ick_3430es1 = { static struct clk hsotgusb_ick_3430es2 = { .name = "hsotgusb_ick", - .ops = &clkops_omap3430es2_hsotgusb_wait, + .ops = &clkops_omap3430es2_iclk_hsotgusb_wait, .parent = &core_l3_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_HSOTGUSB_SHIFT, @@ -1736,6 +1734,7 @@ static struct clk hsotgusb_ick_3430es2 = { .recalc = &followparent_recalc, }; +/* This interface clock does not have a CM_AUTOIDLE bit */ static struct clk sdrc_ick = { .name = "sdrc_ick", .ops = &clkops_omap2_dflt_wait, @@ -1767,7 +1766,7 @@ static struct clk security_l3_ick = { static struct clk pka_ick = { .name = "pka_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &security_l3_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), .enable_bit = OMAP3430_EN_PKA_SHIFT, @@ -1786,7 +1785,7 @@ static struct clk core_l4_ick = { static struct clk usbtll_ick = { .name = "usbtll_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3), .enable_bit = OMAP3430ES2_EN_USBTLL_SHIFT, @@ -1796,7 +1795,7 @@ static struct clk usbtll_ick = { static struct clk mmchs3_ick = { .name = "mmchs3_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430ES2_EN_MMC3_SHIFT, @@ -1807,7 +1806,7 @@ static struct clk mmchs3_ick = { /* Intersystem Communication Registers - chassis mode only */ static struct clk icr_ick = { .name = "icr_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_ICR_SHIFT, @@ -1817,7 +1816,7 @@ static struct clk icr_ick = { static struct clk aes2_ick = { .name = "aes2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_AES2_SHIFT, @@ -1827,7 +1826,7 @@ static struct clk aes2_ick = { static struct clk sha12_ick = { .name = "sha12_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_SHA12_SHIFT, @@ -1837,7 +1836,7 @@ static struct clk sha12_ick = { static struct clk des2_ick = { .name = "des2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_DES2_SHIFT, @@ -1847,7 +1846,7 @@ static struct clk des2_ick = { static struct clk mmchs2_ick = { .name = "mmchs2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MMC2_SHIFT, @@ -1857,7 +1856,7 @@ static struct clk mmchs2_ick = { static struct clk mmchs1_ick = { .name = "mmchs1_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MMC1_SHIFT, @@ -1867,7 +1866,7 @@ static struct clk mmchs1_ick = { static struct clk mspro_ick = { .name = "mspro_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MSPRO_SHIFT, @@ -1877,7 +1876,7 @@ static struct clk mspro_ick = { static struct clk hdq_ick = { .name = "hdq_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_HDQ_SHIFT, @@ -1887,7 +1886,7 @@ static struct clk hdq_ick = { static struct clk mcspi4_ick = { .name = "mcspi4_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MCSPI4_SHIFT, @@ -1897,7 +1896,7 @@ static struct clk mcspi4_ick = { static struct clk mcspi3_ick = { .name = "mcspi3_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MCSPI3_SHIFT, @@ -1907,7 +1906,7 @@ static struct clk mcspi3_ick = { static struct clk mcspi2_ick = { .name = "mcspi2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MCSPI2_SHIFT, @@ -1917,7 +1916,7 @@ static struct clk mcspi2_ick = { static struct clk mcspi1_ick = { .name = "mcspi1_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MCSPI1_SHIFT, @@ -1927,7 +1926,7 @@ static struct clk mcspi1_ick = { static struct clk i2c3_ick = { .name = "i2c3_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_I2C3_SHIFT, @@ -1937,7 +1936,7 @@ static struct clk i2c3_ick = { static struct clk i2c2_ick = { .name = "i2c2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_I2C2_SHIFT, @@ -1947,7 +1946,7 @@ static struct clk i2c2_ick = { static struct clk i2c1_ick = { .name = "i2c1_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_I2C1_SHIFT, @@ -1957,7 +1956,7 @@ static struct clk i2c1_ick = { static struct clk uart2_ick = { .name = "uart2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_UART2_SHIFT, @@ -1967,7 +1966,7 @@ static struct clk uart2_ick = { static struct clk uart1_ick = { .name = "uart1_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_UART1_SHIFT, @@ -1977,7 +1976,7 @@ static struct clk uart1_ick = { static struct clk gpt11_ick = { .name = "gpt11_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_GPT11_SHIFT, @@ -1987,7 +1986,7 @@ static struct clk gpt11_ick = { static struct clk gpt10_ick = { .name = "gpt10_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_GPT10_SHIFT, @@ -1997,7 +1996,7 @@ static struct clk gpt10_ick = { static struct clk mcbsp5_ick = { .name = "mcbsp5_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MCBSP5_SHIFT, @@ -2007,7 +2006,7 @@ static struct clk mcbsp5_ick = { static struct clk mcbsp1_ick = { .name = "mcbsp1_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MCBSP1_SHIFT, @@ -2017,7 +2016,7 @@ static struct clk mcbsp1_ick = { static struct clk fac_ick = { .name = "fac_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430ES1_EN_FAC_SHIFT, @@ -2027,7 +2026,7 @@ static struct clk fac_ick = { static struct clk mailboxes_ick = { .name = "mailboxes_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MAILBOXES_SHIFT, @@ -2037,7 +2036,7 @@ static struct clk mailboxes_ick = { static struct clk omapctrl_ick = { .name = "omapctrl_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_OMAPCTRL_SHIFT, @@ -2057,7 +2056,7 @@ static struct clk ssi_l4_ick = { static struct clk ssi_ick_3430es1 = { .name = "ssi_ick", - .ops = &clkops_omap2_dflt, + .ops = &clkops_omap2_iclk_dflt, .parent = &ssi_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_SSI_SHIFT, @@ -2067,7 +2066,7 @@ static struct clk ssi_ick_3430es1 = { static struct clk ssi_ick_3430es2 = { .name = "ssi_ick", - .ops = &clkops_omap3430es2_ssi_wait, + .ops = &clkops_omap3430es2_iclk_ssi_wait, .parent = &ssi_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_SSI_SHIFT, @@ -2085,7 +2084,7 @@ static const struct clksel usb_l4_clksel[] = { static struct clk usb_l4_ick = { .name = "usb_l4_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &l4_ick, .init = &omap2_init_clksel_parent, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -2107,7 +2106,7 @@ static struct clk security_l4_ick2 = { static struct clk aes1_ick = { .name = "aes1_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &security_l4_ick2, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), .enable_bit = OMAP3430_EN_AES1_SHIFT, @@ -2116,7 +2115,7 @@ static struct clk aes1_ick = { static struct clk rng_ick = { .name = "rng_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &security_l4_ick2, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), .enable_bit = OMAP3430_EN_RNG_SHIFT, @@ -2125,7 +2124,7 @@ static struct clk rng_ick = { static struct clk sha11_ick = { .name = "sha11_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &security_l4_ick2, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), .enable_bit = OMAP3430_EN_SHA11_SHIFT, @@ -2134,7 +2133,7 @@ static struct clk sha11_ick = { static struct clk des1_ick = { .name = "des1_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &security_l4_ick2, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), .enable_bit = OMAP3430_EN_DES1_SHIFT, @@ -2195,7 +2194,7 @@ static struct clk dss2_alwon_fck = { static struct clk dss_ick_3430es1 = { /* Handles both L3 and L4 clocks */ .name = "dss_ick", - .ops = &clkops_omap2_dflt, + .ops = &clkops_omap2_iclk_dflt, .parent = &l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN), .enable_bit = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT, @@ -2206,7 +2205,7 @@ static struct clk dss_ick_3430es1 = { static struct clk dss_ick_3430es2 = { /* Handles both L3 and L4 clocks */ .name = "dss_ick", - .ops = &clkops_omap3430es2_dss_usbhost_wait, + .ops = &clkops_omap3430es2_iclk_dss_usbhost_wait, .parent = &l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN), .enable_bit = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT, @@ -2229,7 +2228,7 @@ static struct clk cam_mclk = { static struct clk cam_ick = { /* Handles both L3 and L4 clocks */ .name = "cam_ick", - .ops = &clkops_omap2_dflt, + .ops = &clkops_omap2_iclk_dflt, .parent = &l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_CAM_SHIFT, @@ -2272,7 +2271,7 @@ static struct clk usbhost_48m_fck = { static struct clk usbhost_ick = { /* Handles both L3 and L4 clocks */ .name = "usbhost_ick", - .ops = &clkops_omap3430es2_dss_usbhost_wait, + .ops = &clkops_omap3430es2_iclk_dss_usbhost_wait, .parent = &l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN), .enable_bit = OMAP3430ES2_EN_USBHOST_SHIFT, @@ -2372,7 +2371,7 @@ static struct clk wkup_l4_ick = { /* Never specifically named in the TRM, so we have to infer a likely name */ static struct clk usim_ick = { .name = "usim_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &wkup_l4_ick, .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP3430ES2_EN_USIMOCP_SHIFT, @@ -2382,7 +2381,7 @@ static struct clk usim_ick = { static struct clk wdt2_ick = { .name = "wdt2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &wkup_l4_ick, .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_WDT2_SHIFT, @@ -2392,7 +2391,7 @@ static struct clk wdt2_ick = { static struct clk wdt1_ick = { .name = "wdt1_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &wkup_l4_ick, .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_WDT1_SHIFT, @@ -2402,7 +2401,7 @@ static struct clk wdt1_ick = { static struct clk gpio1_ick = { .name = "gpio1_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &wkup_l4_ick, .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPIO1_SHIFT, @@ -2412,7 +2411,7 @@ static struct clk gpio1_ick = { static struct clk omap_32ksync_ick = { .name = "omap_32ksync_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &wkup_l4_ick, .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_32KSYNC_SHIFT, @@ -2423,7 +2422,7 @@ static struct clk omap_32ksync_ick = { /* XXX This clock no longer exists in 3430 TRM rev F */ static struct clk gpt12_ick = { .name = "gpt12_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &wkup_l4_ick, .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT12_SHIFT, @@ -2433,7 +2432,7 @@ static struct clk gpt12_ick = { static struct clk gpt1_ick = { .name = "gpt1_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &wkup_l4_ick, .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT1_SHIFT, @@ -2663,7 +2662,7 @@ static struct clk per_l4_ick = { static struct clk gpio6_ick = { .name = "gpio6_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPIO6_SHIFT, @@ -2673,7 +2672,7 @@ static struct clk gpio6_ick = { static struct clk gpio5_ick = { .name = "gpio5_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPIO5_SHIFT, @@ -2683,7 +2682,7 @@ static struct clk gpio5_ick = { static struct clk gpio4_ick = { .name = "gpio4_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPIO4_SHIFT, @@ -2693,7 +2692,7 @@ static struct clk gpio4_ick = { static struct clk gpio3_ick = { .name = "gpio3_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPIO3_SHIFT, @@ -2703,7 +2702,7 @@ static struct clk gpio3_ick = { static struct clk gpio2_ick = { .name = "gpio2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPIO2_SHIFT, @@ -2713,7 +2712,7 @@ static struct clk gpio2_ick = { static struct clk wdt3_ick = { .name = "wdt3_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_WDT3_SHIFT, @@ -2723,7 +2722,7 @@ static struct clk wdt3_ick = { static struct clk uart3_ick = { .name = "uart3_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_UART3_SHIFT, @@ -2733,7 +2732,7 @@ static struct clk uart3_ick = { static struct clk uart4_ick = { .name = "uart4_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3630_EN_UART4_SHIFT, @@ -2743,7 +2742,7 @@ static struct clk uart4_ick = { static struct clk gpt9_ick = { .name = "gpt9_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT9_SHIFT, @@ -2753,7 +2752,7 @@ static struct clk gpt9_ick = { static struct clk gpt8_ick = { .name = "gpt8_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT8_SHIFT, @@ -2763,7 +2762,7 @@ static struct clk gpt8_ick = { static struct clk gpt7_ick = { .name = "gpt7_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT7_SHIFT, @@ -2773,7 +2772,7 @@ static struct clk gpt7_ick = { static struct clk gpt6_ick = { .name = "gpt6_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT6_SHIFT, @@ -2783,7 +2782,7 @@ static struct clk gpt6_ick = { static struct clk gpt5_ick = { .name = "gpt5_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT5_SHIFT, @@ -2793,7 +2792,7 @@ static struct clk gpt5_ick = { static struct clk gpt4_ick = { .name = "gpt4_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT4_SHIFT, @@ -2803,7 +2802,7 @@ static struct clk gpt4_ick = { static struct clk gpt3_ick = { .name = "gpt3_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT3_SHIFT, @@ -2813,7 +2812,7 @@ static struct clk gpt3_ick = { static struct clk gpt2_ick = { .name = "gpt2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_GPT2_SHIFT, @@ -2823,7 +2822,7 @@ static struct clk gpt2_ick = { static struct clk mcbsp2_ick = { .name = "mcbsp2_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_MCBSP2_SHIFT, @@ -2833,7 +2832,7 @@ static struct clk mcbsp2_ick = { static struct clk mcbsp3_ick = { .name = "mcbsp3_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_MCBSP3_SHIFT, @@ -2843,7 +2842,7 @@ static struct clk mcbsp3_ick = { static struct clk mcbsp4_ick = { .name = "mcbsp4_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_MCBSP4_SHIFT, @@ -3186,7 +3185,7 @@ static struct clk vpfe_fck = { */ static struct clk uart4_ick_am35xx = { .name = "uart4_ick", - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2_iclk_dflt_wait, .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = AM35XX_EN_UART4_SHIFT, @@ -3538,6 +3537,9 @@ int __init omap3xxx_clk_init(void) omap2_init_clk_clkdm(c->lk.clk); } + /* Disable autoidle on all clocks; let the PM code enable it later */ + omap_clk_disable_autoidle_all(); + recalculate_root_clocks(); pr_info("Clocking rate (Crystal/Core/MPU): %ld.%01ld/%ld/%ld MHz\n", @@ -3551,7 +3553,8 @@ int __init omap3xxx_clk_init(void) clk_enable_init_clocks(); /* - * Lock DPLL5 and put it in autoidle. + * Lock DPLL5 -- here only until other device init code can + * handle this */ if (!cpu_is_ti816x() && (omap_rev() >= OMAP3430_REV_ES2_0)) omap3_clk_lock_dpll5(); diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index fdbc042..f1fedb7 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -278,8 +278,10 @@ static struct clk dpll_abe_ck = { static struct clk dpll_abe_x2_ck = { .name = "dpll_abe_x2_ck", .parent = &dpll_abe_ck, - .ops = &clkops_null, + .flags = CLOCK_CLKOUTX2, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap3_clkoutx2_recalc, + .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_ABE, }; static const struct clksel_rate div31_1to31_rates[] = { @@ -328,7 +330,7 @@ static struct clk dpll_abe_m2x2_ck = { .clksel = dpll_abe_m2x2_div, .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_ABE, .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate, @@ -395,7 +397,7 @@ static struct clk dpll_abe_m3x2_ck = { .clksel = dpll_abe_m2x2_div, .clksel_reg = OMAP4430_CM_DIV_M3_DPLL_ABE, .clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate, @@ -443,13 +445,14 @@ static struct clk dpll_core_ck = { .parent = &sys_clkin_ck, .dpll_data = &dpll_core_dd, .init = &omap2_init_dpll_parent, - .ops = &clkops_null, + .ops = &clkops_omap3_core_dpll_ops, .recalc = &omap3_dpll_recalc, }; static struct clk dpll_core_x2_ck = { .name = "dpll_core_x2_ck", .parent = &dpll_core_ck, + .flags = CLOCK_CLKOUTX2, .ops = &clkops_null, .recalc = &omap3_clkoutx2_recalc, }; @@ -465,7 +468,7 @@ static struct clk dpll_core_m6x2_ck = { .clksel = dpll_core_m6x2_div, .clksel_reg = OMAP4430_CM_DIV_M6_DPLL_CORE, .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate, @@ -495,7 +498,7 @@ static struct clk dpll_core_m2_ck = { .clksel = dpll_core_m2_div, .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_CORE, .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate, @@ -515,7 +518,7 @@ static struct clk dpll_core_m5x2_ck = { .clksel = dpll_core_m6x2_div, .clksel_reg = OMAP4430_CM_DIV_M5_DPLL_CORE, .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate, @@ -581,7 +584,7 @@ static struct clk dpll_core_m4x2_ck = { .clksel = dpll_core_m6x2_div, .clksel_reg = OMAP4430_CM_DIV_M4_DPLL_CORE, .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate, @@ -606,7 +609,7 @@ static struct clk dpll_abe_m2_ck = { .clksel = dpll_abe_m2_div, .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_ABE, .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate, @@ -632,7 +635,7 @@ static struct clk dpll_core_m7x2_ck = { .clksel = dpll_core_m6x2_div, .clksel_reg = OMAP4430_CM_DIV_M7_DPLL_CORE, .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate, @@ -689,6 +692,7 @@ static struct clk dpll_iva_ck = { static struct clk dpll_iva_x2_ck = { .name = "dpll_iva_x2_ck", .parent = &dpll_iva_ck, + .flags = CLOCK_CLKOUTX2, .ops = &clkops_null, .recalc = &omap3_clkoutx2_recalc, }; @@ -704,7 +708,7 @@ static struct clk dpll_iva_m4x2_ck = { .clksel = dpll_iva_m4x2_div, .clksel_reg = OMAP4430_CM_DIV_M4_DPLL_IVA, .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate, @@ -716,7 +720,7 @@ static struct clk dpll_iva_m5x2_ck = { .clksel = dpll_iva_m4x2_div, .clksel_reg = OMAP4430_CM_DIV_M5_DPLL_IVA, .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate, @@ -764,7 +768,7 @@ static struct clk dpll_mpu_m2_ck = { .clksel = dpll_mpu_m2_div, .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_MPU, .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate, @@ -837,7 +841,7 @@ static struct clk dpll_per_m2_ck = { .clksel = dpll_per_m2_div, .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_PER, .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate, @@ -846,8 +850,10 @@ static struct clk dpll_per_m2_ck = { static struct clk dpll_per_x2_ck = { .name = "dpll_per_x2_ck", .parent = &dpll_per_ck, - .ops = &clkops_null, + .flags = CLOCK_CLKOUTX2, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap3_clkoutx2_recalc, + .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_PER, }; static const struct clksel dpll_per_m2x2_div[] = { @@ -861,7 +867,7 @@ static struct clk dpll_per_m2x2_ck = { .clksel = dpll_per_m2x2_div, .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_PER, .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate, @@ -887,7 +893,7 @@ static struct clk dpll_per_m4x2_ck = { .clksel = dpll_per_m2x2_div, .clksel_reg = OMAP4430_CM_DIV_M4_DPLL_PER, .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate, @@ -899,7 +905,7 @@ static struct clk dpll_per_m5x2_ck = { .clksel = dpll_per_m2x2_div, .clksel_reg = OMAP4430_CM_DIV_M5_DPLL_PER, .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate, @@ -911,7 +917,7 @@ static struct clk dpll_per_m6x2_ck = { .clksel = dpll_per_m2x2_div, .clksel_reg = OMAP4430_CM_DIV_M6_DPLL_PER, .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate, @@ -923,7 +929,7 @@ static struct clk dpll_per_m7x2_ck = { .clksel = dpll_per_m2x2_div, .clksel_reg = OMAP4430_CM_DIV_M7_DPLL_PER, .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate, @@ -964,6 +970,7 @@ static struct clk dpll_unipro_ck = { static struct clk dpll_unipro_x2_ck = { .name = "dpll_unipro_x2_ck", .parent = &dpll_unipro_ck, + .flags = CLOCK_CLKOUTX2, .ops = &clkops_null, .recalc = &omap3_clkoutx2_recalc, }; @@ -979,7 +986,7 @@ static struct clk dpll_unipro_m2x2_ck = { .clksel = dpll_unipro_m2x2_div, .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_UNIPRO, .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate, @@ -1028,7 +1035,8 @@ static struct clk dpll_usb_ck = { static struct clk dpll_usb_clkdcoldo_ck = { .name = "dpll_usb_clkdcoldo_ck", .parent = &dpll_usb_ck, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, + .clksel_reg = OMAP4430_CM_CLKDCOLDO_DPLL_USB, .recalc = &followparent_recalc, }; @@ -1043,7 +1051,7 @@ static struct clk dpll_usb_m2_ck = { .clksel = dpll_usb_m2_div, .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_USB, .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_0_6_MASK, - .ops = &clkops_null, + .ops = &clkops_omap4_dpllmx_ops, .recalc = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, .set_rate = &omap2_clksel_set_rate, @@ -3301,6 +3309,9 @@ int __init omap4xxx_clk_init(void) omap2_init_clk_clkdm(c->lk.clk); } + /* Disable autoidle on all clocks; let the PM code enable it later */ + omap_clk_disable_autoidle_all(); + recalculate_root_clocks(); /* diff --git a/arch/arm/mach-omap2/clock_common_data.c b/arch/arm/mach-omap2/clock_common_data.c index 1cf8131..6424d46 100644 --- a/arch/arm/mach-omap2/clock_common_data.c +++ b/arch/arm/mach-omap2/clock_common_data.c @@ -37,3 +37,9 @@ const struct clksel_rate gfx_l3_rates[] = { { .div = 0 } }; +const struct clksel_rate dsp_ick_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_24XX }, + { .div = 2, .val = 2, .flags = RATE_IN_24XX }, + { .div = 3, .val = 3, .flags = RATE_IN_243X }, + { .div = 0 }, +}; diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 58e42f7..ab87854 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -26,17 +26,8 @@ #include <linux/bitops.h> -#include "prm2xxx_3xxx.h" -#include "prm-regbits-24xx.h" -#include "cm2xxx_3xxx.h" -#include "cm-regbits-24xx.h" -#include "cminst44xx.h" -#include "prcm44xx.h" - #include <plat/clock.h> -#include "powerdomain.h" #include "clockdomain.h" -#include <plat/prcm.h> /* clkdm_list contains all registered struct clockdomains */ static LIST_HEAD(clkdm_list); @@ -44,6 +35,7 @@ static LIST_HEAD(clkdm_list); /* array of clockdomain deps to be added/removed when clkdm in hwsup mode */ static struct clkdm_autodep *autodeps; +static struct clkdm_ops *arch_clkdm; /* Private functions */ @@ -177,11 +169,11 @@ static void _autodep_lookup(struct clkdm_autodep *autodep) * XXX autodeps are deprecated and should be removed at the earliest * opportunity */ -static void _clkdm_add_autodeps(struct clockdomain *clkdm) +void _clkdm_add_autodeps(struct clockdomain *clkdm) { struct clkdm_autodep *autodep; - if (!autodeps) + if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS) return; for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { @@ -211,11 +203,11 @@ static void _clkdm_add_autodeps(struct clockdomain *clkdm) * XXX autodeps are deprecated and should be removed at the earliest * opportunity */ -static void _clkdm_del_autodeps(struct clockdomain *clkdm) +void _clkdm_del_autodeps(struct clockdomain *clkdm) { struct clkdm_autodep *autodep; - if (!autodeps) + if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS) return; for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { @@ -235,55 +227,29 @@ static void _clkdm_del_autodeps(struct clockdomain *clkdm) } /** - * _enable_hwsup - place a clockdomain into hardware-supervised idle - * @clkdm: struct clockdomain * - * - * Place the clockdomain into hardware-supervised idle mode. No return - * value. + * _resolve_clkdm_deps() - resolve clkdm_names in @clkdm_deps to clkdms + * @clkdm: clockdomain that we are resolving dependencies for + * @clkdm_deps: ptr to array of struct clkdm_deps to resolve * - * XXX Should this return an error if the clockdomain does not support - * hardware-supervised idle mode? - */ -static void _enable_hwsup(struct clockdomain *clkdm) -{ - if (cpu_is_omap24xx()) - omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, - clkdm->clktrctrl_mask); - else if (cpu_is_omap34xx()) - omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, - clkdm->clktrctrl_mask); - else if (cpu_is_omap44xx()) - return omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition, - clkdm->cm_inst, - clkdm->clkdm_offs); - else - BUG(); -} - -/** - * _disable_hwsup - place a clockdomain into software-supervised idle - * @clkdm: struct clockdomain * - * - * Place the clockdomain @clkdm into software-supervised idle mode. + * Iterates through @clkdm_deps, looking up the struct clockdomain named by + * clkdm_name and storing the clockdomain pointer in the struct clkdm_dep. * No return value. - * - * XXX Should this return an error if the clockdomain does not support - * software-supervised idle mode? */ -static void _disable_hwsup(struct clockdomain *clkdm) +static void _resolve_clkdm_deps(struct clockdomain *clkdm, + struct clkdm_dep *clkdm_deps) { - if (cpu_is_omap24xx()) - omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, - clkdm->clktrctrl_mask); - else if (cpu_is_omap34xx()) - omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, - clkdm->clktrctrl_mask); - else if (cpu_is_omap44xx()) - return omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition, - clkdm->cm_inst, - clkdm->clkdm_offs); - else - BUG(); + struct clkdm_dep *cd; + + for (cd = clkdm_deps; cd && cd->clkdm_name; cd++) { + if (!omap_chip_is(cd->omap_chip)) + continue; + if (cd->clkdm) + continue; + cd->clkdm = _clkdm_lookup(cd->clkdm_name); + + WARN(!cd->clkdm, "clockdomain: %s: could not find clkdm %s while resolving dependencies - should never happen", + clkdm->name, cd->clkdm_name); + } } /* Public functions */ @@ -292,6 +258,7 @@ static void _disable_hwsup(struct clockdomain *clkdm) * clkdm_init - set up the clockdomain layer * @clkdms: optional pointer to an array of clockdomains to register * @init_autodeps: optional pointer to an array of autodeps to register + * @custom_funcs: func pointers for arch specfic implementations * * Set up internal state. If a pointer to an array of clockdomains * @clkdms was supplied, loop through the list of clockdomains, @@ -300,12 +267,18 @@ static void _disable_hwsup(struct clockdomain *clkdm) * @init_autodeps was provided, register those. No return value. */ void clkdm_init(struct clockdomain **clkdms, - struct clkdm_autodep *init_autodeps) + struct clkdm_autodep *init_autodeps, + struct clkdm_ops *custom_funcs) { struct clockdomain **c = NULL; struct clockdomain *clkdm; struct clkdm_autodep *autodep = NULL; + if (!custom_funcs) + WARN(1, "No custom clkdm functions registered\n"); + else + arch_clkdm = custom_funcs; + if (clkdms) for (c = clkdms; *c; c++) _clkdm_register(*c); @@ -321,11 +294,14 @@ void clkdm_init(struct clockdomain **clkdms, */ list_for_each_entry(clkdm, &clkdm_list, node) { if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) - omap2_clkdm_wakeup(clkdm); + clkdm_wakeup(clkdm); else if (clkdm->flags & CLKDM_CAN_DISABLE_AUTO) - omap2_clkdm_deny_idle(clkdm); + clkdm_deny_idle(clkdm); + _resolve_clkdm_deps(clkdm, clkdm->wkdep_srcs); clkdm_clear_all_wkdeps(clkdm); + + _resolve_clkdm_deps(clkdm, clkdm->sleepdep_srcs); clkdm_clear_all_sleepdeps(clkdm); } } @@ -422,32 +398,32 @@ struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm) int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) { struct clkdm_dep *cd; - - if (!cpu_is_omap24xx() && !cpu_is_omap34xx()) { - pr_err("clockdomain: %s/%s: %s: not yet implemented\n", - clkdm1->name, clkdm2->name, __func__); - return -EINVAL; - } + int ret = 0; if (!clkdm1 || !clkdm2) return -EINVAL; cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); - if (IS_ERR(cd)) { + if (IS_ERR(cd)) + ret = PTR_ERR(cd); + + if (!arch_clkdm || !arch_clkdm->clkdm_add_wkdep) + ret = -EINVAL; + + if (ret) { pr_debug("clockdomain: hardware cannot set/clear wake up of " "%s when %s wakes up\n", clkdm1->name, clkdm2->name); - return PTR_ERR(cd); + return ret; } if (atomic_inc_return(&cd->wkdep_usecount) == 1) { pr_debug("clockdomain: hardware will wake up %s when %s wakes " "up\n", clkdm1->name, clkdm2->name); - omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit), - clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP); + ret = arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2); } - return 0; + return ret; } /** @@ -463,32 +439,32 @@ int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) { struct clkdm_dep *cd; - - if (!cpu_is_omap24xx() && !cpu_is_omap34xx()) { - pr_err("clockdomain: %s/%s: %s: not yet implemented\n", - clkdm1->name, clkdm2->name, __func__); - return -EINVAL; - } + int ret = 0; if (!clkdm1 || !clkdm2) return -EINVAL; cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); - if (IS_ERR(cd)) { + if (IS_ERR(cd)) + ret = PTR_ERR(cd); + + if (!arch_clkdm || !arch_clkdm->clkdm_del_wkdep) + ret = -EINVAL; + + if (ret) { pr_debug("clockdomain: hardware cannot set/clear wake up of " "%s when %s wakes up\n", clkdm1->name, clkdm2->name); - return PTR_ERR(cd); + return ret; } if (atomic_dec_return(&cd->wkdep_usecount) == 0) { pr_debug("clockdomain: hardware will no longer wake up %s " "after %s wakes up\n", clkdm1->name, clkdm2->name); - omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit), - clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP); + ret = arch_clkdm->clkdm_del_wkdep(clkdm1, clkdm2); } - return 0; + return ret; } /** @@ -508,26 +484,26 @@ int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) { struct clkdm_dep *cd; + int ret = 0; if (!clkdm1 || !clkdm2) return -EINVAL; - if (!cpu_is_omap24xx() && !cpu_is_omap34xx()) { - pr_err("clockdomain: %s/%s: %s: not yet implemented\n", - clkdm1->name, clkdm2->name, __func__); - return -EINVAL; - } - cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); - if (IS_ERR(cd)) { + if (IS_ERR(cd)) + ret = PTR_ERR(cd); + + if (!arch_clkdm || !arch_clkdm->clkdm_read_wkdep) + ret = -EINVAL; + + if (ret) { pr_debug("clockdomain: hardware cannot set/clear wake up of " "%s when %s wakes up\n", clkdm1->name, clkdm2->name); - return PTR_ERR(cd); + return ret; } /* XXX It's faster to return the atomic wkdep_usecount */ - return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP, - (1 << clkdm2->dep_bit)); + return arch_clkdm->clkdm_read_wkdep(clkdm1, clkdm2); } /** @@ -542,33 +518,13 @@ int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) */ int clkdm_clear_all_wkdeps(struct clockdomain *clkdm) { - struct clkdm_dep *cd; - u32 mask = 0; - - if (!cpu_is_omap24xx() && !cpu_is_omap34xx()) { - pr_err("clockdomain: %s: %s: not yet implemented\n", - clkdm->name, __func__); - return -EINVAL; - } - if (!clkdm) return -EINVAL; - for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) { - if (!omap_chip_is(cd->omap_chip)) - continue; - - if (!cd->clkdm && cd->clkdm_name) - cd->clkdm = _clkdm_lookup(cd->clkdm_name); - - /* PRM accesses are slow, so minimize them */ - mask |= 1 << cd->clkdm->dep_bit; - atomic_set(&cd->wkdep_usecount, 0); - } - - omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, PM_WKDEP); + if (!arch_clkdm || !arch_clkdm->clkdm_clear_all_wkdeps) + return -EINVAL; - return 0; + return arch_clkdm->clkdm_clear_all_wkdeps(clkdm); } /** @@ -586,31 +542,33 @@ int clkdm_clear_all_wkdeps(struct clockdomain *clkdm) int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) { struct clkdm_dep *cd; - - if (!cpu_is_omap34xx()) - return -EINVAL; + int ret = 0; if (!clkdm1 || !clkdm2) return -EINVAL; cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); - if (IS_ERR(cd)) { + if (IS_ERR(cd)) + ret = PTR_ERR(cd); + + if (!arch_clkdm || !arch_clkdm->clkdm_add_sleepdep) + ret = -EINVAL; + + if (ret) { pr_debug("clockdomain: hardware cannot set/clear sleep " "dependency affecting %s from %s\n", clkdm1->name, clkdm2->name); - return PTR_ERR(cd); + return ret; } if (atomic_inc_return(&cd->sleepdep_usecount) == 1) { pr_debug("clockdomain: will prevent %s from sleeping if %s " "is active\n", clkdm1->name, clkdm2->name); - omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit), - clkdm1->pwrdm.ptr->prcm_offs, - OMAP3430_CM_SLEEPDEP); + ret = arch_clkdm->clkdm_add_sleepdep(clkdm1, clkdm2); } - return 0; + return ret; } /** @@ -628,19 +586,23 @@ int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) { struct clkdm_dep *cd; - - if (!cpu_is_omap34xx()) - return -EINVAL; + int ret = 0; if (!clkdm1 || !clkdm2) return -EINVAL; cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); - if (IS_ERR(cd)) { + if (IS_ERR(cd)) + ret = PTR_ERR(cd); + + if (!arch_clkdm || !arch_clkdm->clkdm_del_sleepdep) + ret = -EINVAL; + + if (ret) { pr_debug("clockdomain: hardware cannot set/clear sleep " "dependency affecting %s from %s\n", clkdm1->name, clkdm2->name); - return PTR_ERR(cd); + return ret; } if (atomic_dec_return(&cd->sleepdep_usecount) == 0) { @@ -648,12 +610,10 @@ int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) "sleeping if %s is active\n", clkdm1->name, clkdm2->name); - omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit), - clkdm1->pwrdm.ptr->prcm_offs, - OMAP3430_CM_SLEEPDEP); + ret = arch_clkdm->clkdm_del_sleepdep(clkdm1, clkdm2); } - return 0; + return ret; } /** @@ -675,25 +635,27 @@ int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) { struct clkdm_dep *cd; - - if (!cpu_is_omap34xx()) - return -EINVAL; + int ret = 0; if (!clkdm1 || !clkdm2) return -EINVAL; cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); - if (IS_ERR(cd)) { + if (IS_ERR(cd)) + ret = PTR_ERR(cd); + + if (!arch_clkdm || !arch_clkdm->clkdm_read_sleepdep) + ret = -EINVAL; + + if (ret) { pr_debug("clockdomain: hardware cannot set/clear sleep " "dependency affecting %s from %s\n", clkdm1->name, clkdm2->name); - return PTR_ERR(cd); + return ret; } /* XXX It's faster to return the atomic sleepdep_usecount */ - return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, - OMAP3430_CM_SLEEPDEP, - (1 << clkdm2->dep_bit)); + return arch_clkdm->clkdm_read_sleepdep(clkdm1, clkdm2); } /** @@ -708,35 +670,17 @@ int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2) */ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm) { - struct clkdm_dep *cd; - u32 mask = 0; - - if (!cpu_is_omap34xx()) - return -EINVAL; - if (!clkdm) return -EINVAL; - for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) { - if (!omap_chip_is(cd->omap_chip)) - continue; - - if (!cd->clkdm && cd->clkdm_name) - cd->clkdm = _clkdm_lookup(cd->clkdm_name); - - /* PRM accesses are slow, so minimize them */ - mask |= 1 << cd->clkdm->dep_bit; - atomic_set(&cd->sleepdep_usecount, 0); - } - - omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, - OMAP3430_CM_SLEEPDEP); + if (!arch_clkdm || !arch_clkdm->clkdm_clear_all_sleepdeps) + return -EINVAL; - return 0; + return arch_clkdm->clkdm_clear_all_sleepdeps(clkdm); } /** - * omap2_clkdm_sleep - force clockdomain sleep transition + * clkdm_sleep - force clockdomain sleep transition * @clkdm: struct clockdomain * * * Instruct the CM to force a sleep transition on the specified @@ -744,7 +688,7 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm) * clockdomain does not support software-initiated sleep; 0 upon * success. */ -int omap2_clkdm_sleep(struct clockdomain *clkdm) +int clkdm_sleep(struct clockdomain *clkdm) { if (!clkdm) return -EINVAL; @@ -755,33 +699,16 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm) return -EINVAL; } - pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name); - - if (cpu_is_omap24xx()) { - - omap2_cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, - clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL); - - } else if (cpu_is_omap34xx()) { - - omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs, - clkdm->clktrctrl_mask); - - } else if (cpu_is_omap44xx()) { - - omap4_cminst_clkdm_force_sleep(clkdm->prcm_partition, - clkdm->cm_inst, - clkdm->clkdm_offs); + if (!arch_clkdm || !arch_clkdm->clkdm_sleep) + return -EINVAL; - } else { - BUG(); - }; + pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name); - return 0; + return arch_clkdm->clkdm_sleep(clkdm); } /** - * omap2_clkdm_wakeup - force clockdomain wakeup transition + * clkdm_wakeup - force clockdomain wakeup transition * @clkdm: struct clockdomain * * * Instruct the CM to force a wakeup transition on the specified @@ -789,7 +716,7 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm) * clockdomain does not support software-controlled wakeup; 0 upon * success. */ -int omap2_clkdm_wakeup(struct clockdomain *clkdm) +int clkdm_wakeup(struct clockdomain *clkdm) { if (!clkdm) return -EINVAL; @@ -800,33 +727,16 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm) return -EINVAL; } - pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name); - - if (cpu_is_omap24xx()) { - - omap2_cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, - clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL); - - } else if (cpu_is_omap34xx()) { - - omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs, - clkdm->clktrctrl_mask); - - } else if (cpu_is_omap44xx()) { - - omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition, - clkdm->cm_inst, - clkdm->clkdm_offs); + if (!arch_clkdm || !arch_clkdm->clkdm_wakeup) + return -EINVAL; - } else { - BUG(); - }; + pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name); - return 0; + return arch_clkdm->clkdm_wakeup(clkdm); } /** - * omap2_clkdm_allow_idle - enable hwsup idle transitions for clkdm + * clkdm_allow_idle - enable hwsup idle transitions for clkdm * @clkdm: struct clockdomain * * * Allow the hardware to automatically switch the clockdomain @clkdm into @@ -835,7 +745,7 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm) * framework, wkdep/sleepdep autodependencies are added; this is so * device drivers can read and write to the device. No return value. */ -void omap2_clkdm_allow_idle(struct clockdomain *clkdm) +void clkdm_allow_idle(struct clockdomain *clkdm) { if (!clkdm) return; @@ -846,27 +756,18 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm) return; } + if (!arch_clkdm || !arch_clkdm->clkdm_allow_idle) + return; + pr_debug("clockdomain: enabling automatic idle transitions for %s\n", clkdm->name); - /* - * XXX This should be removed once TI adds wakeup/sleep - * dependency code and data for OMAP4. - */ - if (cpu_is_omap44xx()) { - pr_err("clockdomain: %s: OMAP4 wakeup/sleep dependency support: not yet implemented\n", clkdm->name); - } else { - if (atomic_read(&clkdm->usecount) > 0) - _clkdm_add_autodeps(clkdm); - } - - _enable_hwsup(clkdm); - + arch_clkdm->clkdm_allow_idle(clkdm); pwrdm_clkdm_state_switch(clkdm); } /** - * omap2_clkdm_deny_idle - disable hwsup idle transitions for clkdm + * clkdm_deny_idle - disable hwsup idle transitions for clkdm * @clkdm: struct clockdomain * * * Prevent the hardware from automatically switching the clockdomain @@ -874,7 +775,7 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm) * downstream clocks enabled in the clock framework, wkdep/sleepdep * autodependencies are removed. No return value. */ -void omap2_clkdm_deny_idle(struct clockdomain *clkdm) +void clkdm_deny_idle(struct clockdomain *clkdm) { if (!clkdm) return; @@ -885,28 +786,20 @@ void omap2_clkdm_deny_idle(struct clockdomain *clkdm) return; } + if (!arch_clkdm || !arch_clkdm->clkdm_deny_idle) + return; + pr_debug("clockdomain: disabling automatic idle transitions for %s\n", clkdm->name); - _disable_hwsup(clkdm); - - /* - * XXX This should be removed once TI adds wakeup/sleep - * dependency code and data for OMAP4. - */ - if (cpu_is_omap44xx()) { - pr_err("clockdomain: %s: OMAP4 wakeup/sleep dependency support: not yet implemented\n", clkdm->name); - } else { - if (atomic_read(&clkdm->usecount) > 0) - _clkdm_del_autodeps(clkdm); - } + arch_clkdm->clkdm_deny_idle(clkdm); } /* Clockdomain-to-clock framework interface code */ /** - * omap2_clkdm_clk_enable - add an enabled downstream clock to this clkdm + * clkdm_clk_enable - add an enabled downstream clock to this clkdm * @clkdm: struct clockdomain * * @clk: struct clk * of the enabled downstream clock * @@ -919,10 +812,8 @@ void omap2_clkdm_deny_idle(struct clockdomain *clkdm) * by on-chip processors. Returns -EINVAL if passed null pointers; * returns 0 upon success or if the clockdomain is in hwsup idle mode. */ -int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) +int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) { - bool hwsup = false; - /* * XXX Rewrite this code to maintain a list of enabled * downstream clocks for debugging purposes? @@ -931,6 +822,9 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) if (!clkdm || !clk) return -EINVAL; + if (!arch_clkdm || !arch_clkdm->clkdm_clk_enable) + return -EINVAL; + if (atomic_inc_return(&clkdm->usecount) > 1) return 0; @@ -939,31 +833,7 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) pr_debug("clockdomain: clkdm %s: clk %s now enabled\n", clkdm->name, clk->name); - if (cpu_is_omap24xx() || cpu_is_omap34xx()) { - - if (!clkdm->clktrctrl_mask) - return 0; - - hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, - clkdm->clktrctrl_mask); - - } else if (cpu_is_omap44xx()) { - - hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition, - clkdm->cm_inst, - clkdm->clkdm_offs); - - } - - if (hwsup) { - /* Disable HW transitions when we are changing deps */ - _disable_hwsup(clkdm); - _clkdm_add_autodeps(clkdm); - _enable_hwsup(clkdm); - } else { - omap2_clkdm_wakeup(clkdm); - } - + arch_clkdm->clkdm_clk_enable(clkdm); pwrdm_wait_transition(clkdm->pwrdm.ptr); pwrdm_clkdm_state_switch(clkdm); @@ -971,7 +841,7 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) } /** - * omap2_clkdm_clk_disable - remove an enabled downstream clock from this clkdm + * clkdm_clk_disable - remove an enabled downstream clock from this clkdm * @clkdm: struct clockdomain * * @clk: struct clk * of the disabled downstream clock * @@ -984,10 +854,8 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) * is enabled; or returns 0 upon success or if the clockdomain is in * hwsup idle mode. */ -int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) +int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) { - bool hwsup = false; - /* * XXX Rewrite this code to maintain a list of enabled * downstream clocks for debugging purposes? @@ -996,6 +864,9 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) if (!clkdm || !clk) return -EINVAL; + if (!arch_clkdm || !arch_clkdm->clkdm_clk_disable) + return -EINVAL; + #ifdef DEBUG if (atomic_read(&clkdm->usecount) == 0) { WARN_ON(1); /* underflow */ @@ -1011,31 +882,7 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) pr_debug("clockdomain: clkdm %s: clk %s now disabled\n", clkdm->name, clk->name); - if (cpu_is_omap24xx() || cpu_is_omap34xx()) { - - if (!clkdm->clktrctrl_mask) - return 0; - - hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, - clkdm->clktrctrl_mask); - - } else if (cpu_is_omap44xx()) { - - hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition, - clkdm->cm_inst, - clkdm->clkdm_offs); - - } - - if (hwsup) { - /* Disable HW transitions when we are changing deps */ - _disable_hwsup(clkdm); - _clkdm_del_autodeps(clkdm); - _enable_hwsup(clkdm); - } else { - omap2_clkdm_sleep(clkdm); - } - + arch_clkdm->clkdm_clk_disable(clkdm); pwrdm_clkdm_state_switch(clkdm); return 0; diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index 9b459c2..85b3dce 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h @@ -4,7 +4,7 @@ * OMAP2/3 clockdomain framework functions * * Copyright (C) 2008 Texas Instruments, Inc. - * Copyright (C) 2008-2010 Nokia Corporation + * Copyright (C) 2008-2011 Nokia Corporation * * Paul Walmsley * @@ -22,11 +22,19 @@ #include <plat/clock.h> #include <plat/cpu.h> -/* Clockdomain capability flags */ +/* + * Clockdomain flags + * + * XXX Document CLKDM_CAN_* flags + * + * CLKDM_NO_AUTODEPS: Prevent "autodeps" from being added/removed from this + * clockdomain. (Currently, this applies to OMAP3 clockdomains only.) + */ #define CLKDM_CAN_FORCE_SLEEP (1 << 0) #define CLKDM_CAN_FORCE_WAKEUP (1 << 1) #define CLKDM_CAN_ENABLE_AUTO (1 << 2) #define CLKDM_CAN_DISABLE_AUTO (1 << 3) +#define CLKDM_NO_AUTODEPS (1 << 4) #define CLKDM_CAN_HWSUP (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO) #define CLKDM_CAN_SWSUP (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP) @@ -116,7 +124,42 @@ struct clockdomain { struct list_head node; }; -void clkdm_init(struct clockdomain **clkdms, struct clkdm_autodep *autodeps); +/** + * struct clkdm_ops - Arch specfic function implementations + * @clkdm_add_wkdep: Add a wakeup dependency between clk domains + * @clkdm_del_wkdep: Delete a wakeup dependency between clk domains + * @clkdm_read_wkdep: Read wakeup dependency state between clk domains + * @clkdm_clear_all_wkdeps: Remove all wakeup dependencies from the clk domain + * @clkdm_add_sleepdep: Add a sleep dependency between clk domains + * @clkdm_del_sleepdep: Delete a sleep dependency between clk domains + * @clkdm_read_sleepdep: Read sleep dependency state between clk domains + * @clkdm_clear_all_sleepdeps: Remove all sleep dependencies from the clk domain + * @clkdm_sleep: Force a clockdomain to sleep + * @clkdm_wakeup: Force a clockdomain to wakeup + * @clkdm_allow_idle: Enable hw supervised idle transitions for clock domain + * @clkdm_deny_idle: Disable hw supervised idle transitions for clock domain + * @clkdm_clk_enable: Put the clkdm in right state for a clock enable + * @clkdm_clk_disable: Put the clkdm in right state for a clock disable + */ +struct clkdm_ops { + int (*clkdm_add_wkdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2); + int (*clkdm_del_wkdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2); + int (*clkdm_read_wkdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2); + int (*clkdm_clear_all_wkdeps)(struct clockdomain *clkdm); + int (*clkdm_add_sleepdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2); + int (*clkdm_del_sleepdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2); + int (*clkdm_read_sleepdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2); + int (*clkdm_clear_all_sleepdeps)(struct clockdomain *clkdm); + int (*clkdm_sleep)(struct clockdomain *clkdm); + int (*clkdm_wakeup)(struct clockdomain *clkdm); + void (*clkdm_allow_idle)(struct clockdomain *clkdm); + void (*clkdm_deny_idle)(struct clockdomain *clkdm); + int (*clkdm_clk_enable)(struct clockdomain *clkdm); + int (*clkdm_clk_disable)(struct clockdomain *clkdm); +}; + +void clkdm_init(struct clockdomain **clkdms, struct clkdm_autodep *autodeps, + struct clkdm_ops *custom_funcs); struct clockdomain *clkdm_lookup(const char *name); int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user), @@ -132,16 +175,23 @@ int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm); -void omap2_clkdm_allow_idle(struct clockdomain *clkdm); -void omap2_clkdm_deny_idle(struct clockdomain *clkdm); +void clkdm_allow_idle(struct clockdomain *clkdm); +void clkdm_deny_idle(struct clockdomain *clkdm); -int omap2_clkdm_wakeup(struct clockdomain *clkdm); -int omap2_clkdm_sleep(struct clockdomain *clkdm); +int clkdm_wakeup(struct clockdomain *clkdm); +int clkdm_sleep(struct clockdomain *clkdm); -int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); -int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk); +int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); +int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk); -extern void __init omap2_clockdomains_init(void); +extern void __init omap2xxx_clockdomains_init(void); +extern void __init omap3xxx_clockdomains_init(void); extern void __init omap44xx_clockdomains_init(void); +extern void _clkdm_add_autodeps(struct clockdomain *clkdm); +extern void _clkdm_del_autodeps(struct clockdomain *clkdm); + +extern struct clkdm_ops omap2_clkdm_operations; +extern struct clkdm_ops omap3_clkdm_operations; +extern struct clkdm_ops omap4_clkdm_operations; #endif diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c new file mode 100644 index 0000000..48d0db7 --- /dev/null +++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c @@ -0,0 +1,274 @@ +/* + * OMAP2 and OMAP3 clockdomain control + * + * Copyright (C) 2008-2010 Texas Instruments, Inc. + * Copyright (C) 2008-2010 Nokia Corporation + * + * Derived from mach-omap2/clockdomain.c written by Paul Walmsley + * Rajendra Nayak <rnayak@ti.com> + * + * 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. + */ + +#include <linux/types.h> +#include <plat/prcm.h> +#include "prm.h" +#include "prm2xxx_3xxx.h" +#include "cm.h" +#include "cm2xxx_3xxx.h" +#include "cm-regbits-24xx.h" +#include "cm-regbits-34xx.h" +#include "prm-regbits-24xx.h" +#include "clockdomain.h" + +static int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) +{ + omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit), + clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP); + return 0; +} + +static int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) +{ + omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit), + clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP); + return 0; +} + +static int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) +{ + return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, + PM_WKDEP, (1 << clkdm2->dep_bit)); +} + +static int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm) +{ + struct clkdm_dep *cd; + u32 mask = 0; + + for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) { + if (!omap_chip_is(cd->omap_chip)) + continue; + if (!cd->clkdm) + continue; /* only happens if data is erroneous */ + + /* PRM accesses are slow, so minimize them */ + mask |= 1 << cd->clkdm->dep_bit; + atomic_set(&cd->wkdep_usecount, 0); + } + + omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, + PM_WKDEP); + return 0; +} + +static int omap3_clkdm_add_sleepdep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) +{ + omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit), + clkdm1->pwrdm.ptr->prcm_offs, + OMAP3430_CM_SLEEPDEP); + return 0; +} + +static int omap3_clkdm_del_sleepdep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) +{ + omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit), + clkdm1->pwrdm.ptr->prcm_offs, + OMAP3430_CM_SLEEPDEP); + return 0; +} + +static int omap3_clkdm_read_sleepdep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) +{ + return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, + OMAP3430_CM_SLEEPDEP, (1 << clkdm2->dep_bit)); +} + +static int omap3_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm) +{ + struct clkdm_dep *cd; + u32 mask = 0; + + for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) { + if (!omap_chip_is(cd->omap_chip)) + continue; + if (!cd->clkdm) + continue; /* only happens if data is erroneous */ + + /* PRM accesses are slow, so minimize them */ + mask |= 1 << cd->clkdm->dep_bit; + atomic_set(&cd->sleepdep_usecount, 0); + } + omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, + OMAP3430_CM_SLEEPDEP); + return 0; +} + +static int omap2_clkdm_sleep(struct clockdomain *clkdm) +{ + omap2_cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, + clkdm->pwrdm.ptr->prcm_offs, + OMAP2_PM_PWSTCTRL); + return 0; +} + +static int omap2_clkdm_wakeup(struct clockdomain *clkdm) +{ + omap2_cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, + clkdm->pwrdm.ptr->prcm_offs, + OMAP2_PM_PWSTCTRL); + return 0; +} + +static void omap2_clkdm_allow_idle(struct clockdomain *clkdm) +{ + if (atomic_read(&clkdm->usecount) > 0) + _clkdm_add_autodeps(clkdm); + + omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); +} + +static void omap2_clkdm_deny_idle(struct clockdomain *clkdm) +{ + omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + + if (atomic_read(&clkdm->usecount) > 0) + _clkdm_del_autodeps(clkdm); +} + +static void _enable_hwsup(struct clockdomain *clkdm) +{ + if (cpu_is_omap24xx()) + omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + else if (cpu_is_omap34xx()) + omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); +} + +static void _disable_hwsup(struct clockdomain *clkdm) +{ + if (cpu_is_omap24xx()) + omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + else if (cpu_is_omap34xx()) + omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); +} + + +static int omap2_clkdm_clk_enable(struct clockdomain *clkdm) +{ + bool hwsup = false; + + if (!clkdm->clktrctrl_mask) + return 0; + + hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + + if (hwsup) { + /* Disable HW transitions when we are changing deps */ + _disable_hwsup(clkdm); + _clkdm_add_autodeps(clkdm); + _enable_hwsup(clkdm); + } else { + clkdm_wakeup(clkdm); + } + + return 0; +} + +static int omap2_clkdm_clk_disable(struct clockdomain *clkdm) +{ + bool hwsup = false; + + if (!clkdm->clktrctrl_mask) + return 0; + + hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + + if (hwsup) { + /* Disable HW transitions when we are changing deps */ + _disable_hwsup(clkdm); + _clkdm_del_autodeps(clkdm); + _enable_hwsup(clkdm); + } else { + clkdm_sleep(clkdm); + } + + return 0; +} + +static int omap3_clkdm_sleep(struct clockdomain *clkdm) +{ + omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + return 0; +} + +static int omap3_clkdm_wakeup(struct clockdomain *clkdm) +{ + omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + return 0; +} + +static void omap3_clkdm_allow_idle(struct clockdomain *clkdm) +{ + if (atomic_read(&clkdm->usecount) > 0) + _clkdm_add_autodeps(clkdm); + + omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); +} + +static void omap3_clkdm_deny_idle(struct clockdomain *clkdm) +{ + omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, + clkdm->clktrctrl_mask); + + if (atomic_read(&clkdm->usecount) > 0) + _clkdm_del_autodeps(clkdm); +} + +struct clkdm_ops omap2_clkdm_operations = { + .clkdm_add_wkdep = omap2_clkdm_add_wkdep, + .clkdm_del_wkdep = omap2_clkdm_del_wkdep, + .clkdm_read_wkdep = omap2_clkdm_read_wkdep, + .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps, + .clkdm_sleep = omap2_clkdm_sleep, + .clkdm_wakeup = omap2_clkdm_wakeup, + .clkdm_allow_idle = omap2_clkdm_allow_idle, + .clkdm_deny_idle = omap2_clkdm_deny_idle, + .clkdm_clk_enable = omap2_clkdm_clk_enable, + .clkdm_clk_disable = omap2_clkdm_clk_disable, +}; + +struct clkdm_ops omap3_clkdm_operations = { + .clkdm_add_wkdep = omap2_clkdm_add_wkdep, + .clkdm_del_wkdep = omap2_clkdm_del_wkdep, + .clkdm_read_wkdep = omap2_clkdm_read_wkdep, + .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps, + .clkdm_add_sleepdep = omap3_clkdm_add_sleepdep, + .clkdm_del_sleepdep = omap3_clkdm_del_sleepdep, + .clkdm_read_sleepdep = omap3_clkdm_read_sleepdep, + .clkdm_clear_all_sleepdeps = omap3_clkdm_clear_all_sleepdeps, + .clkdm_sleep = omap3_clkdm_sleep, + .clkdm_wakeup = omap3_clkdm_wakeup, + .clkdm_allow_idle = omap3_clkdm_allow_idle, + .clkdm_deny_idle = omap3_clkdm_deny_idle, + .clkdm_clk_enable = omap2_clkdm_clk_enable, + .clkdm_clk_disable = omap2_clkdm_clk_disable, +}; diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c new file mode 100644 index 0000000..a1a4ecd --- /dev/null +++ b/arch/arm/mach-omap2/clockdomain44xx.c @@ -0,0 +1,137 @@ +/* + * OMAP4 clockdomain control + * + * Copyright (C) 2008-2010 Texas Instruments, Inc. + * Copyright (C) 2008-2010 Nokia Corporation + * + * Derived from mach-omap2/clockdomain.c written by Paul Walmsley + * Rajendra Nayak <rnayak@ti.com> + * + * 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. + */ + +#include <linux/kernel.h> +#include "clockdomain.h" +#include "cminst44xx.h" +#include "cm44xx.h" + +static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) +{ + omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit), + clkdm1->prcm_partition, + clkdm1->cm_inst, clkdm1->clkdm_offs + + OMAP4_CM_STATICDEP); + return 0; +} + +static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) +{ + omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit), + clkdm1->prcm_partition, + clkdm1->cm_inst, clkdm1->clkdm_offs + + OMAP4_CM_STATICDEP); + return 0; +} + +static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1, + struct clockdomain *clkdm2) +{ + return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition, + clkdm1->cm_inst, clkdm1->clkdm_offs + + OMAP4_CM_STATICDEP, + (1 << clkdm2->dep_bit)); +} + +static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm) +{ + struct clkdm_dep *cd; + u32 mask = 0; + + for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) { + if (!omap_chip_is(cd->omap_chip)) + continue; + if (!cd->clkdm) + continue; /* only happens if data is erroneous */ + + mask |= 1 << cd->clkdm->dep_bit; + atomic_set(&cd->wkdep_usecount, 0); + } + + omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition, + clkdm->cm_inst, clkdm->clkdm_offs + + OMAP4_CM_STATICDEP); + return 0; +} + +static int omap4_clkdm_sleep(struct clockdomain *clkdm) +{ + omap4_cminst_clkdm_force_sleep(clkdm->prcm_partition, + clkdm->cm_inst, clkdm->clkdm_offs); + return 0; +} + +static int omap4_clkdm_wakeup(struct clockdomain *clkdm) +{ + omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition, + clkdm->cm_inst, clkdm->clkdm_offs); + return 0; +} + +static void omap4_clkdm_allow_idle(struct clockdomain *clkdm) +{ + omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition, + clkdm->cm_inst, clkdm->clkdm_offs); +} + +static void omap4_clkdm_deny_idle(struct clockdomain *clkdm) +{ + omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition, + clkdm->cm_inst, clkdm->clkdm_offs); +} + +static int omap4_clkdm_clk_enable(struct clockdomain *clkdm) +{ + bool hwsup = false; + + hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition, + clkdm->cm_inst, clkdm->clkdm_offs); + + if (!hwsup) + clkdm_wakeup(clkdm); + + return 0; +} + +static int omap4_clkdm_clk_disable(struct clockdomain *clkdm) +{ + bool hwsup = false; + + hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition, + clkdm->cm_inst, clkdm->clkdm_offs); + + if (!hwsup) + clkdm_sleep(clkdm); + + return 0; +} + +struct clkdm_ops omap4_clkdm_operations = { + .clkdm_add_wkdep = omap4_clkdm_add_wkup_sleep_dep, + .clkdm_del_wkdep = omap4_clkdm_del_wkup_sleep_dep, + .clkdm_read_wkdep = omap4_clkdm_read_wkup_sleep_dep, + .clkdm_clear_all_wkdeps = omap4_clkdm_clear_all_wkup_sleep_deps, + .clkdm_add_sleepdep = omap4_clkdm_add_wkup_sleep_dep, + .clkdm_del_sleepdep = omap4_clkdm_del_wkup_sleep_dep, + .clkdm_read_sleepdep = omap4_clkdm_read_wkup_sleep_dep, + .clkdm_clear_all_sleepdeps = omap4_clkdm_clear_all_wkup_sleep_deps, + .clkdm_sleep = omap4_clkdm_sleep, + .clkdm_wakeup = omap4_clkdm_wakeup, + .clkdm_allow_idle = omap4_clkdm_allow_idle, + .clkdm_deny_idle = omap4_clkdm_deny_idle, + .clkdm_clk_enable = omap4_clkdm_clk_enable, + .clkdm_clk_disable = omap4_clkdm_clk_disable, +}; diff --git a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c index e6f0d18..13bde95 100644 --- a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c +++ b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c @@ -89,6 +89,8 @@ static struct clkdm_dep gfx_sgx_wkdeps[] = { /* 24XX-specific possible dependencies */ +#ifdef CONFIG_ARCH_OMAP2 + /* Wakeup dependency source arrays */ /* 2420/2430 PM_WKDEP_DSP: CORE, MPU, WKUP */ @@ -168,6 +170,7 @@ static struct clkdm_dep core_24xx_wkdeps[] = { { NULL }, }; +#endif /* CONFIG_ARCH_OMAP2 */ /* 2430-specific possible wakeup dependencies */ @@ -854,7 +857,12 @@ static struct clockdomain *clockdomains_omap2[] __initdata = { NULL, }; -void __init omap2_clockdomains_init(void) +void __init omap2xxx_clockdomains_init(void) +{ + clkdm_init(clockdomains_omap2, clkdm_autodeps, &omap2_clkdm_operations); +} + +void __init omap3xxx_clockdomains_init(void) { - clkdm_init(clockdomains_omap2, clkdm_autodeps); + clkdm_init(clockdomains_omap2, clkdm_autodeps, &omap3_clkdm_operations); } diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c index 10622c9..a607ec1 100644 --- a/arch/arm/mach-omap2/clockdomains44xx_data.c +++ b/arch/arm/mach-omap2/clockdomains44xx_data.c @@ -18,11 +18,6 @@ * published by the Free Software Foundation. */ -/* - * To-Do List - * -> Populate the Sleep/Wakeup dependencies for the domains - */ - #include <linux/kernel.h> #include <linux/io.h> @@ -35,6 +30,355 @@ #include "prcm44xx.h" #include "prcm_mpu44xx.h" +/* Static Dependencies for OMAP4 Clock Domains */ + +static struct clkdm_dep ducati_wkup_sleep_deps[] = { + { + .clkdm_name = "abe_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "ivahd_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_1_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_2_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_dss_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_emif_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_gfx_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_init_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_cfg_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_per_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_secure_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_wkup_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "tesla_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { NULL }, +}; + +static struct clkdm_dep iss_wkup_sleep_deps[] = { + { + .clkdm_name = "ivahd_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_1_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_emif_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { NULL }, +}; + +static struct clkdm_dep ivahd_wkup_sleep_deps[] = { + { + .clkdm_name = "l3_1_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_emif_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { NULL }, +}; + +static struct clkdm_dep l3_d2d_wkup_sleep_deps[] = { + { + .clkdm_name = "abe_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "ivahd_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_1_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_2_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_emif_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_init_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_cfg_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_per_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { NULL }, +}; + +static struct clkdm_dep l3_dma_wkup_sleep_deps[] = { + { + .clkdm_name = "abe_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "ducati_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "ivahd_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_1_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_dss_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_emif_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_init_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_cfg_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_per_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_secure_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_wkup_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { NULL }, +}; + +static struct clkdm_dep l3_dss_wkup_sleep_deps[] = { + { + .clkdm_name = "ivahd_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_2_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_emif_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { NULL }, +}; + +static struct clkdm_dep l3_gfx_wkup_sleep_deps[] = { + { + .clkdm_name = "ivahd_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_1_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_emif_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { NULL }, +}; + +static struct clkdm_dep l3_init_wkup_sleep_deps[] = { + { + .clkdm_name = "abe_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "ivahd_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_emif_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_cfg_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_per_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_secure_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_wkup_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { NULL }, +}; + +static struct clkdm_dep l4_secure_wkup_sleep_deps[] = { + { + .clkdm_name = "l3_1_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_emif_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_per_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { NULL }, +}; + +static struct clkdm_dep mpuss_wkup_sleep_deps[] = { + { + .clkdm_name = "abe_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "ducati_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "ivahd_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_1_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_2_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_dss_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_emif_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_gfx_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_init_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_cfg_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_per_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_secure_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_wkup_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "tesla_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { NULL }, +}; + +static struct clkdm_dep tesla_wkup_sleep_deps[] = { + { + .clkdm_name = "abe_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "ivahd_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_1_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_2_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_emif_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l3_init_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_cfg_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_per_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { + .clkdm_name = "l4_wkup_clkdm", + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430) + }, + { NULL }, +}; static struct clockdomain l4_cefuse_44xx_clkdm = { .name = "l4_cefuse_clkdm", @@ -52,6 +396,7 @@ static struct clockdomain l4_cfg_44xx_clkdm = { .prcm_partition = OMAP4430_CM2_PARTITION, .cm_inst = OMAP4430_CM2_CORE_INST, .clkdm_offs = OMAP4430_CM2_CORE_L4CFG_CDOFFS, + .dep_bit = OMAP4430_L4CFG_STATDEP_SHIFT, .flags = CLKDM_CAN_HWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -62,6 +407,9 @@ static struct clockdomain tesla_44xx_clkdm = { .prcm_partition = OMAP4430_CM1_PARTITION, .cm_inst = OMAP4430_CM1_TESLA_INST, .clkdm_offs = OMAP4430_CM1_TESLA_TESLA_CDOFFS, + .dep_bit = OMAP4430_TESLA_STATDEP_SHIFT, + .wkdep_srcs = tesla_wkup_sleep_deps, + .sleepdep_srcs = tesla_wkup_sleep_deps, .flags = CLKDM_CAN_HWSUP_SWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -72,6 +420,9 @@ static struct clockdomain l3_gfx_44xx_clkdm = { .prcm_partition = OMAP4430_CM2_PARTITION, .cm_inst = OMAP4430_CM2_GFX_INST, .clkdm_offs = OMAP4430_CM2_GFX_GFX_CDOFFS, + .dep_bit = OMAP4430_GFX_STATDEP_SHIFT, + .wkdep_srcs = l3_gfx_wkup_sleep_deps, + .sleepdep_srcs = l3_gfx_wkup_sleep_deps, .flags = CLKDM_CAN_HWSUP_SWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -82,6 +433,9 @@ static struct clockdomain ivahd_44xx_clkdm = { .prcm_partition = OMAP4430_CM2_PARTITION, .cm_inst = OMAP4430_CM2_IVAHD_INST, .clkdm_offs = OMAP4430_CM2_IVAHD_IVAHD_CDOFFS, + .dep_bit = OMAP4430_IVAHD_STATDEP_SHIFT, + .wkdep_srcs = ivahd_wkup_sleep_deps, + .sleepdep_srcs = ivahd_wkup_sleep_deps, .flags = CLKDM_CAN_HWSUP_SWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -92,6 +446,9 @@ static struct clockdomain l4_secure_44xx_clkdm = { .prcm_partition = OMAP4430_CM2_PARTITION, .cm_inst = OMAP4430_CM2_L4PER_INST, .clkdm_offs = OMAP4430_CM2_L4PER_L4SEC_CDOFFS, + .dep_bit = OMAP4430_L4SEC_STATDEP_SHIFT, + .wkdep_srcs = l4_secure_wkup_sleep_deps, + .sleepdep_srcs = l4_secure_wkup_sleep_deps, .flags = CLKDM_CAN_HWSUP_SWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -102,6 +459,7 @@ static struct clockdomain l4_per_44xx_clkdm = { .prcm_partition = OMAP4430_CM2_PARTITION, .cm_inst = OMAP4430_CM2_L4PER_INST, .clkdm_offs = OMAP4430_CM2_L4PER_L4PER_CDOFFS, + .dep_bit = OMAP4430_L4PER_STATDEP_SHIFT, .flags = CLKDM_CAN_HWSUP_SWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -112,6 +470,7 @@ static struct clockdomain abe_44xx_clkdm = { .prcm_partition = OMAP4430_CM1_PARTITION, .cm_inst = OMAP4430_CM1_ABE_INST, .clkdm_offs = OMAP4430_CM1_ABE_ABE_CDOFFS, + .dep_bit = OMAP4430_ABE_STATDEP_SHIFT, .flags = CLKDM_CAN_HWSUP_SWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -131,6 +490,9 @@ static struct clockdomain l3_init_44xx_clkdm = { .prcm_partition = OMAP4430_CM2_PARTITION, .cm_inst = OMAP4430_CM2_L3INIT_INST, .clkdm_offs = OMAP4430_CM2_L3INIT_L3INIT_CDOFFS, + .dep_bit = OMAP4430_L3INIT_STATDEP_SHIFT, + .wkdep_srcs = l3_init_wkup_sleep_deps, + .sleepdep_srcs = l3_init_wkup_sleep_deps, .flags = CLKDM_CAN_HWSUP_SWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -141,6 +503,8 @@ static struct clockdomain mpuss_44xx_clkdm = { .prcm_partition = OMAP4430_CM1_PARTITION, .cm_inst = OMAP4430_CM1_MPU_INST, .clkdm_offs = OMAP4430_CM1_MPU_MPU_CDOFFS, + .wkdep_srcs = mpuss_wkup_sleep_deps, + .sleepdep_srcs = mpuss_wkup_sleep_deps, .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -150,7 +514,7 @@ static struct clockdomain mpu0_44xx_clkdm = { .pwrdm = { .name = "cpu0_pwrdm" }, .prcm_partition = OMAP4430_PRCM_MPU_PARTITION, .cm_inst = OMAP4430_PRCM_MPU_CPU0_INST, - .clkdm_offs = OMAP4430_PRCM_MPU_CPU0_MPU_CDOFFS, + .clkdm_offs = OMAP4430_PRCM_MPU_CPU0_CPU0_CDOFFS, .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -160,7 +524,7 @@ static struct clockdomain mpu1_44xx_clkdm = { .pwrdm = { .name = "cpu1_pwrdm" }, .prcm_partition = OMAP4430_PRCM_MPU_PARTITION, .cm_inst = OMAP4430_PRCM_MPU_CPU1_INST, - .clkdm_offs = OMAP4430_PRCM_MPU_CPU1_MPU_CDOFFS, + .clkdm_offs = OMAP4430_PRCM_MPU_CPU1_CPU1_CDOFFS, .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -171,6 +535,7 @@ static struct clockdomain l3_emif_44xx_clkdm = { .prcm_partition = OMAP4430_CM2_PARTITION, .cm_inst = OMAP4430_CM2_CORE_INST, .clkdm_offs = OMAP4430_CM2_CORE_MEMIF_CDOFFS, + .dep_bit = OMAP4430_MEMIF_STATDEP_SHIFT, .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -191,6 +556,9 @@ static struct clockdomain ducati_44xx_clkdm = { .prcm_partition = OMAP4430_CM2_PARTITION, .cm_inst = OMAP4430_CM2_CORE_INST, .clkdm_offs = OMAP4430_CM2_CORE_DUCATI_CDOFFS, + .dep_bit = OMAP4430_DUCATI_STATDEP_SHIFT, + .wkdep_srcs = ducati_wkup_sleep_deps, + .sleepdep_srcs = ducati_wkup_sleep_deps, .flags = CLKDM_CAN_HWSUP_SWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -201,6 +569,7 @@ static struct clockdomain l3_2_44xx_clkdm = { .prcm_partition = OMAP4430_CM2_PARTITION, .cm_inst = OMAP4430_CM2_CORE_INST, .clkdm_offs = OMAP4430_CM2_CORE_L3_2_CDOFFS, + .dep_bit = OMAP4430_L3_2_STATDEP_SHIFT, .flags = CLKDM_CAN_HWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -211,6 +580,7 @@ static struct clockdomain l3_1_44xx_clkdm = { .prcm_partition = OMAP4430_CM2_PARTITION, .cm_inst = OMAP4430_CM2_CORE_INST, .clkdm_offs = OMAP4430_CM2_CORE_L3_1_CDOFFS, + .dep_bit = OMAP4430_L3_1_STATDEP_SHIFT, .flags = CLKDM_CAN_HWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -221,6 +591,8 @@ static struct clockdomain l3_d2d_44xx_clkdm = { .prcm_partition = OMAP4430_CM2_PARTITION, .cm_inst = OMAP4430_CM2_CORE_INST, .clkdm_offs = OMAP4430_CM2_CORE_D2D_CDOFFS, + .wkdep_srcs = l3_d2d_wkup_sleep_deps, + .sleepdep_srcs = l3_d2d_wkup_sleep_deps, .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -231,6 +603,8 @@ static struct clockdomain iss_44xx_clkdm = { .prcm_partition = OMAP4430_CM2_PARTITION, .cm_inst = OMAP4430_CM2_CAM_INST, .clkdm_offs = OMAP4430_CM2_CAM_CAM_CDOFFS, + .wkdep_srcs = iss_wkup_sleep_deps, + .sleepdep_srcs = iss_wkup_sleep_deps, .flags = CLKDM_CAN_HWSUP_SWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -241,6 +615,9 @@ static struct clockdomain l3_dss_44xx_clkdm = { .prcm_partition = OMAP4430_CM2_PARTITION, .cm_inst = OMAP4430_CM2_DSS_INST, .clkdm_offs = OMAP4430_CM2_DSS_DSS_CDOFFS, + .dep_bit = OMAP4430_DSS_STATDEP_SHIFT, + .wkdep_srcs = l3_dss_wkup_sleep_deps, + .sleepdep_srcs = l3_dss_wkup_sleep_deps, .flags = CLKDM_CAN_HWSUP_SWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -251,6 +628,7 @@ static struct clockdomain l4_wkup_44xx_clkdm = { .prcm_partition = OMAP4430_PRM_PARTITION, .cm_inst = OMAP4430_PRM_WKUP_CM_INST, .clkdm_offs = OMAP4430_PRM_WKUP_CM_WKUP_CDOFFS, + .dep_bit = OMAP4430_L4WKUP_STATDEP_SHIFT, .flags = CLKDM_CAN_HWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -271,6 +649,8 @@ static struct clockdomain l3_dma_44xx_clkdm = { .prcm_partition = OMAP4430_CM2_PARTITION, .cm_inst = OMAP4430_CM2_CORE_INST, .clkdm_offs = OMAP4430_CM2_CORE_SDMA_CDOFFS, + .wkdep_srcs = l3_dma_wkup_sleep_deps, + .sleepdep_srcs = l3_dma_wkup_sleep_deps, .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; @@ -305,5 +685,5 @@ static struct clockdomain *clockdomains_omap44xx[] __initdata = { void __init omap44xx_clockdomains_init(void) { - clkdm_init(clockdomains_omap44xx, NULL); + clkdm_init(clockdomains_omap44xx, NULL, &omap4_clkdm_operations); } diff --git a/arch/arm/mach-omap2/cm-regbits-24xx.h b/arch/arm/mach-omap2/cm-regbits-24xx.h index d70660e..6862904 100644 --- a/arch/arm/mach-omap2/cm-regbits-24xx.h +++ b/arch/arm/mach-omap2/cm-regbits-24xx.h @@ -210,8 +210,11 @@ #define OMAP24XX_AUTO_USB_MASK (1 << 0) /* CM_AUTOIDLE3_CORE */ +#define OMAP24XX_AUTO_SDRC_SHIFT 2 #define OMAP24XX_AUTO_SDRC_MASK (1 << 2) +#define OMAP24XX_AUTO_GPMC_SHIFT 1 #define OMAP24XX_AUTO_GPMC_MASK (1 << 1) +#define OMAP24XX_AUTO_SDMA_SHIFT 0 #define OMAP24XX_AUTO_SDMA_MASK (1 << 0) /* CM_AUTOIDLE4_CORE */ diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.c b/arch/arm/mach-omap2/cm2xxx_3xxx.c index 96954aa..9d0dec8 100644 --- a/arch/arm/mach-omap2/cm2xxx_3xxx.c +++ b/arch/arm/mach-omap2/cm2xxx_3xxx.c @@ -25,6 +25,14 @@ #include "cm-regbits-24xx.h" #include "cm-regbits-34xx.h" +/* CM_AUTOIDLE_PLL.AUTO_* bit values for DPLLs */ +#define DPLL_AUTOIDLE_DISABLE 0x0 +#define OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP 0x3 + +/* CM_AUTOIDLE_PLL.AUTO_* bit values for APLLs (OMAP2xxx only) */ +#define OMAP2XXX_APLL_AUTOIDLE_DISABLE 0x0 +#define OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP 0x3 + static const u8 cm_idlest_offs[] = { CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3 }; @@ -125,6 +133,67 @@ void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask) _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, module, mask); } +/* + * DPLL autoidle control + */ + +static void _omap2xxx_set_dpll_autoidle(u8 m) +{ + u32 v; + + v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE); + v &= ~OMAP24XX_AUTO_DPLL_MASK; + v |= m << OMAP24XX_AUTO_DPLL_SHIFT; + omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE); +} + +void omap2xxx_cm_set_dpll_disable_autoidle(void) +{ + _omap2xxx_set_dpll_autoidle(OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP); +} + +void omap2xxx_cm_set_dpll_auto_low_power_stop(void) +{ + _omap2xxx_set_dpll_autoidle(DPLL_AUTOIDLE_DISABLE); +} + +/* + * APLL autoidle control + */ + +static void _omap2xxx_set_apll_autoidle(u8 m, u32 mask) +{ + u32 v; + + v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE); + v &= ~mask; + v |= m << __ffs(mask); + omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE); +} + +void omap2xxx_cm_set_apll54_disable_autoidle(void) +{ + _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP, + OMAP24XX_AUTO_54M_MASK); +} + +void omap2xxx_cm_set_apll54_auto_low_power_stop(void) +{ + _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE, + OMAP24XX_AUTO_54M_MASK); +} + +void omap2xxx_cm_set_apll96_disable_autoidle(void) +{ + _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP, + OMAP24XX_AUTO_96M_MASK); +} + +void omap2xxx_cm_set_apll96_auto_low_power_stop(void) +{ + _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE, + OMAP24XX_AUTO_96M_MASK); +} /* * diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.h b/arch/arm/mach-omap2/cm2xxx_3xxx.h index 5e9ea5b..088bbad 100644 --- a/arch/arm/mach-omap2/cm2xxx_3xxx.h +++ b/arch/arm/mach-omap2/cm2xxx_3xxx.h @@ -122,6 +122,14 @@ extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask); extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask); extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask); +extern void omap2xxx_cm_set_dpll_disable_autoidle(void); +extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void); + +extern void omap2xxx_cm_set_apll54_disable_autoidle(void); +extern void omap2xxx_cm_set_apll54_auto_low_power_stop(void); +extern void omap2xxx_cm_set_apll96_disable_autoidle(void); +extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void); + #endif /* CM register bits shared between 24XX and 3430 */ diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h index 48fc3f4..0b87ec8 100644 --- a/arch/arm/mach-omap2/cm44xx.h +++ b/arch/arm/mach-omap2/cm44xx.h @@ -21,6 +21,7 @@ #include "cm.h" #define OMAP4_CM_CLKSTCTRL 0x0000 +#define OMAP4_CM_STATICDEP 0x0004 /* Function prototypes */ # ifndef __ASSEMBLER__ diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index c04bbbe..a482bfa 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c @@ -73,6 +73,27 @@ u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst, return v; } +u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, s16 inst, s16 idx) +{ + return omap4_cminst_rmw_inst_reg_bits(bits, bits, part, inst, idx); +} + +u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, s16 inst, s16 idx) +{ + return omap4_cminst_rmw_inst_reg_bits(bits, 0x0, part, inst, idx); +} + +u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, u32 mask) +{ + u32 v; + + v = omap4_cminst_read_inst_reg(part, inst, idx); + v &= mask; + v >>= __ffs(mask); + + return v; +} + /* * */ diff --git a/arch/arm/mach-omap2/cminst44xx.h b/arch/arm/mach-omap2/cminst44xx.h index a6abd0a..2b32c18 100644 --- a/arch/arm/mach-omap2/cminst44xx.h +++ b/arch/arm/mach-omap2/cminst44xx.h @@ -25,6 +25,12 @@ extern u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx); extern void omap4_cminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx); extern u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst, s16 idx); +extern u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, s16 inst, + s16 idx); +extern u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, s16 inst, + s16 idx); +extern u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, + u32 mask); extern int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg); diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index f7b22a1..7cc8071 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -99,14 +99,14 @@ static int omap3_idle_bm_check(void) static int _cpuidle_allow_idle(struct powerdomain *pwrdm, struct clockdomain *clkdm) { - omap2_clkdm_allow_idle(clkdm); + clkdm_allow_idle(clkdm); return 0; } static int _cpuidle_deny_idle(struct powerdomain *pwrdm, struct clockdomain *clkdm) { - omap2_clkdm_deny_idle(clkdm); + clkdm_deny_idle(clkdm); return 0; } diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c new file mode 100644 index 0000000..4e4da61 --- /dev/null +++ b/arch/arm/mach-omap2/dpll44xx.c @@ -0,0 +1,84 @@ +/* + * OMAP4-specific DPLL control functions + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Rajendra Nayak + * + * 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. + */ + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/bitops.h> + +#include <plat/cpu.h> +#include <plat/clock.h> + +#include "clock.h" +#include "cm-regbits-44xx.h" + +/* Supported only on OMAP4 */ +int omap4_dpllmx_gatectrl_read(struct clk *clk) +{ + u32 v; + u32 mask; + + if (!clk || !clk->clksel_reg || !cpu_is_omap44xx()) + return -EINVAL; + + mask = clk->flags & CLOCK_CLKOUTX2 ? + OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK : + OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK; + + v = __raw_readl(clk->clksel_reg); + v &= mask; + v >>= __ffs(mask); + + return v; +} + +void omap4_dpllmx_allow_gatectrl(struct clk *clk) +{ + u32 v; + u32 mask; + + if (!clk || !clk->clksel_reg || !cpu_is_omap44xx()) + return; + + mask = clk->flags & CLOCK_CLKOUTX2 ? + OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK : + OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK; + + v = __raw_readl(clk->clksel_reg); + /* Clear the bit to allow gatectrl */ + v &= ~mask; + __raw_writel(v, clk->clksel_reg); +} + +void omap4_dpllmx_deny_gatectrl(struct clk *clk) +{ + u32 v; + u32 mask; + + if (!clk || !clk->clksel_reg || !cpu_is_omap44xx()) + return; + + mask = clk->flags & CLOCK_CLKOUTX2 ? + OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK : + OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK; + + v = __raw_readl(clk->clksel_reg); + /* Set the bit to deny gatectrl */ + v |= mask; + __raw_writel(v, clk->clksel_reg); +} + +const struct clkops clkops_omap4_dpllmx_ops = { + .allow_idle = omap4_dpllmx_allow_gatectrl, + .deny_idle = omap4_dpllmx_deny_gatectrl, +}; + diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 657f3c8..441e79d 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -356,15 +356,15 @@ void __init omap2_init_common_infrastructure(void) if (cpu_is_omap242x()) { omap2xxx_powerdomains_init(); - omap2_clockdomains_init(); + omap2xxx_clockdomains_init(); omap2420_hwmod_init(); } else if (cpu_is_omap243x()) { omap2xxx_powerdomains_init(); - omap2_clockdomains_init(); + omap2xxx_clockdomains_init(); omap2430_hwmod_init(); } else if (cpu_is_omap34xx()) { omap3xxx_powerdomains_init(); - omap2_clockdomains_init(); + omap3xxx_clockdomains_init(); omap3xxx_hwmod_init(); } else if (cpu_is_omap44xx()) { omap44xx_powerdomains_init(); diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 1125134..e39772b 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -457,14 +457,18 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v) * will be accessed by a particular initiator (e.g., if a module will * be accessed by the IVA, there should be a sleepdep between the IVA * initiator and the module). Only applies to modules in smart-idle - * mode. Returns -EINVAL upon error or passes along - * clkdm_add_sleepdep() value upon success. + * mode. If the clockdomain is marked as not needing autodeps, return + * 0 without doing anything. Otherwise, returns -EINVAL upon error or + * passes along clkdm_add_sleepdep() value upon success. */ static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) { if (!oh->_clk) return -EINVAL; + if (oh->_clk->clkdm && oh->_clk->clkdm->flags & CLKDM_NO_AUTODEPS) + return 0; + return clkdm_add_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm); } @@ -477,14 +481,18 @@ static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) * be accessed by a particular initiator (e.g., if a module will not * be accessed by the IVA, there should be no sleepdep between the IVA * initiator and the module). Only applies to modules in smart-idle - * mode. Returns -EINVAL upon error or passes along - * clkdm_del_sleepdep() value upon success. + * mode. If the clockdomain is marked as not needing autodeps, return + * 0 without doing anything. Returns -EINVAL upon error or passes + * along clkdm_del_sleepdep() value upon success. */ static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) { if (!oh->_clk) return -EINVAL; + if (oh->_clk->clkdm && oh->_clk->clkdm->flags & CLKDM_NO_AUTODEPS) + return 0; + return clkdm_del_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm); } @@ -1283,6 +1291,42 @@ static int _idle(struct omap_hwmod *oh) } /** + * omap_hwmod_set_ocp_autoidle - set the hwmod's OCP autoidle bit + * @oh: struct omap_hwmod * + * @autoidle: desired AUTOIDLE bitfield value (0 or 1) + * + * Sets the IP block's OCP autoidle bit in hardware, and updates our + * local copy. Intended to be used by drivers that require + * direct manipulation of the AUTOIDLE bits. + * Returns -EINVAL if @oh is null or is not in the ENABLED state, or passes + * along the return value from _set_module_autoidle(). + * + * Any users of this function should be scrutinized carefully. + */ +int omap_hwmod_set_ocp_autoidle(struct omap_hwmod *oh, u8 autoidle) +{ + u32 v; + int retval = 0; + unsigned long flags; + + if (!oh || oh->_state != _HWMOD_STATE_ENABLED) + return -EINVAL; + + spin_lock_irqsave(&oh->_lock, flags); + + v = oh->_sysc_cache; + + retval = _set_module_autoidle(oh, autoidle, &v); + + if (!retval) + _write_sysconfig(v, oh); + + spin_unlock_irqrestore(&oh->_lock, flags); + + return retval; +} + +/** * _shutdown - shutdown an omap_hwmod * @oh: struct omap_hwmod * * @@ -2286,3 +2330,29 @@ u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh) return ret; } + +/** + * omap_hwmod_no_setup_reset - prevent a hwmod from being reset upon setup + * @oh: struct omap_hwmod * + * + * Prevent the hwmod @oh from being reset during the setup process. + * Intended for use by board-*.c files on boards with devices that + * cannot tolerate being reset. Must be called before the hwmod has + * been set up. Returns 0 upon success or negative error code upon + * failure. + */ +int omap_hwmod_no_setup_reset(struct omap_hwmod *oh) +{ + if (!oh) + return -EINVAL; + + if (oh->_state != _HWMOD_STATE_REGISTERED) { + pr_err("omap_hwmod: %s: cannot prevent setup reset; in wrong state\n", + oh->name); + return -EINVAL; + } + + oh->flags |= HWMOD_INIT_NO_RESET; + + return 0; +} diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 229eb94..2e275cb 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1284,6 +1284,11 @@ static struct omap_hwmod omap3xxx_wd_timer2_hwmod = { .slaves = omap3xxx_wd_timer2_slaves, .slaves_cnt = ARRAY_SIZE(omap3xxx_wd_timer2_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), + /* + * XXX: Use software supervised mode, HW supervised smartidle seems to + * block CORE power domain idle transitions. Maybe a HW bug in wdt2? + */ + .flags = HWMOD_SWSUP_SIDLE, }; /* UART common */ diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index d5a102c..7bb64d8 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -124,7 +124,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) { sleep_switch = LOWPOWERSTATE_SWITCH; } else { - omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]); + clkdm_wakeup(pwrdm->pwrdm_clkdms[0]); pwrdm_wait_transition(pwrdm); sleep_switch = FORCEWAKEUP_SWITCH; } @@ -140,9 +140,9 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) switch (sleep_switch) { case FORCEWAKEUP_SWITCH: if (pwrdm->pwrdm_clkdms[0]->flags & CLKDM_CAN_ENABLE_AUTO) - omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]); + clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]); else - omap2_clkdm_sleep(pwrdm->pwrdm_clkdms[0]); + clkdm_sleep(pwrdm->pwrdm_clkdms[0]); break; case LOWPOWERSTATE_SWITCH: pwrdm_set_lowpwrstchange(pwrdm); diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index 97feb3a..96907da 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -367,10 +367,10 @@ static int __init clkdms_setup(struct clockdomain *clkdm, void *unused) clkdm_clear_all_sleepdeps(clkdm); if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO) - omap2_clkdm_allow_idle(clkdm); + clkdm_allow_idle(clkdm); else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && atomic_read(&clkdm->usecount) == 0) - omap2_clkdm_sleep(clkdm); + clkdm_sleep(clkdm); return 0; } @@ -379,7 +379,10 @@ static void __init prcm_setup_regs(void) int i, num_mem_banks; struct powerdomain *pwrdm; - /* Enable autoidle */ + /* + * Enable autoidle + * XXX This should be handled by hwmod code or PRCM init code + */ omap2_prm_write_mod_reg(OMAP24XX_AUTOIDLE_MASK, OCP_MOD, OMAP2_PRCM_SYSCONFIG_OFFSET); @@ -405,11 +408,11 @@ static void __init prcm_setup_regs(void) pwrdm = clkdm_get_pwrdm(dsp_clkdm); pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF); - omap2_clkdm_sleep(dsp_clkdm); + clkdm_sleep(dsp_clkdm); pwrdm = clkdm_get_pwrdm(gfx_clkdm); pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF); - omap2_clkdm_sleep(gfx_clkdm); + clkdm_sleep(gfx_clkdm); /* * Clear clockdomain wakeup dependencies and enable @@ -418,70 +421,6 @@ static void __init prcm_setup_regs(void) clkdm_for_each(clkdms_setup, NULL); clkdm_add_wkdep(mpu_clkdm, wkup_clkdm); - /* Enable clock autoidle for all domains */ - omap2_cm_write_mod_reg(OMAP24XX_AUTO_CAM_MASK | - OMAP24XX_AUTO_MAILBOXES_MASK | - OMAP24XX_AUTO_WDT4_MASK | - OMAP2420_AUTO_WDT3_MASK | - OMAP24XX_AUTO_MSPRO_MASK | - OMAP2420_AUTO_MMC_MASK | - OMAP24XX_AUTO_FAC_MASK | - OMAP2420_AUTO_EAC_MASK | - OMAP24XX_AUTO_HDQ_MASK | - OMAP24XX_AUTO_UART2_MASK | - OMAP24XX_AUTO_UART1_MASK | - OMAP24XX_AUTO_I2C2_MASK | - OMAP24XX_AUTO_I2C1_MASK | - OMAP24XX_AUTO_MCSPI2_MASK | - OMAP24XX_AUTO_MCSPI1_MASK | - OMAP24XX_AUTO_MCBSP2_MASK | - OMAP24XX_AUTO_MCBSP1_MASK | - OMAP24XX_AUTO_GPT12_MASK | - OMAP24XX_AUTO_GPT11_MASK | - OMAP24XX_AUTO_GPT10_MASK | - OMAP24XX_AUTO_GPT9_MASK | - OMAP24XX_AUTO_GPT8_MASK | - OMAP24XX_AUTO_GPT7_MASK | - OMAP24XX_AUTO_GPT6_MASK | - OMAP24XX_AUTO_GPT5_MASK | - OMAP24XX_AUTO_GPT4_MASK | - OMAP24XX_AUTO_GPT3_MASK | - OMAP24XX_AUTO_GPT2_MASK | - OMAP2420_AUTO_VLYNQ_MASK | - OMAP24XX_AUTO_DSS_MASK, - CORE_MOD, CM_AUTOIDLE1); - omap2_cm_write_mod_reg(OMAP24XX_AUTO_UART3_MASK | - OMAP24XX_AUTO_SSI_MASK | - OMAP24XX_AUTO_USB_MASK, - CORE_MOD, CM_AUTOIDLE2); - omap2_cm_write_mod_reg(OMAP24XX_AUTO_SDRC_MASK | - OMAP24XX_AUTO_GPMC_MASK | - OMAP24XX_AUTO_SDMA_MASK, - CORE_MOD, CM_AUTOIDLE3); - omap2_cm_write_mod_reg(OMAP24XX_AUTO_PKA_MASK | - OMAP24XX_AUTO_AES_MASK | - OMAP24XX_AUTO_RNG_MASK | - OMAP24XX_AUTO_SHA_MASK | - OMAP24XX_AUTO_DES_MASK, - CORE_MOD, OMAP24XX_CM_AUTOIDLE4); - - omap2_cm_write_mod_reg(OMAP2420_AUTO_DSP_IPI_MASK, OMAP24XX_DSP_MOD, - CM_AUTOIDLE); - - /* Put DPLL and both APLLs into autoidle mode */ - omap2_cm_write_mod_reg((0x03 << OMAP24XX_AUTO_DPLL_SHIFT) | - (0x03 << OMAP24XX_AUTO_96M_SHIFT) | - (0x03 << OMAP24XX_AUTO_54M_SHIFT), - PLL_MOD, CM_AUTOIDLE); - - omap2_cm_write_mod_reg(OMAP24XX_AUTO_OMAPCTRL_MASK | - OMAP24XX_AUTO_WDT1_MASK | - OMAP24XX_AUTO_MPU_WDT_MASK | - OMAP24XX_AUTO_GPIOS_MASK | - OMAP24XX_AUTO_32KSYNC_MASK | - OMAP24XX_AUTO_GPT1_MASK, - WKUP_MOD, CM_AUTOIDLE); - /* REVISIT: Configure number of 32 kHz clock cycles for sys_clk * stabilisation */ omap2_prm_write_mod_reg(15 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD, diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 2f864e4..3d6a00e 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -496,7 +496,7 @@ console_still_active: pwrdm_post_transition(); - omap2_clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]); + clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]); } int omap3_can_sleep(void) @@ -688,14 +688,11 @@ static void __init omap3_d2d_idle(void) static void __init prcm_setup_regs(void) { - u32 omap3630_auto_uart4_mask = cpu_is_omap3630() ? - OMAP3630_AUTO_UART4_MASK : 0; u32 omap3630_en_uart4_mask = cpu_is_omap3630() ? OMAP3630_EN_UART4_MASK : 0; u32 omap3630_grpsel_uart4_mask = cpu_is_omap3630() ? OMAP3630_GRPSEL_UART4_MASK : 0; - /* XXX Reset all wkdeps. This should be done when initializing * powerdomains */ omap2_prm_write_mod_reg(0, OMAP3430_IVA2_MOD, PM_WKDEP); @@ -710,127 +707,10 @@ static void __init prcm_setup_regs(void) } else omap2_prm_write_mod_reg(0, GFX_MOD, PM_WKDEP); - /* - * Enable interface clock autoidle for all modules. - * Note that in the long run this should be done by clockfw - */ - omap2_cm_write_mod_reg( - OMAP3430_AUTO_MODEM_MASK | - OMAP3430ES2_AUTO_MMC3_MASK | - OMAP3430ES2_AUTO_ICR_MASK | - OMAP3430_AUTO_AES2_MASK | - OMAP3430_AUTO_SHA12_MASK | - OMAP3430_AUTO_DES2_MASK | - OMAP3430_AUTO_MMC2_MASK | - OMAP3430_AUTO_MMC1_MASK | - OMAP3430_AUTO_MSPRO_MASK | - OMAP3430_AUTO_HDQ_MASK | - OMAP3430_AUTO_MCSPI4_MASK | - OMAP3430_AUTO_MCSPI3_MASK | - OMAP3430_AUTO_MCSPI2_MASK | - OMAP3430_AUTO_MCSPI1_MASK | - OMAP3430_AUTO_I2C3_MASK | - OMAP3430_AUTO_I2C2_MASK | - OMAP3430_AUTO_I2C1_MASK | - OMAP3430_AUTO_UART2_MASK | - OMAP3430_AUTO_UART1_MASK | - OMAP3430_AUTO_GPT11_MASK | - OMAP3430_AUTO_GPT10_MASK | - OMAP3430_AUTO_MCBSP5_MASK | - OMAP3430_AUTO_MCBSP1_MASK | - OMAP3430ES1_AUTO_FAC_MASK | /* This is es1 only */ - OMAP3430_AUTO_MAILBOXES_MASK | - OMAP3430_AUTO_OMAPCTRL_MASK | - OMAP3430ES1_AUTO_FSHOSTUSB_MASK | - OMAP3430_AUTO_HSOTGUSB_MASK | - OMAP3430_AUTO_SAD2D_MASK | - OMAP3430_AUTO_SSI_MASK, - CORE_MOD, CM_AUTOIDLE1); - - omap2_cm_write_mod_reg( - OMAP3430_AUTO_PKA_MASK | - OMAP3430_AUTO_AES1_MASK | - OMAP3430_AUTO_RNG_MASK | - OMAP3430_AUTO_SHA11_MASK | - OMAP3430_AUTO_DES1_MASK, - CORE_MOD, CM_AUTOIDLE2); - - if (omap_rev() > OMAP3430_REV_ES1_0) { - omap2_cm_write_mod_reg( - OMAP3430_AUTO_MAD2D_MASK | - OMAP3430ES2_AUTO_USBTLL_MASK, - CORE_MOD, CM_AUTOIDLE3); - } - - omap2_cm_write_mod_reg( - OMAP3430_AUTO_WDT2_MASK | - OMAP3430_AUTO_WDT1_MASK | - OMAP3430_AUTO_GPIO1_MASK | - OMAP3430_AUTO_32KSYNC_MASK | - OMAP3430_AUTO_GPT12_MASK | - OMAP3430_AUTO_GPT1_MASK, - WKUP_MOD, CM_AUTOIDLE); - - omap2_cm_write_mod_reg( - OMAP3430_AUTO_DSS_MASK, - OMAP3430_DSS_MOD, - CM_AUTOIDLE); - - omap2_cm_write_mod_reg( - OMAP3430_AUTO_CAM_MASK, - OMAP3430_CAM_MOD, - CM_AUTOIDLE); - - omap2_cm_write_mod_reg( - omap3630_auto_uart4_mask | - OMAP3430_AUTO_GPIO6_MASK | - OMAP3430_AUTO_GPIO5_MASK | - OMAP3430_AUTO_GPIO4_MASK | - OMAP3430_AUTO_GPIO3_MASK | - OMAP3430_AUTO_GPIO2_MASK | - OMAP3430_AUTO_WDT3_MASK | - OMAP3430_AUTO_UART3_MASK | - OMAP3430_AUTO_GPT9_MASK | - OMAP3430_AUTO_GPT8_MASK | - OMAP3430_AUTO_GPT7_MASK | - OMAP3430_AUTO_GPT6_MASK | - OMAP3430_AUTO_GPT5_MASK | - OMAP3430_AUTO_GPT4_MASK | - OMAP3430_AUTO_GPT3_MASK | - OMAP3430_AUTO_GPT2_MASK | - OMAP3430_AUTO_MCBSP4_MASK | - OMAP3430_AUTO_MCBSP3_MASK | - OMAP3430_AUTO_MCBSP2_MASK, - OMAP3430_PER_MOD, - CM_AUTOIDLE); - - if (omap_rev() > OMAP3430_REV_ES1_0) { - omap2_cm_write_mod_reg( - OMAP3430ES2_AUTO_USBHOST_MASK, - OMAP3430ES2_USBHOST_MOD, - CM_AUTOIDLE); - } - + /* XXX This should be handled by hwmod code or SCM init code */ omap_ctrl_writel(OMAP3430_AUTOIDLE_MASK, OMAP2_CONTROL_SYSCONFIG); /* - * Set all plls to autoidle. This is needed until autoidle is - * enabled by clockfw - */ - omap2_cm_write_mod_reg(1 << OMAP3430_AUTO_IVA2_DPLL_SHIFT, - OMAP3430_IVA2_MOD, CM_AUTOIDLE2); - omap2_cm_write_mod_reg(1 << OMAP3430_AUTO_MPU_DPLL_SHIFT, - MPU_MOD, - CM_AUTOIDLE2); - omap2_cm_write_mod_reg((1 << OMAP3430_AUTO_PERIPH_DPLL_SHIFT) | - (1 << OMAP3430_AUTO_CORE_DPLL_SHIFT), - PLL_MOD, - CM_AUTOIDLE); - omap2_cm_write_mod_reg(1 << OMAP3430ES2_AUTO_PERIPH2_DPLL_SHIFT, - PLL_MOD, - CM_AUTOIDLE2); - - /* * Enable control of expternal oscillator through * sys_clkreq. In the long run clock framework should * take care of this. @@ -990,10 +870,10 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) static int __init clkdms_setup(struct clockdomain *clkdm, void *unused) { if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO) - omap2_clkdm_allow_idle(clkdm); + clkdm_allow_idle(clkdm); else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && atomic_read(&clkdm->usecount) == 0) - omap2_clkdm_sleep(clkdm); + clkdm_sleep(clkdm); return 0; } diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index eaed0df..a11be81 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -2,7 +2,7 @@ * OMAP powerdomain control * * Copyright (C) 2007-2008 Texas Instruments, Inc. - * Copyright (C) 2007-2009 Nokia Corporation + * Copyright (C) 2007-2011 Nokia Corporation * * Written by Paul Walmsley * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com> @@ -938,3 +938,44 @@ u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm) return count; } + +/** + * pwrdm_can_ever_lose_context - can this powerdomain ever lose context? + * @pwrdm: struct powerdomain * + * + * Given a struct powerdomain * @pwrdm, returns 1 if the powerdomain + * can lose either memory or logic context or if @pwrdm is invalid, or + * returns 0 otherwise. This function is not concerned with how the + * powerdomain registers are programmed (i.e., to go off or not); it's + * concerned with whether it's ever possible for this powerdomain to + * go off while some other part of the chip is active. This function + * assumes that every powerdomain can go to either ON or INACTIVE. + */ +bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm) +{ + int i; + + if (IS_ERR_OR_NULL(pwrdm)) { + pr_debug("powerdomain: %s: invalid powerdomain pointer\n", + __func__); + return 1; + } + + if (pwrdm->pwrsts & PWRSTS_OFF) + return 1; + + if (pwrdm->pwrsts & PWRSTS_RET) { + if (pwrdm->pwrsts_logic_ret & PWRSTS_OFF) + return 1; + + for (i = 0; i < pwrdm->banks; i++) + if (pwrdm->pwrsts_mem_ret[i] & PWRSTS_OFF) + return 1; + } + + for (i = 0; i < pwrdm->banks; i++) + if (pwrdm->pwrsts_mem_on[i] & PWRSTS_OFF) + return 1; + + return 0; +} diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h index c66431e..027f40b 100644 --- a/arch/arm/mach-omap2/powerdomain.h +++ b/arch/arm/mach-omap2/powerdomain.h @@ -2,7 +2,7 @@ * OMAP2/3/4 powerdomain control * * Copyright (C) 2007-2008, 2010 Texas Instruments, Inc. - * Copyright (C) 2007-2010 Nokia Corporation + * Copyright (C) 2007-2011 Nokia Corporation * * Paul Walmsley * @@ -34,17 +34,14 @@ /* Powerdomain allowable state bitfields */ #define PWRSTS_ON (1 << PWRDM_POWER_ON) +#define PWRSTS_INACTIVE (1 << PWRDM_POWER_INACTIVE) +#define PWRSTS_RET (1 << PWRDM_POWER_RET) #define PWRSTS_OFF (1 << PWRDM_POWER_OFF) -#define PWRSTS_OFF_ON ((1 << PWRDM_POWER_OFF) | \ - (1 << PWRDM_POWER_ON)) -#define PWRSTS_OFF_RET ((1 << PWRDM_POWER_OFF) | \ - (1 << PWRDM_POWER_RET)) - -#define PWRSTS_RET_ON ((1 << PWRDM_POWER_RET) | \ - (1 << PWRDM_POWER_ON)) - -#define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | (1 << PWRDM_POWER_ON)) +#define PWRSTS_OFF_ON (PWRSTS_OFF | PWRSTS_ON) +#define PWRSTS_OFF_RET (PWRSTS_OFF | PWRSTS_RET) +#define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON) +#define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | PWRSTS_ON) /* Powerdomain flags */ @@ -165,7 +162,6 @@ struct pwrdm_ops { int (*pwrdm_wait_transition)(struct powerdomain *pwrdm); }; -void pwrdm_fw_init(void); void pwrdm_init(struct powerdomain **pwrdm_list, struct pwrdm_ops *custom_funcs); struct powerdomain *pwrdm_lookup(const char *name); @@ -212,6 +208,7 @@ int pwrdm_pre_transition(void); int pwrdm_post_transition(void); int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm); u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm); +bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm); extern void omap2xxx_powerdomains_init(void); extern void omap3xxx_powerdomains_init(void); diff --git a/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c index 5b4dd97..4210c33 100644 --- a/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c +++ b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c @@ -2,7 +2,7 @@ * OMAP2/3 common powerdomain definitions * * Copyright (C) 2007-2008 Texas Instruments, Inc. - * Copyright (C) 2007-2010 Nokia Corporation + * Copyright (C) 2007-2011 Nokia Corporation * * Paul Walmsley, Jouni Högander * @@ -62,13 +62,13 @@ struct powerdomain gfx_omap2_pwrdm = { .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430ES1), .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, + .pwrsts_logic_ret = PWRSTS_RET, .banks = 1, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ + [0] = PWRSTS_RET, /* MEMRETSTATE */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ + [0] = PWRSTS_ON, /* MEMONSTATE */ }, }; @@ -76,4 +76,5 @@ struct powerdomain wkup_omap2_pwrdm = { .name = "wkup_pwrdm", .prcm_offs = WKUP_MOD, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430), + .pwrsts = PWRSTS_ON, }; diff --git a/arch/arm/mach-omap2/powerdomains2xxx_data.c b/arch/arm/mach-omap2/powerdomains2xxx_data.c index 78739e1..cc389fb 100644 --- a/arch/arm/mach-omap2/powerdomains2xxx_data.c +++ b/arch/arm/mach-omap2/powerdomains2xxx_data.c @@ -2,7 +2,7 @@ * OMAP2XXX powerdomain definitions * * Copyright (C) 2007-2008 Texas Instruments, Inc. - * Copyright (C) 2007-2010 Nokia Corporation + * Copyright (C) 2007-2011 Nokia Corporation * * Paul Walmsley, Jouni Högander * @@ -30,13 +30,13 @@ static struct powerdomain dsp_pwrdm = { .prcm_offs = OMAP24XX_DSP_MOD, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX), .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, + .pwrsts_logic_ret = PWRSTS_RET, .banks = 1, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, + [0] = PWRSTS_RET, }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, + [0] = PWRSTS_ON, }, }; @@ -48,10 +48,10 @@ static struct powerdomain mpu_24xx_pwrdm = { .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 1, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, + [0] = PWRSTS_RET, }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, + [0] = PWRSTS_ON, }, }; @@ -87,13 +87,13 @@ static struct powerdomain mdm_pwrdm = { .prcm_offs = OMAP2430_MDM_MOD, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, + .pwrsts_logic_ret = PWRSTS_RET, .banks = 1, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ + [0] = PWRSTS_RET, /* MEMRETSTATE */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ + [0] = PWRSTS_ON, /* MEMONSTATE */ }, }; diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c index e1bec56..9c9c113 100644 --- a/arch/arm/mach-omap2/powerdomains3xxx_data.c +++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c @@ -2,7 +2,7 @@ * OMAP3 powerdomain definitions * * Copyright (C) 2007-2008 Texas Instruments, Inc. - * Copyright (C) 2007-2010 Nokia Corporation + * Copyright (C) 2007-2011 Nokia Corporation * * Paul Walmsley, Jouni Högander * @@ -47,10 +47,10 @@ static struct powerdomain iva2_pwrdm = { [3] = PWRSTS_OFF_RET, }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, - [1] = PWRDM_POWER_ON, + [0] = PWRSTS_ON, + [1] = PWRSTS_ON, [2] = PWRSTS_OFF_ON, - [3] = PWRDM_POWER_ON, + [3] = PWRSTS_ON, }, }; @@ -128,13 +128,13 @@ static struct powerdomain dss_pwrdm = { .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), .prcm_offs = OMAP3430_DSS_MOD, .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, + .pwrsts_logic_ret = PWRSTS_RET, .banks = 1, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ + [0] = PWRSTS_RET, /* MEMRETSTATE */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ + [0] = PWRSTS_ON, /* MEMONSTATE */ }, }; @@ -149,13 +149,13 @@ static struct powerdomain sgx_pwrdm = { .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2), /* XXX This is accurate for 3430 SGX, but what about GFX? */ .pwrsts = PWRSTS_OFF_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, + .pwrsts_logic_ret = PWRSTS_RET, .banks = 1, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ + [0] = PWRSTS_RET, /* MEMRETSTATE */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ + [0] = PWRSTS_ON, /* MEMONSTATE */ }, }; @@ -164,13 +164,13 @@ static struct powerdomain cam_pwrdm = { .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), .prcm_offs = OMAP3430_CAM_MOD, .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, + .pwrsts_logic_ret = PWRSTS_RET, .banks = 1, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ + [0] = PWRSTS_RET, /* MEMRETSTATE */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ + [0] = PWRSTS_ON, /* MEMONSTATE */ }, }; @@ -182,10 +182,10 @@ static struct powerdomain per_pwrdm = { .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 1, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ + [0] = PWRSTS_RET, /* MEMRETSTATE */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ + [0] = PWRSTS_ON, /* MEMONSTATE */ }, }; @@ -200,7 +200,7 @@ static struct powerdomain neon_pwrdm = { .prcm_offs = OMAP3430_NEON_MOD, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, + .pwrsts_logic_ret = PWRSTS_RET, }; static struct powerdomain usbhost_pwrdm = { @@ -208,7 +208,7 @@ static struct powerdomain usbhost_pwrdm = { .prcm_offs = OMAP3430ES2_USBHOST_MOD, .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2), .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_RET, + .pwrsts_logic_ret = PWRSTS_RET, /* * REVISIT: Enabling usb host save and restore mechanism seems to * leave the usb host domain permanently in ACTIVE mode after @@ -218,10 +218,10 @@ static struct powerdomain usbhost_pwrdm = { /*.flags = PWRDM_HAS_HDWR_SAR,*/ /* for USBHOST ctrlr only */ .banks = 1, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* MEMRETSTATE */ + [0] = PWRSTS_RET, /* MEMRETSTATE */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* MEMONSTATE */ + [0] = PWRSTS_ON, /* MEMONSTATE */ }, }; diff --git a/arch/arm/mach-omap2/powerdomains44xx_data.c b/arch/arm/mach-omap2/powerdomains44xx_data.c index 26d7641..c4222c7 100644 --- a/arch/arm/mach-omap2/powerdomains44xx_data.c +++ b/arch/arm/mach-omap2/powerdomains44xx_data.c @@ -2,7 +2,7 @@ * OMAP4 Power domains framework * * Copyright (C) 2009-2010 Texas Instruments, Inc. - * Copyright (C) 2009-2010 Nokia Corporation + * Copyright (C) 2009-2011 Nokia Corporation * * Abhijit Pagare (abhijitpagare@ti.com) * Benoit Cousson (b-cousson@ti.com) @@ -40,18 +40,18 @@ static struct powerdomain core_44xx_pwrdm = { .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 5, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_OFF, /* core_nret_bank */ + [0] = PWRSTS_OFF, /* core_nret_bank */ [1] = PWRSTS_OFF_RET, /* core_ocmram */ - [2] = PWRDM_POWER_RET, /* core_other_bank */ + [2] = PWRSTS_RET, /* core_other_bank */ [3] = PWRSTS_OFF_RET, /* ducati_l2ram */ [4] = PWRSTS_OFF_RET, /* ducati_unicache */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* core_nret_bank */ + [0] = PWRSTS_ON, /* core_nret_bank */ [1] = PWRSTS_OFF_RET, /* core_ocmram */ - [2] = PWRDM_POWER_ON, /* core_other_bank */ - [3] = PWRDM_POWER_ON, /* ducati_l2ram */ - [4] = PWRDM_POWER_ON, /* ducati_unicache */ + [2] = PWRSTS_ON, /* core_other_bank */ + [3] = PWRSTS_ON, /* ducati_l2ram */ + [4] = PWRSTS_ON, /* ducati_unicache */ }, .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; @@ -65,10 +65,10 @@ static struct powerdomain gfx_44xx_pwrdm = { .pwrsts = PWRSTS_OFF_ON, .banks = 1, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_OFF, /* gfx_mem */ + [0] = PWRSTS_OFF, /* gfx_mem */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* gfx_mem */ + [0] = PWRSTS_ON, /* gfx_mem */ }, .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; @@ -80,15 +80,15 @@ static struct powerdomain abe_44xx_pwrdm = { .prcm_partition = OMAP4430_PRM_PARTITION, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_OFF, + .pwrsts_logic_ret = PWRSTS_OFF, .banks = 2, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* aessmem */ - [1] = PWRDM_POWER_OFF, /* periphmem */ + [0] = PWRSTS_RET, /* aessmem */ + [1] = PWRSTS_OFF, /* periphmem */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* aessmem */ - [1] = PWRDM_POWER_ON, /* periphmem */ + [0] = PWRSTS_ON, /* aessmem */ + [1] = PWRSTS_ON, /* periphmem */ }, .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; @@ -103,10 +103,10 @@ static struct powerdomain dss_44xx_pwrdm = { .pwrsts_logic_ret = PWRSTS_OFF, .banks = 1, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_OFF, /* dss_mem */ + [0] = PWRSTS_OFF, /* dss_mem */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* dss_mem */ + [0] = PWRSTS_ON, /* dss_mem */ }, .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; @@ -121,14 +121,14 @@ static struct powerdomain tesla_44xx_pwrdm = { .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 3, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_RET, /* tesla_edma */ + [0] = PWRSTS_RET, /* tesla_edma */ [1] = PWRSTS_OFF_RET, /* tesla_l1 */ [2] = PWRSTS_OFF_RET, /* tesla_l2 */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* tesla_edma */ - [1] = PWRDM_POWER_ON, /* tesla_l1 */ - [2] = PWRDM_POWER_ON, /* tesla_l2 */ + [0] = PWRSTS_ON, /* tesla_edma */ + [1] = PWRSTS_ON, /* tesla_l1 */ + [2] = PWRSTS_ON, /* tesla_l2 */ }, .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; @@ -142,10 +142,10 @@ static struct powerdomain wkup_44xx_pwrdm = { .pwrsts = PWRSTS_ON, .banks = 1, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_OFF, /* wkup_bank */ + [0] = PWRSTS_OFF, /* wkup_bank */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* wkup_bank */ + [0] = PWRSTS_ON, /* wkup_bank */ }, }; @@ -162,7 +162,7 @@ static struct powerdomain cpu0_44xx_pwrdm = { [0] = PWRSTS_OFF_RET, /* cpu0_l1 */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* cpu0_l1 */ + [0] = PWRSTS_ON, /* cpu0_l1 */ }, }; @@ -179,7 +179,7 @@ static struct powerdomain cpu1_44xx_pwrdm = { [0] = PWRSTS_OFF_RET, /* cpu1_l1 */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* cpu1_l1 */ + [0] = PWRSTS_ON, /* cpu1_l1 */ }, }; @@ -192,10 +192,10 @@ static struct powerdomain emu_44xx_pwrdm = { .pwrsts = PWRSTS_OFF_ON, .banks = 1, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_OFF, /* emu_bank */ + [0] = PWRSTS_OFF, /* emu_bank */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* emu_bank */ + [0] = PWRSTS_ON, /* emu_bank */ }, }; @@ -211,12 +211,12 @@ static struct powerdomain mpu_44xx_pwrdm = { .pwrsts_mem_ret = { [0] = PWRSTS_OFF_RET, /* mpu_l1 */ [1] = PWRSTS_OFF_RET, /* mpu_l2 */ - [2] = PWRDM_POWER_RET, /* mpu_ram */ + [2] = PWRSTS_RET, /* mpu_ram */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* mpu_l1 */ - [1] = PWRDM_POWER_ON, /* mpu_l2 */ - [2] = PWRDM_POWER_ON, /* mpu_ram */ + [0] = PWRSTS_ON, /* mpu_l1 */ + [1] = PWRSTS_ON, /* mpu_l2 */ + [2] = PWRSTS_ON, /* mpu_ram */ }, }; @@ -227,19 +227,19 @@ static struct powerdomain ivahd_44xx_pwrdm = { .prcm_partition = OMAP4430_PRM_PARTITION, .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), .pwrsts = PWRSTS_OFF_RET_ON, - .pwrsts_logic_ret = PWRDM_POWER_OFF, + .pwrsts_logic_ret = PWRSTS_OFF, .banks = 4, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_OFF, /* hwa_mem */ + [0] = PWRSTS_OFF, /* hwa_mem */ [1] = PWRSTS_OFF_RET, /* sl2_mem */ [2] = PWRSTS_OFF_RET, /* tcm1_mem */ [3] = PWRSTS_OFF_RET, /* tcm2_mem */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* hwa_mem */ - [1] = PWRDM_POWER_ON, /* sl2_mem */ - [2] = PWRDM_POWER_ON, /* tcm1_mem */ - [3] = PWRDM_POWER_ON, /* tcm2_mem */ + [0] = PWRSTS_ON, /* hwa_mem */ + [1] = PWRSTS_ON, /* sl2_mem */ + [2] = PWRSTS_ON, /* tcm1_mem */ + [3] = PWRSTS_ON, /* tcm2_mem */ }, .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; @@ -253,10 +253,10 @@ static struct powerdomain cam_44xx_pwrdm = { .pwrsts = PWRSTS_OFF_ON, .banks = 1, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_OFF, /* cam_mem */ + [0] = PWRSTS_OFF, /* cam_mem */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* cam_mem */ + [0] = PWRSTS_ON, /* cam_mem */ }, .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; @@ -271,10 +271,10 @@ static struct powerdomain l3init_44xx_pwrdm = { .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 1, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_OFF, /* l3init_bank1 */ + [0] = PWRSTS_OFF, /* l3init_bank1 */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* l3init_bank1 */ + [0] = PWRSTS_ON, /* l3init_bank1 */ }, .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; @@ -289,12 +289,12 @@ static struct powerdomain l4per_44xx_pwrdm = { .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 2, .pwrsts_mem_ret = { - [0] = PWRDM_POWER_OFF, /* nonretained_bank */ - [1] = PWRDM_POWER_RET, /* retained_bank */ + [0] = PWRSTS_OFF, /* nonretained_bank */ + [1] = PWRSTS_RET, /* retained_bank */ }, .pwrsts_mem_on = { - [0] = PWRDM_POWER_ON, /* nonretained_bank */ - [1] = PWRDM_POWER_ON, /* retained_bank */ + [0] = PWRSTS_ON, /* nonretained_bank */ + [1] = PWRSTS_ON, /* retained_bank */ }, .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; diff --git a/arch/arm/mach-omap2/prcm_mpu44xx.h b/arch/arm/mach-omap2/prcm_mpu44xx.h index 3300ff6..d22d1b4 100644 --- a/arch/arm/mach-omap2/prcm_mpu44xx.h +++ b/arch/arm/mach-omap2/prcm_mpu44xx.h @@ -38,8 +38,8 @@ #define OMAP4430_PRCM_MPU_CPU1_INST 0x0800 /* PRCM_MPU clockdomain register offsets (from instance start) */ -#define OMAP4430_PRCM_MPU_CPU0_MPU_CDOFFS 0x0018 -#define OMAP4430_PRCM_MPU_CPU1_MPU_CDOFFS 0x0018 +#define OMAP4430_PRCM_MPU_CPU0_CPU0_CDOFFS 0x0018 +#define OMAP4430_PRCM_MPU_CPU1_CPU1_CDOFFS 0x0018 /* diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index fc62fb5..c9122dd 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -37,14 +37,16 @@ static struct clk_functions *arch_clock; int clk_enable(struct clk *clk) { unsigned long flags; - int ret = 0; + int ret; if (clk == NULL || IS_ERR(clk)) return -EINVAL; + if (!arch_clock || !arch_clock->clk_enable) + return -EINVAL; + spin_lock_irqsave(&clockfw_lock, flags); - if (arch_clock->clk_enable) - ret = arch_clock->clk_enable(clk); + ret = arch_clock->clk_enable(clk); spin_unlock_irqrestore(&clockfw_lock, flags); return ret; @@ -58,6 +60,9 @@ void clk_disable(struct clk *clk) if (clk == NULL || IS_ERR(clk)) return; + if (!arch_clock || !arch_clock->clk_disable) + return; + spin_lock_irqsave(&clockfw_lock, flags); if (clk->usecount == 0) { pr_err("Trying disable clock %s with 0 usecount\n", @@ -66,8 +71,7 @@ void clk_disable(struct clk *clk) goto out; } - if (arch_clock->clk_disable) - arch_clock->clk_disable(clk); + arch_clock->clk_disable(clk); out: spin_unlock_irqrestore(&clockfw_lock, flags); @@ -77,7 +81,7 @@ EXPORT_SYMBOL(clk_disable); unsigned long clk_get_rate(struct clk *clk) { unsigned long flags; - unsigned long ret = 0; + unsigned long ret; if (clk == NULL || IS_ERR(clk)) return 0; @@ -97,14 +101,16 @@ EXPORT_SYMBOL(clk_get_rate); long clk_round_rate(struct clk *clk, unsigned long rate) { unsigned long flags; - long ret = 0; + long ret; if (clk == NULL || IS_ERR(clk)) - return ret; + return 0; + + if (!arch_clock || !arch_clock->clk_round_rate) + return 0; spin_lock_irqsave(&clockfw_lock, flags); - if (arch_clock->clk_round_rate) - ret = arch_clock->clk_round_rate(clk, rate); + ret = arch_clock->clk_round_rate(clk, rate); spin_unlock_irqrestore(&clockfw_lock, flags); return ret; @@ -119,14 +125,13 @@ int clk_set_rate(struct clk *clk, unsigned long rate) if (clk == NULL || IS_ERR(clk)) return ret; + if (!arch_clock || !arch_clock->clk_set_rate) + return ret; + spin_lock_irqsave(&clockfw_lock, flags); - if (arch_clock->clk_set_rate) - ret = arch_clock->clk_set_rate(clk, rate); - if (ret == 0) { - if (clk->recalc) - clk->rate = clk->recalc(clk); + ret = arch_clock->clk_set_rate(clk, rate); + if (ret == 0) propagate_rate(clk); - } spin_unlock_irqrestore(&clockfw_lock, flags); return ret; @@ -141,15 +146,14 @@ int clk_set_parent(struct clk *clk, struct clk *parent) if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent)) return ret; + if (!arch_clock || !arch_clock->clk_set_parent) + return ret; + spin_lock_irqsave(&clockfw_lock, flags); if (clk->usecount == 0) { - if (arch_clock->clk_set_parent) - ret = arch_clock->clk_set_parent(clk, parent); - if (ret == 0) { - if (clk->recalc) - clk->rate = clk->recalc(clk); + ret = arch_clock->clk_set_parent(clk, parent); + if (ret == 0) propagate_rate(clk); - } } else ret = -EBUSY; spin_unlock_irqrestore(&clockfw_lock, flags); @@ -335,6 +339,38 @@ struct clk *omap_clk_get_by_name(const char *name) return ret; } +int omap_clk_enable_autoidle_all(void) +{ + struct clk *c; + unsigned long flags; + + spin_lock_irqsave(&clockfw_lock, flags); + + list_for_each_entry(c, &clocks, node) + if (c->ops->allow_idle) + c->ops->allow_idle(c); + + spin_unlock_irqrestore(&clockfw_lock, flags); + + return 0; +} + +int omap_clk_disable_autoidle_all(void) +{ + struct clk *c; + unsigned long flags; + + spin_lock_irqsave(&clockfw_lock, flags); + + list_for_each_entry(c, &clocks, node) + if (c->ops->deny_idle) + c->ops->deny_idle(c); + + spin_unlock_irqrestore(&clockfw_lock, flags); + + return 0; +} + /* * Low level helpers */ @@ -367,9 +403,11 @@ void clk_init_cpufreq_table(struct cpufreq_frequency_table **table) { unsigned long flags; + if (!arch_clock || !arch_clock->clk_init_cpufreq_table) + return; + spin_lock_irqsave(&clockfw_lock, flags); - if (arch_clock->clk_init_cpufreq_table) - arch_clock->clk_init_cpufreq_table(table); + arch_clock->clk_init_cpufreq_table(table); spin_unlock_irqrestore(&clockfw_lock, flags); } @@ -377,9 +415,11 @@ void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table) { unsigned long flags; + if (!arch_clock || !arch_clock->clk_exit_cpufreq_table) + return; + spin_lock_irqsave(&clockfw_lock, flags); - if (arch_clock->clk_exit_cpufreq_table) - arch_clock->clk_exit_cpufreq_table(table); + arch_clock->clk_exit_cpufreq_table(table); spin_unlock_irqrestore(&clockfw_lock, flags); } #endif @@ -397,6 +437,9 @@ static int __init clk_disable_unused(void) struct clk *ck; unsigned long flags; + if (!arch_clock || !arch_clock->clk_disable_unused) + return 0; + pr_info("clock: disabling unused clocks to save power\n"); list_for_each_entry(ck, &clocks, node) { if (ck->ops == &clkops_null) @@ -406,14 +449,14 @@ static int __init clk_disable_unused(void) continue; spin_lock_irqsave(&clockfw_lock, flags); - if (arch_clock->clk_disable_unused) - arch_clock->clk_disable_unused(ck); + arch_clock->clk_disable_unused(ck); spin_unlock_irqrestore(&clockfw_lock, flags); } return 0; } late_initcall(clk_disable_unused); +late_initcall(omap_clk_enable_autoidle_all); #endif int __init clk_init(struct clk_functions * custom_clocks) diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 1d706cf..ee9f6eb 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -342,6 +342,10 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer) l |= 0x02 << 3; /* Set to smart-idle mode */ l |= 0x2 << 8; /* Set clock activity to perserve f-clock on idle */ + /* Enable autoidle on OMAP2 / OMAP3 */ + if (cpu_is_omap24xx() || cpu_is_omap34xx()) + l |= 0x1 << 0; + /* * Enable wake-up on OMAP2 CPUs. */ diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h index d43e623..006e599 100644 --- a/arch/arm/plat-omap/include/plat/clock.h +++ b/arch/arm/plat-omap/include/plat/clock.h @@ -25,6 +25,8 @@ struct clockdomain; * @disable: fn ptr that enables the current clock in hardware * @find_idlest: function returning the IDLEST register for the clock's IP blk * @find_companion: function returning the "companion" clk reg for the clock + * @allow_idle: fn ptr that enables autoidle for the current clock in hardware + * @deny_idle: fn ptr that disables autoidle for the current clock in hardware * * A "companion" clk is an accompanying clock to the one being queried * that must be enabled for the IP module connected to the clock to @@ -42,6 +44,8 @@ struct clkops { u8 *, u8 *); void (*find_companion)(struct clk *, void __iomem **, u8 *); + void (*allow_idle)(struct clk *); + void (*deny_idle)(struct clk *); }; #ifdef CONFIG_ARCH_OMAP2PLUS @@ -105,7 +109,6 @@ struct clksel { * @clk_ref: struct clk pointer to the clock's reference clock input * @control_reg: register containing the DPLL mode bitfield * @enable_mask: mask of the DPLL mode bitfield in @control_reg - * @rate_tolerance: maximum variance allowed from target rate (in Hz) * @last_rounded_rate: cache of the last rate result of omap2_dpll_round_rate() * @last_rounded_m: cache of the last M result of omap2_dpll_round_rate() * @max_multiplier: maximum valid non-bypass multiplier value (actual) @@ -131,12 +134,9 @@ struct clksel { * XXX Some DPLLs have multiple bypass inputs, so it's not technically * correct to only have one @clk_bypass pointer. * - * XXX @rate_tolerance should probably be deprecated - currently there - * don't seem to be any usecases for DPLL rounding that is not exact. - * * XXX The runtime-variable fields (@last_rounded_rate, @last_rounded_m, * @last_rounded_n) should be separated from the runtime-fixed fields - * and placed into a differenct structure, so that the runtime-fixed data + * and placed into a different structure, so that the runtime-fixed data * can be placed into read-only space. */ struct dpll_data { @@ -147,7 +147,6 @@ struct dpll_data { struct clk *clk_ref; void __iomem *control_reg; u32 enable_mask; - unsigned int rate_tolerance; unsigned long last_rounded_rate; u16 last_rounded_m; u16 max_multiplier; @@ -172,12 +171,24 @@ struct dpll_data { #endif -/* struct clk.flags possibilities */ +/* + * struct clk.flags possibilities + * + * XXX document the rest of the clock flags here + * + * CLOCK_CLKOUTX2: (OMAP4 only) DPLL CLKOUT and CLKOUTX2 GATE_CTRL + * bits share the same register. This flag allows the + * omap4_dpllmx*() code to determine which GATE_CTRL bit field + * should be used. This is a temporary solution - a better approach + * would be to associate clock type-specific data with the clock, + * similar to the struct dpll_data approach. + */ #define ENABLE_REG_32BIT (1 << 0) /* Use 32-bit access */ #define CLOCK_IDLE_CONTROL (1 << 1) #define CLOCK_NO_IDLE_PARENT (1 << 2) #define ENABLE_ON_INIT (1 << 3) /* Enable upon framework init */ #define INVERT_ENABLE (1 << 4) /* 0 enables, 1 disables */ +#define CLOCK_CLKOUTX2 (1 << 5) /** * struct clk - OMAP struct clk @@ -293,6 +304,8 @@ extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table); extern void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table); #endif extern struct clk *omap_clk_get_by_name(const char *name); +extern int omap_clk_enable_autoidle_all(void); +extern int omap_clk_disable_autoidle_all(void); extern const struct clkops clkops_null; diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 97aa8e7..8a1368f 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -561,6 +561,7 @@ int omap_hwmod_enable_clocks(struct omap_hwmod *oh); int omap_hwmod_disable_clocks(struct omap_hwmod *oh); int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode); +int omap_hwmod_set_ocp_autoidle(struct omap_hwmod *oh, u8 autoidle); int omap_hwmod_reset(struct omap_hwmod *oh); void omap_hwmod_ocp_barrier(struct omap_hwmod *oh); @@ -595,6 +596,8 @@ int omap_hwmod_for_each_by_class(const char *classname, int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state); u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh); +int omap_hwmod_no_setup_reset(struct omap_hwmod *oh); + /* * Chip variant-specific hwmod init routines - XXX should be converted * to use initcalls once the initial boot ordering is straightened out diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index 57adb27..9bbda9a 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -83,9 +83,11 @@ #include <linux/err.h> #include <linux/io.h> #include <linux/clk.h> +#include <linux/clkdev.h> #include <plat/omap_device.h> #include <plat/omap_hwmod.h> +#include <plat/clock.h> /* These parameters are passed to _omap_device_{de,}activate() */ #define USE_WAKEUP_LAT 0 @@ -239,12 +241,12 @@ static inline struct omap_device *_find_by_pdev(struct platform_device *pdev) } /** - * _add_optional_clock_alias - Add clock alias for hwmod optional clocks + * _add_optional_clock_clkdev - Add clkdev entry for hwmod optional clocks * @od: struct omap_device *od * * For every optional clock present per hwmod per omap_device, this function - * adds an entry in the clocks list of the form <dev-id=dev_name, con-id=role> - * if an entry is already present in it with the form <dev-id=NULL, con-id=role> + * adds an entry in the clkdev table of the form <dev-id=dev_name, con-id=role> + * if it does not exist already. * * The function is called from inside omap_device_build_ss(), after * omap_device_register. @@ -254,25 +256,39 @@ static inline struct omap_device *_find_by_pdev(struct platform_device *pdev) * * No return value. */ -static void _add_optional_clock_alias(struct omap_device *od, +static void _add_optional_clock_clkdev(struct omap_device *od, struct omap_hwmod *oh) { int i; for (i = 0; i < oh->opt_clks_cnt; i++) { struct omap_hwmod_opt_clk *oc; - int r; + struct clk *r; + struct clk_lookup *l; oc = &oh->opt_clks[i]; if (!oc->_clk) continue; - r = clk_add_alias(oc->role, dev_name(&od->pdev.dev), - (char *)oc->clk, &od->pdev.dev); - if (r) - pr_err("omap_device: %s: clk_add_alias for %s failed\n", + r = clk_get_sys(dev_name(&od->pdev.dev), oc->role); + if (!IS_ERR(r)) + continue; /* clkdev entry exists */ + + r = omap_clk_get_by_name((char *)oc->clk); + if (IS_ERR(r)) { + pr_err("omap_device: %s: omap_clk_get_by_name for %s failed\n", + dev_name(&od->pdev.dev), oc->clk); + continue; + } + + l = clkdev_alloc(r, oc->role, dev_name(&od->pdev.dev)); + if (!l) { + pr_err("omap_device: %s: clkdev_alloc for %s failed\n", dev_name(&od->pdev.dev), oc->role); + return; + } + clkdev_add(l); } } @@ -480,7 +496,7 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, for (i = 0; i < oh_cnt; i++) { hwmods[i]->od = od; - _add_optional_clock_alias(od, hwmods[i]); + _add_optional_clock_clkdev(od, hwmods[i]); } if (ret) |