aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-ux500/clock.c
diff options
context:
space:
mode:
authorSundar Iyer <sundar.iyer@stericsson.com>2010-12-03 10:05:51 -0500
committerLinus Walleij <linus.walleij@stericsson.com>2010-12-08 07:15:03 -0500
commitf306954c9b69aa21bd26724c59ac8c98b7d6e003 (patch)
tree14a1657c5bb442ed0a3957b13b9aeb71c5dcbec6 /arch/arm/mach-ux500/clock.c
parentdacdc96cd33dee876c704aaed78f41515abe8a81 (diff)
mach-ux500: explicit enable MTU TCR in the kernel
PRCM_TCR enables the various timers in the system. This must be achieved before any of the MTUs are usable for kernel usage. Explicit enabling of this in the kernel makes it independent of bootloader actions. Signed-off-by: Sundar Iyer <sundar.iyer@stericsson.com> Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
Diffstat (limited to 'arch/arm/mach-ux500/clock.c')
-rw-r--r--arch/arm/mach-ux500/clock.c49
1 files changed, 9 insertions, 40 deletions
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
index 1675047daf20..a7cd0d55828e 100644
--- a/arch/arm/mach-ux500/clock.c
+++ b/arch/arm/mach-ux500/clock.c
@@ -133,7 +133,7 @@ static unsigned long clk_mtu_get_rate(struct clk *clk)
133{ 133{
134 void __iomem *addr = __io_address(UX500_PRCMU_BASE) 134 void __iomem *addr = __io_address(UX500_PRCMU_BASE)
135 + PRCM_TCR; 135 + PRCM_TCR;
136 u32 tcr = readl(addr); 136 u32 tcr;
137 int mtu = (int) clk->data; 137 int mtu = (int) clk->data;
138 /* 138 /*
139 * One of these is selected eventually 139 * One of these is selected eventually
@@ -144,6 +144,14 @@ static unsigned long clk_mtu_get_rate(struct clk *clk)
144 unsigned long mturate; 144 unsigned long mturate;
145 unsigned long retclk; 145 unsigned long retclk;
146 146
147 /*
148 * On a startup, always conifgure the TCR to the doze mode;
149 * bootloaders do it for us. Do this in the kernel too.
150 */
151 writel(PRCM_TCR_DOZE_MODE, addr);
152
153 tcr = readl(addr);
154
147 /* Get the rate from the parent as a default */ 155 /* Get the rate from the parent as a default */
148 if (clk->parent_periph) 156 if (clk->parent_periph)
149 mturate = clk_get_rate(clk->parent_periph); 157 mturate = clk_get_rate(clk->parent_periph);
@@ -153,45 +161,6 @@ static unsigned long clk_mtu_get_rate(struct clk *clk)
153 /* We need to be connected SOMEWHERE */ 161 /* We need to be connected SOMEWHERE */
154 BUG(); 162 BUG();
155 163
156 /*
157 * Are we in doze mode?
158 * In this mode the parent peripheral or the fixed 32768 Hz
159 * clock is fed into the block.
160 */
161 if (!(tcr & PRCM_TCR_DOZE_MODE)) {
162 /*
163 * Here we're using the clock input from the APE ULP
164 * clock domain. But first: are the timers stopped?
165 */
166 if (tcr & PRCM_TCR_STOPPED) {
167 clk32k = 0;
168 mturate = 0;
169 } else {
170 /* Else default mode: 0 and 2.4 MHz */
171 clk32k = 0;
172 if (cpu_is_u5500())
173 /* DB5500 divides by 8 */
174 mturate /= 8;
175 else if (cpu_is_u8500ed()) {
176 /*
177 * This clocking setting must not be used
178 * in the ED chip, it is simply not
179 * connected anywhere!
180 */
181 mturate = 0;
182 BUG();
183 } else
184 /*
185 * In this mode the ulp38m4 clock is divided
186 * by a factor 16, on the DB8500 typically
187 * 38400000 / 16 ~ 2.4 MHz.
188 * TODO: Replace the constant with a reference
189 * to the ULP source once this is modeled.
190 */
191 mturate = 38400000 / 16;
192 }
193 }
194
195 /* Return the clock selected for this MTU */ 164 /* Return the clock selected for this MTU */
196 if (tcr & (1 << mtu)) 165 if (tcr & (1 << mtu))
197 retclk = clk32k; 166 retclk = clk32k;