aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuha Yrjola <juha.yrjola@solidboot.com>2006-09-25 05:41:50 -0400
committerTony Lindgren <tony@atomide.com>2006-09-25 05:41:50 -0400
commitddc32a87497d8806e361cfe7168f173396fe9219 (patch)
tree41e4235bb358443fa187b11c49d8d9c418dbff99
parentdc0d794e488090082b7194738a08f18db0874900 (diff)
ARM: OMAP2: Make sure peripherals can be accessed after clk_enable
Some peripherals seem to need additional delay until they can actually be accessed after enabling their FCLK and ICLK. Signed-off-by: Juha Yrjola <juha.yrjola@solidboot.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
-rw-r--r--arch/arm/mach-omap2/clock.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index eee273bdd191..26ac49ecb78d 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -32,6 +32,8 @@
32#include "memory.h" 32#include "memory.h"
33#include "clock.h" 33#include "clock.h"
34 34
35#undef DEBUG
36
35//#define DOWN_VARIABLE_DPLL 1 /* Experimental */ 37//#define DOWN_VARIABLE_DPLL 1 /* Experimental */
36 38
37static struct prcm_config *curr_prcm_set; 39static struct prcm_config *curr_prcm_set;
@@ -114,9 +116,51 @@ static void omap2_clk_fixed_enable(struct clk *clk)
114 while (!(CM_IDLEST_CKGEN & cval)) { /* Wait for lock */ 116 while (!(CM_IDLEST_CKGEN & cval)) { /* Wait for lock */
115 ++i; 117 ++i;
116 udelay(1); 118 udelay(1);
117 if (i == 100000) 119 if (i == 100000) {
120 printk(KERN_ERR "Clock %s didn't lock\n", clk->name);
121 break;
122 }
123 }
124}
125
126static void omap2_clk_wait_ready(struct clk *clk)
127{
128 unsigned long reg, other_reg, st_reg;
129 u32 bit;
130 int i;
131
132 reg = (unsigned long) clk->enable_reg;
133 if (reg == (unsigned long) &CM_FCLKEN1_CORE ||
134 reg == (unsigned long) &CM_FCLKEN2_CORE)
135 other_reg = (reg & ~0xf0) | 0x10;
136 else if (reg == (unsigned long) &CM_ICLKEN1_CORE ||
137 reg == (unsigned long) &CM_ICLKEN2_CORE)
138 other_reg = (reg & ~0xf0) | 0x00;
139 else
140 return;
141
142 /* No check for DSS or cam clocks */
143 if ((reg & 0x0f) == 0) {
144 if (clk->enable_bit <= 1 || clk->enable_bit == 31)
145 return;
146 }
147
148 /* Check if both functional and interface clocks
149 * are running. */
150 bit = 1 << clk->enable_bit;
151 if (!(__raw_readl(other_reg) & bit))
152 return;
153 st_reg = (other_reg & ~0xf0) | 0x20;
154 i = 0;
155 while (!(__raw_readl(st_reg) & bit)) {
156 i++;
157 if (i == 100000) {
158 printk(KERN_ERR "Timeout enabling clock %s\n", clk->name);
118 break; 159 break;
160 }
119 } 161 }
162 if (i)
163 pr_debug("Clock %s stable after %d loops\n", clk->name, i);
120} 164}
121 165
122/* Enables clock without considering parent dependencies or use count 166/* Enables clock without considering parent dependencies or use count
@@ -150,6 +194,8 @@ static int _omap2_clk_enable(struct clk * clk)
150 __raw_writel(regval32, clk->enable_reg); 194 __raw_writel(regval32, clk->enable_reg);
151 wmb(); 195 wmb();
152 196
197 omap2_clk_wait_ready(clk);
198
153 return 0; 199 return 0;
154} 200}
155 201