1 /* 2 * Atheros AR71XX/AR724X/AR913X common routines 3 * 4 * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> 5 * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> 6 * 7 * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License version 2 as published 11 * by the Free Software Foundation. 12 */ 13 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/init.h> 17 #include <linux/err.h> 18 #include <linux/clk.h> 19 #include <linux/clkdev.h> 20 21 #include <asm/div64.h> 22 23 #include <asm/mach-ath79/ath79.h> 24 #include <asm/mach-ath79/ar71xx_regs.h> 25 #include "common.h" 26 27 #define AR71XX_BASE_FREQ 40000000 28 #define AR724X_BASE_FREQ 5000000 29 #define AR913X_BASE_FREQ 5000000 30 31 struct clk { 32 unsigned long rate; 33 }; 34 35 static void __init ath79_add_sys_clkdev(const char *id, unsigned long rate) 36 { 37 struct clk *clk; 38 int err; 39 40 clk = kzalloc(sizeof(*clk), GFP_KERNEL); 41 if (!clk) 42 panic("failed to allocate %s clock structure", id); 43 44 clk->rate = rate; 45 46 err = clk_register_clkdev(clk, id, NULL); 47 if (err) 48 panic("unable to register %s clock device", id); 49 } 50 51 static void __init ar71xx_clocks_init(void) 52 { 53 unsigned long ref_rate; 54 unsigned long cpu_rate; 55 unsigned long ddr_rate; 56 unsigned long ahb_rate; 57 u32 pll; 58 u32 freq; 59 u32 div; 60 61 ref_rate = AR71XX_BASE_FREQ; 62 63 pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG); 64 65 div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1; 66 freq = div * ref_rate; 67 68 div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1; 69 cpu_rate = freq / div; 70 71 div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1; 72 ddr_rate = freq / div; 73 74 div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; 75 ahb_rate = cpu_rate / div; 76 77 ath79_add_sys_clkdev("ref", ref_rate); 78 ath79_add_sys_clkdev("cpu", cpu_rate); 79 ath79_add_sys_clkdev("ddr", ddr_rate); 80 ath79_add_sys_clkdev("ahb", ahb_rate); 81 82 clk_add_alias("wdt", NULL, "ahb", NULL); 83 clk_add_alias("uart", NULL, "ahb", NULL); 84 } 85 86 static void __init ar724x_clocks_init(void) 87 { 88 unsigned long ref_rate; 89 unsigned long cpu_rate; 90 unsigned long ddr_rate; 91 unsigned long ahb_rate; 92 u32 pll; 93 u32 freq; 94 u32 div; 95 96 ref_rate = AR724X_BASE_FREQ; 97 pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG); 98 99 div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK); 100 freq = div * ref_rate; 101 102 div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK); 103 freq *= div; 104 105 cpu_rate = freq; 106 107 div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; 108 ddr_rate = freq / div; 109 110 div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; 111 ahb_rate = cpu_rate / div; 112 113 ath79_add_sys_clkdev("ref", ref_rate); 114 ath79_add_sys_clkdev("cpu", cpu_rate); 115 ath79_add_sys_clkdev("ddr", ddr_rate); 116 ath79_add_sys_clkdev("ahb", ahb_rate); 117 118 clk_add_alias("wdt", NULL, "ahb", NULL); 119 clk_add_alias("uart", NULL, "ahb", NULL); 120 } 121 122 static void __init ar913x_clocks_init(void) 123 { 124 unsigned long ref_rate; 125 unsigned long cpu_rate; 126 unsigned long ddr_rate; 127 unsigned long ahb_rate; 128 u32 pll; 129 u32 freq; 130 u32 div; 131 132 ref_rate = AR913X_BASE_FREQ; 133 pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG); 134 135 div = ((pll >> AR913X_PLL_DIV_SHIFT) & AR913X_PLL_DIV_MASK); 136 freq = div * ref_rate; 137 138 cpu_rate = freq; 139 140 div = ((pll >> AR913X_DDR_DIV_SHIFT) & AR913X_DDR_DIV_MASK) + 1; 141 ddr_rate = freq / div; 142 143 div = (((pll >> AR913X_AHB_DIV_SHIFT) & AR913X_AHB_DIV_MASK) + 1) * 2; 144 ahb_rate = cpu_rate / div; 145 146 ath79_add_sys_clkdev("ref", ref_rate); 147 ath79_add_sys_clkdev("cpu", cpu_rate); 148 ath79_add_sys_clkdev("ddr", ddr_rate); 149 ath79_add_sys_clkdev("ahb", ahb_rate); 150 151 clk_add_alias("wdt", NULL, "ahb", NULL); 152 clk_add_alias("uart", NULL, "ahb", NULL); 153 } 154 155 static void __init ar933x_clocks_init(void) 156 { 157 unsigned long ref_rate; 158 unsigned long cpu_rate; 159 unsigned long ddr_rate; 160 unsigned long ahb_rate; 161 u32 clock_ctrl; 162 u32 cpu_config; 163 u32 freq; 164 u32 t; 165 166 t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); 167 if (t & AR933X_BOOTSTRAP_REF_CLK_40) 168 ref_rate = (40 * 1000 * 1000); 169 else 170 ref_rate = (25 * 1000 * 1000); 171 172 clock_ctrl = ath79_pll_rr(AR933X_PLL_CLOCK_CTRL_REG); 173 if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { 174 cpu_rate = ref_rate; 175 ahb_rate = ref_rate; 176 ddr_rate = ref_rate; 177 } else { 178 cpu_config = ath79_pll_rr(AR933X_PLL_CPU_CONFIG_REG); 179 180 t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 181 AR933X_PLL_CPU_CONFIG_REFDIV_MASK; 182 freq = ref_rate / t; 183 184 t = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) & 185 AR933X_PLL_CPU_CONFIG_NINT_MASK; 186 freq *= t; 187 188 t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 189 AR933X_PLL_CPU_CONFIG_OUTDIV_MASK; 190 if (t == 0) 191 t = 1; 192 193 freq >>= t; 194 195 t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) & 196 AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1; 197 cpu_rate = freq / t; 198 199 t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) & 200 AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1; 201 ddr_rate = freq / t; 202 203 t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) & 204 AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; 205 ahb_rate = freq / t; 206 } 207 208 ath79_add_sys_clkdev("ref", ref_rate); 209 ath79_add_sys_clkdev("cpu", cpu_rate); 210 ath79_add_sys_clkdev("ddr", ddr_rate); 211 ath79_add_sys_clkdev("ahb", ahb_rate); 212 213 clk_add_alias("wdt", NULL, "ahb", NULL); 214 clk_add_alias("uart", NULL, "ref", NULL); 215 } 216 217 static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac, 218 u32 frac, u32 out_div) 219 { 220 u64 t; 221 u32 ret; 222 223 t = ref; 224 t *= nint; 225 do_div(t, ref_div); 226 ret = t; 227 228 t = ref; 229 t *= nfrac; 230 do_div(t, ref_div * frac); 231 ret += t; 232 233 ret /= (1 << out_div); 234 return ret; 235 } 236 237 static void __init ar934x_clocks_init(void) 238 { 239 unsigned long ref_rate; 240 unsigned long cpu_rate; 241 unsigned long ddr_rate; 242 unsigned long ahb_rate; 243 u32 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv; 244 u32 cpu_pll, ddr_pll; 245 u32 bootstrap; 246 void __iomem *dpll_base; 247 248 dpll_base = ioremap(AR934X_SRIF_BASE, AR934X_SRIF_SIZE); 249 250 bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); 251 if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40) 252 ref_rate = 40 * 1000 * 1000; 253 else 254 ref_rate = 25 * 1000 * 1000; 255 256 pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG); 257 if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { 258 out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & 259 AR934X_SRIF_DPLL2_OUTDIV_MASK; 260 pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL1_REG); 261 nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & 262 AR934X_SRIF_DPLL1_NINT_MASK; 263 nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; 264 ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & 265 AR934X_SRIF_DPLL1_REFDIV_MASK; 266 frac = 1 << 18; 267 } else { 268 pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG); 269 out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 270 AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; 271 ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 272 AR934X_PLL_CPU_CONFIG_REFDIV_MASK; 273 nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) & 274 AR934X_PLL_CPU_CONFIG_NINT_MASK; 275 nfrac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) & 276 AR934X_PLL_CPU_CONFIG_NFRAC_MASK; 277 frac = 1 << 6; 278 } 279 280 cpu_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, 281 nfrac, frac, out_div); 282 283 pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG); 284 if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { 285 out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & 286 AR934X_SRIF_DPLL2_OUTDIV_MASK; 287 pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL1_REG); 288 nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & 289 AR934X_SRIF_DPLL1_NINT_MASK; 290 nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; 291 ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & 292 AR934X_SRIF_DPLL1_REFDIV_MASK; 293 frac = 1 << 18; 294 } else { 295 pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG); 296 out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 297 AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; 298 ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 299 AR934X_PLL_DDR_CONFIG_REFDIV_MASK; 300 nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) & 301 AR934X_PLL_DDR_CONFIG_NINT_MASK; 302 nfrac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) & 303 AR934X_PLL_DDR_CONFIG_NFRAC_MASK; 304 frac = 1 << 10; 305 } 306 307 ddr_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, 308 nfrac, frac, out_div); 309 310 clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG); 311 312 postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) & 313 AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK; 314 315 if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS) 316 cpu_rate = ref_rate; 317 else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL) 318 cpu_rate = cpu_pll / (postdiv + 1); 319 else 320 cpu_rate = ddr_pll / (postdiv + 1); 321 322 postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT) & 323 AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK; 324 325 if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS) 326 ddr_rate = ref_rate; 327 else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL) 328 ddr_rate = ddr_pll / (postdiv + 1); 329 else 330 ddr_rate = cpu_pll / (postdiv + 1); 331 332 postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT) & 333 AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK; 334 335 if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS) 336 ahb_rate = ref_rate; 337 else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL) 338 ahb_rate = ddr_pll / (postdiv + 1); 339 else 340 ahb_rate = cpu_pll / (postdiv + 1); 341 342 ath79_add_sys_clkdev("ref", ref_rate); 343 ath79_add_sys_clkdev("cpu", cpu_rate); 344 ath79_add_sys_clkdev("ddr", ddr_rate); 345 ath79_add_sys_clkdev("ahb", ahb_rate); 346 347 clk_add_alias("wdt", NULL, "ref", NULL); 348 clk_add_alias("uart", NULL, "ref", NULL); 349 350 iounmap(dpll_base); 351 } 352 353 static void __init qca955x_clocks_init(void) 354 { 355 unsigned long ref_rate; 356 unsigned long cpu_rate; 357 unsigned long ddr_rate; 358 unsigned long ahb_rate; 359 u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; 360 u32 cpu_pll, ddr_pll; 361 u32 bootstrap; 362 363 bootstrap = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP); 364 if (bootstrap & QCA955X_BOOTSTRAP_REF_CLK_40) 365 ref_rate = 40 * 1000 * 1000; 366 else 367 ref_rate = 25 * 1000 * 1000; 368 369 pll = ath79_pll_rr(QCA955X_PLL_CPU_CONFIG_REG); 370 out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & 371 QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK; 372 ref_div = (pll >> QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT) & 373 QCA955X_PLL_CPU_CONFIG_REFDIV_MASK; 374 nint = (pll >> QCA955X_PLL_CPU_CONFIG_NINT_SHIFT) & 375 QCA955X_PLL_CPU_CONFIG_NINT_MASK; 376 frac = (pll >> QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT) & 377 QCA955X_PLL_CPU_CONFIG_NFRAC_MASK; 378 379 cpu_pll = nint * ref_rate / ref_div; 380 cpu_pll += frac * ref_rate / (ref_div * (1 << 6)); 381 cpu_pll /= (1 << out_div); 382 383 pll = ath79_pll_rr(QCA955X_PLL_DDR_CONFIG_REG); 384 out_div = (pll >> QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & 385 QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK; 386 ref_div = (pll >> QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT) & 387 QCA955X_PLL_DDR_CONFIG_REFDIV_MASK; 388 nint = (pll >> QCA955X_PLL_DDR_CONFIG_NINT_SHIFT) & 389 QCA955X_PLL_DDR_CONFIG_NINT_MASK; 390 frac = (pll >> QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT) & 391 QCA955X_PLL_DDR_CONFIG_NFRAC_MASK; 392 393 ddr_pll = nint * ref_rate / ref_div; 394 ddr_pll += frac * ref_rate / (ref_div * (1 << 10)); 395 ddr_pll /= (1 << out_div); 396 397 clk_ctrl = ath79_pll_rr(QCA955X_PLL_CLK_CTRL_REG); 398 399 postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & 400 QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; 401 402 if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS) 403 cpu_rate = ref_rate; 404 else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL) 405 cpu_rate = ddr_pll / (postdiv + 1); 406 else 407 cpu_rate = cpu_pll / (postdiv + 1); 408 409 postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & 410 QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; 411 412 if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS) 413 ddr_rate = ref_rate; 414 else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL) 415 ddr_rate = cpu_pll / (postdiv + 1); 416 else 417 ddr_rate = ddr_pll / (postdiv + 1); 418 419 postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & 420 QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; 421 422 if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS) 423 ahb_rate = ref_rate; 424 else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) 425 ahb_rate = ddr_pll / (postdiv + 1); 426 else 427 ahb_rate = cpu_pll / (postdiv + 1); 428 429 ath79_add_sys_clkdev("ref", ref_rate); 430 ath79_add_sys_clkdev("cpu", cpu_rate); 431 ath79_add_sys_clkdev("ddr", ddr_rate); 432 ath79_add_sys_clkdev("ahb", ahb_rate); 433 434 clk_add_alias("wdt", NULL, "ref", NULL); 435 clk_add_alias("uart", NULL, "ref", NULL); 436 } 437 438 void __init ath79_clocks_init(void) 439 { 440 if (soc_is_ar71xx()) 441 ar71xx_clocks_init(); 442 else if (soc_is_ar724x()) 443 ar724x_clocks_init(); 444 else if (soc_is_ar913x()) 445 ar913x_clocks_init(); 446 else if (soc_is_ar933x()) 447 ar933x_clocks_init(); 448 else if (soc_is_ar934x()) 449 ar934x_clocks_init(); 450 else if (soc_is_qca955x()) 451 qca955x_clocks_init(); 452 else 453 BUG(); 454 } 455 456 unsigned long __init 457 ath79_get_sys_clk_rate(const char *id) 458 { 459 struct clk *clk; 460 unsigned long rate; 461 462 clk = clk_get(NULL, id); 463 if (IS_ERR(clk)) 464 panic("unable to get %s clock, err=%d", id, (int) PTR_ERR(clk)); 465 466 rate = clk_get_rate(clk); 467 clk_put(clk); 468 469 return rate; 470 } 471 472 /* 473 * Linux clock API 474 */ 475 int clk_enable(struct clk *clk) 476 { 477 return 0; 478 } 479 EXPORT_SYMBOL(clk_enable); 480 481 void clk_disable(struct clk *clk) 482 { 483 } 484 EXPORT_SYMBOL(clk_disable); 485 486 unsigned long clk_get_rate(struct clk *clk) 487 { 488 return clk->rate; 489 } 490 EXPORT_SYMBOL(clk_get_rate); 491