1 /* 2 * arch/arm/mach-ep93xx/clock.c 3 * Clock control for Cirrus EP93xx chips. 4 * 5 * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or (at 10 * your option) any later version. 11 */ 12 13 #include <linux/kernel.h> 14 #include <linux/clk.h> 15 #include <linux/err.h> 16 #include <linux/module.h> 17 #include <linux/string.h> 18 #include <linux/io.h> 19 20 #include <asm/clkdev.h> 21 #include <asm/div64.h> 22 #include <mach/hardware.h> 23 24 25 struct clk { 26 unsigned long rate; 27 int users; 28 int sw_locked; 29 void __iomem *enable_reg; 30 u32 enable_mask; 31 32 unsigned long (*get_rate)(struct clk *clk); 33 int (*set_rate)(struct clk *clk, unsigned long rate); 34 }; 35 36 37 static unsigned long get_uart_rate(struct clk *clk); 38 39 static int set_keytchclk_rate(struct clk *clk, unsigned long rate); 40 static int set_div_rate(struct clk *clk, unsigned long rate); 41 42 static struct clk clk_uart1 = { 43 .sw_locked = 1, 44 .enable_reg = EP93XX_SYSCON_DEVCFG, 45 .enable_mask = EP93XX_SYSCON_DEVCFG_U1EN, 46 .get_rate = get_uart_rate, 47 }; 48 static struct clk clk_uart2 = { 49 .sw_locked = 1, 50 .enable_reg = EP93XX_SYSCON_DEVCFG, 51 .enable_mask = EP93XX_SYSCON_DEVCFG_U2EN, 52 .get_rate = get_uart_rate, 53 }; 54 static struct clk clk_uart3 = { 55 .sw_locked = 1, 56 .enable_reg = EP93XX_SYSCON_DEVCFG, 57 .enable_mask = EP93XX_SYSCON_DEVCFG_U3EN, 58 .get_rate = get_uart_rate, 59 }; 60 static struct clk clk_pll1; 61 static struct clk clk_f; 62 static struct clk clk_h; 63 static struct clk clk_p; 64 static struct clk clk_pll2; 65 static struct clk clk_usb_host = { 66 .enable_reg = EP93XX_SYSCON_PWRCNT, 67 .enable_mask = EP93XX_SYSCON_PWRCNT_USH_EN, 68 }; 69 static struct clk clk_keypad = { 70 .sw_locked = 1, 71 .enable_reg = EP93XX_SYSCON_KEYTCHCLKDIV, 72 .enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_KEN, 73 .set_rate = set_keytchclk_rate, 74 }; 75 static struct clk clk_pwm = { 76 .rate = EP93XX_EXT_CLK_RATE, 77 }; 78 79 static struct clk clk_video = { 80 .sw_locked = 1, 81 .enable_reg = EP93XX_SYSCON_VIDCLKDIV, 82 .enable_mask = EP93XX_SYSCON_CLKDIV_ENABLE, 83 .set_rate = set_div_rate, 84 }; 85 86 /* DMA Clocks */ 87 static struct clk clk_m2p0 = { 88 .enable_reg = EP93XX_SYSCON_PWRCNT, 89 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P0, 90 }; 91 static struct clk clk_m2p1 = { 92 .enable_reg = EP93XX_SYSCON_PWRCNT, 93 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P1, 94 }; 95 static struct clk clk_m2p2 = { 96 .enable_reg = EP93XX_SYSCON_PWRCNT, 97 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P2, 98 }; 99 static struct clk clk_m2p3 = { 100 .enable_reg = EP93XX_SYSCON_PWRCNT, 101 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P3, 102 }; 103 static struct clk clk_m2p4 = { 104 .enable_reg = EP93XX_SYSCON_PWRCNT, 105 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P4, 106 }; 107 static struct clk clk_m2p5 = { 108 .enable_reg = EP93XX_SYSCON_PWRCNT, 109 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P5, 110 }; 111 static struct clk clk_m2p6 = { 112 .enable_reg = EP93XX_SYSCON_PWRCNT, 113 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P6, 114 }; 115 static struct clk clk_m2p7 = { 116 .enable_reg = EP93XX_SYSCON_PWRCNT, 117 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P7, 118 }; 119 static struct clk clk_m2p8 = { 120 .enable_reg = EP93XX_SYSCON_PWRCNT, 121 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P8, 122 }; 123 static struct clk clk_m2p9 = { 124 .enable_reg = EP93XX_SYSCON_PWRCNT, 125 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P9, 126 }; 127 static struct clk clk_m2m0 = { 128 .enable_reg = EP93XX_SYSCON_PWRCNT, 129 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2M0, 130 }; 131 static struct clk clk_m2m1 = { 132 .enable_reg = EP93XX_SYSCON_PWRCNT, 133 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2M1, 134 }; 135 136 #define INIT_CK(dev,con,ck) \ 137 { .dev_id = dev, .con_id = con, .clk = ck } 138 139 static struct clk_lookup clocks[] = { 140 INIT_CK("apb:uart1", NULL, &clk_uart1), 141 INIT_CK("apb:uart2", NULL, &clk_uart2), 142 INIT_CK("apb:uart3", NULL, &clk_uart3), 143 INIT_CK(NULL, "pll1", &clk_pll1), 144 INIT_CK(NULL, "fclk", &clk_f), 145 INIT_CK(NULL, "hclk", &clk_h), 146 INIT_CK(NULL, "pclk", &clk_p), 147 INIT_CK(NULL, "pll2", &clk_pll2), 148 INIT_CK("ep93xx-ohci", NULL, &clk_usb_host), 149 INIT_CK("ep93xx-keypad", NULL, &clk_keypad), 150 INIT_CK("ep93xx-fb", NULL, &clk_video), 151 INIT_CK(NULL, "pwm_clk", &clk_pwm), 152 INIT_CK(NULL, "m2p0", &clk_m2p0), 153 INIT_CK(NULL, "m2p1", &clk_m2p1), 154 INIT_CK(NULL, "m2p2", &clk_m2p2), 155 INIT_CK(NULL, "m2p3", &clk_m2p3), 156 INIT_CK(NULL, "m2p4", &clk_m2p4), 157 INIT_CK(NULL, "m2p5", &clk_m2p5), 158 INIT_CK(NULL, "m2p6", &clk_m2p6), 159 INIT_CK(NULL, "m2p7", &clk_m2p7), 160 INIT_CK(NULL, "m2p8", &clk_m2p8), 161 INIT_CK(NULL, "m2p9", &clk_m2p9), 162 INIT_CK(NULL, "m2m0", &clk_m2m0), 163 INIT_CK(NULL, "m2m1", &clk_m2m1), 164 }; 165 166 167 int clk_enable(struct clk *clk) 168 { 169 if (!clk->users++ && clk->enable_reg) { 170 u32 value; 171 172 value = __raw_readl(clk->enable_reg); 173 value |= clk->enable_mask; 174 if (clk->sw_locked) 175 ep93xx_syscon_swlocked_write(value, clk->enable_reg); 176 else 177 __raw_writel(value, clk->enable_reg); 178 } 179 180 return 0; 181 } 182 EXPORT_SYMBOL(clk_enable); 183 184 void clk_disable(struct clk *clk) 185 { 186 if (!--clk->users && clk->enable_reg) { 187 u32 value; 188 189 value = __raw_readl(clk->enable_reg); 190 value &= ~clk->enable_mask; 191 if (clk->sw_locked) 192 ep93xx_syscon_swlocked_write(value, clk->enable_reg); 193 else 194 __raw_writel(value, clk->enable_reg); 195 } 196 } 197 EXPORT_SYMBOL(clk_disable); 198 199 static unsigned long get_uart_rate(struct clk *clk) 200 { 201 u32 value; 202 203 value = __raw_readl(EP93XX_SYSCON_PWRCNT); 204 if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD) 205 return EP93XX_EXT_CLK_RATE; 206 else 207 return EP93XX_EXT_CLK_RATE / 2; 208 } 209 210 unsigned long clk_get_rate(struct clk *clk) 211 { 212 if (clk->get_rate) 213 return clk->get_rate(clk); 214 215 return clk->rate; 216 } 217 EXPORT_SYMBOL(clk_get_rate); 218 219 static int set_keytchclk_rate(struct clk *clk, unsigned long rate) 220 { 221 u32 val; 222 u32 div_bit; 223 224 val = __raw_readl(clk->enable_reg); 225 226 /* 227 * The Key Matrix and ADC clocks are configured using the same 228 * System Controller register. The clock used will be either 229 * 1/4 or 1/16 the external clock rate depending on the 230 * EP93XX_SYSCON_KEYTCHCLKDIV_KDIV/EP93XX_SYSCON_KEYTCHCLKDIV_ADIV 231 * bit being set or cleared. 232 */ 233 div_bit = clk->enable_mask >> 15; 234 235 if (rate == EP93XX_KEYTCHCLK_DIV4) 236 val |= div_bit; 237 else if (rate == EP93XX_KEYTCHCLK_DIV16) 238 val &= ~div_bit; 239 else 240 return -EINVAL; 241 242 ep93xx_syscon_swlocked_write(val, clk->enable_reg); 243 clk->rate = rate; 244 return 0; 245 } 246 247 static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel, 248 int *pdiv, int *div) 249 { 250 unsigned long max_rate, best_rate = 0, 251 actual_rate = 0, mclk_rate = 0, rate_err = -1; 252 int i, found = 0, __div = 0, __pdiv = 0; 253 254 /* Don't exceed the maximum rate */ 255 max_rate = max(max(clk_pll1.rate / 4, clk_pll2.rate / 4), 256 (unsigned long)EP93XX_EXT_CLK_RATE / 4); 257 rate = min(rate, max_rate); 258 259 /* 260 * Try the two pll's and the external clock 261 * Because the valid predividers are 2, 2.5 and 3, we multiply 262 * all the clocks by 2 to avoid floating point math. 263 * 264 * This is based on the algorithm in the ep93xx raster guide: 265 * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf 266 * 267 */ 268 for (i = 0; i < 3; i++) { 269 if (i == 0) 270 mclk_rate = EP93XX_EXT_CLK_RATE * 2; 271 else if (i == 1) 272 mclk_rate = clk_pll1.rate * 2; 273 else if (i == 2) 274 mclk_rate = clk_pll2.rate * 2; 275 276 /* Try each predivider value */ 277 for (__pdiv = 4; __pdiv <= 6; __pdiv++) { 278 __div = mclk_rate / (rate * __pdiv); 279 if (__div < 2 || __div > 127) 280 continue; 281 282 actual_rate = mclk_rate / (__pdiv * __div); 283 284 if (!found || abs(actual_rate - rate) < rate_err) { 285 *pdiv = __pdiv - 3; 286 *div = __div; 287 *psel = (i == 2); 288 *esel = (i != 0); 289 best_rate = actual_rate; 290 rate_err = abs(actual_rate - rate); 291 found = 1; 292 } 293 } 294 } 295 296 if (!found) 297 return 0; 298 299 return best_rate; 300 } 301 302 static int set_div_rate(struct clk *clk, unsigned long rate) 303 { 304 unsigned long actual_rate; 305 int psel = 0, esel = 0, pdiv = 0, div = 0; 306 u32 val; 307 308 actual_rate = calc_clk_div(rate, &psel, &esel, &pdiv, &div); 309 if (actual_rate == 0) 310 return -EINVAL; 311 clk->rate = actual_rate; 312 313 /* Clear the esel, psel, pdiv and div bits */ 314 val = __raw_readl(clk->enable_reg); 315 val &= ~0x7fff; 316 317 /* Set the new esel, psel, pdiv and div bits for the new clock rate */ 318 val |= (esel ? EP93XX_SYSCON_CLKDIV_ESEL : 0) | 319 (psel ? EP93XX_SYSCON_CLKDIV_PSEL : 0) | 320 (pdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | div; 321 ep93xx_syscon_swlocked_write(val, clk->enable_reg); 322 return 0; 323 } 324 325 int clk_set_rate(struct clk *clk, unsigned long rate) 326 { 327 if (clk->set_rate) 328 return clk->set_rate(clk, rate); 329 330 return -EINVAL; 331 } 332 EXPORT_SYMBOL(clk_set_rate); 333 334 335 static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 }; 336 static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 }; 337 static char pclk_divisors[] = { 1, 2, 4, 8 }; 338 339 /* 340 * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS 341 */ 342 static unsigned long calc_pll_rate(u32 config_word) 343 { 344 unsigned long long rate; 345 int i; 346 347 rate = EP93XX_EXT_CLK_RATE; 348 rate *= ((config_word >> 11) & 0x1f) + 1; /* X1FBD */ 349 rate *= ((config_word >> 5) & 0x3f) + 1; /* X2FBD */ 350 do_div(rate, (config_word & 0x1f) + 1); /* X2IPD */ 351 for (i = 0; i < ((config_word >> 16) & 3); i++) /* PS */ 352 rate >>= 1; 353 354 return (unsigned long)rate; 355 } 356 357 static void __init ep93xx_dma_clock_init(void) 358 { 359 clk_m2p0.rate = clk_h.rate; 360 clk_m2p1.rate = clk_h.rate; 361 clk_m2p2.rate = clk_h.rate; 362 clk_m2p3.rate = clk_h.rate; 363 clk_m2p4.rate = clk_h.rate; 364 clk_m2p5.rate = clk_h.rate; 365 clk_m2p6.rate = clk_h.rate; 366 clk_m2p7.rate = clk_h.rate; 367 clk_m2p8.rate = clk_h.rate; 368 clk_m2p9.rate = clk_h.rate; 369 clk_m2m0.rate = clk_h.rate; 370 clk_m2m1.rate = clk_h.rate; 371 } 372 373 static int __init ep93xx_clock_init(void) 374 { 375 u32 value; 376 int i; 377 378 value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1); 379 if (!(value & 0x00800000)) { /* PLL1 bypassed? */ 380 clk_pll1.rate = EP93XX_EXT_CLK_RATE; 381 } else { 382 clk_pll1.rate = calc_pll_rate(value); 383 } 384 clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7]; 385 clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7]; 386 clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3]; 387 ep93xx_dma_clock_init(); 388 389 value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2); 390 if (!(value & 0x00080000)) { /* PLL2 bypassed? */ 391 clk_pll2.rate = EP93XX_EXT_CLK_RATE; 392 } else if (value & 0x00040000) { /* PLL2 enabled? */ 393 clk_pll2.rate = calc_pll_rate(value); 394 } else { 395 clk_pll2.rate = 0; 396 } 397 clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1); 398 399 printk(KERN_INFO "ep93xx: PLL1 running at %ld MHz, PLL2 at %ld MHz\n", 400 clk_pll1.rate / 1000000, clk_pll2.rate / 1000000); 401 printk(KERN_INFO "ep93xx: FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n", 402 clk_f.rate / 1000000, clk_h.rate / 1000000, 403 clk_p.rate / 1000000); 404 405 for (i = 0; i < ARRAY_SIZE(clocks); i++) 406 clkdev_add(&clocks[i]); 407 return 0; 408 } 409 arch_initcall(ep93xx_clock_init); 410