OMAP2/3 clock: fix module IDLEST code for unusual devs
Paul Walmsley
maintainercover OMAP2/3 clock: fix module IDLEST code for unusual devs
Hello,
After Linux enables an OMAP device's clocks, it must wait for the device to leave the 'idle' state, or register accesses may result in an interconnect error and subsequent system crash. Code to do this is currently in the OMAP clock code, but is overgeneralized, and will not work correctly for several exception cases - one on 2430, and four on OMAP3.
This series fixes these bugs by modularizing omap2_clk_wait_ready(), allowing custom CM_IDLEST register and bit shift data to be supplied on a per-clock basis, if necessary. (This was originally fixed in the linux-omap kernel during 2.6.29 in a slightly different manner.)
In the medium term, the module wait code will be moved to omap_hwmod or a similar OMAP device layer.
Tested on BeagleBoard rev C2 (OMAP3530 ES3); compile-tested with the N800 defconfig.
- Paul
---
text data bss dec hex filename
3346788 187872 103104 3637764 378204 vmlinux.beagle.orig 3347316 188608 103104 3639028 3786f4 vmlinux.beagle
Paul Walmsley (3):
OMAP3 clock: correct module IDLEST bits: SSI; DSS; USBHOST; HSOTGUSB OMAP2 clock: 2430 I2CHS uses non-standard CM_IDLEST register OMAP2/3 clock: split, rename omap2_wait_clock_ready()
arch/arm/mach-omap2/clock.c | 126 +++++++++++------------------ arch/arm/mach-omap2/clock.h | 6 + arch/arm/mach-omap2/clock24xx.c | 37 ++++++++- arch/arm/mach-omap2/clock24xx.h | 4 - arch/arm/mach-omap2/clock34xx.c | 133 +++++++++++++++++++++++++++++-- arch/arm/mach-omap2/clock34xx.h | 85 +++++++++++++++++--- arch/arm/mach-omap2/prcm.c | 43 ++++++++++ arch/arm/plat-omap/include/mach/clock.h | 2 arch/arm/plat-omap/include/mach/prcm.h | 1 9 files changed, 338 insertions(+), 99 deletions(-)
Paul Walmsley
maintainerPATCH 1/3 OMAP2/3 clock: split, rename omap2_wait_clock_ready()
Some OMAP2/3 hardware modules have CM_IDLEST attributes that are not handled by the current omap2_wait_clock_ready() code. In preparation for patches that fix the unusual devices, rename the function omap2_wait_clock_ready() to omap2_wait_module_ready() and split it into three parts:
1. A clkops-specific companion clock return function (by default, omap2_clk_dflt_find_companion())
2. A clkops-specific CM_IDLEST register address and bit shift return function (by default, omap2_clk_dflt_find_idlest())
3. Code to wait for the CM to indicate that the module is ready (omap2_cm_wait_idlest())
Clocks can now specify their own custom find_companion() and find_idlest() functions; used in subsequent patches.
--- arch/arm/mach-omap2/clock.c | 126 ++++++++++++------------------- arch/arm/mach-omap2/clock.h | 6 + arch/arm/mach-omap2/prcm.c | 43 +++++++++++ arch/arm/plat-omap/include/mach/clock.h | 2 arch/arm/plat-omap/include/mach/prcm.h | 1 5 files changed, 101 insertions(+), 77 deletions(-)
arch/arm/mach-omap2/clock.c +49 -77
@@ -27,6 +27,7 @@#include <mach/clock.h> #include <mach/clockdomain.h> #include <mach/cpu.h> +#include <mach/prcm.h> #include <asm/div64.h> #include <mach/sdrc.h>
@@ -38,8 +39,6 @@#include "cm-regbits-24xx.h" #include "cm-regbits-34xx.h" -#define MAX_CLOCK_ENABLE_WAIT 100000 -/* DPLL rate rounding: minimum DPLL multiplier, divider values */ #define DPLL_MIN_MULTIPLIER 1#define DPLL_MIN_DIVIDER 1
@@ -273,84 +272,68 @@ unsigned long omap2_fixed_divisor_recalc(struct clk *clk)return clk->parent->rate / clk->fixed_div; } -/** -* omap2_wait_clock_ready - wait for clock to enable -* @reg: physical address of clock IDLEST register -* @mask: value to mask against to determine if the clock is active -* @name: name of the clock (for printk) +/* +* XXX document +* +* Note: We don't need special code here for INVERT_ENABLE for the +* time being since INVERT_ENABLE only applies to clocks enabled by +* CM_CLKEN_PLL * -* Returns 1 if the clock enabled in time, or 0 if it failed to enable -* in roughly MAX_CLOCK_ENABLE_WAIT microseconds. +* Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes it's +* just a matter of XORing the bits. */ -int omap2_wait_clock_ready (void __iomem *reg,u32 mask,const char *name) +void omap2_clk_dflt_find_companion (struct clk *clk,void __iomem **other_reg, +u8 *other_bit) { -int i =0 ; -int ena =0 ; +u32 r;/* -* 24xx uses 0 to indicate not ready, and 1 to indicate ready. -* 34xx reverses this, just to keep us on our toes +* Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes +* it's just a matter of XORing the bits. */ -if (cpu_mask & (RATE_IN_242X |RATE_IN_243X )) - ena = mask; -else if (cpu_mask &RATE_IN_343X ) - ena =0 ; - -/* Wait for lock */ -while (((__raw_readl (reg) & mask) != ena) && - (i++ <MAX_CLOCK_ENABLE_WAIT )) { -udelay (1 ); - } - -if (i <=MAX_CLOCK_ENABLE_WAIT ) -pr_debug ("Clock %s stable after %d loops\n" , name, i); -else -printk (KERN_ERR "Clock %s didn't enable in %d tries\n" , - name,MAX_CLOCK_ENABLE_WAIT ); + r = ((u32 )clk->enable_reg ^ (CM_FCLKEN ^CM_ICLKEN )); + *other_reg = (void __iomem *)r; + *other_bit = clk->enable_bit; +} -return (i <MAX_CLOCK_ENABLE_WAIT ) ?1 :0 ; -}; - +/* XXX document */ +/* CM_IDLEST* */ +void omap2_clk_dflt_find_idlest (struct clk *clk,void __iomem **idlest_reg, +u8 *idlest_bit) +{ + *idlest_reg = (void __iomem *)(((u32 )clk->enable_reg & ~0xf0 ) |0x20 ); + *idlest_bit = clk->enable_bit; +}/* -* Note: We don't need special code here for INVERT_ENABLE -* for the time being since INVERT_ENABLE only applies to clocks enabled by -* CM_CLKEN_PLL +* XXX document +* +* XXX belongs elsewhere */ -static void omap2_clk_wait_ready (struct clk *clk) +static void omap2_module_wait_ready (struct clk *clk) { -void __iomem *reg, *other_reg, *st_reg; -u32 bit; - -/* -* REVISIT: This code is pretty ugly. It would be nice to generalize -* it and pull it into struct clk itself somehow. -*/ - reg = clk->enable_reg; +void __iomem *companion_reg, *idlest_reg; +u8 other_bit, idlest_bit; -/* -* Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes -* it's just a matter of XORing the bits. -*/ - other_reg = (void __iomem *)((u32 )reg ^ (CM_FCLKEN ^CM_ICLKEN )); +/* Not all modules have multiple clocks that their IDLEST depends on */ +if (clk->ops->find_companion) { + clk->ops->find_companion (clk, &companion_reg, &other_bit); +if (!(__raw_readl (companion_reg) & (1 << other_bit))) +return ; + } -/* Check if both functional and interface clocks -* are running. */ - bit =1 << clk->enable_bit; -if (!(__raw_readl (other_reg) & bit)) -return ; - st_reg = (void __iomem *)(((u32 )other_reg & ~0xf0 ) |0x20 );/* CM_IDLEST* */ + clk->ops->find_idlest (clk, &idlest_reg, &idlest_bit); -omap2_wait_clock_ready (st_reg, bit, clk->name); +omap2_cm_wait_idlest (idlest_reg, (1 << idlest_bit), clk->name); } -static int omap2_dflt_clk_enable (struct clk *clk) +int omap2_dflt_clk_enable (struct clk *clk) {u32 v;if (unlikely (clk->enable_reg ==NULL )) { -printk (KERN_ERR "clock.c: Enable for %s without enable code\n" , +pr_err ("clock.c: Enable for %s without enable code\n" , clk->name);return 0 ;/* REVISIT: -EINVAL */ }
@@ -363,26 +346,13 @@ static int omap2_dflt_clk_enable(struct clk *clk)__raw_writel (v, clk->enable_reg); v =__raw_readl (clk->enable_reg);/* OCP barrier */ -return 0 ; -} +if (clk->ops->find_idlest) +omap2_module_wait_ready (clk); -static int omap2_dflt_clk_enable_wait (struct clk *clk) -{ -int ret; - -if (!clk->enable_reg) { -printk (KERN_ERR "clock.c: Enable for %s without enable code\n" , - clk->name); -return 0 ;/* REVISIT: -EINVAL */ - } - - ret =omap2_dflt_clk_enable (clk); -if (ret ==0 ) -omap2_clk_wait_ready (clk); -return ret; +return 0 ; } -static void omap2_dflt_clk_disable (struct clk *clk) +void omap2_dflt_clk_disable (struct clk *clk) {u32 v;
@@ -406,8 +376,10 @@ static void omap2_dflt_clk_disable(struct clk *clk) }const struct clkops clkops_omap2_dflt_wait = { - .enable = omap2_dflt_clk_enable_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, };const struct clkops clkops_omap2_dflt = {
arch/arm/mach-omap2/clock.h +6 -0
@@ -65,6 +65,12 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate);u32 omap2_get_dpll_rate (struct clk *clk);int omap2_wait_clock_ready (void __iomem *reg,u32 cval,const char *name);void omap2_clk_prepare_for_reboot (void ); +int omap2_dflt_clk_enable (struct clk *clk); +void omap2_dflt_clk_disable (struct clk *clk); +void omap2_clk_dflt_find_companion (struct clk *clk,void __iomem **other_reg, +u8 *other_bit); +void omap2_clk_dflt_find_idlest (struct clk *clk,void __iomem **idlest_reg, +u8 *idlest_bit);extern const struct clkops clkops_omap2_dflt_wait;extern const struct clkops clkops_omap2_dflt;
arch/arm/mach-omap2/prcm.c +43 -0
61 lines not on this page · raw message
arch/arm/plat-omap/include/mach/clock.h +2 -0
@@ -20,6 +20,8 @@ struct clockdomain;struct clkops {int (*enable)(struct clk *);void (*disable)(struct clk *); +void (*find_idlest)(struct clk *,void __iomem **,u8 *); +void (*find_companion)(struct clk *,void __iomem **,u8 *); }; #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
arch/arm/plat-omap/include/mach/prcm.h +1 -0
@@ -25,6 +25,7 @@u32 omap_prcm_get_reset_sources (void );void omap_prcm_arch_reset (char mode); +int omap2_cm_wait_idlest (void __iomem *reg,u32 mask,const char *name);#endif
Paul Walmsley
maintainerPATCH 2/3 OMAP2 clock: 2430 I2CHS uses non-standard CM_IDLEST register
In reply to Paul WalmsleyOMAP2430 I2CHS CM_IDLEST bits are in CM_IDLEST1_CORE, but the CM_*CLKEN bits are in CM_{I,F}CLKEN2_CORE [1]. Fix by implementing a custom clkops .find_idlest function to return the correct slave IDLEST register.
...
1. OMAP2430 Multimedia Device Package-on-Package (POP) Silicon Revision 2.1 (Rev. V) Technical Reference Manual, tables 4-99 and 4-105.
--- arch/arm/mach-omap2/clock24xx.c | 37 +++++++++++++++++++++++++++++++++++-- arch/arm/mach-omap2/clock24xx.h | 4 ++-- 2 files changed, 37 insertions(+), 4 deletions(-)
arch/arm/mach-omap2/clock24xx.c +35 -2
@@ -30,6 +30,7 @@#include <mach/clock.h> #include <mach/sram.h> +#include <mach/prcm.h> #include <asm/div64.h> #include <asm/clkdev.h>
@@ -43,6 +44,18 @@static const struct clkops clkops_oscck;static const struct clkops clkops_fixed; +static void omap2430_clk_i2chs_find_idlest (struct clk *clk, +void __iomem **idlest_reg, +u8 *idlest_bit); + +/* 2430 I2CHS has non-standard IDLEST register */ +static const struct clkops clkops_omap2430_i2chs_wait = { + .enable = omap2_dflt_clk_enable, + .disable = omap2_dflt_clk_disable, + .find_idlest = omap2430_clk_i2chs_find_idlest, + .find_companion = omap2_clk_dflt_find_companion, +}; +#include "clock24xx.h" struct omap_clk {
@@ -240,6 +253,26 @@ static void __iomem *prcm_clksrc_ctrl;*-------------------------------------------------------------------------*/ /** +* omap2430_clk_i2chs_find_idlest - return CM_IDLEST info for 2430 I2CHS +* @clk: struct clk * being enabled +* @idlest_reg: void __iomem ** to store CM_IDLEST reg address into +* @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into +* +* OMAP2430 I2CHS CM_IDLEST bits are in CM_IDLEST1_CORE, but the +* CM_*CLKEN bits are in CM_{I,F}CLKEN2_CORE. This custom function +* passes back the correct CM_IDLEST register address for I2CHS +* modules. No return value. +*/ +static void omap2430_clk_i2chs_find_idlest (struct clk *clk, +void __iomem **idlest_reg, +u8 *idlest_bit) +{ + *idlest_reg =OMAP_CM_REGADDR (CORE_MOD ,CM_IDLEST ); + *idlest_bit = clk->enable_bit; +} + + +/** * omap2xxx_clk_get_core_rate - return the CORE_CLK rate * @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck") *
@@ -325,8 +358,8 @@ static int omap2_clk_fixed_enable(struct clk *clk)else if (clk == &apll54_ck) cval =OMAP24XX_ST_54M_APLL ; -omap2_wait_clock_ready (OMAP_CM_REGADDR (PLL_MOD ,CM_IDLEST ), cval, - clk->name); +omap2_cm_wait_idlest (OMAP_CM_REGADDR (PLL_MOD ,CM_IDLEST ), cval, + clk->name);/* * REVISIT: Should we return an error code if omap2_wait_clock_ready()
arch/arm/mach-omap2/clock24xx.h +2 -2
@@ -2337,7 +2337,7 @@ static struct clk i2c2_fck = {static struct clk i2chs2_fck = { .name ="i2c_fck" , - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2430_i2chs_wait, .id =2 , .parent = &func_96m_ck, .clkdm_name ="core_l4_clkdm" ,
@@ -2370,7 +2370,7 @@ static struct clk i2c1_fck = {static struct clk i2chs1_fck = { .name ="i2c_fck" , - .ops = &clkops_omap2_dflt_wait, + .ops = &clkops_omap2430_i2chs_wait, .id =1 , .parent = &func_96m_ck, .clkdm_name ="core_l4_clkdm" ,
Paul Walmsley
maintainerPATCH 3/3 OMAP3 clock: correct module IDLEST bits: SSI; DSS; USBHOST; HSOTGUSB
In reply to Paul WalmsleyFix two bugs in the OMAP3 clock tree pertaining to the SSI, DSS, USBHOST, and HSOTGUSB devices. These devices are both interconnect initiators and targets.
First, target CM_IDLEST register bits were only added on ES2+ chips. ES1 chips should not wait for these clocks to enable. So, split the appropriate clocks into ES1 and ES2+ variants, so that kernels running on ES1 devices won't try to wait.
Second, the current heuristic in omap2_clk_dflt_find_idlest() will fail for these clocks. It assumes that the CM_IDLEST bit to wait upon is the same as the CM_*CLKEN bit, which is false[1]. Fix by implementing custom clkops .find_idlest function pointers for the appropriate clocks that return the correct slave IDLEST bit shift.
This was originally fixed in the linux-omap kernel during 2.6.29 in a slightly different manner[2][3].
In the medium-term future, all of the module IDLEST code will eventually be moved to the omap_hwmod code.
Problem reported by Jarkko Nikula <[email protected]>.
...
1. See for example 34xx TRM Revision P Table 4-213 and 4-217 (for the DSS case).
2. http://www.spinics.net/lists/linux-omap/msg05512.html et seq.
3. http://lkml.indiana.edu/hypermail/linux/kernel/0901.3/01498.html
--- arch/arm/mach-omap2/clock34xx.c | 133 +++++++++++++++++++++++++++++++++++++-- arch/arm/mach-omap2/clock34xx.h | 85 ++++++++++++++++++++++--- 2 files changed, 200 insertions(+), 18 deletions(-)
arch/arm/mach-omap2/clock34xx.c +126 -7
@@ -2,7 +2,7 @@* OMAP3-specific clock framework functions * * Copyright (C) 2007-2008 Texas Instruments, Inc. -* Copyright (C) 2007-2008 Nokia Corporation +* Copyright (C) 2007-2009 Nokia Corporation * * Written by Paul Walmsley * Testing and integration fixes by Jouni Högander
@@ -41,6 +41,47 @@static const struct clkops clkops_noncore_dpll_ops; +static void omap3430es2_clk_ssi_find_idlest (struct clk *clk, +void __iomem **idlest_reg, +u8 *idlest_bit); +static void omap3430es2_clk_hsotgusb_find_idlest (struct clk *clk, +void __iomem **idlest_reg, +u8 *idlest_bit); +static void omap3430es2_clk_dss_find_idlest (struct clk *clk, +void __iomem **idlest_reg, +u8 *idlest_bit); +static void omap3430es2_clk_usbhost_find_idlest (struct clk *clk, +void __iomem **idlest_reg, +u8 *idlest_bit); + +static const struct clkops clkops_omap3430es2_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, +}; + +static const struct clkops clkops_omap3430es2_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, +}; + +static const struct clkops clkops_omap3430es2_dss_wait = { + .enable = omap2_dflt_clk_enable, + .disable = omap2_dflt_clk_disable, + .find_idlest = omap3430es2_clk_dss_find_idlest, + .find_companion = omap2_clk_dflt_find_companion, +}; + +static const struct clkops clkops_omap3430es2_usbhost_wait = { + .enable = omap2_dflt_clk_enable, + .disable = omap2_dflt_clk_disable, + .find_idlest = omap3430es2_clk_usbhost_find_idlest, + .find_companion = omap2_clk_dflt_find_companion, +}; +#include "clock34xx.h" struct omap_clk {
@@ -157,10 +198,13 @@ static struct omap_clk omap34xx_clks[] = {CLK (NULL ,"fshostusb_fck" , &fshostusb_fck,CK_3430ES1 ),CLK (NULL ,"core_12m_fck" , &core_12m_fck,CK_343X ),CLK ("omap_hdq.0" ,"fck" , &hdq_fck,CK_343X ), -CLK (NULL ,"ssi_ssr_fck" , &ssi_ssr_fck,CK_343X ), -CLK (NULL ,"ssi_sst_fck" , &ssi_sst_fck,CK_343X ), +CLK (NULL ,"ssi_ssr_fck" , &ssi_ssr_fck_3430es1,CK_3430ES1 ), +CLK (NULL ,"ssi_ssr_fck" , &ssi_ssr_fck_3430es2,CK_3430ES2 ), +CLK (NULL ,"ssi_sst_fck" , &ssi_sst_fck_3430es1,CK_3430ES1 ), +CLK (NULL ,"ssi_sst_fck" , &ssi_sst_fck_3430es2,CK_3430ES2 ),CLK (NULL ,"core_l3_ick" , &core_l3_ick,CK_343X ), -CLK ("musb_hdrc" ,"ick" , &hsotgusb_ick,CK_343X ), +CLK ("musb_hdrc" ,"ick" , &hsotgusb_ick_3430es1,CK_3430ES1 ), +CLK ("musb_hdrc" ,"ick" , &hsotgusb_ick_3430es2,CK_3430ES2 ),CLK (NULL ,"sdrc_ick" , &sdrc_ick,CK_343X ),CLK (NULL ,"gpmc_fck" , &gpmc_fck,CK_343X ), CLK(NULL, "security_l3_ick", &security_l3_ick, CK_343X),
@@ -193,18 +237,21 @@ static struct omap_clk omap34xx_clks[] = {CLK (NULL ,"mailboxes_ick" , &mailboxes_ick,CK_343X ),CLK (NULL ,"omapctrl_ick" , &omapctrl_ick,CK_343X ),CLK (NULL ,"ssi_l4_ick" , &ssi_l4_ick,CK_343X ), -CLK (NULL ,"ssi_ick" , &ssi_ick,CK_343X ), +CLK (NULL ,"ssi_ick" , &ssi_ick_3430es1,CK_3430ES1 ), +CLK (NULL ,"ssi_ick" , &ssi_ick_3430es2,CK_3430ES2 ),CLK (NULL ,"usb_l4_ick" , &usb_l4_ick,CK_3430ES1 ),CLK (NULL ,"security_l4_ick2" , &security_l4_ick2,CK_343X ),CLK (NULL ,"aes1_ick" , &aes1_ick,CK_343X ),CLK ("omap_rng" ,"ick" , &rng_ick,CK_343X ),CLK (NULL ,"sha11_ick" , &sha11_ick,CK_343X ),CLK (NULL ,"des1_ick" , &des1_ick,CK_343X ), -CLK ("omapfb" ,"dss1_fck" , &dss1_alwon_fck,CK_343X ), +CLK ("omapfb" ,"dss1_fck" , &dss1_alwon_fck_3430es1,CK_3430ES1 ), +CLK ("omapfb" ,"dss1_fck" , &dss1_alwon_fck_3430es2,CK_3430ES2 ),CLK ("omapfb" ,"tv_fck" , &dss_tv_fck,CK_343X ),CLK ("omapfb" ,"video_fck" , &dss_96m_fck,CK_343X ),CLK ("omapfb" ,"dss2_fck" , &dss2_alwon_fck,CK_343X ), -CLK ("omapfb" ,"ick" , &dss_ick,CK_343X ), +CLK ("omapfb" ,"ick" , &dss_ick_3430es1,CK_3430ES1 ), +CLK ("omapfb" ,"ick" , &dss_ick_3430es2,CK_3430ES2 ),CLK (NULL ,"cam_mclk" , &cam_mclk,CK_343X ),CLK (NULL ,"cam_ick" , &cam_ick,CK_343X ), CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_343X),
@@ -301,6 +348,78 @@ static struct omap_clk omap34xx_clks[] = {#define SDRC_MPURATE_LOOPS 96/** +* omap3430es2_clk_ssi_find_idlest - return CM_IDLEST info for SSI +* @clk: struct clk * being enabled +* @idlest_reg: void __iomem ** to store CM_IDLEST reg address into +* @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into +* +* The OMAP3430ES2 SSI target CM_IDLEST bit is at a different shift +* from the CM_{I,F}CLKEN bit. Pass back the correct info via +* @idlest_reg and @idlest_bit. No return value. +*/ +static void omap3430es2_clk_ssi_find_idlest (struct clk *clk, +void __iomem **idlest_reg, +u8 *idlest_bit) +{ + *idlest_reg = (void __iomem *)(((u32 )clk->enable_reg & ~0xf0 ) |0x20 ); + *idlest_bit =OMAP3430ES2_ST_SSI_IDLE_SHIFT ; +} + +/** +* omap3430es2_clk_hsotgusb_find_idlest - return CM_IDLEST info for HSOTGUSB +* @clk: struct clk * being enabled +* @idlest_reg: void __iomem ** to store CM_IDLEST reg address into +* @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into +* +* The OMAP3430ES2 HSOTGUSB target CM_IDLEST bit is at a different +* shift from the CM_{I,F}CLKEN bit. Pass back the correct info via +* @idlest_reg and @idlest_bit. No return value. +*/ +static void omap3430es2_clk_hsotgusb_find_idlest (struct clk *clk, +void __iomem **idlest_reg, +u8 *idlest_bit) +{ + *idlest_reg = (void __iomem *)(((u32 )clk->enable_reg & ~0xf0 ) |0x20 ); + *idlest_bit =OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT ; +} + +/** +* omap3430es2_clk_dss_find_idlest - return CM_IDLEST info for DSS +* @clk: struct clk * being enabled +* @idlest_reg: void __iomem ** to store CM_IDLEST reg address into +* @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into +* +* The OMAP3430ES2 DSS target CM_IDLEST bit is at a different shift +* from the CM_{I,F}CLKEN bit. Pass back the correct info via +* @idlest_reg and @idlest_bit. No return value. +*/ +static void omap3430es2_clk_dss_find_idlest (struct clk *clk, +void __iomem **idlest_reg, +u8 *idlest_bit) +{ + *idlest_reg = (void __iomem *)(((u32 )clk->enable_reg & ~0xf0 ) |0x20 ); + *idlest_bit =OMAP3430ES2_ST_DSS_IDLE_SHIFT ; +} + +/** +* omap3430es2_clk_usbhost_find_idlest - return CM_IDLEST info for USBHOST +* @clk: struct clk * being enabled +* @idlest_reg: void __iomem ** to store CM_IDLEST reg address into +* @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into +* +* The OMAP3430ES2 USBHOST target CM_IDLEST bit is at a different +* shift from the CM_{I,F}CLKEN bit. Pass back the correct info via +* @idlest_reg and @idlest_bit. No return value. +*/ +static void omap3430es2_clk_usbhost_find_idlest (struct clk *clk, +void __iomem **idlest_reg, +u8 *idlest_bit) +{ + *idlest_reg = (void __iomem *)(((u32 )clk->enable_reg & ~0xf0 ) |0x20 ); + *idlest_bit =OMAP3430ES2_ST_USBHOST_IDLE_SHIFT ; +} + +/** * omap3_dpll_recalc - recalculate DPLL rate * @clk: DPLL struct clk *
arch/arm/mach-omap2/clock34xx.h +74 -11
160 lines not on this page · raw message
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html