1/* 2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de> 3 * JZ4740 SoC clock support 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License as published by the 7 * Free Software Foundation; either version 2 of the License, or (at your 8 * option) any later version. 9 * 10 * You should have received a copy of the GNU General Public License along 11 * with this program; if not, write to the Free Software Foundation, Inc., 12 * 675 Mass Ave, Cambridge, MA 02139, USA. 13 * 14 */ 15 16#include <linux/kernel.h> 17#include <linux/errno.h> 18#include <linux/clk.h> 19#include <linux/spinlock.h> 20#include <linux/io.h> 21#include <linux/module.h> 22#include <linux/list.h> 23#include <linux/err.h> 24 25#include <asm/mach-jz4740/clock.h> 26#include <asm/mach-jz4740/base.h> 27 28#include "clock.h" 29 30#define JZ_REG_CLOCK_CTRL 0x00 31#define JZ_REG_CLOCK_LOW_POWER 0x04 32#define JZ_REG_CLOCK_PLL 0x10 33#define JZ_REG_CLOCK_GATE 0x20 34#define JZ_REG_CLOCK_SLEEP_CTRL 0x24 35#define JZ_REG_CLOCK_I2S 0x60 36#define JZ_REG_CLOCK_LCD 0x64 37#define JZ_REG_CLOCK_MMC 0x68 38#define JZ_REG_CLOCK_UHC 0x6C 39#define JZ_REG_CLOCK_SPI 0x74 40 41#define JZ_CLOCK_CTRL_I2S_SRC_PLL BIT(31) 42#define JZ_CLOCK_CTRL_KO_ENABLE BIT(30) 43#define JZ_CLOCK_CTRL_UDC_SRC_PLL BIT(29) 44#define JZ_CLOCK_CTRL_UDIV_MASK 0x1f800000 45#define JZ_CLOCK_CTRL_CHANGE_ENABLE BIT(22) 46#define JZ_CLOCK_CTRL_PLL_HALF BIT(21) 47#define JZ_CLOCK_CTRL_LDIV_MASK 0x001f0000 48#define JZ_CLOCK_CTRL_UDIV_OFFSET 23 49#define JZ_CLOCK_CTRL_LDIV_OFFSET 16 50#define JZ_CLOCK_CTRL_MDIV_OFFSET 12 51#define JZ_CLOCK_CTRL_PDIV_OFFSET 8 52#define JZ_CLOCK_CTRL_HDIV_OFFSET 4 53#define JZ_CLOCK_CTRL_CDIV_OFFSET 0 54 55#define JZ_CLOCK_GATE_UART0 BIT(0) 56#define JZ_CLOCK_GATE_TCU BIT(1) 57#define JZ_CLOCK_GATE_RTC BIT(2) 58#define JZ_CLOCK_GATE_I2C BIT(3) 59#define JZ_CLOCK_GATE_SPI BIT(4) 60#define JZ_CLOCK_GATE_AIC BIT(5) 61#define JZ_CLOCK_GATE_I2S BIT(6) 62#define JZ_CLOCK_GATE_MMC BIT(7) 63#define JZ_CLOCK_GATE_ADC BIT(8) 64#define JZ_CLOCK_GATE_CIM BIT(9) 65#define JZ_CLOCK_GATE_LCD BIT(10) 66#define JZ_CLOCK_GATE_UDC BIT(11) 67#define JZ_CLOCK_GATE_DMAC BIT(12) 68#define JZ_CLOCK_GATE_IPU BIT(13) 69#define JZ_CLOCK_GATE_UHC BIT(14) 70#define JZ_CLOCK_GATE_UART1 BIT(15) 71 72#define JZ_CLOCK_I2S_DIV_MASK 0x01ff 73 74#define JZ_CLOCK_LCD_DIV_MASK 0x01ff 75 76#define JZ_CLOCK_MMC_DIV_MASK 0x001f 77 78#define JZ_CLOCK_UHC_DIV_MASK 0x000f 79 80#define JZ_CLOCK_SPI_SRC_PLL BIT(31) 81#define JZ_CLOCK_SPI_DIV_MASK 0x000f 82 83#define JZ_CLOCK_PLL_M_MASK 0x01ff 84#define JZ_CLOCK_PLL_N_MASK 0x001f 85#define JZ_CLOCK_PLL_OD_MASK 0x0003 86#define JZ_CLOCK_PLL_STABLE BIT(10) 87#define JZ_CLOCK_PLL_BYPASS BIT(9) 88#define JZ_CLOCK_PLL_ENABLED BIT(8) 89#define JZ_CLOCK_PLL_STABLIZE_MASK 0x000f 90#define JZ_CLOCK_PLL_M_OFFSET 23 91#define JZ_CLOCK_PLL_N_OFFSET 18 92#define JZ_CLOCK_PLL_OD_OFFSET 16 93 94#define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2) 95#define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0) 96 97#define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(7) 98#define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(6) 99 100static void __iomem *jz_clock_base; 101static spinlock_t jz_clock_lock; 102static LIST_HEAD(jz_clocks); 103 104struct main_clk { 105 struct clk clk; 106 uint32_t div_offset; 107}; 108 109struct divided_clk { 110 struct clk clk; 111 uint32_t reg; 112 uint32_t mask; 113}; 114 115struct static_clk { 116 struct clk clk; 117 unsigned long rate; 118}; 119 120static uint32_t jz_clk_reg_read(int reg) 121{ 122 return readl(jz_clock_base + reg); 123} 124 125static void jz_clk_reg_write_mask(int reg, uint32_t val, uint32_t mask) 126{ 127 uint32_t val2; 128 129 spin_lock(&jz_clock_lock); 130 val2 = readl(jz_clock_base + reg); 131 val2 &= ~mask; 132 val2 |= val; 133 writel(val2, jz_clock_base + reg); 134 spin_unlock(&jz_clock_lock); 135} 136 137static void jz_clk_reg_set_bits(int reg, uint32_t mask) 138{ 139 uint32_t val; 140 141 spin_lock(&jz_clock_lock); 142 val = readl(jz_clock_base + reg); 143 val |= mask; 144 writel(val, jz_clock_base + reg); 145 spin_unlock(&jz_clock_lock); 146} 147 148static void jz_clk_reg_clear_bits(int reg, uint32_t mask) 149{ 150 uint32_t val; 151 152 spin_lock(&jz_clock_lock); 153 val = readl(jz_clock_base + reg); 154 val &= ~mask; 155 writel(val, jz_clock_base + reg); 156 spin_unlock(&jz_clock_lock); 157} 158 159static int jz_clk_enable_gating(struct clk *clk) 160{ 161 if (clk->gate_bit == JZ4740_CLK_NOT_GATED) 162 return -EINVAL; 163 164 jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, clk->gate_bit); 165 return 0; 166} 167 168static int jz_clk_disable_gating(struct clk *clk) 169{ 170 if (clk->gate_bit == JZ4740_CLK_NOT_GATED) 171 return -EINVAL; 172 173 jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, clk->gate_bit); 174 return 0; 175} 176 177static int jz_clk_is_enabled_gating(struct clk *clk) 178{ 179 if (clk->gate_bit == JZ4740_CLK_NOT_GATED) 180 return 1; 181 182 return !(jz_clk_reg_read(JZ_REG_CLOCK_GATE) & clk->gate_bit); 183} 184 185static unsigned long jz_clk_static_get_rate(struct clk *clk) 186{ 187 return ((struct static_clk *)clk)->rate; 188} 189 190static int jz_clk_ko_enable(struct clk *clk) 191{ 192 jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE); 193 return 0; 194} 195 196static int jz_clk_ko_disable(struct clk *clk) 197{ 198 jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE); 199 return 0; 200} 201 202static int jz_clk_ko_is_enabled(struct clk *clk) 203{ 204 return !!(jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_KO_ENABLE); 205} 206 207static const int pllno[] = {1, 2, 2, 4}; 208 209static unsigned long jz_clk_pll_get_rate(struct clk *clk) 210{ 211 uint32_t val; 212 int m; 213 int n; 214 int od; 215 216 val = jz_clk_reg_read(JZ_REG_CLOCK_PLL); 217 218 if (val & JZ_CLOCK_PLL_BYPASS) 219 return clk_get_rate(clk->parent); 220 221 m = ((val >> 23) & 0x1ff) + 2; 222 n = ((val >> 18) & 0x1f) + 2; 223 od = (val >> 16) & 0x3; 224 225 return ((clk_get_rate(clk->parent) / n) * m) / pllno[od]; 226} 227 228static unsigned long jz_clk_pll_half_get_rate(struct clk *clk) 229{ 230 uint32_t reg; 231 232 reg = jz_clk_reg_read(JZ_REG_CLOCK_CTRL); 233 if (reg & JZ_CLOCK_CTRL_PLL_HALF) 234 return jz_clk_pll_get_rate(clk->parent); 235 return jz_clk_pll_get_rate(clk->parent) >> 1; 236} 237 238static const int jz_clk_main_divs[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; 239 240static unsigned long jz_clk_main_round_rate(struct clk *clk, unsigned long rate) 241{ 242 unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent); 243 int div; 244 245 div = parent_rate / rate; 246 if (div > 32) 247 return parent_rate / 32; 248 else if (div < 1) 249 return parent_rate; 250 251 div &= (0x3 << (ffs(div) - 1)); 252 253 return parent_rate / div; 254} 255 256static unsigned long jz_clk_main_get_rate(struct clk *clk) 257{ 258 struct main_clk *mclk = (struct main_clk *)clk; 259 uint32_t div; 260 261 div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL); 262 263 div >>= mclk->div_offset; 264 div &= 0xf; 265 266 if (div >= ARRAY_SIZE(jz_clk_main_divs)) 267 div = ARRAY_SIZE(jz_clk_main_divs) - 1; 268 269 return jz_clk_pll_get_rate(clk->parent) / jz_clk_main_divs[div]; 270} 271 272static int jz_clk_main_set_rate(struct clk *clk, unsigned long rate) 273{ 274 struct main_clk *mclk = (struct main_clk *)clk; 275 int i; 276 int div; 277 unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent); 278 279 rate = jz_clk_main_round_rate(clk, rate); 280 281 div = parent_rate / rate; 282 283 i = (ffs(div) - 1) << 1; 284 if (i > 0 && !(div & BIT(i-1))) 285 i -= 1; 286 287 jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, i << mclk->div_offset, 288 0xf << mclk->div_offset); 289 290 return 0; 291} 292 293static struct clk_ops jz_clk_static_ops = { 294 .get_rate = jz_clk_static_get_rate, 295 .enable = jz_clk_enable_gating, 296 .disable = jz_clk_disable_gating, 297 .is_enabled = jz_clk_is_enabled_gating, 298}; 299 300static struct static_clk jz_clk_ext = { 301 .clk = { 302 .name = "ext", 303 .gate_bit = JZ4740_CLK_NOT_GATED, 304 .ops = &jz_clk_static_ops, 305 }, 306}; 307 308static struct clk_ops jz_clk_pll_ops = { 309 .get_rate = jz_clk_pll_get_rate, 310}; 311 312static struct clk jz_clk_pll = { 313 .name = "pll", 314 .parent = &jz_clk_ext.clk, 315 .ops = &jz_clk_pll_ops, 316}; 317 318static struct clk_ops jz_clk_pll_half_ops = { 319 .get_rate = jz_clk_pll_half_get_rate, 320}; 321 322static struct clk jz_clk_pll_half = { 323 .name = "pll half", 324 .parent = &jz_clk_pll, 325 .ops = &jz_clk_pll_half_ops, 326}; 327 328static const struct clk_ops jz_clk_main_ops = { 329 .get_rate = jz_clk_main_get_rate, 330 .set_rate = jz_clk_main_set_rate, 331 .round_rate = jz_clk_main_round_rate, 332}; 333 334static struct main_clk jz_clk_cpu = { 335 .clk = { 336 .name = "cclk", 337 .parent = &jz_clk_pll, 338 .ops = &jz_clk_main_ops, 339 }, 340 .div_offset = JZ_CLOCK_CTRL_CDIV_OFFSET, 341}; 342 343static struct main_clk jz_clk_memory = { 344 .clk = { 345 .name = "mclk", 346 .parent = &jz_clk_pll, 347 .ops = &jz_clk_main_ops, 348 }, 349 .div_offset = JZ_CLOCK_CTRL_MDIV_OFFSET, 350}; 351 352static struct main_clk jz_clk_high_speed_peripheral = { 353 .clk = { 354 .name = "hclk", 355 .parent = &jz_clk_pll, 356 .ops = &jz_clk_main_ops, 357 }, 358 .div_offset = JZ_CLOCK_CTRL_HDIV_OFFSET, 359}; 360 361 362static struct main_clk jz_clk_low_speed_peripheral = { 363 .clk = { 364 .name = "pclk", 365 .parent = &jz_clk_pll, 366 .ops = &jz_clk_main_ops, 367 }, 368 .div_offset = JZ_CLOCK_CTRL_PDIV_OFFSET, 369}; 370 371static const struct clk_ops jz_clk_ko_ops = { 372 .enable = jz_clk_ko_enable, 373 .disable = jz_clk_ko_disable, 374 .is_enabled = jz_clk_ko_is_enabled, 375}; 376 377static struct clk jz_clk_ko = { 378 .name = "cko", 379 .parent = &jz_clk_memory.clk, 380 .ops = &jz_clk_ko_ops, 381}; 382 383static int jz_clk_spi_set_parent(struct clk *clk, struct clk *parent) 384{ 385 if (parent == &jz_clk_pll) 386 jz_clk_reg_set_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI); 387 else if (parent == &jz_clk_ext.clk) 388 jz_clk_reg_clear_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI); 389 else 390 return -EINVAL; 391 392 clk->parent = parent; 393 394 return 0; 395} 396 397static int jz_clk_i2s_set_parent(struct clk *clk, struct clk *parent) 398{ 399 if (parent == &jz_clk_pll_half) 400 jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL); 401 else if (parent == &jz_clk_ext.clk) 402 jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL); 403 else 404 return -EINVAL; 405 406 clk->parent = parent; 407 408 return 0; 409} 410 411static int jz_clk_udc_enable(struct clk *clk) 412{ 413 jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL, 414 JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC); 415 416 return 0; 417} 418 419static int jz_clk_udc_disable(struct clk *clk) 420{ 421 jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL, 422 JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC); 423 424 return 0; 425} 426 427static int jz_clk_udc_is_enabled(struct clk *clk) 428{ 429 return !!(jz_clk_reg_read(JZ_REG_CLOCK_SLEEP_CTRL) & 430 JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC); 431} 432 433static int jz_clk_udc_set_parent(struct clk *clk, struct clk *parent) 434{ 435 if (parent == &jz_clk_pll_half) 436 jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL); 437 else if (parent == &jz_clk_ext.clk) 438 jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL); 439 else 440 return -EINVAL; 441 442 clk->parent = parent; 443 444 return 0; 445} 446 447static int jz_clk_udc_set_rate(struct clk *clk, unsigned long rate) 448{ 449 int div; 450 451 if (clk->parent == &jz_clk_ext.clk) 452 return -EINVAL; 453 454 div = clk_get_rate(clk->parent) / rate - 1; 455 456 if (div < 0) 457 div = 0; 458 else if (div > 63) 459 div = 63; 460 461 jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_UDIV_OFFSET, 462 JZ_CLOCK_CTRL_UDIV_MASK); 463 return 0; 464} 465 466static unsigned long jz_clk_udc_get_rate(struct clk *clk) 467{ 468 int div; 469 470 if (clk->parent == &jz_clk_ext.clk) 471 return clk_get_rate(clk->parent); 472 473 div = (jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_UDIV_MASK); 474 div >>= JZ_CLOCK_CTRL_UDIV_OFFSET; 475 div += 1; 476 477 return clk_get_rate(clk->parent) / div; 478} 479 480static unsigned long jz_clk_divided_get_rate(struct clk *clk) 481{ 482 struct divided_clk *dclk = (struct divided_clk *)clk; 483 int div; 484 485 if (clk->parent == &jz_clk_ext.clk) 486 return clk_get_rate(clk->parent); 487 488 div = (jz_clk_reg_read(dclk->reg) & dclk->mask) + 1; 489 490 return clk_get_rate(clk->parent) / div; 491} 492 493static int jz_clk_divided_set_rate(struct clk *clk, unsigned long rate) 494{ 495 struct divided_clk *dclk = (struct divided_clk *)clk; 496 int div; 497 498 if (clk->parent == &jz_clk_ext.clk) 499 return -EINVAL; 500 501 div = clk_get_rate(clk->parent) / rate - 1; 502 503 if (div < 0) 504 div = 0; 505 else if (div > dclk->mask) 506 div = dclk->mask; 507 508 jz_clk_reg_write_mask(dclk->reg, div, dclk->mask); 509 510 return 0; 511} 512 513static unsigned long jz_clk_ldclk_round_rate(struct clk *clk, unsigned long rate) 514{ 515 int div; 516 unsigned long parent_rate = jz_clk_pll_half_get_rate(clk->parent); 517 518 if (rate > 150000000) 519 return 150000000; 520 521 div = parent_rate / rate; 522 if (div < 1) 523 div = 1; 524 else if (div > 32) 525 div = 32; 526 527 return parent_rate / div; 528} 529 530static int jz_clk_ldclk_set_rate(struct clk *clk, unsigned long rate) 531{ 532 int div; 533 534 if (rate > 150000000) 535 return -EINVAL; 536 537 div = jz_clk_pll_half_get_rate(clk->parent) / rate - 1; 538 if (div < 0) 539 div = 0; 540 else if (div > 31) 541 div = 31; 542 543 jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_LDIV_OFFSET, 544 JZ_CLOCK_CTRL_LDIV_MASK); 545 546 return 0; 547} 548 549static unsigned long jz_clk_ldclk_get_rate(struct clk *clk) 550{ 551 int div; 552 553 div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_LDIV_MASK; 554 div >>= JZ_CLOCK_CTRL_LDIV_OFFSET; 555 556 return jz_clk_pll_half_get_rate(clk->parent) / (div + 1); 557} 558 559static const struct clk_ops jz_clk_ops_ld = { 560 .set_rate = jz_clk_ldclk_set_rate, 561 .get_rate = jz_clk_ldclk_get_rate, 562 .round_rate = jz_clk_ldclk_round_rate, 563 .enable = jz_clk_enable_gating, 564 .disable = jz_clk_disable_gating, 565 .is_enabled = jz_clk_is_enabled_gating, 566}; 567 568static struct clk jz_clk_ld = { 569 .name = "lcd", 570 .gate_bit = JZ_CLOCK_GATE_LCD, 571 .parent = &jz_clk_pll_half, 572 .ops = &jz_clk_ops_ld, 573}; 574 575static const struct clk_ops jz_clk_i2s_ops = { 576 .set_rate = jz_clk_divided_set_rate, 577 .get_rate = jz_clk_divided_get_rate, 578 .enable = jz_clk_enable_gating, 579 .disable = jz_clk_disable_gating, 580 .is_enabled = jz_clk_is_enabled_gating, 581 .set_parent = jz_clk_i2s_set_parent, 582}; 583 584static const struct clk_ops jz_clk_spi_ops = { 585 .set_rate = jz_clk_divided_set_rate, 586 .get_rate = jz_clk_divided_get_rate, 587 .enable = jz_clk_enable_gating, 588 .disable = jz_clk_disable_gating, 589 .is_enabled = jz_clk_is_enabled_gating, 590 .set_parent = jz_clk_spi_set_parent, 591}; 592 593static const struct clk_ops jz_clk_divided_ops = { 594 .set_rate = jz_clk_divided_set_rate, 595 .get_rate = jz_clk_divided_get_rate, 596 .enable = jz_clk_enable_gating, 597 .disable = jz_clk_disable_gating, 598 .is_enabled = jz_clk_is_enabled_gating, 599}; 600 601static struct divided_clk jz4740_clock_divided_clks[] = { 602 [0] = { 603 .clk = { 604 .name = "i2s", 605 .parent = &jz_clk_ext.clk, 606 .gate_bit = JZ_CLOCK_GATE_I2S, 607 .ops = &jz_clk_i2s_ops, 608 }, 609 .reg = JZ_REG_CLOCK_I2S, 610 .mask = JZ_CLOCK_I2S_DIV_MASK, 611 }, 612 [1] = { 613 .clk = { 614 .name = "spi", 615 .parent = &jz_clk_ext.clk, 616 .gate_bit = JZ_CLOCK_GATE_SPI, 617 .ops = &jz_clk_spi_ops, 618 }, 619 .reg = JZ_REG_CLOCK_SPI, 620 .mask = JZ_CLOCK_SPI_DIV_MASK, 621 }, 622 [2] = { 623 .clk = { 624 .name = "lcd_pclk", 625 .parent = &jz_clk_pll_half, 626 .gate_bit = JZ4740_CLK_NOT_GATED, 627 .ops = &jz_clk_divided_ops, 628 }, 629 .reg = JZ_REG_CLOCK_LCD, 630 .mask = JZ_CLOCK_LCD_DIV_MASK, 631 }, 632 [3] = { 633 .clk = { 634 .name = "mmc", 635 .parent = &jz_clk_pll_half, 636 .gate_bit = JZ_CLOCK_GATE_MMC, 637 .ops = &jz_clk_divided_ops, 638 }, 639 .reg = JZ_REG_CLOCK_MMC, 640 .mask = JZ_CLOCK_MMC_DIV_MASK, 641 }, 642 [4] = { 643 .clk = { 644 .name = "uhc", 645 .parent = &jz_clk_pll_half, 646 .gate_bit = JZ_CLOCK_GATE_UHC, 647 .ops = &jz_clk_divided_ops, 648 }, 649 .reg = JZ_REG_CLOCK_UHC, 650 .mask = JZ_CLOCK_UHC_DIV_MASK, 651 }, 652}; 653 654static const struct clk_ops jz_clk_udc_ops = { 655 .set_parent = jz_clk_udc_set_parent, 656 .set_rate = jz_clk_udc_set_rate, 657 .get_rate = jz_clk_udc_get_rate, 658 .enable = jz_clk_udc_enable, 659 .disable = jz_clk_udc_disable, 660 .is_enabled = jz_clk_udc_is_enabled, 661}; 662 663static const struct clk_ops jz_clk_simple_ops = { 664 .enable = jz_clk_enable_gating, 665 .disable = jz_clk_disable_gating, 666 .is_enabled = jz_clk_is_enabled_gating, 667}; 668 669static struct clk jz4740_clock_simple_clks[] = { 670 [0] = { 671 .name = "udc", 672 .parent = &jz_clk_ext.clk, 673 .ops = &jz_clk_udc_ops, 674 }, 675 [1] = { 676 .name = "uart0", 677 .parent = &jz_clk_ext.clk, 678 .gate_bit = JZ_CLOCK_GATE_UART0, 679 .ops = &jz_clk_simple_ops, 680 }, 681 [2] = { 682 .name = "uart1", 683 .parent = &jz_clk_ext.clk, 684 .gate_bit = JZ_CLOCK_GATE_UART1, 685 .ops = &jz_clk_simple_ops, 686 }, 687 [3] = { 688 .name = "dma", 689 .parent = &jz_clk_high_speed_peripheral.clk, 690 .gate_bit = JZ_CLOCK_GATE_UART0, 691 .ops = &jz_clk_simple_ops, 692 }, 693 [4] = { 694 .name = "ipu", 695 .parent = &jz_clk_high_speed_peripheral.clk, 696 .gate_bit = JZ_CLOCK_GATE_IPU, 697 .ops = &jz_clk_simple_ops, 698 }, 699 [5] = { 700 .name = "adc", 701 .parent = &jz_clk_ext.clk, 702 .gate_bit = JZ_CLOCK_GATE_ADC, 703 .ops = &jz_clk_simple_ops, 704 }, 705 [6] = { 706 .name = "i2c", 707 .parent = &jz_clk_ext.clk, 708 .gate_bit = JZ_CLOCK_GATE_I2C, 709 .ops = &jz_clk_simple_ops, 710 }, 711 [7] = { 712 .name = "aic", 713 .parent = &jz_clk_ext.clk, 714 .gate_bit = JZ_CLOCK_GATE_AIC, 715 .ops = &jz_clk_simple_ops, 716 }, 717}; 718 719static struct static_clk jz_clk_rtc = { 720 .clk = { 721 .name = "rtc", 722 .gate_bit = JZ_CLOCK_GATE_RTC, 723 .ops = &jz_clk_static_ops, 724 }, 725 .rate = 32768, 726}; 727 728int clk_enable(struct clk *clk) 729{ 730 if (!clk->ops->enable) 731 return -EINVAL; 732 733 return clk->ops->enable(clk); 734} 735EXPORT_SYMBOL_GPL(clk_enable); 736 737void clk_disable(struct clk *clk) 738{ 739 if (clk->ops->disable) 740 clk->ops->disable(clk); 741} 742EXPORT_SYMBOL_GPL(clk_disable); 743 744int clk_is_enabled(struct clk *clk) 745{ 746 if (clk->ops->is_enabled) 747 return clk->ops->is_enabled(clk); 748 749 return 1; 750} 751 752unsigned long clk_get_rate(struct clk *clk) 753{ 754 if (clk->ops->get_rate) 755 return clk->ops->get_rate(clk); 756 if (clk->parent) 757 return clk_get_rate(clk->parent); 758 759 return -EINVAL; 760} 761EXPORT_SYMBOL_GPL(clk_get_rate); 762 763int clk_set_rate(struct clk *clk, unsigned long rate) 764{ 765 if (!clk->ops->set_rate) 766 return -EINVAL; 767 return clk->ops->set_rate(clk, rate); 768} 769EXPORT_SYMBOL_GPL(clk_set_rate); 770 771long clk_round_rate(struct clk *clk, unsigned long rate) 772{ 773 if (clk->ops->round_rate) 774 return clk->ops->round_rate(clk, rate); 775 776 return -EINVAL; 777} 778EXPORT_SYMBOL_GPL(clk_round_rate); 779 780int clk_set_parent(struct clk *clk, struct clk *parent) 781{ 782 int ret; 783 int enabled; 784 785 if (!clk->ops->set_parent) 786 return -EINVAL; 787 788 enabled = clk_is_enabled(clk); 789 if (enabled) 790 clk_disable(clk); 791 ret = clk->ops->set_parent(clk, parent); 792 if (enabled) 793 clk_enable(clk); 794 795 jz4740_clock_debugfs_update_parent(clk); 796 797 return ret; 798} 799EXPORT_SYMBOL_GPL(clk_set_parent); 800 801struct clk *clk_get(struct device *dev, const char *name) 802{ 803 struct clk *clk; 804 805 list_for_each_entry(clk, &jz_clocks, list) { 806 if (strcmp(clk->name, name) == 0) 807 return clk; 808 } 809 return ERR_PTR(-ENXIO); 810} 811EXPORT_SYMBOL_GPL(clk_get); 812 813void clk_put(struct clk *clk) 814{ 815} 816EXPORT_SYMBOL_GPL(clk_put); 817 818static inline void clk_add(struct clk *clk) 819{ 820 list_add_tail(&clk->list, &jz_clocks); 821 822 jz4740_clock_debugfs_add_clk(clk); 823} 824 825static void clk_register_clks(void) 826{ 827 size_t i; 828 829 clk_add(&jz_clk_ext.clk); 830 clk_add(&jz_clk_pll); 831 clk_add(&jz_clk_pll_half); 832 clk_add(&jz_clk_cpu.clk); 833 clk_add(&jz_clk_high_speed_peripheral.clk); 834 clk_add(&jz_clk_low_speed_peripheral.clk); 835 clk_add(&jz_clk_ko); 836 clk_add(&jz_clk_ld); 837 clk_add(&jz_clk_rtc.clk); 838 839 for (i = 0; i < ARRAY_SIZE(jz4740_clock_divided_clks); ++i) 840 clk_add(&jz4740_clock_divided_clks[i].clk); 841 842 for (i = 0; i < ARRAY_SIZE(jz4740_clock_simple_clks); ++i) 843 clk_add(&jz4740_clock_simple_clks[i]); 844} 845 846void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode) 847{ 848 switch (mode) { 849 case JZ4740_WAIT_MODE_IDLE: 850 jz_clk_reg_clear_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP); 851 break; 852 case JZ4740_WAIT_MODE_SLEEP: 853 jz_clk_reg_set_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP); 854 break; 855 } 856} 857 858void jz4740_clock_udc_disable_auto_suspend(void) 859{ 860 jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC); 861} 862EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend); 863 864void jz4740_clock_udc_enable_auto_suspend(void) 865{ 866 jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC); 867} 868EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend); 869 870void jz4740_clock_suspend(void) 871{ 872 jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, 873 JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0); 874 875 jz_clk_reg_clear_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED); 876} 877 878void jz4740_clock_resume(void) 879{ 880 uint32_t pll; 881 882 jz_clk_reg_set_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED); 883 884 do { 885 pll = jz_clk_reg_read(JZ_REG_CLOCK_PLL); 886 } while (!(pll & JZ_CLOCK_PLL_STABLE)); 887 888 jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, 889 JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0); 890} 891 892static int jz4740_clock_init(void) 893{ 894 uint32_t val; 895 896 jz_clock_base = ioremap(JZ4740_CPM_BASE_ADDR, 0x100); 897 if (!jz_clock_base) 898 return -EBUSY; 899 900 spin_lock_init(&jz_clock_lock); 901 902 jz_clk_ext.rate = jz4740_clock_bdata.ext_rate; 903 jz_clk_rtc.rate = jz4740_clock_bdata.rtc_rate; 904 905 val = jz_clk_reg_read(JZ_REG_CLOCK_SPI); 906 907 if (val & JZ_CLOCK_SPI_SRC_PLL) 908 jz4740_clock_divided_clks[1].clk.parent = &jz_clk_pll_half; 909 910 val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL); 911 912 if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL) 913 jz4740_clock_divided_clks[0].clk.parent = &jz_clk_pll_half; 914 915 if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL) 916 jz4740_clock_simple_clks[0].parent = &jz_clk_pll_half; 917 918 jz4740_clock_debugfs_init(); 919 920 clk_register_clks(); 921 922 return 0; 923} 924arch_initcall(jz4740_clock_init); 925