1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> 4 */ 5 6 #include <linux/clk-provider.h> 7 #include <linux/clkdev.h> 8 #include <linux/clk/at91_pmc.h> 9 #include <linux/delay.h> 10 #include <linux/mfd/syscon.h> 11 #include <linux/regmap.h> 12 13 #include "pmc.h" 14 15 #define SLOW_CLOCK_FREQ 32768 16 #define MAINF_DIV 16 17 #define MAINFRDY_TIMEOUT (((MAINF_DIV + 1) * USEC_PER_SEC) / \ 18 SLOW_CLOCK_FREQ) 19 #define MAINF_LOOP_MIN_WAIT (USEC_PER_SEC / SLOW_CLOCK_FREQ) 20 #define MAINF_LOOP_MAX_WAIT MAINFRDY_TIMEOUT 21 22 #define MOR_KEY_MASK (0xff << 16) 23 24 #define clk_main_parent_select(s) (((s) & \ 25 (AT91_PMC_MOSCEN | \ 26 AT91_PMC_OSCBYPASS)) ? 1 : 0) 27 28 struct clk_main_osc { 29 struct clk_hw hw; 30 struct regmap *regmap; 31 struct at91_clk_pms pms; 32 }; 33 34 #define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, hw) 35 36 struct clk_main_rc_osc { 37 struct clk_hw hw; 38 struct regmap *regmap; 39 unsigned long frequency; 40 unsigned long accuracy; 41 struct at91_clk_pms pms; 42 }; 43 44 #define to_clk_main_rc_osc(hw) container_of(hw, struct clk_main_rc_osc, hw) 45 46 struct clk_rm9200_main { 47 struct clk_hw hw; 48 struct regmap *regmap; 49 }; 50 51 #define to_clk_rm9200_main(hw) container_of(hw, struct clk_rm9200_main, hw) 52 53 struct clk_sam9x5_main { 54 struct clk_hw hw; 55 struct regmap *regmap; 56 struct at91_clk_pms pms; 57 u8 parent; 58 }; 59 60 #define to_clk_sam9x5_main(hw) container_of(hw, struct clk_sam9x5_main, hw) 61 62 static inline bool clk_main_osc_ready(struct regmap *regmap) 63 { 64 unsigned int status; 65 66 regmap_read(regmap, AT91_PMC_SR, &status); 67 68 return status & AT91_PMC_MOSCS; 69 } 70 71 static int clk_main_osc_prepare(struct clk_hw *hw) 72 { 73 struct clk_main_osc *osc = to_clk_main_osc(hw); 74 struct regmap *regmap = osc->regmap; 75 u32 tmp; 76 77 regmap_read(regmap, AT91_CKGR_MOR, &tmp); 78 tmp &= ~MOR_KEY_MASK; 79 80 if (tmp & AT91_PMC_OSCBYPASS) 81 return 0; 82 83 if (!(tmp & AT91_PMC_MOSCEN)) { 84 tmp |= AT91_PMC_MOSCEN | AT91_PMC_KEY; 85 regmap_write(regmap, AT91_CKGR_MOR, tmp); 86 } 87 88 while (!clk_main_osc_ready(regmap)) 89 cpu_relax(); 90 91 return 0; 92 } 93 94 static void clk_main_osc_unprepare(struct clk_hw *hw) 95 { 96 struct clk_main_osc *osc = to_clk_main_osc(hw); 97 struct regmap *regmap = osc->regmap; 98 u32 tmp; 99 100 regmap_read(regmap, AT91_CKGR_MOR, &tmp); 101 if (tmp & AT91_PMC_OSCBYPASS) 102 return; 103 104 if (!(tmp & AT91_PMC_MOSCEN)) 105 return; 106 107 tmp &= ~(AT91_PMC_KEY | AT91_PMC_MOSCEN); 108 regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_KEY); 109 } 110 111 static int clk_main_osc_is_prepared(struct clk_hw *hw) 112 { 113 struct clk_main_osc *osc = to_clk_main_osc(hw); 114 struct regmap *regmap = osc->regmap; 115 u32 tmp, status; 116 117 regmap_read(regmap, AT91_CKGR_MOR, &tmp); 118 if (tmp & AT91_PMC_OSCBYPASS) 119 return 1; 120 121 regmap_read(regmap, AT91_PMC_SR, &status); 122 123 return (status & AT91_PMC_MOSCS) && clk_main_parent_select(tmp); 124 } 125 126 static int clk_main_osc_save_context(struct clk_hw *hw) 127 { 128 struct clk_main_osc *osc = to_clk_main_osc(hw); 129 130 osc->pms.status = clk_main_osc_is_prepared(hw); 131 132 return 0; 133 } 134 135 static void clk_main_osc_restore_context(struct clk_hw *hw) 136 { 137 struct clk_main_osc *osc = to_clk_main_osc(hw); 138 139 if (osc->pms.status) 140 clk_main_osc_prepare(hw); 141 } 142 143 static const struct clk_ops main_osc_ops = { 144 .prepare = clk_main_osc_prepare, 145 .unprepare = clk_main_osc_unprepare, 146 .is_prepared = clk_main_osc_is_prepared, 147 .save_context = clk_main_osc_save_context, 148 .restore_context = clk_main_osc_restore_context, 149 }; 150 151 struct clk_hw * __init 152 at91_clk_register_main_osc(struct regmap *regmap, 153 const char *name, 154 const char *parent_name, 155 struct clk_parent_data *parent_data, 156 bool bypass) 157 { 158 struct clk_main_osc *osc; 159 struct clk_init_data init = {}; 160 struct clk_hw *hw; 161 int ret; 162 163 if (!name || !(parent_name || parent_data)) 164 return ERR_PTR(-EINVAL); 165 166 osc = kzalloc(sizeof(*osc), GFP_KERNEL); 167 if (!osc) 168 return ERR_PTR(-ENOMEM); 169 170 init.name = name; 171 init.ops = &main_osc_ops; 172 if (parent_data) 173 init.parent_data = (const struct clk_parent_data *)parent_data; 174 else 175 init.parent_names = &parent_name; 176 init.num_parents = 1; 177 init.flags = CLK_IGNORE_UNUSED; 178 179 osc->hw.init = &init; 180 osc->regmap = regmap; 181 182 if (bypass) 183 regmap_update_bits(regmap, 184 AT91_CKGR_MOR, MOR_KEY_MASK | 185 AT91_PMC_OSCBYPASS, 186 AT91_PMC_OSCBYPASS | AT91_PMC_KEY); 187 188 hw = &osc->hw; 189 ret = clk_hw_register(NULL, &osc->hw); 190 if (ret) { 191 kfree(osc); 192 hw = ERR_PTR(ret); 193 } 194 195 return hw; 196 } 197 198 static bool clk_main_rc_osc_ready(struct regmap *regmap) 199 { 200 unsigned int status; 201 202 regmap_read(regmap, AT91_PMC_SR, &status); 203 204 return !!(status & AT91_PMC_MOSCRCS); 205 } 206 207 static int clk_main_rc_osc_prepare(struct clk_hw *hw) 208 { 209 struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); 210 struct regmap *regmap = osc->regmap; 211 unsigned int mor; 212 213 regmap_read(regmap, AT91_CKGR_MOR, &mor); 214 215 if (!(mor & AT91_PMC_MOSCRCEN)) 216 regmap_update_bits(regmap, AT91_CKGR_MOR, 217 MOR_KEY_MASK | AT91_PMC_MOSCRCEN, 218 AT91_PMC_MOSCRCEN | AT91_PMC_KEY); 219 220 while (!clk_main_rc_osc_ready(regmap)) 221 cpu_relax(); 222 223 return 0; 224 } 225 226 static void clk_main_rc_osc_unprepare(struct clk_hw *hw) 227 { 228 struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); 229 struct regmap *regmap = osc->regmap; 230 unsigned int mor; 231 232 regmap_read(regmap, AT91_CKGR_MOR, &mor); 233 234 if (!(mor & AT91_PMC_MOSCRCEN)) 235 return; 236 237 regmap_update_bits(regmap, AT91_CKGR_MOR, 238 MOR_KEY_MASK | AT91_PMC_MOSCRCEN, AT91_PMC_KEY); 239 } 240 241 static int clk_main_rc_osc_is_prepared(struct clk_hw *hw) 242 { 243 struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); 244 struct regmap *regmap = osc->regmap; 245 unsigned int mor, status; 246 247 regmap_read(regmap, AT91_CKGR_MOR, &mor); 248 regmap_read(regmap, AT91_PMC_SR, &status); 249 250 return (mor & AT91_PMC_MOSCRCEN) && (status & AT91_PMC_MOSCRCS); 251 } 252 253 static unsigned long clk_main_rc_osc_recalc_rate(struct clk_hw *hw, 254 unsigned long parent_rate) 255 { 256 struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); 257 258 return osc->frequency; 259 } 260 261 static unsigned long clk_main_rc_osc_recalc_accuracy(struct clk_hw *hw, 262 unsigned long parent_acc) 263 { 264 struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); 265 266 return osc->accuracy; 267 } 268 269 static int clk_main_rc_osc_save_context(struct clk_hw *hw) 270 { 271 struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); 272 273 osc->pms.status = clk_main_rc_osc_is_prepared(hw); 274 275 return 0; 276 } 277 278 static void clk_main_rc_osc_restore_context(struct clk_hw *hw) 279 { 280 struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); 281 282 if (osc->pms.status) 283 clk_main_rc_osc_prepare(hw); 284 } 285 286 static const struct clk_ops main_rc_osc_ops = { 287 .prepare = clk_main_rc_osc_prepare, 288 .unprepare = clk_main_rc_osc_unprepare, 289 .is_prepared = clk_main_rc_osc_is_prepared, 290 .recalc_rate = clk_main_rc_osc_recalc_rate, 291 .recalc_accuracy = clk_main_rc_osc_recalc_accuracy, 292 .save_context = clk_main_rc_osc_save_context, 293 .restore_context = clk_main_rc_osc_restore_context, 294 }; 295 296 struct clk_hw * __init 297 at91_clk_register_main_rc_osc(struct regmap *regmap, 298 const char *name, 299 u32 frequency, u32 accuracy) 300 { 301 struct clk_main_rc_osc *osc; 302 struct clk_init_data init; 303 struct clk_hw *hw; 304 int ret; 305 306 if (!name || !frequency) 307 return ERR_PTR(-EINVAL); 308 309 osc = kzalloc(sizeof(*osc), GFP_KERNEL); 310 if (!osc) 311 return ERR_PTR(-ENOMEM); 312 313 init.name = name; 314 init.ops = &main_rc_osc_ops; 315 init.parent_names = NULL; 316 init.num_parents = 0; 317 init.flags = CLK_IGNORE_UNUSED; 318 319 osc->hw.init = &init; 320 osc->regmap = regmap; 321 osc->frequency = frequency; 322 osc->accuracy = accuracy; 323 324 hw = &osc->hw; 325 ret = clk_hw_register(NULL, hw); 326 if (ret) { 327 kfree(osc); 328 hw = ERR_PTR(ret); 329 } 330 331 return hw; 332 } 333 334 static int clk_main_probe_frequency(struct regmap *regmap) 335 { 336 unsigned long prep_time, timeout; 337 unsigned int mcfr; 338 339 timeout = jiffies + usecs_to_jiffies(MAINFRDY_TIMEOUT); 340 do { 341 prep_time = jiffies; 342 regmap_read(regmap, AT91_CKGR_MCFR, &mcfr); 343 if (mcfr & AT91_PMC_MAINRDY) 344 return 0; 345 if (system_state < SYSTEM_RUNNING) 346 udelay(MAINF_LOOP_MIN_WAIT); 347 else 348 usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT); 349 } while (time_before(prep_time, timeout)); 350 351 return -ETIMEDOUT; 352 } 353 354 static unsigned long clk_main_recalc_rate(struct regmap *regmap, 355 unsigned long parent_rate) 356 { 357 unsigned int mcfr; 358 359 if (parent_rate) 360 return parent_rate; 361 362 pr_warn("Main crystal frequency not set, using approximate value\n"); 363 regmap_read(regmap, AT91_CKGR_MCFR, &mcfr); 364 if (!(mcfr & AT91_PMC_MAINRDY)) 365 return 0; 366 367 return ((mcfr & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV; 368 } 369 370 static int clk_rm9200_main_prepare(struct clk_hw *hw) 371 { 372 struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw); 373 374 return clk_main_probe_frequency(clkmain->regmap); 375 } 376 377 static int clk_rm9200_main_is_prepared(struct clk_hw *hw) 378 { 379 struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw); 380 unsigned int status; 381 382 regmap_read(clkmain->regmap, AT91_CKGR_MCFR, &status); 383 384 return !!(status & AT91_PMC_MAINRDY); 385 } 386 387 static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw, 388 unsigned long parent_rate) 389 { 390 struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw); 391 392 return clk_main_recalc_rate(clkmain->regmap, parent_rate); 393 } 394 395 static const struct clk_ops rm9200_main_ops = { 396 .prepare = clk_rm9200_main_prepare, 397 .is_prepared = clk_rm9200_main_is_prepared, 398 .recalc_rate = clk_rm9200_main_recalc_rate, 399 }; 400 401 struct clk_hw * __init 402 at91_clk_register_rm9200_main(struct regmap *regmap, 403 const char *name, 404 const char *parent_name, 405 struct clk_hw *parent_hw) 406 { 407 struct clk_rm9200_main *clkmain; 408 struct clk_init_data init = {}; 409 struct clk_hw *hw; 410 int ret; 411 412 if (!name) 413 return ERR_PTR(-EINVAL); 414 415 if (!(parent_name || parent_hw)) 416 return ERR_PTR(-EINVAL); 417 418 clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL); 419 if (!clkmain) 420 return ERR_PTR(-ENOMEM); 421 422 init.name = name; 423 init.ops = &rm9200_main_ops; 424 if (parent_hw) 425 init.parent_hws = (const struct clk_hw **)&parent_hw; 426 else 427 init.parent_names = &parent_name; 428 init.num_parents = 1; 429 init.flags = 0; 430 431 clkmain->hw.init = &init; 432 clkmain->regmap = regmap; 433 434 hw = &clkmain->hw; 435 ret = clk_hw_register(NULL, &clkmain->hw); 436 if (ret) { 437 kfree(clkmain); 438 hw = ERR_PTR(ret); 439 } 440 441 return hw; 442 } 443 444 static inline bool clk_sam9x5_main_ready(struct regmap *regmap) 445 { 446 unsigned int status; 447 448 regmap_read(regmap, AT91_PMC_SR, &status); 449 450 return !!(status & AT91_PMC_MOSCSELS); 451 } 452 453 static int clk_sam9x5_main_prepare(struct clk_hw *hw) 454 { 455 struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); 456 struct regmap *regmap = clkmain->regmap; 457 458 while (!clk_sam9x5_main_ready(regmap)) 459 cpu_relax(); 460 461 return clk_main_probe_frequency(regmap); 462 } 463 464 static int clk_sam9x5_main_is_prepared(struct clk_hw *hw) 465 { 466 struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); 467 468 return clk_sam9x5_main_ready(clkmain->regmap); 469 } 470 471 static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw, 472 unsigned long parent_rate) 473 { 474 struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); 475 476 return clk_main_recalc_rate(clkmain->regmap, parent_rate); 477 } 478 479 static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index) 480 { 481 struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); 482 struct regmap *regmap = clkmain->regmap; 483 unsigned int tmp; 484 485 if (index > 1) 486 return -EINVAL; 487 488 regmap_read(regmap, AT91_CKGR_MOR, &tmp); 489 490 if (index && !(tmp & AT91_PMC_MOSCSEL)) 491 tmp = AT91_PMC_MOSCSEL; 492 else if (!index && (tmp & AT91_PMC_MOSCSEL)) 493 tmp = 0; 494 else 495 return 0; 496 497 regmap_update_bits(regmap, AT91_CKGR_MOR, 498 AT91_PMC_MOSCSEL | MOR_KEY_MASK, 499 tmp | AT91_PMC_KEY); 500 501 while (!clk_sam9x5_main_ready(regmap)) 502 cpu_relax(); 503 504 return 0; 505 } 506 507 static u8 clk_sam9x5_main_get_parent(struct clk_hw *hw) 508 { 509 struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); 510 unsigned int status; 511 512 regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status); 513 514 return clk_main_parent_select(status); 515 } 516 517 static int clk_sam9x5_main_save_context(struct clk_hw *hw) 518 { 519 struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); 520 521 clkmain->pms.status = clk_main_rc_osc_is_prepared(&clkmain->hw); 522 clkmain->pms.parent = clk_sam9x5_main_get_parent(&clkmain->hw); 523 524 return 0; 525 } 526 527 static void clk_sam9x5_main_restore_context(struct clk_hw *hw) 528 { 529 struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); 530 int ret; 531 532 ret = clk_sam9x5_main_set_parent(hw, clkmain->pms.parent); 533 if (ret) 534 return; 535 536 if (clkmain->pms.status) 537 clk_sam9x5_main_prepare(hw); 538 } 539 540 static const struct clk_ops sam9x5_main_ops = { 541 .prepare = clk_sam9x5_main_prepare, 542 .is_prepared = clk_sam9x5_main_is_prepared, 543 .recalc_rate = clk_sam9x5_main_recalc_rate, 544 .determine_rate = clk_hw_determine_rate_no_reparent, 545 .set_parent = clk_sam9x5_main_set_parent, 546 .get_parent = clk_sam9x5_main_get_parent, 547 .save_context = clk_sam9x5_main_save_context, 548 .restore_context = clk_sam9x5_main_restore_context, 549 }; 550 551 struct clk_hw * __init 552 at91_clk_register_sam9x5_main(struct regmap *regmap, 553 const char *name, 554 const char **parent_names, 555 struct clk_hw **parent_hws, 556 int num_parents) 557 { 558 struct clk_sam9x5_main *clkmain; 559 struct clk_init_data init = {}; 560 unsigned int status; 561 struct clk_hw *hw; 562 int ret; 563 564 if (!name) 565 return ERR_PTR(-EINVAL); 566 567 if (!(parent_hws || parent_names) || !num_parents) 568 return ERR_PTR(-EINVAL); 569 570 clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL); 571 if (!clkmain) 572 return ERR_PTR(-ENOMEM); 573 574 init.name = name; 575 init.ops = &sam9x5_main_ops; 576 if (parent_hws) 577 init.parent_hws = (const struct clk_hw **)parent_hws; 578 else 579 init.parent_names = parent_names; 580 init.num_parents = num_parents; 581 init.flags = CLK_SET_PARENT_GATE; 582 583 clkmain->hw.init = &init; 584 clkmain->regmap = regmap; 585 regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status); 586 clkmain->parent = clk_main_parent_select(status); 587 588 hw = &clkmain->hw; 589 ret = clk_hw_register(NULL, &clkmain->hw); 590 if (ret) { 591 kfree(clkmain); 592 hw = ERR_PTR(ret); 593 } 594 595 return hw; 596 } 597