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