aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRanjith Lohithakshan <ranjithl@ti.com>2010-02-24 14:05:54 -0500
committerPaul Walmsley <paul@pwsan.com>2010-02-24 14:05:54 -0500
commit419cc97d3678f0fca5e60b3853dd9c1371f67805 (patch)
treea3997e3f9ad52abf927597f8e241fb6dfb02ab00
parentcde08f81b1d7952ae00c4be2165da629ef985522 (diff)
OMAP2/3 clock: Extend find_idlest() to pass back idle state value
Current implementation defines clock idle state indicators based on the cpu information (cpu_is_omap24xx() or cpu_is_omap34xx()) in a system wide manner. This patch extends the find_idlest() function in clkops to pass back the idle state indicator for that clock, thus allowing idle state indicators to be defined on a per clock basis if required. This is specifically needed on AM35xx devices as the new IPSS clocks indicates the idle status (0 is idle, 1 is ready) in a way just opposite to how its handled in OMAP3 (0 is ready, 1 is idle). Signed-off-by: Ranjith Lohithakshan <ranjithl@ti.com> [paul@pwsan.com: updated to apply after commit 98c45457 et seq.] Signed-off-by: Paul Walmsley <paul@pwsan.com>
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_apll.c2
-rw-r--r--arch/arm/mach-omap2/clock.c25
-rw-r--r--arch/arm/mach-omap2/clock.h2
-rw-r--r--arch/arm/mach-omap2/clock2xxx.c5
-rw-r--r--arch/arm/mach-omap2/clock34xx.c15
-rw-r--r--arch/arm/mach-omap2/cm.h3
-rw-r--r--arch/arm/mach-omap2/prcm.c14
-rw-r--r--arch/arm/plat-omap/include/plat/clock.h6
-rw-r--r--arch/arm/plat-omap/include/plat/prcm.h3
9 files changed, 52 insertions, 23 deletions
diff --git a/arch/arm/mach-omap2/clkt2xxx_apll.c b/arch/arm/mach-omap2/clkt2xxx_apll.c
index fc32ff8e790f..d5b8b2bb0e9d 100644
--- a/arch/arm/mach-omap2/clkt2xxx_apll.c
+++ b/arch/arm/mach-omap2/clkt2xxx_apll.c
@@ -57,7 +57,7 @@ static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask)
57 cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN); 57 cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
58 58
59 omap2_cm_wait_idlest(OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), status_mask, 59 omap2_cm_wait_idlest(OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), status_mask,
60 clk->name); 60 OMAP24XX_CM_IDLEST_VAL, clk->name);
61 61
62 /* 62 /*
63 * REVISIT: Should we return an error code if omap2_wait_clock_ready() 63 * REVISIT: Should we return an error code if omap2_wait_clock_ready()
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 999b91e023b1..3bb3292ec469 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -57,7 +57,7 @@ u8 cpu_mask;
57static void _omap2_module_wait_ready(struct clk *clk) 57static void _omap2_module_wait_ready(struct clk *clk)
58{ 58{
59 void __iomem *companion_reg, *idlest_reg; 59 void __iomem *companion_reg, *idlest_reg;
60 u8 other_bit, idlest_bit; 60 u8 other_bit, idlest_bit, idlest_val;
61 61
62 /* Not all modules have multiple clocks that their IDLEST depends on */ 62 /* Not all modules have multiple clocks that their IDLEST depends on */
63 if (clk->ops->find_companion) { 63 if (clk->ops->find_companion) {
@@ -66,9 +66,10 @@ static void _omap2_module_wait_ready(struct clk *clk)
66 return; 66 return;
67 } 67 }
68 68
69 clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit); 69 clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit, &idlest_val);
70 70
71 omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), clk->name); 71 omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), idlest_val,
72 clk->name);
72} 73}
73 74
74/* Enables clock without considering parent dependencies or use count 75/* Enables clock without considering parent dependencies or use count
@@ -175,7 +176,8 @@ void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
175 * omap2_clk_dflt_find_idlest - find CM_IDLEST reg va, bit shift for @clk 176 * omap2_clk_dflt_find_idlest - find CM_IDLEST reg va, bit shift for @clk
176 * @clk: struct clk * to find IDLEST info for 177 * @clk: struct clk * to find IDLEST info for
177 * @idlest_reg: void __iomem ** to return the CM_IDLEST va in 178 * @idlest_reg: void __iomem ** to return the CM_IDLEST va in
178 * @idlest_bit: u8 ** to return the CM_IDLEST bit shift in 179 * @idlest_bit: u8 * to return the CM_IDLEST bit shift in
180 * @idlest_val: u8 * to return the idle status indicator
179 * 181 *
180 * Return the CM_IDLEST register address and bit shift corresponding 182 * Return the CM_IDLEST register address and bit shift corresponding
181 * to the module that "owns" this clock. This default code assumes 183 * to the module that "owns" this clock. This default code assumes
@@ -185,13 +187,26 @@ void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
185 * CM_IDLEST2). This is not true for all modules. No return value. 187 * CM_IDLEST2). This is not true for all modules. No return value.
186 */ 188 */
187void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg, 189void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
188 u8 *idlest_bit) 190 u8 *idlest_bit, u8 *idlest_val)
189{ 191{
190 u32 r; 192 u32 r;
191 193
192 r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); 194 r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
193 *idlest_reg = (__force void __iomem *)r; 195 *idlest_reg = (__force void __iomem *)r;
194 *idlest_bit = clk->enable_bit; 196 *idlest_bit = clk->enable_bit;
197
198 /*
199 * 24xx uses 0 to indicate not ready, and 1 to indicate ready.
200 * 34xx reverses this, just to keep us on our toes
201 * AM35xx uses both, depending on the module.
202 */
203 if (cpu_is_omap24xx())
204 *idlest_val = OMAP24XX_CM_IDLEST_VAL;
205 else if (cpu_is_omap34xx())
206 *idlest_val = OMAP34XX_CM_IDLEST_VAL;
207 else
208 BUG();
209
195} 210}
196 211
197int omap2_dflt_clk_enable(struct clk *clk) 212int omap2_dflt_clk_enable(struct clk *clk)
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index fcb99cce5fc8..86e32bf2a693 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -114,7 +114,7 @@ void omap2_dflt_clk_disable(struct clk *clk);
114void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg, 114void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
115 u8 *other_bit); 115 u8 *other_bit);
116void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg, 116void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
117 u8 *idlest_bit); 117 u8 *idlest_bit, u8 *idlest_val);
118void omap2xxx_clk_commit(struct clk *clk); 118void omap2xxx_clk_commit(struct clk *clk);
119 119
120extern u8 cpu_mask; 120extern u8 cpu_mask;
diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c
index a48b01ab0e35..94fb8a67b503 100644
--- a/arch/arm/mach-omap2/clock2xxx.c
+++ b/arch/arm/mach-omap2/clock2xxx.c
@@ -42,6 +42,7 @@ struct clk *vclk, *sclk, *dclk;
42 * @clk: struct clk * being enabled 42 * @clk: struct clk * being enabled
43 * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into 43 * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
44 * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into 44 * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
45 * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
45 * 46 *
46 * OMAP2430 I2CHS CM_IDLEST bits are in CM_IDLEST1_CORE, but the 47 * OMAP2430 I2CHS CM_IDLEST bits are in CM_IDLEST1_CORE, but the
47 * CM_*CLKEN bits are in CM_{I,F}CLKEN2_CORE. This custom function 48 * CM_*CLKEN bits are in CM_{I,F}CLKEN2_CORE. This custom function
@@ -50,10 +51,12 @@ struct clk *vclk, *sclk, *dclk;
50 */ 51 */
51static void omap2430_clk_i2chs_find_idlest(struct clk *clk, 52static void omap2430_clk_i2chs_find_idlest(struct clk *clk,
52 void __iomem **idlest_reg, 53 void __iomem **idlest_reg,
53 u8 *idlest_bit) 54 u8 *idlest_bit,
55 u8 *idlest_val)
54{ 56{
55 *idlest_reg = OMAP_CM_REGADDR(CORE_MOD, CM_IDLEST); 57 *idlest_reg = OMAP_CM_REGADDR(CORE_MOD, CM_IDLEST);
56 *idlest_bit = clk->enable_bit; 58 *idlest_bit = clk->enable_bit;
59 *idlest_val = OMAP24XX_CM_IDLEST_VAL;
57} 60}
58 61
59#else 62#else
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index ae9e2c82eb6a..49d93efc1911 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -47,6 +47,7 @@ struct clk *sdrc_ick_p, *arm_fck_p;
47 * @clk: struct clk * being enabled 47 * @clk: struct clk * being enabled
48 * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into 48 * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
49 * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into 49 * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
50 * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
50 * 51 *
51 * The OMAP3430ES2 SSI target CM_IDLEST bit is at a different shift 52 * The OMAP3430ES2 SSI target CM_IDLEST bit is at a different shift
52 * from the CM_{I,F}CLKEN bit. Pass back the correct info via 53 * from the CM_{I,F}CLKEN bit. Pass back the correct info via
@@ -54,13 +55,15 @@ struct clk *sdrc_ick_p, *arm_fck_p;
54 */ 55 */
55static void omap3430es2_clk_ssi_find_idlest(struct clk *clk, 56static void omap3430es2_clk_ssi_find_idlest(struct clk *clk,
56 void __iomem **idlest_reg, 57 void __iomem **idlest_reg,
57 u8 *idlest_bit) 58 u8 *idlest_bit,
59 u8 *idlest_val)
58{ 60{
59 u32 r; 61 u32 r;
60 62
61 r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); 63 r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
62 *idlest_reg = (__force void __iomem *)r; 64 *idlest_reg = (__force void __iomem *)r;
63 *idlest_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT; 65 *idlest_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT;
66 *idlest_val = OMAP34XX_CM_IDLEST_VAL;
64} 67}
65 68
66const struct clkops clkops_omap3430es2_ssi_wait = { 69const struct clkops clkops_omap3430es2_ssi_wait = {
@@ -75,6 +78,7 @@ const struct clkops clkops_omap3430es2_ssi_wait = {
75 * @clk: struct clk * being enabled 78 * @clk: struct clk * being enabled
76 * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into 79 * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
77 * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into 80 * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
81 * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
78 * 82 *
79 * Some OMAP modules on OMAP3 ES2+ chips have both initiator and 83 * Some OMAP modules on OMAP3 ES2+ chips have both initiator and
80 * target IDLEST bits. For our purposes, we are concerned with the 84 * target IDLEST bits. For our purposes, we are concerned with the
@@ -85,7 +89,8 @@ const struct clkops clkops_omap3430es2_ssi_wait = {
85 */ 89 */
86static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk, 90static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk,
87 void __iomem **idlest_reg, 91 void __iomem **idlest_reg,
88 u8 *idlest_bit) 92 u8 *idlest_bit,
93 u8 *idlest_val)
89{ 94{
90 u32 r; 95 u32 r;
91 96
@@ -93,6 +98,7 @@ static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk,
93 *idlest_reg = (__force void __iomem *)r; 98 *idlest_reg = (__force void __iomem *)r;
94 /* USBHOST_IDLE has same shift */ 99 /* USBHOST_IDLE has same shift */
95 *idlest_bit = OMAP3430ES2_ST_DSS_IDLE_SHIFT; 100 *idlest_bit = OMAP3430ES2_ST_DSS_IDLE_SHIFT;
101 *idlest_val = OMAP34XX_CM_IDLEST_VAL;
96} 102}
97 103
98const struct clkops clkops_omap3430es2_dss_usbhost_wait = { 104const struct clkops clkops_omap3430es2_dss_usbhost_wait = {
@@ -107,6 +113,7 @@ const struct clkops clkops_omap3430es2_dss_usbhost_wait = {
107 * @clk: struct clk * being enabled 113 * @clk: struct clk * being enabled
108 * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into 114 * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
109 * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into 115 * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
116 * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
110 * 117 *
111 * The OMAP3430ES2 HSOTGUSB target CM_IDLEST bit is at a different 118 * The OMAP3430ES2 HSOTGUSB target CM_IDLEST bit is at a different
112 * shift from the CM_{I,F}CLKEN bit. Pass back the correct info via 119 * shift from the CM_{I,F}CLKEN bit. Pass back the correct info via
@@ -114,13 +121,15 @@ const struct clkops clkops_omap3430es2_dss_usbhost_wait = {
114 */ 121 */
115static void omap3430es2_clk_hsotgusb_find_idlest(struct clk *clk, 122static void omap3430es2_clk_hsotgusb_find_idlest(struct clk *clk,
116 void __iomem **idlest_reg, 123 void __iomem **idlest_reg,
117 u8 *idlest_bit) 124 u8 *idlest_bit,
125 u8 *idlest_val)
118{ 126{
119 u32 r; 127 u32 r;
120 128
121 r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); 129 r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
122 *idlest_reg = (__force void __iomem *)r; 130 *idlest_reg = (__force void __iomem *)r;
123 *idlest_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT; 131 *idlest_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT;
132 *idlest_val = OMAP34XX_CM_IDLEST_VAL;
124} 133}
125 134
126const struct clkops clkops_omap3430es2_hsotgusb_wait = { 135const struct clkops clkops_omap3430es2_hsotgusb_wait = {
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h
index 4e4ac8ccd7f5..94728b1ee3c4 100644
--- a/arch/arm/mach-omap2/cm.h
+++ b/arch/arm/mach-omap2/cm.h
@@ -139,5 +139,8 @@ static inline u32 cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
139/* CM_IDLEST_GFX */ 139/* CM_IDLEST_GFX */
140#define OMAP_ST_GFX (1 << 0) 140#define OMAP_ST_GFX (1 << 0)
141 141
142/* CM_IDLEST indicator */
143#define OMAP24XX_CM_IDLEST_VAL 0
144#define OMAP34XX_CM_IDLEST_VAL 1
142 145
143#endif 146#endif
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
index e8e121a41d6d..0f87fdce02a9 100644
--- a/arch/arm/mach-omap2/prcm.c
+++ b/arch/arm/mach-omap2/prcm.c
@@ -242,26 +242,22 @@ u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
242 * omap2_cm_wait_idlest - wait for IDLEST bit to indicate module readiness 242 * omap2_cm_wait_idlest - wait for IDLEST bit to indicate module readiness
243 * @reg: physical address of module IDLEST register 243 * @reg: physical address of module IDLEST register
244 * @mask: value to mask against to determine if the module is active 244 * @mask: value to mask against to determine if the module is active
245 * @idlest: idle state indicator (0 or 1) for the clock
245 * @name: name of the clock (for printk) 246 * @name: name of the clock (for printk)
246 * 247 *
247 * Returns 1 if the module indicated readiness in time, or 0 if it 248 * Returns 1 if the module indicated readiness in time, or 0 if it
248 * failed to enable in roughly MAX_MODULE_ENABLE_WAIT microseconds. 249 * failed to enable in roughly MAX_MODULE_ENABLE_WAIT microseconds.
249 */ 250 */
250int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, const char *name) 251int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, u8 idlest,
252 const char *name)
251{ 253{
252 int i = 0; 254 int i = 0;
253 int ena = 0; 255 int ena = 0;
254 256
255 /* 257 if (idlest)
256 * 24xx uses 0 to indicate not ready, and 1 to indicate ready.
257 * 34xx reverses this, just to keep us on our toes
258 */
259 if (cpu_is_omap24xx())
260 ena = mask;
261 else if (cpu_is_omap34xx())
262 ena = 0; 258 ena = 0;
263 else 259 else
264 BUG(); 260 ena = mask;
265 261
266 /* Wait for lock */ 262 /* Wait for lock */
267 omap_test_timeout(((__raw_readl(reg) & mask) == ena), 263 omap_test_timeout(((__raw_readl(reg) & mask) == ena),
diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h
index 8a86df4ad99c..e49162469791 100644
--- a/arch/arm/plat-omap/include/plat/clock.h
+++ b/arch/arm/plat-omap/include/plat/clock.h
@@ -22,8 +22,10 @@ struct clockdomain;
22struct clkops { 22struct clkops {
23 int (*enable)(struct clk *); 23 int (*enable)(struct clk *);
24 void (*disable)(struct clk *); 24 void (*disable)(struct clk *);
25 void (*find_idlest)(struct clk *, void __iomem **, u8 *); 25 void (*find_idlest)(struct clk *, void __iomem **,
26 void (*find_companion)(struct clk *, void __iomem **, u8 *); 26 u8 *, u8 *);
27 void (*find_companion)(struct clk *, void __iomem **,
28 u8 *);
27}; 29};
28 30
29#ifdef CONFIG_ARCH_OMAP2PLUS 31#ifdef CONFIG_ARCH_OMAP2PLUS
diff --git a/arch/arm/plat-omap/include/plat/prcm.h b/arch/arm/plat-omap/include/plat/prcm.h
index 66938a9f8dae..d6a0e27d5a7f 100644
--- a/arch/arm/plat-omap/include/plat/prcm.h
+++ b/arch/arm/plat-omap/include/plat/prcm.h
@@ -25,7 +25,8 @@
25 25
26u32 omap_prcm_get_reset_sources(void); 26u32 omap_prcm_get_reset_sources(void);
27void omap_prcm_arch_reset(char mode); 27void omap_prcm_arch_reset(char mode);
28int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, const char *name); 28int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, u8 idlest,
29 const char *name);
29 30
30#define START_PADCONF_SAVE 0x2 31#define START_PADCONF_SAVE 0x2
31#define PADCONF_SAVE_DONE 0x1 32#define PADCONF_SAVE_DONE 0x1