xref: /linux/drivers/clk/tenstorrent/atlantis-prcm.c (revision 0fc8f6200d2313278fbf4539bbab74677c685531)
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