1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * drivers/clk/at91/sckc.c 4 * 5 * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> 6 */ 7 8 #include <linux/clk-provider.h> 9 #include <linux/clkdev.h> 10 #include <linux/delay.h> 11 #include <linux/of.h> 12 #include <linux/of_address.h> 13 #include <linux/io.h> 14 15 #include <dt-bindings/clock/at91.h> 16 17 #define SLOW_CLOCK_FREQ 32768 18 #define SLOWCK_SW_CYCLES 5 19 #define SLOWCK_SW_TIME_USEC ((SLOWCK_SW_CYCLES * USEC_PER_SEC) / \ 20 SLOW_CLOCK_FREQ) 21 22 #define AT91_SCKC_CR 0x00 23 24 struct clk_slow_bits { 25 u32 cr_rcen; 26 u32 cr_osc32en; 27 u32 cr_osc32byp; 28 u32 cr_oscsel; 29 }; 30 31 struct clk_slow_osc { 32 struct clk_hw hw; 33 void __iomem *sckcr; 34 const struct clk_slow_bits *bits; 35 unsigned long startup_usec; 36 }; 37 38 #define to_clk_slow_osc(hw) container_of(hw, struct clk_slow_osc, hw) 39 40 struct clk_sama5d4_slow_osc { 41 struct clk_hw hw; 42 void __iomem *sckcr; 43 const struct clk_slow_bits *bits; 44 unsigned long startup_usec; 45 bool prepared; 46 }; 47 48 #define to_clk_sama5d4_slow_osc(hw) container_of(hw, struct clk_sama5d4_slow_osc, hw) 49 50 struct clk_slow_rc_osc { 51 struct clk_hw hw; 52 void __iomem *sckcr; 53 const struct clk_slow_bits *bits; 54 unsigned long frequency; 55 unsigned long accuracy; 56 unsigned long startup_usec; 57 }; 58 59 #define to_clk_slow_rc_osc(hw) container_of(hw, struct clk_slow_rc_osc, hw) 60 61 struct clk_sam9x5_slow { 62 struct clk_hw hw; 63 void __iomem *sckcr; 64 const struct clk_slow_bits *bits; 65 u8 parent; 66 }; 67 68 #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw) 69 70 static int clk_slow_osc_prepare(struct clk_hw *hw) 71 { 72 struct clk_slow_osc *osc = to_clk_slow_osc(hw); 73 void __iomem *sckcr = osc->sckcr; 74 u32 tmp = readl(sckcr); 75 76 if (tmp & (osc->bits->cr_osc32byp | osc->bits->cr_osc32en)) 77 return 0; 78 79 writel(tmp | osc->bits->cr_osc32en, sckcr); 80 81 if (system_state < SYSTEM_RUNNING) 82 udelay(osc->startup_usec); 83 else 84 usleep_range(osc->startup_usec, osc->startup_usec + 1); 85 86 return 0; 87 } 88 89 static void clk_slow_osc_unprepare(struct clk_hw *hw) 90 { 91 struct clk_slow_osc *osc = to_clk_slow_osc(hw); 92 void __iomem *sckcr = osc->sckcr; 93 u32 tmp = readl(sckcr); 94 95 if (tmp & osc->bits->cr_osc32byp) 96 return; 97 98 writel(tmp & ~osc->bits->cr_osc32en, sckcr); 99 } 100 101 static int clk_slow_osc_is_prepared(struct clk_hw *hw) 102 { 103 struct clk_slow_osc *osc = to_clk_slow_osc(hw); 104 void __iomem *sckcr = osc->sckcr; 105 u32 tmp = readl(sckcr); 106 107 if (tmp & osc->bits->cr_osc32byp) 108 return 1; 109 110 return !!(tmp & osc->bits->cr_osc32en); 111 } 112 113 static const struct clk_ops slow_osc_ops = { 114 .prepare = clk_slow_osc_prepare, 115 .unprepare = clk_slow_osc_unprepare, 116 .is_prepared = clk_slow_osc_is_prepared, 117 }; 118 119 static struct clk_hw * __init 120 at91_clk_register_slow_osc(void __iomem *sckcr, 121 const char *name, 122 const struct clk_parent_data *parent_data, 123 unsigned long startup, 124 bool bypass, 125 const struct clk_slow_bits *bits) 126 { 127 struct clk_slow_osc *osc; 128 struct clk_hw *hw; 129 struct clk_init_data init = {}; 130 int ret; 131 132 if (!sckcr || !name || !parent_data) 133 return ERR_PTR(-EINVAL); 134 135 osc = kzalloc(sizeof(*osc), GFP_KERNEL); 136 if (!osc) 137 return ERR_PTR(-ENOMEM); 138 139 init.name = name; 140 init.ops = &slow_osc_ops; 141 init.parent_data = parent_data; 142 init.num_parents = 1; 143 init.flags = CLK_IGNORE_UNUSED; 144 145 osc->hw.init = &init; 146 osc->sckcr = sckcr; 147 osc->startup_usec = startup; 148 osc->bits = bits; 149 150 if (bypass) 151 writel((readl(sckcr) & ~osc->bits->cr_osc32en) | 152 osc->bits->cr_osc32byp, sckcr); 153 154 hw = &osc->hw; 155 ret = clk_hw_register(NULL, &osc->hw); 156 if (ret) { 157 kfree(osc); 158 hw = ERR_PTR(ret); 159 } 160 161 return hw; 162 } 163 164 static void at91_clk_unregister_slow_osc(struct clk_hw *hw) 165 { 166 struct clk_slow_osc *osc = to_clk_slow_osc(hw); 167 168 clk_hw_unregister(hw); 169 kfree(osc); 170 } 171 172 static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw, 173 unsigned long parent_rate) 174 { 175 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 176 177 return osc->frequency; 178 } 179 180 static unsigned long clk_slow_rc_osc_recalc_accuracy(struct clk_hw *hw, 181 unsigned long parent_acc) 182 { 183 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 184 185 return osc->accuracy; 186 } 187 188 static int clk_slow_rc_osc_prepare(struct clk_hw *hw) 189 { 190 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 191 void __iomem *sckcr = osc->sckcr; 192 193 writel(readl(sckcr) | osc->bits->cr_rcen, sckcr); 194 195 if (system_state < SYSTEM_RUNNING) 196 udelay(osc->startup_usec); 197 else 198 usleep_range(osc->startup_usec, osc->startup_usec + 1); 199 200 return 0; 201 } 202 203 static void clk_slow_rc_osc_unprepare(struct clk_hw *hw) 204 { 205 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 206 void __iomem *sckcr = osc->sckcr; 207 208 writel(readl(sckcr) & ~osc->bits->cr_rcen, sckcr); 209 } 210 211 static int clk_slow_rc_osc_is_prepared(struct clk_hw *hw) 212 { 213 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 214 215 return !!(readl(osc->sckcr) & osc->bits->cr_rcen); 216 } 217 218 static const struct clk_ops slow_rc_osc_ops = { 219 .prepare = clk_slow_rc_osc_prepare, 220 .unprepare = clk_slow_rc_osc_unprepare, 221 .is_prepared = clk_slow_rc_osc_is_prepared, 222 .recalc_rate = clk_slow_rc_osc_recalc_rate, 223 .recalc_accuracy = clk_slow_rc_osc_recalc_accuracy, 224 }; 225 226 static struct clk_hw * __init 227 at91_clk_register_slow_rc_osc(void __iomem *sckcr, 228 const char *name, 229 unsigned long frequency, 230 unsigned long accuracy, 231 unsigned long startup, 232 const struct clk_slow_bits *bits) 233 { 234 struct clk_slow_rc_osc *osc; 235 struct clk_hw *hw; 236 struct clk_init_data init; 237 int ret; 238 239 if (!sckcr || !name) 240 return ERR_PTR(-EINVAL); 241 242 osc = kzalloc(sizeof(*osc), GFP_KERNEL); 243 if (!osc) 244 return ERR_PTR(-ENOMEM); 245 246 init.name = name; 247 init.ops = &slow_rc_osc_ops; 248 init.parent_names = NULL; 249 init.num_parents = 0; 250 init.flags = CLK_IGNORE_UNUSED; 251 252 osc->hw.init = &init; 253 osc->sckcr = sckcr; 254 osc->bits = bits; 255 osc->frequency = frequency; 256 osc->accuracy = accuracy; 257 osc->startup_usec = startup; 258 259 hw = &osc->hw; 260 ret = clk_hw_register(NULL, &osc->hw); 261 if (ret) { 262 kfree(osc); 263 hw = ERR_PTR(ret); 264 } 265 266 return hw; 267 } 268 269 static void at91_clk_unregister_slow_rc_osc(struct clk_hw *hw) 270 { 271 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 272 273 clk_hw_unregister(hw); 274 kfree(osc); 275 } 276 277 static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index) 278 { 279 struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); 280 void __iomem *sckcr = slowck->sckcr; 281 u32 tmp; 282 283 if (index > 1) 284 return -EINVAL; 285 286 tmp = readl(sckcr); 287 288 if ((!index && !(tmp & slowck->bits->cr_oscsel)) || 289 (index && (tmp & slowck->bits->cr_oscsel))) 290 return 0; 291 292 if (index) 293 tmp |= slowck->bits->cr_oscsel; 294 else 295 tmp &= ~slowck->bits->cr_oscsel; 296 297 writel(tmp, sckcr); 298 299 if (system_state < SYSTEM_RUNNING) 300 udelay(SLOWCK_SW_TIME_USEC); 301 else 302 usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1); 303 304 return 0; 305 } 306 307 static u8 clk_sam9x5_slow_get_parent(struct clk_hw *hw) 308 { 309 struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); 310 311 return !!(readl(slowck->sckcr) & slowck->bits->cr_oscsel); 312 } 313 314 static const struct clk_ops sam9x5_slow_ops = { 315 .determine_rate = clk_hw_determine_rate_no_reparent, 316 .set_parent = clk_sam9x5_slow_set_parent, 317 .get_parent = clk_sam9x5_slow_get_parent, 318 }; 319 320 static struct clk_hw * __init 321 at91_clk_register_sam9x5_slow(void __iomem *sckcr, 322 const char *name, 323 const struct clk_hw **parent_hws, 324 int num_parents, 325 const struct clk_slow_bits *bits) 326 { 327 struct clk_sam9x5_slow *slowck; 328 struct clk_hw *hw; 329 struct clk_init_data init = {}; 330 int ret; 331 332 if (!sckcr || !name || !parent_hws || !num_parents) 333 return ERR_PTR(-EINVAL); 334 335 slowck = kzalloc(sizeof(*slowck), GFP_KERNEL); 336 if (!slowck) 337 return ERR_PTR(-ENOMEM); 338 339 init.name = name; 340 init.ops = &sam9x5_slow_ops; 341 init.parent_hws = parent_hws; 342 init.num_parents = num_parents; 343 init.flags = 0; 344 345 slowck->hw.init = &init; 346 slowck->sckcr = sckcr; 347 slowck->bits = bits; 348 slowck->parent = !!(readl(sckcr) & slowck->bits->cr_oscsel); 349 350 hw = &slowck->hw; 351 ret = clk_hw_register(NULL, &slowck->hw); 352 if (ret) { 353 kfree(slowck); 354 hw = ERR_PTR(ret); 355 } 356 357 return hw; 358 } 359 360 static void at91_clk_unregister_sam9x5_slow(struct clk_hw *hw) 361 { 362 struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); 363 364 clk_hw_unregister(hw); 365 kfree(slowck); 366 } 367 368 static void __init at91sam9x5_sckc_register(struct device_node *np, 369 unsigned int rc_osc_startup_us, 370 const struct clk_slow_bits *bits) 371 { 372 void __iomem *regbase = of_iomap(np, 0); 373 struct device_node *child = NULL; 374 const char *xtal_name; 375 struct clk_hw *slow_rc, *slow_osc, *slowck; 376 static struct clk_parent_data parent_data = { 377 .name = "slow_xtal", 378 }; 379 const struct clk_hw *parent_hws[2]; 380 bool bypass; 381 int ret; 382 383 if (!regbase) 384 return; 385 386 slow_rc = at91_clk_register_slow_rc_osc(regbase, "slow_rc_osc", 387 32768, 50000000, 388 rc_osc_startup_us, bits); 389 if (IS_ERR(slow_rc)) 390 return; 391 392 xtal_name = of_clk_get_parent_name(np, 0); 393 if (!xtal_name) { 394 /* DT backward compatibility */ 395 child = of_get_compatible_child(np, "atmel,at91sam9x5-clk-slow-osc"); 396 if (!child) 397 goto unregister_slow_rc; 398 399 xtal_name = of_clk_get_parent_name(child, 0); 400 bypass = of_property_read_bool(child, "atmel,osc-bypass"); 401 402 child = of_get_compatible_child(np, "atmel,at91sam9x5-clk-slow"); 403 } else { 404 bypass = of_property_read_bool(np, "atmel,osc-bypass"); 405 } 406 407 if (!xtal_name) 408 goto unregister_slow_rc; 409 410 parent_data.fw_name = xtal_name; 411 412 slow_osc = at91_clk_register_slow_osc(regbase, "slow_osc", 413 &parent_data, 1200000, bypass, bits); 414 if (IS_ERR(slow_osc)) 415 goto unregister_slow_rc; 416 417 parent_hws[0] = slow_rc; 418 parent_hws[1] = slow_osc; 419 slowck = at91_clk_register_sam9x5_slow(regbase, "slowck", parent_hws, 420 2, bits); 421 if (IS_ERR(slowck)) 422 goto unregister_slow_osc; 423 424 /* DT backward compatibility */ 425 if (child) 426 ret = of_clk_add_hw_provider(child, of_clk_hw_simple_get, 427 slowck); 428 else 429 ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, slowck); 430 431 if (WARN_ON(ret)) 432 goto unregister_slowck; 433 434 return; 435 436 unregister_slowck: 437 at91_clk_unregister_sam9x5_slow(slowck); 438 unregister_slow_osc: 439 at91_clk_unregister_slow_osc(slow_osc); 440 unregister_slow_rc: 441 at91_clk_unregister_slow_rc_osc(slow_rc); 442 } 443 444 static const struct clk_slow_bits at91sam9x5_bits = { 445 .cr_rcen = BIT(0), 446 .cr_osc32en = BIT(1), 447 .cr_osc32byp = BIT(2), 448 .cr_oscsel = BIT(3), 449 }; 450 451 static void __init of_at91sam9x5_sckc_setup(struct device_node *np) 452 { 453 at91sam9x5_sckc_register(np, 75, &at91sam9x5_bits); 454 } 455 CLK_OF_DECLARE(at91sam9x5_clk_sckc, "atmel,at91sam9x5-sckc", 456 of_at91sam9x5_sckc_setup); 457 458 static void __init of_sama5d3_sckc_setup(struct device_node *np) 459 { 460 at91sam9x5_sckc_register(np, 500, &at91sam9x5_bits); 461 } 462 CLK_OF_DECLARE(sama5d3_clk_sckc, "atmel,sama5d3-sckc", 463 of_sama5d3_sckc_setup); 464 465 static const struct clk_slow_bits at91sam9x60_bits = { 466 .cr_osc32en = BIT(1), 467 .cr_osc32byp = BIT(2), 468 .cr_oscsel = BIT(24), 469 }; 470 471 static void __init of_sam9x60_sckc_setup(struct device_node *np) 472 { 473 void __iomem *regbase = of_iomap(np, 0); 474 struct clk_hw_onecell_data *clk_data; 475 struct clk_hw *slow_rc, *slow_osc, *hw; 476 const char *xtal_name; 477 const struct clk_hw *parent_hws[2]; 478 static struct clk_parent_data parent_data = { 479 .name = "slow_xtal", 480 }; 481 bool bypass; 482 int ret; 483 484 if (!regbase) 485 return; 486 487 slow_rc = clk_hw_register_fixed_rate_with_accuracy(NULL, "slow_rc_osc", 488 NULL, 0, 32768, 489 93750000); 490 if (IS_ERR(slow_rc)) 491 return; 492 493 xtal_name = of_clk_get_parent_name(np, 0); 494 if (!xtal_name) 495 goto unregister_slow_rc; 496 497 parent_data.fw_name = xtal_name; 498 bypass = of_property_read_bool(np, "atmel,osc-bypass"); 499 slow_osc = at91_clk_register_slow_osc(regbase, "slow_osc", 500 &parent_data, 5000000, bypass, 501 &at91sam9x60_bits); 502 if (IS_ERR(slow_osc)) 503 goto unregister_slow_rc; 504 505 clk_data = kzalloc(struct_size(clk_data, hws, 2), GFP_KERNEL); 506 if (!clk_data) 507 goto unregister_slow_osc; 508 509 /* MD_SLCK and TD_SLCK. */ 510 clk_data->num = 2; 511 hw = clk_hw_register_fixed_rate_parent_hw(NULL, "md_slck", slow_rc, 512 0, 32768); 513 if (IS_ERR(hw)) 514 goto clk_data_free; 515 clk_data->hws[SCKC_MD_SLCK] = hw; 516 517 parent_hws[0] = slow_rc; 518 parent_hws[1] = slow_osc; 519 hw = at91_clk_register_sam9x5_slow(regbase, "td_slck", parent_hws, 520 2, &at91sam9x60_bits); 521 if (IS_ERR(hw)) 522 goto unregister_md_slck; 523 clk_data->hws[SCKC_TD_SLCK] = hw; 524 525 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data); 526 if (WARN_ON(ret)) 527 goto unregister_td_slck; 528 529 return; 530 531 unregister_td_slck: 532 at91_clk_unregister_sam9x5_slow(clk_data->hws[SCKC_TD_SLCK]); 533 unregister_md_slck: 534 clk_hw_unregister(clk_data->hws[SCKC_MD_SLCK]); 535 clk_data_free: 536 kfree(clk_data); 537 unregister_slow_osc: 538 at91_clk_unregister_slow_osc(slow_osc); 539 unregister_slow_rc: 540 clk_hw_unregister(slow_rc); 541 } 542 CLK_OF_DECLARE(sam9x60_clk_sckc, "microchip,sam9x60-sckc", 543 of_sam9x60_sckc_setup); 544 545 static int clk_sama5d4_slow_osc_prepare(struct clk_hw *hw) 546 { 547 struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw); 548 549 if (osc->prepared) 550 return 0; 551 552 /* 553 * Assume that if it has already been selected (for example by the 554 * bootloader), enough time has already passed. 555 */ 556 if ((readl(osc->sckcr) & osc->bits->cr_oscsel)) { 557 osc->prepared = true; 558 return 0; 559 } 560 561 if (system_state < SYSTEM_RUNNING) 562 udelay(osc->startup_usec); 563 else 564 usleep_range(osc->startup_usec, osc->startup_usec + 1); 565 osc->prepared = true; 566 567 return 0; 568 } 569 570 static int clk_sama5d4_slow_osc_is_prepared(struct clk_hw *hw) 571 { 572 struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw); 573 574 return osc->prepared; 575 } 576 577 static const struct clk_ops sama5d4_slow_osc_ops = { 578 .prepare = clk_sama5d4_slow_osc_prepare, 579 .is_prepared = clk_sama5d4_slow_osc_is_prepared, 580 }; 581 582 static const struct clk_slow_bits at91sama5d4_bits = { 583 .cr_oscsel = BIT(3), 584 }; 585 586 static void __init of_sama5d4_sckc_setup(struct device_node *np) 587 { 588 void __iomem *regbase = of_iomap(np, 0); 589 struct clk_hw *slow_rc, *slowck; 590 struct clk_sama5d4_slow_osc *osc; 591 struct clk_init_data init = {}; 592 const char *xtal_name; 593 const struct clk_hw *parent_hws[2]; 594 static struct clk_parent_data parent_data = { 595 .name = "slow_xtal", 596 }; 597 int ret; 598 599 if (!regbase) 600 return; 601 602 slow_rc = clk_hw_register_fixed_rate_with_accuracy(NULL, 603 "slow_rc_osc", 604 NULL, 0, 32768, 605 250000000); 606 if (IS_ERR(slow_rc)) 607 return; 608 609 xtal_name = of_clk_get_parent_name(np, 0); 610 if (!xtal_name) 611 goto unregister_slow_rc; 612 parent_data.fw_name = xtal_name; 613 614 osc = kzalloc(sizeof(*osc), GFP_KERNEL); 615 if (!osc) 616 goto unregister_slow_rc; 617 618 init.name = "slow_osc"; 619 init.ops = &sama5d4_slow_osc_ops; 620 init.parent_data = &parent_data; 621 init.num_parents = 1; 622 init.flags = CLK_IGNORE_UNUSED; 623 624 osc->hw.init = &init; 625 osc->sckcr = regbase; 626 osc->startup_usec = 1200000; 627 osc->bits = &at91sama5d4_bits; 628 629 ret = clk_hw_register(NULL, &osc->hw); 630 if (ret) 631 goto free_slow_osc_data; 632 633 parent_hws[0] = slow_rc; 634 parent_hws[1] = &osc->hw; 635 slowck = at91_clk_register_sam9x5_slow(regbase, "slowck", 636 parent_hws, 2, 637 &at91sama5d4_bits); 638 if (IS_ERR(slowck)) 639 goto unregister_slow_osc; 640 641 ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, slowck); 642 if (WARN_ON(ret)) 643 goto unregister_slowck; 644 645 return; 646 647 unregister_slowck: 648 at91_clk_unregister_sam9x5_slow(slowck); 649 unregister_slow_osc: 650 clk_hw_unregister(&osc->hw); 651 free_slow_osc_data: 652 kfree(osc); 653 unregister_slow_rc: 654 clk_hw_unregister(slow_rc); 655 } 656 CLK_OF_DECLARE(sama5d4_clk_sckc, "atmel,sama5d4-sckc", 657 of_sama5d4_sckc_setup); 658