aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tcc8k/clock.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/arch/arm/mach-tcc8k/clock.c b/arch/arm/mach-tcc8k/clock.c
index 3970a9cdce26..7ebcbff4652a 100644
--- a/arch/arm/mach-tcc8k/clock.c
+++ b/arch/arm/mach-tcc8k/clock.c
@@ -50,6 +50,8 @@
50#define ACLKTCX (CKC_BASE + ACLKTCX_OFFS) 50#define ACLKTCX (CKC_BASE + ACLKTCX_OFFS)
51#define ACLKTCZ (CKC_BASE + ACLKTCZ_OFFS) 51#define ACLKTCZ (CKC_BASE + ACLKTCZ_OFFS)
52 52
53#define ACLK_MAX_DIV (0xfff + 1)
54
53/* Crystal frequencies */ 55/* Crystal frequencies */
54static unsigned long xi_rate, xti_rate; 56static unsigned long xi_rate, xti_rate;
55 57
@@ -258,14 +260,19 @@ static unsigned long aclk_best_div(struct clk *clk, unsigned long rate)
258{ 260{
259 unsigned long div, src, freq, r1, r2; 261 unsigned long div, src, freq, r1, r2;
260 262
263 if (!rate)
264 return ACLK_MAX_DIV;
265
261 src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT; 266 src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT;
262 src &= CLK_SRC_MASK; 267 src &= CLK_SRC_MASK;
263 freq = root_clk_get_rate(src); 268 freq = root_clk_get_rate(src);
264 div = freq / rate + 1; 269 div = freq / rate;
270 if (!div)
271 return 1;
272 if (div >= ACLK_MAX_DIV)
273 return ACLK_MAX_DIV;
265 r1 = freq / div; 274 r1 = freq / div;
266 r2 = freq / (div + 1); 275 r2 = freq / (div + 1);
267 if (r2 >= rate)
268 return div + 1;
269 if ((rate - r2) < (r1 - rate)) 276 if ((rate - r2) < (r1 - rate))
270 return div + 1; 277 return div + 1;
271 278
@@ -287,7 +294,8 @@ static int aclk_set_rate(struct clk *clk, unsigned long rate)
287 u32 reg; 294 u32 reg;
288 295
289 reg = __raw_readl(clk->aclkreg) & ~ACLK_DIV_MASK; 296 reg = __raw_readl(clk->aclkreg) & ~ACLK_DIV_MASK;
290 reg |= aclk_best_div(clk, rate); 297 reg |= aclk_best_div(clk, rate) - 1;
298 __raw_writel(reg, clk->aclkreg);
291 return 0; 299 return 0;
292} 300}
293 301