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