blob: c8735d869cf9380ca0f626d12ca63827ee39a23a [file] [log] [blame]
Paul Barker132d7ea2023-10-16 10:25:29 +01001// SPDX-License-Identifier: GPL-2.0
2/*
3 * RZ/G2L Clock Pulse Generator
4 *
5 * Copyright (C) 2021-2023 Renesas Electronics Corp.
6 *
7 * Based on renesas-cpg-mssr.c
8 *
9 * Copyright (C) 2015 Glider bvba
10 * Copyright (C) 2013 Ideas On Board SPRL
11 * Copyright (C) 2015 Renesas Electronics Corp.
12 */
13
Paul Barker132d7ea2023-10-16 10:25:29 +010014#include <asm/io.h>
15#include <clk-uclass.h>
16#include <dm.h>
17#include <dm/device-internal.h>
18#include <dm/device_compat.h>
19#include <dm/devres.h>
20#include <dm/lists.h>
21#include <dt-bindings/clock/renesas-cpg-mssr.h>
22#include <linux/clk-provider.h>
23#include <linux/iopoll.h>
24#include <reset-uclass.h>
25#include <reset.h>
Paul Barker2fcb4962024-02-27 20:40:28 +000026#include <wait_bit.h>
Paul Barker132d7ea2023-10-16 10:25:29 +010027
28#include "rzg2l-cpg.h"
29
Paul Barker2fcb4962024-02-27 20:40:28 +000030/*
31 * Monitor registers for both clock and reset signals are offset by 0x180 from
32 * the corresponding control registers.
33 */
Paul Barker132d7ea2023-10-16 10:25:29 +010034#define CLK_MON_R(reg) (0x180 + (reg))
Paul Barker2fcb4962024-02-27 20:40:28 +000035#define RST_MON_R(reg) (0x180 + (reg))
36
37#define CPG_TIMEOUT_MSEC 100
Paul Barker132d7ea2023-10-16 10:25:29 +010038
39static ulong rzg2l_cpg_clk_get_rate_by_id(struct udevice *dev, unsigned int id);
40static ulong rzg2l_cpg_clk_get_rate_by_name(struct udevice *dev, const char *name);
41
42struct rzg2l_cpg_data {
43 void __iomem *base;
44 struct rzg2l_cpg_info *info;
45};
46
47/*
48 * The top 16 bits of the clock ID are used to identify if it is a core clock or
49 * a module clock.
50 */
51#define CPG_CLK_TYPE_SHIFT 16
52#define CPG_CLK_ID_MASK 0xffff
53#define CPG_CLK_ID(x) ((x) & CPG_CLK_ID_MASK)
54#define CPG_CLK_PACK(type, id) (((type) << CPG_CLK_TYPE_SHIFT) | CPG_CLK_ID(id))
55
56static inline bool is_mod_clk(unsigned int id)
57{
58 return (id >> CPG_CLK_TYPE_SHIFT) == CPG_MOD;
59}
60
61static int rzg2l_cpg_clk_set(struct clk *clk, bool enable)
62{
63 struct rzg2l_cpg_data *data =
64 (struct rzg2l_cpg_data *)dev_get_driver_data(clk->dev);
65 const unsigned int cpg_clk_id = CPG_CLK_ID(clk->id);
66 const struct rzg2l_mod_clk *mod_clk = NULL;
67 u32 value;
68 unsigned int i;
69
70 dev_dbg(clk->dev, "%s %s clock %u\n", enable ? "enable" : "disable",
71 is_mod_clk(clk->id) ? "module" : "core", cpg_clk_id);
72 if (!is_mod_clk(clk->id)) {
73 dev_err(clk->dev, "ID %lu is not a module clock\n", clk->id);
74 return -EINVAL;
75 }
76
77 for (i = 0; i < data->info->num_mod_clks; i++) {
78 if (data->info->mod_clks[i].id == cpg_clk_id) {
79 mod_clk = &data->info->mod_clks[i];
80 break;
81 }
82 }
83
84 if (!mod_clk) {
85 dev_err(clk->dev, "Module clock %u not found\n", cpg_clk_id);
86 return -ENODEV;
87 }
88
89 value = BIT(mod_clk->bit) << 16;
90 if (enable)
91 value |= BIT(mod_clk->bit);
92 writel(value, data->base + mod_clk->off);
93
Paul Barker2fcb4962024-02-27 20:40:28 +000094 if (enable && wait_for_bit_32(data->base + CLK_MON_R(mod_clk->off),
95 BIT(mod_clk->bit), enable,
96 CPG_TIMEOUT_MSEC, false)) {
Paul Barker132d7ea2023-10-16 10:25:29 +010097 dev_err(clk->dev, "Timeout\n");
98 return -ETIMEDOUT;
99 }
100
101 return 0;
102}
103
104static int rzg2l_cpg_clk_enable(struct clk *clk)
105{
106 return rzg2l_cpg_clk_set(clk, true);
107}
108
109static int rzg2l_cpg_clk_disable(struct clk *clk)
110{
111 return rzg2l_cpg_clk_set(clk, false);
112}
113
114static int rzg2l_cpg_clk_of_xlate(struct clk *clk,
115 struct ofnode_phandle_args *args)
116{
117 struct rzg2l_cpg_data *data =
118 (struct rzg2l_cpg_data *)dev_get_driver_data(clk->dev);
119 u32 cpg_clk_type, cpg_clk_id;
120 bool found = false;
121 unsigned int i;
122
123 if (args->args_count != 2) {
124 dev_dbg(clk->dev, "Invalid args_count: %d\n", args->args_count);
125 return -EINVAL;
126 }
127
128 cpg_clk_type = args->args[0];
129 cpg_clk_id = args->args[1];
130
131 switch (cpg_clk_type) {
132 case CPG_CORE:
133 for (i = 0; i < data->info->num_core_clks; i++) {
134 if (data->info->core_clks[i].id == cpg_clk_id) {
135 found = true;
136 break;
137 }
138 }
139 if (!found) {
140 dev_dbg(clk->dev,
141 "Invalid second argument %u: Must be a valid core clock ID\n",
142 cpg_clk_id);
143 return -EINVAL;
144 }
145 break;
146 case CPG_MOD:
147 for (i = 0; i < data->info->num_mod_clks; i++) {
148 if (data->info->mod_clks[i].id == cpg_clk_id) {
149 found = true;
150 break;
151 }
152 }
153 if (!found) {
154 dev_dbg(clk->dev,
155 "Invalid second argument %u: Must be a valid module clock ID\n",
156 cpg_clk_id);
157 return -EINVAL;
158 }
159 break;
160 default:
161 dev_dbg(clk->dev,
162 "Invalid first argument %u: Must be CPG_CORE or CPG_MOD\n",
163 cpg_clk_type);
164 return -EINVAL;
165 }
166
167 clk->id = CPG_CLK_PACK(cpg_clk_type, cpg_clk_id);
168
169 return 0;
170}
171
172static ulong rzg2l_sdhi_clk_get_rate(struct udevice *dev, const struct cpg_core_clk *cc)
173{
174 struct rzg2l_cpg_data *data =
175 (struct rzg2l_cpg_data *)dev_get_driver_data(dev);
176 const ulong offset = CPG_CONF_OFFSET(cc->conf);
177 const int shift = CPG_CONF_BITPOS(cc->conf);
178 const u32 mask = CPG_CONF_BITMASK(cc->conf);
179 unsigned int sel;
180
181 sel = (readl(data->base + offset) >> shift) & mask;
182
183 if (!sel || sel > cc->num_parents) {
184 dev_err(dev, "Invalid SEL_SDHI%d_SET value %u\n", shift / 4, sel);
185 return -EIO;
186 }
187 return rzg2l_cpg_clk_get_rate_by_name(dev, cc->parent_names[sel - 1]);
188}
189
190static ulong rzg2l_div_clk_get_rate(struct udevice *dev, const struct cpg_core_clk *cc)
191{
192 struct rzg2l_cpg_data *data =
193 (struct rzg2l_cpg_data *)dev_get_driver_data(dev);
194 const ulong offset = CPG_CONF_OFFSET(cc->conf);
195 const int shift = CPG_CONF_BITPOS(cc->conf);
196 const u32 mask = CPG_CONF_BITMASK(cc->conf);
197 unsigned int sel, i;
198
199 sel = (readl(data->base + offset) >> shift) & mask;
200
201 for (i = 0; cc->dtable[i].div; i++) {
202 if (cc->dtable[i].val == sel)
203 return rzg2l_cpg_clk_get_rate_by_id(dev, cc->parent) / cc->dtable[i].div;
204 }
205 dev_err(dev, "Invalid selector value %u for clock %s\n", sel, cc->name);
206 return -EINVAL;
207}
208
209static ulong rzg2l_core_clk_get_rate(struct udevice *dev, const struct cpg_core_clk *cc)
210{
211 switch (cc->type) {
212 case CLK_TYPE_FF:
213 const ulong parent_rate = rzg2l_cpg_clk_get_rate_by_id(dev, cc->parent);
214 return parent_rate * cc->mult / cc->div;
215 case CLK_TYPE_IN:
216 struct clk clk_in;
217 clk_get_by_name(dev, cc->name, &clk_in);
218 return clk_get_rate(&clk_in);
219 case CLK_TYPE_SD_MUX:
220 return rzg2l_sdhi_clk_get_rate(dev, cc);
221 case CLK_TYPE_DIV:
222 return rzg2l_div_clk_get_rate(dev, cc);
223 default:
224 dev_err(dev, "get_rate needed for clock %u, type %d\n", cc->id, cc->type);
225 return -ENOSYS;
226 }
227}
228
229static ulong rzg2l_cpg_clk_get_rate_by_id(struct udevice *dev, unsigned int id)
230{
231 struct rzg2l_cpg_data *data =
232 (struct rzg2l_cpg_data *)dev_get_driver_data(dev);
233 const unsigned int cpg_clk_id = CPG_CLK_ID(id);
234 unsigned int i;
235
236 if (is_mod_clk(id)) {
237 for (i = 0; i < data->info->num_mod_clks; i++) {
238 if (data->info->mod_clks[i].id == cpg_clk_id)
239 return rzg2l_cpg_clk_get_rate_by_id(dev,
240 data->info->mod_clks[i].parent);
241 }
242
243 dev_err(dev, "Module clock ID %u not found\n", cpg_clk_id);
244 return -ENODEV;
245 }
246
247 for (i = 0; i < data->info->num_core_clks; i++) {
248 if (data->info->core_clks[i].id == cpg_clk_id)
249 return rzg2l_core_clk_get_rate(dev, &data->info->core_clks[i]);
250 }
251
252 dev_err(dev, "Core clock ID %u not found\n", cpg_clk_id);
253 return -ENODEV;
254}
255
256static ulong rzg2l_cpg_clk_get_rate_by_name(struct udevice *dev, const char *name)
257{
258 struct rzg2l_cpg_data *data =
259 (struct rzg2l_cpg_data *)dev_get_driver_data(dev);
260 unsigned int i;
261
262 for (i = 0; i < data->info->num_mod_clks; i++) {
263 if (!strcmp(name, data->info->mod_clks[i].name))
264 return rzg2l_cpg_clk_get_rate_by_id(dev, data->info->mod_clks[i].parent);
265 }
266 for (i = 0; i < data->info->num_core_clks; i++) {
267 if (!strcmp(name, data->info->core_clks[i].name))
268 return rzg2l_core_clk_get_rate(dev, &data->info->core_clks[i]);
269 }
270
271 dev_err(dev, "Clock name %s not found\n", name);
272 return -EINVAL;
273}
274
275static ulong rzg2l_cpg_clk_get_rate(struct clk *clk)
276{
277 return rzg2l_cpg_clk_get_rate_by_id(clk->dev, clk->id);
278}
279
280static ulong rzg2l_sdhi_clk_set_rate(struct udevice *dev, const struct cpg_core_clk *cc, ulong rate)
281{
282 struct rzg2l_cpg_data *data =
283 (struct rzg2l_cpg_data *)dev_get_driver_data(dev);
284 const ulong offset = CPG_CONF_OFFSET(cc->conf);
285 const int shift = CPG_CONF_BITPOS(cc->conf);
286 int channel, new_sel, prev_sel;
287 ulong target_rate;
288 unsigned int i;
289 u32 value;
290
291 prev_sel = (readl(data->base + offset) >> shift) & 0x3;
292 channel = shift / 4;
293
294 /*
295 * Round the requested rate down, unless it is below the minimum
296 * supported rate. Assume that the parent clock names are listed in
297 * order of descending rate.
298 */
299 for (i = 0; i < cc->num_parents; i++) {
300 target_rate = rzg2l_cpg_clk_get_rate_by_name(dev, cc->parent_names[i]);
301 if (rate >= target_rate) {
302 new_sel = i + 1;
303 break;
304 }
305 }
306 if (!new_sel)
307 new_sel = cc->num_parents - 1;
308
309 if (new_sel == prev_sel)
310 return target_rate;
311 dev_dbg(dev, "sdhi set_rate rate=%lu target_rate=%lu sel=%d\n",
312 rate, target_rate, new_sel);
313
314 /*
315 * As per the HW manual, we should not directly switch from 533 MHz to
Michal Simekcc046dc2024-04-16 08:55:19 +0200316 * 400 MHz and vice versa. To change the setting from 2'b01 (533 MHz)
317 * to 2'b10 (400 MHz) or vice versa, Switch to 2'b11 (266 MHz) first,
318 * and then switch to the target setting (2'b01 (533 MHz) or 2'b10
Paul Barker132d7ea2023-10-16 10:25:29 +0100319 * (400 MHz)).
320 */
321 if (new_sel != SEL_SDHI_266MHz && prev_sel != SEL_SDHI_266MHz) {
322 u32 waitbit;
323 int ret;
324
325 dev_dbg(dev, "sdhi set_rate via 266MHz\n");
326 value = (SEL_SDHI_WRITE_ENABLE | SEL_SDHI_266MHz) << shift;
327 writel(value, data->base + offset);
328
329 /* Wait for the switch to complete. */
330 waitbit = channel ? CPG_CLKSTATUS_SELSDHI1_STS : CPG_CLKSTATUS_SELSDHI0_STS;
331 ret = readl_poll_timeout(data->base + CPG_CLKSTATUS, value,
332 !(value & waitbit),
333 CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US);
334 if (ret) {
335 dev_err(dev, "Failed to switch SDHI%d clock source\n", channel);
336 return -EIO;
337 }
338 }
339
340 value = (SEL_SDHI_WRITE_ENABLE | new_sel) << shift;
341 writel(value, data->base + offset);
342
343 return target_rate;
344}
345
346static ulong rzg2l_core_clk_set_rate(struct udevice *dev, const struct cpg_core_clk *cc, ulong rate)
347{
348 if (cc->type == CLK_TYPE_SD_MUX)
349 return rzg2l_sdhi_clk_set_rate(dev, cc, rate);
350
351 /*
352 * The sdhi driver calls clk_set_rate for SD0_DIV4 and SD1_DIV4, even
353 * though they're in a fixed relationship with SD0 and SD1 respectively.
354 * To allow the driver to proceed, simply return the current rates
355 * without making any change.
356 */
357 if (cc->id == CLK_SD0_DIV4 || cc->id == CLK_SD1_DIV4)
358 return rzg2l_core_clk_get_rate(dev, cc);
359
360 dev_err(dev, "set_rate needed for clock %u, type %d\n", cc->id, cc->type);
361 return -ENOSYS;
362}
363
364static ulong rzg2l_cpg_clk_set_rate_by_id(struct udevice *dev, unsigned int id, ulong rate)
365{
366 struct rzg2l_cpg_data *data =
367 (struct rzg2l_cpg_data *)dev_get_driver_data(dev);
368 const unsigned int cpg_clk_id = CPG_CLK_ID(id);
369 unsigned int i;
370
371 if (is_mod_clk(id)) {
372 for (i = 0; i < data->info->num_mod_clks; i++) {
373 if (data->info->mod_clks[i].id == cpg_clk_id)
374 return rzg2l_cpg_clk_set_rate_by_id(dev,
375 data->info->mod_clks[i].parent,
376 rate);
377 }
378
379 dev_err(dev, "Module clock ID %u not found\n", cpg_clk_id);
380 return -ENODEV;
381 }
382
383 for (i = 0; i < data->info->num_core_clks; i++) {
384 if (data->info->core_clks[i].id == cpg_clk_id)
385 return rzg2l_core_clk_set_rate(dev, &data->info->core_clks[i], rate);
386 }
387
388 dev_err(dev, "Core clock ID %u not found\n", cpg_clk_id);
389 return -ENODEV;
390}
391
392static ulong rzg2l_cpg_clk_set_rate(struct clk *clk, ulong rate)
393{
394 return rzg2l_cpg_clk_set_rate_by_id(clk->dev, clk->id, rate);
395}
396
397static const struct clk_ops rzg2l_cpg_clk_ops = {
398 .enable = rzg2l_cpg_clk_enable,
399 .disable = rzg2l_cpg_clk_disable,
400 .of_xlate = rzg2l_cpg_clk_of_xlate,
401 .get_rate = rzg2l_cpg_clk_get_rate,
402 .set_rate = rzg2l_cpg_clk_set_rate,
403};
404
405U_BOOT_DRIVER(rzg2l_cpg_clk) = {
406 .name = "rzg2l-cpg-clk",
407 .id = UCLASS_CLK,
408 .ops = &rzg2l_cpg_clk_ops,
409 .flags = DM_FLAG_VITAL,
410};
411
412static int rzg2l_cpg_rst_set(struct reset_ctl *reset_ctl, bool asserted)
413{
414 struct rzg2l_cpg_data *data =
415 (struct rzg2l_cpg_data *)dev_get_driver_data(reset_ctl->dev);
416 const struct rzg2l_reset *rst;
417 u32 value;
418
419 dev_dbg(reset_ctl->dev, "%s %lu\n", asserted ? "assert" : "deassert", reset_ctl->id);
420 if (reset_ctl->id >= data->info->num_resets) {
421 dev_err(reset_ctl->dev, "Invalid reset id %lu\n", reset_ctl->id);
422 return -EINVAL;
423 }
424 rst = &data->info->resets[reset_ctl->id];
425
426 value = BIT(rst->bit) << 16;
427 if (!asserted)
428 value |= BIT(rst->bit);
429 writel(value, data->base + rst->off);
430
Paul Barker2fcb4962024-02-27 20:40:28 +0000431 return wait_for_bit_32(data->base + RST_MON_R(rst->off), BIT(rst->bit),
432 asserted, CPG_TIMEOUT_MSEC, false);
Paul Barker132d7ea2023-10-16 10:25:29 +0100433}
434
435static int rzg2l_cpg_rst_assert(struct reset_ctl *reset_ctl)
436{
437 return rzg2l_cpg_rst_set(reset_ctl, true);
438}
439
440static int rzg2l_cpg_rst_deassert(struct reset_ctl *reset_ctl)
441{
442 return rzg2l_cpg_rst_set(reset_ctl, false);
443}
444
445static int rzg2l_cpg_rst_of_xlate(struct reset_ctl *reset_ctl,
446 struct ofnode_phandle_args *args)
447{
448 struct rzg2l_cpg_data *data =
449 (struct rzg2l_cpg_data *)dev_get_driver_data(reset_ctl->dev);
450
451 if (args->args[0] >= data->info->num_resets)
452 return -EINVAL;
453
454 reset_ctl->id = args->args[0];
455 return 0;
456}
457
458static const struct reset_ops rzg2l_cpg_rst_ops = {
459 .rst_assert = rzg2l_cpg_rst_assert,
460 .rst_deassert = rzg2l_cpg_rst_deassert,
461 .of_xlate = rzg2l_cpg_rst_of_xlate,
462};
463
464U_BOOT_DRIVER(rzg2l_cpg_rst) = {
465 .name = "rzg2l-cpg-rst",
466 .id = UCLASS_RESET,
467 .ops = &rzg2l_cpg_rst_ops,
468 .flags = DM_FLAG_VITAL,
469};
470
471int rzg2l_cpg_bind(struct udevice *parent)
472{
473 struct udevice *cdev, *rdev;
474 struct rzg2l_cpg_data *data;
475 struct driver *drv;
476 int ret;
477
478 data = devm_kmalloc(parent, sizeof(*data), 0);
479 if (!data)
480 return -ENOMEM;
481
482 data->base = dev_read_addr_ptr(parent);
483 if (!data->base)
484 return -EINVAL;
485
486 data->info = (struct rzg2l_cpg_info *)dev_get_driver_data(parent);
487 if (!data->info)
488 return -EINVAL;
489
490 drv = lists_driver_lookup_name("rzg2l-cpg-clk");
491 if (!drv)
492 return -ENOENT;
493
494 ret = device_bind_with_driver_data(parent, drv, parent->name,
495 (ulong)data, dev_ofnode(parent),
496 &cdev);
497 if (ret)
498 return ret;
499
500 drv = lists_driver_lookup_name("rzg2l-cpg-rst");
501 if (!drv) {
502 device_unbind(cdev);
503 return -ENOENT;
504 }
505
506 ret = device_bind_with_driver_data(parent, drv, parent->name,
507 (ulong)data, dev_ofnode(parent),
508 &rdev);
509 if (ret)
510 device_unbind(cdev);
511
512 return ret;
513}