1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Tenstorrent Atlantis PRCM Clock Driver 4 * 5 * Copyright (c) 2026 Tenstorrent 6 */ 7 8 #include <dt-bindings/clock/tenstorrent,atlantis-prcm-rcpu.h> 9 #include <linux/auxiliary_bus.h> 10 #include <linux/bitfield.h> 11 #include <linux/clk-provider.h> 12 #include <linux/platform_device.h> 13 #include <linux/regmap.h> 14 #include <linux/slab.h> 15 16 /* RCPU Clock Register Offsets */ 17 #define PLL_RCPU_CFG_REG 0x0000 18 #define PLL_NOCC_CFG_REG 0x0004 19 #define NOCC_CLK_CFG_REG 0x0008 20 #define RCPU_DIV_CFG_REG 0x000C 21 #define RCPU_BLK_CG_REG 0x0014 22 #define LSIO_BLK_CG_REG 0x0018 23 #define PLL_RCPU_EN_REG 0x011C 24 #define PLL_NOCC_EN_REG 0x0120 25 #define BUS_CG_REG 0x01FC 26 27 /* PLL Bit Definitions */ 28 #define PLL_CFG_EN_BIT BIT(0) 29 #define PLL_CFG_BYPASS_BIT BIT(1) 30 #define PLL_CFG_REFDIV_MASK GENMASK(7, 2) 31 #define PLL_CFG_REFDIV_SHIFT 2 32 #define PLL_CFG_POSTDIV1_MASK GENMASK(10, 8) 33 #define PLL_CFG_POSTDIV1_SHIFT 8 34 #define PLL_CFG_POSTDIV2_MASK GENMASK(13, 11) 35 #define PLL_CFG_POSTDIV2_SHIFT 11 36 #define PLL_CFG_FBDIV_MASK GENMASK(25, 14) 37 #define PLL_CFG_FBDIV_SHIFT 14 38 #define PLL_CFG_LKDT_BIT BIT(30) 39 #define PLL_CFG_LOCK_BIT BIT(31) 40 #define PLL_LOCK_TIMEOUT_US 1000 41 #define PLL_BYPASS_WAIT_US 500 42 43 struct atlantis_clk_common { 44 int clkid; 45 struct regmap *regmap; 46 struct clk_hw hw; 47 }; 48 49 static inline struct atlantis_clk_common * 50 hw_to_atlantis_clk_common(struct clk_hw *hw) 51 { 52 return container_of(hw, struct atlantis_clk_common, hw); 53 } 54 55 struct atlantis_clk_mux_config { 56 u8 shift; 57 u8 width; 58 u32 reg_offset; 59 }; 60 61 struct atlantis_clk_mux { 62 struct atlantis_clk_common common; 63 struct atlantis_clk_mux_config config; 64 }; 65 66 struct atlantis_clk_gate_config { 67 u32 reg_offset; 68 u32 enable; 69 }; 70 71 struct atlantis_clk_gate { 72 struct atlantis_clk_common common; 73 struct atlantis_clk_gate_config config; 74 }; 75 76 struct atlantis_clk_divider_config { 77 u8 shift; 78 u8 width; 79 u32 flags; 80 u32 reg_offset; 81 }; 82 83 struct atlantis_clk_divider { 84 struct atlantis_clk_common common; 85 struct atlantis_clk_divider_config config; 86 }; 87 88 struct atlantis_clk_pll_config { 89 u32 tbl_num; 90 u32 reg_offset; 91 u32 en_reg_offset; 92 u32 cg_reg_offset; 93 u32 cg_reg_enable; 94 }; 95 96 /* Models a PLL with Bypass Functionality and Enable Bit + an optional Gate Clock at it's output */ 97 struct atlantis_clk_pll { 98 struct atlantis_clk_common common; 99 struct atlantis_clk_pll_config config; 100 }; 101 102 struct atlantis_clk_gate_shared_config { 103 u32 reg_offset; 104 u32 enable; 105 unsigned int *share_count; 106 spinlock_t *refcount_lock; 107 }; 108 109 struct atlantis_clk_gate_shared { 110 struct atlantis_clk_common common; 111 struct atlantis_clk_gate_shared_config config; 112 }; 113 114 struct atlantis_clk_fixed_factor_config { 115 unsigned int mult; 116 unsigned int div; 117 }; 118 119 struct atlantis_clk_fixed_factor { 120 struct atlantis_clk_fixed_factor_config config; 121 struct atlantis_clk_common common; 122 }; 123 124 static inline struct atlantis_clk_mux *hw_to_atlantis_clk_mux(struct clk_hw *hw) 125 { 126 struct atlantis_clk_common *common = hw_to_atlantis_clk_common(hw); 127 128 return container_of(common, struct atlantis_clk_mux, common); 129 } 130 131 static inline struct atlantis_clk_gate * 132 hw_to_atlantis_clk_gate(struct clk_hw *hw) 133 { 134 struct atlantis_clk_common *common = hw_to_atlantis_clk_common(hw); 135 136 return container_of(common, struct atlantis_clk_gate, common); 137 } 138 139 static inline struct atlantis_clk_divider * 140 hw_to_atlantis_clk_divider(struct clk_hw *hw) 141 { 142 struct atlantis_clk_common *common = hw_to_atlantis_clk_common(hw); 143 144 return container_of(common, struct atlantis_clk_divider, common); 145 } 146 147 static inline struct atlantis_clk_pll *hw_to_atlantis_pll(struct clk_hw *hw) 148 { 149 struct atlantis_clk_common *common = hw_to_atlantis_clk_common(hw); 150 151 return container_of(common, struct atlantis_clk_pll, common); 152 } 153 154 static inline struct atlantis_clk_gate_shared * 155 hw_to_atlantis_clk_gate_shared(struct clk_hw *hw) 156 { 157 struct atlantis_clk_common *common = hw_to_atlantis_clk_common(hw); 158 159 return container_of(common, struct atlantis_clk_gate_shared, common); 160 } 161 162 static inline struct atlantis_clk_fixed_factor * 163 hw_to_atlantis_clk_fixed_factor(struct clk_hw *hw) 164 { 165 struct atlantis_clk_common *common = hw_to_atlantis_clk_common(hw); 166 167 return container_of(common, struct atlantis_clk_fixed_factor, common); 168 } 169 170 static u8 atlantis_clk_mux_get_parent(struct clk_hw *hw) 171 { 172 struct atlantis_clk_mux *mux = hw_to_atlantis_clk_mux(hw); 173 u32 val; 174 175 regmap_read(mux->common.regmap, mux->config.reg_offset, &val); 176 val >>= mux->config.shift; 177 val &= (BIT(mux->config.width) - 1); 178 179 return val; 180 } 181 182 static int atlantis_clk_mux_set_parent(struct clk_hw *hw, u8 index) 183 { 184 struct atlantis_clk_mux *mux = hw_to_atlantis_clk_mux(hw); 185 u32 val = index; 186 187 return regmap_update_bits(mux->common.regmap, mux->config.reg_offset, 188 (BIT(mux->config.width) - 1) << mux->config.shift, 189 val << mux->config.shift); 190 } 191 192 static int atlantis_clk_mux_determine_rate(struct clk_hw *hw, 193 struct clk_rate_request *req) 194 { 195 return clk_mux_determine_rate_flags(hw, req, hw->init->flags); 196 } 197 198 static const struct clk_ops atlantis_clk_mux_ops = { 199 .get_parent = atlantis_clk_mux_get_parent, 200 .set_parent = atlantis_clk_mux_set_parent, 201 .determine_rate = atlantis_clk_mux_determine_rate, 202 }; 203 204 static int atlantis_clk_gate_endisable(struct clk_hw *hw, int enable) 205 { 206 struct atlantis_clk_gate *gate = hw_to_atlantis_clk_gate(hw); 207 208 if (enable) 209 return regmap_set_bits(gate->common.regmap, 210 gate->config.reg_offset, 211 gate->config.enable); 212 else 213 return regmap_clear_bits(gate->common.regmap, 214 gate->config.reg_offset, 215 gate->config.enable); 216 } 217 218 static int atlantis_clk_gate_enable(struct clk_hw *hw) 219 { 220 return atlantis_clk_gate_endisable(hw, 1); 221 } 222 223 static void atlantis_clk_gate_disable(struct clk_hw *hw) 224 { 225 atlantis_clk_gate_endisable(hw, 0); 226 } 227 228 static int atlantis_clk_gate_is_enabled(struct clk_hw *hw) 229 { 230 struct atlantis_clk_gate *gate = hw_to_atlantis_clk_gate(hw); 231 232 return regmap_test_bits(gate->common.regmap, gate->config.reg_offset, gate->config.enable); 233 } 234 235 static const struct clk_ops atlantis_clk_gate_ops = { 236 .enable = atlantis_clk_gate_enable, 237 .disable = atlantis_clk_gate_disable, 238 .is_enabled = atlantis_clk_gate_is_enabled, 239 }; 240 241 static unsigned long atlantis_clk_divider_recalc_rate(struct clk_hw *hw, 242 unsigned long parent_rate) 243 { 244 struct atlantis_clk_divider *divider = hw_to_atlantis_clk_divider(hw); 245 u32 val; 246 247 regmap_read(divider->common.regmap, divider->config.reg_offset, &val); 248 249 val >>= divider->config.shift; 250 val &= ((1 << (divider->config.width)) - 1); 251 252 return DIV_ROUND_UP_ULL((u64)parent_rate, val + 1); 253 } 254 255 static const struct clk_ops atlantis_clk_divider_ops = { 256 .recalc_rate = atlantis_clk_divider_recalc_rate, 257 }; 258 259 static unsigned long 260 atlantis_clk_fixed_factor_recalc_rate(struct clk_hw *hw, 261 unsigned long parent_rate) 262 { 263 struct atlantis_clk_fixed_factor *factor = 264 hw_to_atlantis_clk_fixed_factor(hw); 265 unsigned long long rate; 266 267 rate = (unsigned long long)parent_rate * factor->config.mult; 268 do_div(rate, factor->config.div); 269 270 return (unsigned long)rate; 271 } 272 273 static const struct clk_ops atlantis_clk_fixed_factor_ops = { 274 .recalc_rate = atlantis_clk_fixed_factor_recalc_rate, 275 }; 276 277 static int atlantis_clk_pll_is_enabled(struct clk_hw *hw) 278 { 279 struct atlantis_clk_pll *pll = hw_to_atlantis_pll(hw); 280 u32 val, en_val, cg_val; 281 282 regmap_read(pll->common.regmap, pll->config.reg_offset, &val); 283 regmap_read(pll->common.regmap, pll->config.en_reg_offset, &en_val); 284 regmap_read(pll->common.regmap, pll->config.cg_reg_offset, &cg_val); 285 286 /* Check if PLL is powered on, locked, not bypassed and Gate clk is enabled */ 287 return !!(en_val & PLL_CFG_EN_BIT) && !!(val & PLL_CFG_LOCK_BIT) && 288 (!pll->config.cg_reg_enable || (cg_val & pll->config.cg_reg_enable)) && 289 !(val & PLL_CFG_BYPASS_BIT); 290 } 291 292 static int atlantis_clk_pll_enable(struct clk_hw *hw) 293 { 294 struct atlantis_clk_pll *pll = hw_to_atlantis_pll(hw); 295 u32 val, en_val, cg_val; 296 int ret; 297 298 regmap_read(pll->common.regmap, pll->config.reg_offset, &val); 299 regmap_read(pll->common.regmap, pll->config.en_reg_offset, &en_val); 300 regmap_read(pll->common.regmap, pll->config.cg_reg_offset, &cg_val); 301 302 /* Check if PLL is already enabled, locked, not bypassed and Gate clk is enabled */ 303 if ((en_val & PLL_CFG_EN_BIT) && (val & PLL_CFG_LOCK_BIT) && 304 (!pll->config.cg_reg_enable || (cg_val & pll->config.cg_reg_enable)) && 305 !(val & PLL_CFG_BYPASS_BIT)) { 306 return 0; 307 } 308 309 /* Step 1: Set bypass mode first */ 310 regmap_update_bits(pll->common.regmap, pll->config.reg_offset, 311 PLL_CFG_BYPASS_BIT, PLL_CFG_BYPASS_BIT); 312 313 /* Step 2: Enable PLL (clear then set power bit) */ 314 regmap_update_bits(pll->common.regmap, pll->config.en_reg_offset, 315 PLL_CFG_EN_BIT, 0); 316 317 regmap_update_bits(pll->common.regmap, pll->config.en_reg_offset, 318 PLL_CFG_EN_BIT, PLL_CFG_EN_BIT); 319 320 /* Step 3: Wait for PLL lock */ 321 ret = regmap_read_poll_timeout(pll->common.regmap, 322 pll->config.reg_offset, val, 323 val & PLL_CFG_LOCK_BIT, 324 PLL_BYPASS_WAIT_US, PLL_LOCK_TIMEOUT_US); 325 if (ret) { 326 pr_err("PLL failed to lock within timeout\n"); 327 return ret; 328 } 329 330 /* Step 4: Switch from bypass to PLL output */ 331 regmap_update_bits(pll->common.regmap, pll->config.reg_offset, 332 PLL_CFG_BYPASS_BIT, 0); 333 334 /* Enable Gate clk at PLL Output */ 335 return regmap_update_bits(pll->common.regmap, pll->config.cg_reg_offset, 336 pll->config.cg_reg_enable, 337 pll->config.cg_reg_enable); 338 } 339 340 static void atlantis_clk_pll_disable(struct clk_hw *hw) 341 { 342 struct atlantis_clk_pll *pll = hw_to_atlantis_pll(hw); 343 344 /* Step 1: Switch to bypass mode before disabling */ 345 regmap_update_bits(pll->common.regmap, pll->config.reg_offset, 346 PLL_CFG_BYPASS_BIT, PLL_CFG_BYPASS_BIT); 347 /* Step 2: Power down PLL */ 348 regmap_update_bits(pll->common.regmap, pll->config.en_reg_offset, 349 PLL_CFG_EN_BIT, 0); 350 } 351 352 static unsigned long atlantis_clk_pll_recalc_rate(struct clk_hw *hw, 353 unsigned long parent_rate) 354 { 355 struct atlantis_clk_pll *pll = hw_to_atlantis_pll(hw); 356 357 u32 val, refdiv, fbdiv, postdiv1, postdiv2; 358 u64 fout; 359 360 regmap_read(pll->common.regmap, pll->config.reg_offset, &val); 361 362 if (val & PLL_CFG_BYPASS_BIT) 363 return parent_rate; 364 365 refdiv = FIELD_GET(PLL_CFG_REFDIV_MASK, val); 366 fbdiv = FIELD_GET(PLL_CFG_FBDIV_MASK, val); 367 postdiv1 = FIELD_GET(PLL_CFG_POSTDIV1_MASK, val); 368 postdiv2 = FIELD_GET(PLL_CFG_POSTDIV2_MASK, val); 369 370 if (!refdiv) 371 refdiv = 1; 372 if (!postdiv1) 373 postdiv1 = 1; 374 if (!postdiv2) 375 postdiv2 = 1; 376 if (!fbdiv) 377 return 0; 378 379 fout = div64_u64((u64)parent_rate * fbdiv, 380 refdiv * postdiv1 * postdiv2); 381 382 return fout; 383 } 384 385 static const struct clk_ops atlantis_clk_pll_ops = { 386 .enable = atlantis_clk_pll_enable, 387 .disable = atlantis_clk_pll_disable, 388 .recalc_rate = atlantis_clk_pll_recalc_rate, 389 .is_enabled = atlantis_clk_pll_is_enabled, 390 }; 391 392 static int atlantis_clk_gate_shared_enable(struct clk_hw *hw) 393 { 394 struct atlantis_clk_gate_shared *gate = 395 hw_to_atlantis_clk_gate_shared(hw); 396 bool need_enable; 397 398 scoped_guard(spinlock_irqsave, gate->config.refcount_lock) 399 { 400 need_enable = (*gate->config.share_count)++ == 0; 401 if (need_enable) { 402 regmap_set_bits(gate->common.regmap, 403 gate->config.reg_offset, 404 gate->config.enable); 405 } 406 } 407 408 if (need_enable) { 409 if (!regmap_test_bits(gate->common.regmap, 410 gate->config.reg_offset, 411 gate->config.enable)) { 412 pr_warn("%s: gate enable %d failed to enable\n", 413 clk_hw_get_name(hw), gate->config.enable); 414 return -EIO; 415 } 416 } 417 418 return 0; 419 } 420 421 static void atlantis_clk_gate_shared_disable(struct clk_hw *hw) 422 { 423 struct atlantis_clk_gate_shared *gate = 424 hw_to_atlantis_clk_gate_shared(hw); 425 426 scoped_guard(spinlock_irqsave, gate->config.refcount_lock) 427 { 428 if (WARN_ON(*gate->config.share_count == 0)) 429 return; 430 if (--(*gate->config.share_count) > 0) 431 return; 432 433 regmap_clear_bits(gate->common.regmap, 434 gate->config.reg_offset, 435 gate->config.enable); 436 } 437 } 438 439 static int atlantis_clk_gate_shared_is_enabled(struct clk_hw *hw) 440 { 441 struct atlantis_clk_gate_shared *gate = 442 hw_to_atlantis_clk_gate_shared(hw); 443 444 return regmap_test_bits(gate->common.regmap, gate->config.reg_offset, gate->config.enable); 445 } 446 447 static void atlantis_clk_gate_shared_disable_unused(struct clk_hw *hw) 448 { 449 struct atlantis_clk_gate_shared *gate = 450 hw_to_atlantis_clk_gate_shared(hw); 451 452 scoped_guard(spinlock_irqsave, gate->config.refcount_lock) 453 { 454 if (*gate->config.share_count == 0) 455 regmap_clear_bits(gate->common.regmap, 456 gate->config.reg_offset, 457 gate->config.enable); 458 } 459 } 460 461 static const struct clk_ops atlantis_clk_gate_shared_ops = { 462 .enable = atlantis_clk_gate_shared_enable, 463 .disable = atlantis_clk_gate_shared_disable, 464 .disable_unused = atlantis_clk_gate_shared_disable_unused, 465 .is_enabled = atlantis_clk_gate_shared_is_enabled, 466 }; 467 468 #define ATLANTIS_PLL_CONFIG(_reg_offset, _en_reg_offset, _cg_reg_offset, \ 469 _cg_reg_enable) \ 470 { \ 471 .reg_offset = (_reg_offset), \ 472 .en_reg_offset = (_en_reg_offset), \ 473 .cg_reg_offset = (_cg_reg_offset), \ 474 .cg_reg_enable = (_cg_reg_enable), \ 475 } 476 477 #define ATLANTIS_PLL_DEFINE(_clkid, _name, _parent, _reg_offset, \ 478 _en_reg_offset, _cg_reg_offset, _cg_reg_enable, \ 479 _flags) \ 480 static struct atlantis_clk_pll _name = { \ 481 .config = ATLANTIS_PLL_CONFIG(_reg_offset, _en_reg_offset, \ 482 _cg_reg_offset, _cg_reg_enable), \ 483 .common = { .clkid = _clkid, \ 484 .hw.init = CLK_HW_INIT_PARENTS_DATA( \ 485 #_name, _parent, &atlantis_clk_pll_ops, \ 486 _flags) }, \ 487 } 488 #define ATLANTIS_MUX_CONFIG(_shift, _width, _reg_offset) \ 489 { \ 490 .shift = _shift, .width = _width, .reg_offset = _reg_offset \ 491 } 492 493 #define ATLANTIS_MUX_DEFINE(_clkid, _name, _parents, _reg_offset, _shift, \ 494 _width, _flags) \ 495 static struct atlantis_clk_mux _name = { \ 496 .config = ATLANTIS_MUX_CONFIG(_shift, _width, _reg_offset), \ 497 .common = { .clkid = _clkid, \ 498 .hw.init = CLK_HW_INIT_PARENTS_DATA( \ 499 #_name, _parents, &atlantis_clk_mux_ops, \ 500 _flags) } \ 501 } 502 503 #define ATLANTIS_DIVIDER_CONFIG(_shift, _width, _flags, _reg_offset) \ 504 { \ 505 .shift = _shift, .width = _width, .flags = _flags, \ 506 .reg_offset = _reg_offset \ 507 } 508 509 #define ATLANTIS_DIVIDER_DEFINE(_clkid, _name, _parent, _reg_offset, _shift, \ 510 _width, _divflags, _flags) \ 511 static struct atlantis_clk_divider _name = { \ 512 .config = ATLANTIS_DIVIDER_CONFIG(_shift, _width, _divflags, \ 513 _reg_offset), \ 514 .common = { .clkid = _clkid, \ 515 .hw.init = CLK_HW_INIT_HW( \ 516 #_name, &_parent.common.hw, \ 517 &atlantis_clk_divider_ops, _flags) } \ 518 } 519 #define ATLANTIS_GATE_CONFIG(_enable, _reg_offset) \ 520 { \ 521 .enable = _enable, .reg_offset = _reg_offset \ 522 } 523 524 #define ATLANTIS_GATE_DEFINE(_clkid, _name, _parent, _reg_offset, _enable, \ 525 _flags) \ 526 static struct atlantis_clk_gate _name = { \ 527 .config = ATLANTIS_GATE_CONFIG(_enable, _reg_offset), \ 528 .common = { .clkid = _clkid, \ 529 .hw.init = CLK_HW_INIT_HW( \ 530 #_name, &_parent.common.hw, \ 531 &atlantis_clk_gate_ops, _flags) } \ 532 } 533 #define ATLANTIS_GATE_SHARED_CONFIG(_reg_offset, _enable, _share_count) \ 534 { \ 535 .reg_offset = _reg_offset, .enable = _enable, \ 536 .share_count = _share_count, .refcount_lock = &refcount_lock \ 537 } 538 #define ATLANTIS_GATE_SHARED_DEFINE(_clkid, _name, _parent, _reg_offset, \ 539 _enable, _share_count, _flags) \ 540 static struct atlantis_clk_gate_shared _name = { \ 541 .config = ATLANTIS_GATE_SHARED_CONFIG(_reg_offset, _enable, \ 542 _share_count), \ 543 .common = { .clkid = _clkid, \ 544 .hw.init = CLK_HW_INIT_HW( \ 545 #_name, &_parent.common.hw, \ 546 &atlantis_clk_gate_shared_ops, _flags) } \ 547 } 548 #define ATLANTIS_FIXED_FACTOR_DEFINE(_clkid, _name, _parent, _mult, _div, \ 549 _flags) \ 550 static struct atlantis_clk_fixed_factor _name = { \ 551 .config = { .mult = _mult, .div = _div }, \ 552 .common = { .clkid = _clkid, \ 553 .hw.init = CLK_HW_INIT_HW( \ 554 #_name, &_parent.common.hw, \ 555 &atlantis_clk_fixed_factor_ops, _flags) } \ 556 } 557 558 static DEFINE_SPINLOCK(refcount_lock); /* Lock for refcount value accesses */ 559 560 static const struct regmap_config atlantis_prcm_regmap_config = { 561 .reg_bits = 32, 562 .reg_stride = 4, 563 .val_bits = 32, 564 .max_register = 0xFFFC, 565 .cache_type = REGCACHE_NONE, 566 }; 567 568 struct atlantis_prcm_data { 569 struct clk_hw **hws; 570 size_t num; 571 const char *reset_name; 572 }; 573 574 static const struct clk_parent_data osc_24m_clk[] = { 575 { .index = 0 }, 576 }; 577 578 ATLANTIS_PLL_DEFINE(CLK_RCPU_PLL, rcpu_pll_clk, osc_24m_clk, PLL_RCPU_CFG_REG, 579 PLL_RCPU_EN_REG, BUS_CG_REG, 0, /* No Gate Clk at Output */ 580 CLK_GET_RATE_NOCACHE | CLK_IS_CRITICAL); 581 582 static const struct clk_parent_data rcpu_root_parents[] = { 583 { .index = 0 }, 584 { .hw = &rcpu_pll_clk.common.hw }, 585 }; 586 587 ATLANTIS_MUX_DEFINE(CLK_RCPU_ROOT, rcpu_root_clk, rcpu_root_parents, 588 RCPU_DIV_CFG_REG, 0, 1, CLK_SET_RATE_NO_REPARENT); 589 590 ATLANTIS_DIVIDER_DEFINE(CLK_RCPU_DIV2, rcpu_div2_clk, rcpu_root_clk, 591 RCPU_DIV_CFG_REG, 2, 4, 0, 0); 592 ATLANTIS_DIVIDER_DEFINE(CLK_RCPU_DIV4, rcpu_div4_clk, rcpu_root_clk, 593 RCPU_DIV_CFG_REG, 7, 4, 0, 0); 594 ATLANTIS_DIVIDER_DEFINE(CLK_RCPU_RTC, rcpu_rtc_clk, rcpu_div4_clk, 595 RCPU_DIV_CFG_REG, 12, 6, 0, 0); 596 597 ATLANTIS_GATE_DEFINE(CLK_SMNDMA0_ACLK, rcpu_dma0_clk, rcpu_div2_clk, 598 RCPU_BLK_CG_REG, BIT(0), 0); 599 ATLANTIS_GATE_DEFINE(CLK_SMNDMA1_ACLK, rcpu_dma1_clk, rcpu_div2_clk, 600 RCPU_BLK_CG_REG, BIT(1), 0); 601 ATLANTIS_GATE_DEFINE(CLK_WDT0_PCLK, sl_wdt0_pclk, rcpu_div4_clk, 602 RCPU_BLK_CG_REG, BIT(2), 0); 603 ATLANTIS_GATE_DEFINE(CLK_WDT1_PCLK, sl_wdt1_pclk, rcpu_div4_clk, 604 RCPU_BLK_CG_REG, BIT(3), 0); 605 ATLANTIS_GATE_DEFINE(CLK_TIMER_PCLK, sl_timer_pclk, rcpu_div4_clk, 606 RCPU_BLK_CG_REG, BIT(4), 0); 607 ATLANTIS_GATE_DEFINE(CLK_PVTC_PCLK, sl_pvtc_pclk, rcpu_div4_clk, 608 RCPU_BLK_CG_REG, BIT(12), 0); 609 ATLANTIS_GATE_DEFINE(CLK_PMU_PCLK, sl_pmu_pclk, rcpu_div4_clk, RCPU_BLK_CG_REG, 610 BIT(13), 0); 611 ATLANTIS_GATE_DEFINE(CLK_MAILBOX_HCLK, rcpu_ipc_clk, rcpu_div2_clk, 612 RCPU_BLK_CG_REG, BIT(14), 0); 613 ATLANTIS_GATE_DEFINE(CLK_SEC_SPACC_HCLK, sec_spacc_hclk, rcpu_div2_clk, 614 RCPU_BLK_CG_REG, BIT(26), 0); 615 ATLANTIS_GATE_DEFINE(CLK_SEC_OTP_HCLK, sec_otp_hclk, rcpu_div2_clk, 616 RCPU_BLK_CG_REG, BIT(28), 0); 617 ATLANTIS_GATE_DEFINE(CLK_TRNG_PCLK, sec_trng_pclk, rcpu_div4_clk, 618 RCPU_BLK_CG_REG, BIT(29), 0); 619 ATLANTIS_GATE_DEFINE(CLK_SEC_CRC_HCLK, sec_crc_hclk, rcpu_div2_clk, 620 RCPU_BLK_CG_REG, BIT(30), 0); 621 622 ATLANTIS_FIXED_FACTOR_DEFINE(CLK_SMN_HCLK, rcpu_smn_hclk, rcpu_div2_clk, 1, 1, 623 0); 624 ATLANTIS_FIXED_FACTOR_DEFINE(CLK_AHB0_HCLK, rcpu_ahb0_hclk, rcpu_div2_clk, 1, 1, 625 0); 626 627 ATLANTIS_FIXED_FACTOR_DEFINE(CLK_SMN_PCLK, rcpu_smn_pclk, rcpu_div4_clk, 1, 1, 628 0); 629 630 ATLANTIS_FIXED_FACTOR_DEFINE(CLK_SMN_CLK, rcpu_smn_clk, rcpu_root_clk, 1, 1, 0); 631 ATLANTIS_FIXED_FACTOR_DEFINE(CLK_SCRATCHPAD_CLK, rcpu_scratchpad_aclk, 632 rcpu_root_clk, 1, 1, 0); 633 ATLANTIS_FIXED_FACTOR_DEFINE(CLK_RCPU_CORE_CLK, rcpu_core_clk, rcpu_root_clk, 1, 634 1, 0); 635 ATLANTIS_FIXED_FACTOR_DEFINE(CLK_RCPU_ROM_CLK, rcpu_rom_aclk, rcpu_root_clk, 1, 636 1, 0); 637 638 static struct atlantis_clk_fixed_factor 639 otp_load_clk = { .config = { .mult = 1, .div = 1 }, 640 .common = { 641 .clkid = CLK_OTP_LOAD_CLK, 642 .hw.init = CLK_HW_INIT_PARENTS_DATA( 643 "otp_load_clk", osc_24m_clk, 644 &atlantis_clk_fixed_factor_ops, 645 CLK_SET_RATE_NO_REPARENT), 646 } }; 647 648 ATLANTIS_PLL_DEFINE(CLK_NOC_PLL, nocc_pll_clk, osc_24m_clk, PLL_NOCC_CFG_REG, 649 PLL_NOCC_EN_REG, BUS_CG_REG, BIT(0), 650 CLK_GET_RATE_NOCACHE | CLK_IS_CRITICAL); 651 652 static const struct clk_parent_data nocc_mux_parents[] = { 653 { .index = 0 }, 654 { .hw = &nocc_pll_clk.common.hw }, 655 }; 656 657 ATLANTIS_MUX_DEFINE(CLK_NOCC_CLK, nocc_clk, nocc_mux_parents, NOCC_CLK_CFG_REG, 658 0, 1, CLK_SET_RATE_NO_REPARENT); 659 660 ATLANTIS_DIVIDER_DEFINE(CLK_NOCC_DIV2, nocc_div2_clk, nocc_clk, 661 NOCC_CLK_CFG_REG, 1, 4, 0, 0); 662 ATLANTIS_DIVIDER_DEFINE(CLK_NOCC_DIV4, nocc_div4_clk, nocc_clk, 663 NOCC_CLK_CFG_REG, 5, 4, 0, 0); 664 ATLANTIS_DIVIDER_DEFINE(CLK_NOCC_RTC, nocc_rtc_clk, nocc_div4_clk, 665 NOCC_CLK_CFG_REG, 9, 6, 0, 0); 666 ATLANTIS_DIVIDER_DEFINE(CLK_NOCC_CAN, nocc_can_clk, nocc_clk, NOCC_CLK_CFG_REG, 667 15, 4, 0, 0); 668 669 static unsigned int refcnt_qspi; 670 ATLANTIS_GATE_SHARED_DEFINE(CLK_QSPI_SCLK, lsio_qspi_sclk, nocc_clk, 671 LSIO_BLK_CG_REG, BIT(0), &refcnt_qspi, 0); 672 ATLANTIS_GATE_SHARED_DEFINE(CLK_QSPI_HCLK, lsio_qspi_hclk, nocc_div2_clk, 673 LSIO_BLK_CG_REG, BIT(0), &refcnt_qspi, 0); 674 ATLANTIS_GATE_DEFINE(CLK_I2C0_PCLK, lsio_i2c0_pclk, nocc_div4_clk, 675 LSIO_BLK_CG_REG, BIT(1), 0); 676 ATLANTIS_GATE_DEFINE(CLK_I2C1_PCLK, lsio_i2c1_pclk, nocc_div4_clk, 677 LSIO_BLK_CG_REG, BIT(2), 0); 678 ATLANTIS_GATE_DEFINE(CLK_I2C2_PCLK, lsio_i2c2_pclk, nocc_div4_clk, 679 LSIO_BLK_CG_REG, BIT(3), 0); 680 ATLANTIS_GATE_DEFINE(CLK_I2C3_PCLK, lsio_i2c3_pclk, nocc_div4_clk, 681 LSIO_BLK_CG_REG, BIT(4), 0); 682 ATLANTIS_GATE_DEFINE(CLK_I2C4_PCLK, lsio_i2c4_pclk, nocc_div4_clk, 683 LSIO_BLK_CG_REG, BIT(5), 0); 684 685 ATLANTIS_GATE_DEFINE(CLK_UART0_PCLK, lsio_uart0_pclk, nocc_div4_clk, 686 LSIO_BLK_CG_REG, BIT(6), 0); 687 ATLANTIS_GATE_DEFINE(CLK_UART1_PCLK, lsio_uart1_pclk, nocc_div4_clk, 688 LSIO_BLK_CG_REG, BIT(7), 0); 689 ATLANTIS_GATE_DEFINE(CLK_UART2_PCLK, lsio_uart2_pclk, nocc_div4_clk, 690 LSIO_BLK_CG_REG, BIT(8), 0); 691 ATLANTIS_GATE_DEFINE(CLK_UART3_PCLK, lsio_uart3_pclk, nocc_div4_clk, 692 LSIO_BLK_CG_REG, BIT(9), 0); 693 ATLANTIS_GATE_DEFINE(CLK_UART4_PCLK, lsio_uart4_pclk, nocc_div4_clk, 694 LSIO_BLK_CG_REG, BIT(10), 0); 695 ATLANTIS_GATE_DEFINE(CLK_SPI0_PCLK, lsio_spi0_pclk, nocc_div4_clk, 696 LSIO_BLK_CG_REG, BIT(11), 0); 697 ATLANTIS_GATE_DEFINE(CLK_SPI1_PCLK, lsio_spi1_pclk, nocc_div4_clk, 698 LSIO_BLK_CG_REG, BIT(12), 0); 699 ATLANTIS_GATE_DEFINE(CLK_SPI2_PCLK, lsio_spi2_pclk, nocc_div4_clk, 700 LSIO_BLK_CG_REG, BIT(13), 0); 701 ATLANTIS_GATE_DEFINE(CLK_SPI3_PCLK, lsio_spi3_pclk, nocc_div4_clk, 702 LSIO_BLK_CG_REG, BIT(14), 0); 703 ATLANTIS_GATE_DEFINE(CLK_GPIO_PCLK, lsio_gpio_pclk, nocc_div4_clk, 704 LSIO_BLK_CG_REG, BIT(15), 0); 705 706 static unsigned int refcnt_can0; 707 ATLANTIS_GATE_SHARED_DEFINE(CLK_CAN0_HCLK, lsio_can0_hclk, nocc_div2_clk, 708 LSIO_BLK_CG_REG, BIT(17), &refcnt_can0, 0); 709 ATLANTIS_GATE_SHARED_DEFINE(CLK_CAN0_CLK, lsio_can0_clk, nocc_can_clk, 710 LSIO_BLK_CG_REG, BIT(17), &refcnt_can0, 0); 711 712 static unsigned int refcnt_can1; 713 ATLANTIS_GATE_SHARED_DEFINE(CLK_CAN1_HCLK, lsio_can1_hclk, nocc_div2_clk, 714 LSIO_BLK_CG_REG, BIT(18), &refcnt_can1, 0); 715 ATLANTIS_GATE_SHARED_DEFINE(CLK_CAN1_CLK, lsio_can1_clk, nocc_can_clk, 716 LSIO_BLK_CG_REG, BIT(18), &refcnt_can1, 0); 717 718 ATLANTIS_FIXED_FACTOR_DEFINE(CLK_CAN0_TIMER_CLK, lsio_can0_timer_clk, 719 nocc_rtc_clk, 1, 1, 0); 720 ATLANTIS_FIXED_FACTOR_DEFINE(CLK_CAN1_TIMER_CLK, lsio_can1_timer_clk, 721 nocc_rtc_clk, 1, 1, 0); 722 723 static struct clk_hw *atlantis_rcpu_clks[] = { 724 [CLK_RCPU_PLL] = &rcpu_pll_clk.common.hw, 725 [CLK_RCPU_ROOT] = &rcpu_root_clk.common.hw, 726 [CLK_RCPU_DIV2] = &rcpu_div2_clk.common.hw, 727 [CLK_RCPU_DIV4] = &rcpu_div4_clk.common.hw, 728 [CLK_RCPU_RTC] = &rcpu_rtc_clk.common.hw, 729 [CLK_SMNDMA0_ACLK] = &rcpu_dma0_clk.common.hw, 730 [CLK_SMNDMA1_ACLK] = &rcpu_dma1_clk.common.hw, 731 [CLK_WDT0_PCLK] = &sl_wdt0_pclk.common.hw, 732 [CLK_WDT1_PCLK] = &sl_wdt1_pclk.common.hw, 733 [CLK_TIMER_PCLK] = &sl_timer_pclk.common.hw, 734 [CLK_PVTC_PCLK] = &sl_pvtc_pclk.common.hw, 735 [CLK_PMU_PCLK] = &sl_pmu_pclk.common.hw, 736 [CLK_MAILBOX_HCLK] = &rcpu_ipc_clk.common.hw, 737 [CLK_SEC_SPACC_HCLK] = &sec_spacc_hclk.common.hw, 738 [CLK_SEC_OTP_HCLK] = &sec_otp_hclk.common.hw, 739 [CLK_TRNG_PCLK] = &sec_trng_pclk.common.hw, 740 [CLK_SEC_CRC_HCLK] = &sec_crc_hclk.common.hw, 741 [CLK_SMN_HCLK] = &rcpu_smn_hclk.common.hw, 742 [CLK_AHB0_HCLK] = &rcpu_ahb0_hclk.common.hw, 743 [CLK_SMN_PCLK] = &rcpu_smn_pclk.common.hw, 744 [CLK_SMN_CLK] = &rcpu_smn_clk.common.hw, 745 [CLK_SCRATCHPAD_CLK] = &rcpu_scratchpad_aclk.common.hw, 746 [CLK_RCPU_CORE_CLK] = &rcpu_core_clk.common.hw, 747 [CLK_RCPU_ROM_CLK] = &rcpu_rom_aclk.common.hw, 748 [CLK_OTP_LOAD_CLK] = &otp_load_clk.common.hw, 749 [CLK_NOC_PLL] = &nocc_pll_clk.common.hw, 750 [CLK_NOCC_CLK] = &nocc_clk.common.hw, 751 [CLK_NOCC_DIV2] = &nocc_div2_clk.common.hw, 752 [CLK_NOCC_DIV4] = &nocc_div4_clk.common.hw, 753 [CLK_NOCC_RTC] = &nocc_rtc_clk.common.hw, 754 [CLK_NOCC_CAN] = &nocc_can_clk.common.hw, 755 [CLK_QSPI_SCLK] = &lsio_qspi_sclk.common.hw, 756 [CLK_QSPI_HCLK] = &lsio_qspi_hclk.common.hw, 757 [CLK_I2C0_PCLK] = &lsio_i2c0_pclk.common.hw, 758 [CLK_I2C1_PCLK] = &lsio_i2c1_pclk.common.hw, 759 [CLK_I2C2_PCLK] = &lsio_i2c2_pclk.common.hw, 760 [CLK_I2C3_PCLK] = &lsio_i2c3_pclk.common.hw, 761 [CLK_I2C4_PCLK] = &lsio_i2c4_pclk.common.hw, 762 [CLK_UART0_PCLK] = &lsio_uart0_pclk.common.hw, 763 [CLK_UART1_PCLK] = &lsio_uart1_pclk.common.hw, 764 [CLK_UART2_PCLK] = &lsio_uart2_pclk.common.hw, 765 [CLK_UART3_PCLK] = &lsio_uart3_pclk.common.hw, 766 [CLK_UART4_PCLK] = &lsio_uart4_pclk.common.hw, 767 [CLK_SPI0_PCLK] = &lsio_spi0_pclk.common.hw, 768 [CLK_SPI1_PCLK] = &lsio_spi1_pclk.common.hw, 769 [CLK_SPI2_PCLK] = &lsio_spi2_pclk.common.hw, 770 [CLK_SPI3_PCLK] = &lsio_spi3_pclk.common.hw, 771 [CLK_GPIO_PCLK] = &lsio_gpio_pclk.common.hw, 772 [CLK_CAN0_HCLK] = &lsio_can0_hclk.common.hw, 773 [CLK_CAN0_CLK] = &lsio_can0_clk.common.hw, 774 [CLK_CAN1_HCLK] = &lsio_can1_hclk.common.hw, 775 [CLK_CAN1_CLK] = &lsio_can1_clk.common.hw, 776 [CLK_CAN0_TIMER_CLK] = &lsio_can0_timer_clk.common.hw, 777 [CLK_CAN1_TIMER_CLK] = &lsio_can1_timer_clk.common.hw, 778 }; 779 780 static const struct atlantis_prcm_data atlantis_prcm_rcpu_data = { 781 .hws = atlantis_rcpu_clks, 782 .num = ARRAY_SIZE(atlantis_rcpu_clks), 783 .reset_name = "rcpu-reset" 784 }; 785 786 static int atlantis_prcm_clocks_register(struct device *dev, 787 struct regmap *regmap, 788 const struct atlantis_prcm_data *data) 789 { 790 struct clk_hw_onecell_data *clk_data; 791 int i, ret; 792 size_t num_clks = data->num; 793 794 clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, data->num), 795 GFP_KERNEL); 796 if (!clk_data) 797 return -ENOMEM; 798 799 for (i = 0; i < data->num; i++) { 800 struct clk_hw *hw = data->hws[i]; 801 struct atlantis_clk_common *common = 802 hw_to_atlantis_clk_common(hw); 803 common->regmap = regmap; 804 805 ret = devm_clk_hw_register(dev, hw); 806 if (ret) 807 return ret; 808 809 clk_data->hws[common->clkid] = hw; 810 } 811 812 clk_data->num = num_clks; 813 814 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); 815 } 816 817 static int atlantis_prcm_probe(struct platform_device *pdev) 818 { 819 const struct atlantis_prcm_data *data; 820 struct auxiliary_device *reset_adev; 821 struct regmap *regmap; 822 void __iomem *base; 823 struct device *dev = &pdev->dev; 824 int ret; 825 826 base = devm_platform_ioremap_resource(pdev, 0); 827 if (IS_ERR(base)) 828 return dev_err_probe(dev, PTR_ERR(base), 829 "Failed to map registers\n"); 830 831 regmap = devm_regmap_init_mmio(dev, base, &atlantis_prcm_regmap_config); 832 if (IS_ERR(regmap)) 833 return dev_err_probe(dev, PTR_ERR(regmap), 834 "Failed to init regmap\n"); 835 836 data = of_device_get_match_data(dev); 837 838 ret = atlantis_prcm_clocks_register(dev, regmap, data); 839 if (ret) 840 return dev_err_probe(dev, ret, "failed to register clocks\n"); 841 842 reset_adev = devm_auxiliary_device_create(dev, data->reset_name, NULL); 843 if (!reset_adev) 844 return dev_err_probe(dev, -ENODEV, "failed to register resets\n"); 845 846 return 0; 847 } 848 849 static const struct of_device_id atlantis_prcm_of_match[] = { 850 { 851 .compatible = "tenstorrent,atlantis-prcm-rcpu", 852 .data = &atlantis_prcm_rcpu_data, 853 }, 854 {} 855 856 }; 857 MODULE_DEVICE_TABLE(of, atlantis_prcm_of_match); 858 859 static struct platform_driver atlantis_prcm_driver = { 860 .probe = atlantis_prcm_probe, 861 .driver = { 862 .name = "atlantis-prcm", 863 .of_match_table = atlantis_prcm_of_match, 864 }, 865 }; 866 module_platform_driver(atlantis_prcm_driver); 867 868 MODULE_DESCRIPTION("Tenstorrent Atlantis PRCM Clock Controller Driver"); 869 MODULE_AUTHOR("Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>"); 870 MODULE_LICENSE("GPL"); 871