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