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