1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Renesas RCar Gen3 CPG MSSR driver
4 *
5 * Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com>
6 *
7 * Based on the following driver from Linux kernel:
8 * r8a7796 Clock Pulse Generator / Module Standby and Software Reset
9 *
10 * Copyright (C) 2016 Glider bvba
11 */
12
13#include <clk-uclass.h>
14#include <dm.h>
15#include <dm/device-internal.h>
16#include <dm/lists.h>
17#include <errno.h>
18#include <log.h>
19#include <wait_bit.h>
20#include <asm/global_data.h>
21#include <asm/io.h>
22#include <linux/bitfield.h>
23#include <linux/bitops.h>
24#include <linux/clk-provider.h>
25#include <reset-uclass.h>
26
27#include <dt-bindings/clock/renesas-cpg-mssr.h>
28
29#include "renesas-cpg-mssr.h"
30#include "rcar-gen3-cpg.h"
31#include "rcar-cpg-lib.h"
32
33#define CPG_PLL0CR		0x00d8
34#define CPG_PLL2CR		0x002c
35#define CPG_PLL4CR		0x01f4
36
37#define SD0CKCR1		0x08a4
38
39static const struct clk_div_table gen3_cpg_rpcsrc_div_table[] = {
40	{ 2, 5 }, { 3, 6 }, { 0, 0 },
41};
42
43static const struct clk_div_table gen4_cpg_rpcsrc_div_table[] = {
44	{ 0, 4 }, { 1, 6 }, { 2, 5 }, { 3, 6 }, { 0, 0 },
45};
46
47static const struct clk_div_table r8a77970_cpg_sd0h_div_table[] = {
48	{  0,  2 }, {  1,  3 }, {  2,  4 }, {  3,  6 },
49	{  4,  8 }, {  5, 12 }, {  6, 16 }, {  7, 18 },
50	{  8, 24 }, { 10, 36 }, { 11, 48 }, {  0,  0 },
51};
52
53static const struct clk_div_table r8a77970_cpg_sd0_div_table[] = {
54	{  4,  8 }, {  5, 12 }, {  6, 16 }, {  7, 18 },
55	{  8, 24 }, { 10, 36 }, { 11, 48 }, { 12, 10 },
56	{  0,  0 },
57};
58
59static int gen3_clk_get_parent(struct gen3_clk_priv *priv, struct clk *clk,
60			       struct cpg_mssr_info *info, struct clk *parent)
61{
62	const struct cpg_core_clk *core;
63	u8 shift;
64	int ret;
65
66	if (!renesas_clk_is_mod(clk)) {
67		ret = renesas_clk_get_core(clk, info, &core);
68		if (ret)
69			return ret;
70
71		if (core->type == CLK_TYPE_GEN3_MDSEL) {
72			shift = priv->cpg_mode & BIT(core->offset) ? 16 : 0;
73			parent->dev = clk->dev;
74			parent->id = core->parent >> shift;
75			parent->id &= 0xffff;
76			return 0;
77		}
78	}
79
80	return renesas_clk_get_parent(clk, info, parent);
81}
82
83static int gen3_clk_enable(struct clk *clk)
84{
85	struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
86
87	return renesas_clk_endisable(clk, priv->base, priv->info, true);
88}
89
90static int gen3_clk_disable(struct clk *clk)
91{
92	struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
93
94	return renesas_clk_endisable(clk, priv->base, priv->info, false);
95}
96
97static u64 gen3_clk_get_rate64(struct clk *clk);
98
99static int gen3_clk_setup_sdif_div(struct clk *clk, ulong rate)
100{
101	struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
102	struct cpg_mssr_info *info = priv->info;
103	const struct cpg_core_clk *core;
104	struct clk parent, grandparent;
105	int ret;
106
107	/*
108	 * The clk may be either CPG_MOD or core clock, in case this is MOD
109	 * clock, use core clock one level up, otherwise use the clock as-is.
110	 * Note that parent clock here always represents core clock. Also note
111	 * that grandparent clock are the parent clock of the core clock here.
112	 */
113	if (renesas_clk_is_mod(clk)) {
114		ret = gen3_clk_get_parent(priv, clk, info, &parent);
115		if (ret) {
116			printf("%s[%i] parent fail, ret=%i\n", __func__, __LINE__, ret);
117			return ret;
118		}
119	} else {
120		parent = *clk;
121	}
122
123	if (renesas_clk_is_mod(&parent))
124		return 0;
125
126	ret = renesas_clk_get_core(&parent, info, &core);
127	if (ret)
128		return ret;
129
130	ret = renesas_clk_get_parent(&parent, info, &grandparent);
131	if (ret) {
132		printf("%s[%i] grandparent fail, ret=%i\n", __func__, __LINE__, ret);
133		return ret;
134	}
135
136	switch (core->type) {
137	case CLK_TYPE_GEN3_SDH:
138		fallthrough;
139	case CLK_TYPE_GEN4_SDH:
140		return rcar_clk_set_rate64_sdh(core->parent,
141					       gen3_clk_get_rate64(&grandparent),
142					       rate, priv->base + core->offset);
143
144	case CLK_TYPE_GEN3_SD:
145		fallthrough;
146	case CLK_TYPE_GEN4_SD:
147		return rcar_clk_set_rate64_sd(core->parent,
148					      gen3_clk_get_rate64(&grandparent),
149					      rate, priv->base + core->offset);
150
151	case CLK_TYPE_R8A77970_SD0:
152		return rcar_clk_set_rate64_div_table(core->parent,
153						     gen3_clk_get_rate64(&grandparent),
154						     rate, priv->base + core->offset,
155						     CPG_SDCKCR_SD0FC_MASK,
156						     r8a77970_cpg_sd0_div_table, "SD");
157	}
158
159	return 0;
160}
161
162static u64 gen3_clk_get_rate64_pll_mul_reg(struct gen3_clk_priv *priv,
163					   struct clk *parent,
164					   u32 mul_reg, u32 mult, u32 div,
165					   char *name)
166{
167	u32 value;
168	u64 rate;
169
170	if (mul_reg) {
171		value = readl(priv->base + mul_reg);
172		mult = (((value >> 24) & 0x7f) + 1) * 2;
173		div = 1;
174	}
175
176	rate = (gen3_clk_get_rate64(parent) * mult) / div;
177
178	debug("%s[%i] %s clk: mult=%u div=%u => rate=%llu\n",
179	      __func__, __LINE__, name, mult, div, rate);
180	return rate;
181}
182
183static u64 gen3_clk_get_rate64(struct clk *clk)
184{
185	struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
186	struct cpg_mssr_info *info = priv->info;
187	struct clk parent;
188	const struct cpg_core_clk *core;
189	const struct rcar_gen3_cpg_pll_config *gen3_pll_config =
190					priv->gen3_cpg_pll_config;
191	const struct rcar_gen4_cpg_pll_config *gen4_pll_config =
192					priv->gen4_cpg_pll_config;
193	u32 value, div;
194	u64 rate = 0;
195	u8 shift;
196	int ret;
197
198	debug("%s[%i] Clock: id=%lu\n", __func__, __LINE__, clk->id);
199
200	ret = gen3_clk_get_parent(priv, clk, info, &parent);
201	if (ret) {
202		printf("%s[%i] parent fail, ret=%i\n", __func__, __LINE__, ret);
203		return ret;
204	}
205
206	if (renesas_clk_is_mod(clk)) {
207		rate = gen3_clk_get_rate64(&parent);
208		debug("%s[%i] MOD clk: parent=%lu => rate=%llu\n",
209		      __func__, __LINE__, parent.id, rate);
210		return rate;
211	}
212
213	ret = renesas_clk_get_core(clk, info, &core);
214	if (ret)
215		return ret;
216
217	switch (core->type) {
218	case CLK_TYPE_IN:
219		if (core->id == info->clk_extal_id) {
220			rate = clk_get_rate(&priv->clk_extal);
221			debug("%s[%i] EXTAL clk: rate=%llu\n",
222			      __func__, __LINE__, rate);
223			return rate;
224		}
225
226		if (core->id == info->clk_extalr_id) {
227			rate = clk_get_rate(&priv->clk_extalr);
228			debug("%s[%i] EXTALR clk: rate=%llu\n",
229			      __func__, __LINE__, rate);
230			return rate;
231		}
232
233		return -EINVAL;
234
235	case CLK_TYPE_GEN3_MAIN:
236		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
237						0, 1, gen3_pll_config->extal_div,
238						"MAIN");
239
240	case CLK_TYPE_GEN3_PLL0:
241		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
242						CPG_PLL0CR, 0, 0, "PLL0");
243
244	case CLK_TYPE_GEN3_PLL1:
245		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
246						0, gen3_pll_config->pll1_mult,
247						gen3_pll_config->pll1_div,
248						"PLL1");
249
250	case CLK_TYPE_GEN3_PLL2:
251		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
252						CPG_PLL2CR, 0, 0, "PLL2");
253
254	case CLK_TYPE_GEN3_PLL3:
255		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
256						0, gen3_pll_config->pll3_mult,
257						gen3_pll_config->pll3_div,
258						"PLL3");
259
260	case CLK_TYPE_GEN3_PLL4:
261		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
262						CPG_PLL4CR, 0, 0, "PLL4");
263
264	case CLK_TYPE_GEN4_MAIN:
265		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
266						0, 1, gen4_pll_config->extal_div,
267						"MAIN");
268
269	case CLK_TYPE_GEN4_PLL1:
270		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
271						0, gen4_pll_config->pll1_mult,
272						gen4_pll_config->pll1_div,
273						"PLL1");
274
275	case CLK_TYPE_GEN4_PLL2:
276		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
277						0, gen4_pll_config->pll2_mult,
278						gen4_pll_config->pll2_div,
279						"PLL2");
280
281	case CLK_TYPE_GEN4_PLL2X_3X:
282		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
283						core->offset, 0, 0, "PLL2X_3X");
284
285	case CLK_TYPE_GEN4_PLL3:
286		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
287						0, gen4_pll_config->pll3_mult,
288						gen4_pll_config->pll3_div,
289						"PLL3");
290
291	case CLK_TYPE_GEN4_PLL4:
292		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
293						0, gen4_pll_config->pll4_mult,
294						gen4_pll_config->pll4_div,
295						"PLL4");
296
297	case CLK_TYPE_GEN4_PLL5:
298		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
299						0, gen4_pll_config->pll5_mult,
300						gen4_pll_config->pll5_div,
301						"PLL5");
302
303	case CLK_TYPE_GEN4_PLL6:
304		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
305						0, gen4_pll_config->pll6_mult,
306						gen4_pll_config->pll6_div,
307						"PLL6");
308
309	case CLK_TYPE_GEN4_PLL7:
310		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
311						0, gen4_pll_config->pll7_mult,
312						gen4_pll_config->pll7_div,
313						"PLL7");
314
315	case CLK_TYPE_FF:
316		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
317						0, core->mult, core->div,
318						"FIXED");
319
320	case CLK_TYPE_GEN3_MDSEL:
321		shift = priv->cpg_mode & BIT(core->offset) ? 16 : 0;
322		div = (core->div >> shift) & 0xffff;
323		rate = gen3_clk_get_rate64(&parent) / div;
324		debug("%s[%i] PE clk: parent=%i div=%u => rate=%llu\n",
325		      __func__, __LINE__, (core->parent >> shift) & 0xffff,
326		      div, rate);
327		return rate;
328
329	case CLK_TYPE_GEN4_SDSRC:
330		div = ((readl(priv->base + SD0CKCR1) >> 29) & 0x03) + 4;
331		rate = gen3_clk_get_rate64(&parent) / div;
332		debug("%s[%i] SDSRC clk: parent=%i div=%u => rate=%llu\n",
333		      __func__, __LINE__, core->parent, div, rate);
334		return rate;
335
336	case CLK_TYPE_GEN3_SDH:	/* Fixed factor 1:1 */
337		fallthrough;
338	case CLK_TYPE_GEN4_SDH:	/* Fixed factor 1:1 */
339		return rcar_clk_get_rate64_sdh(core->parent,
340					       gen3_clk_get_rate64(&parent),
341					       priv->base + core->offset);
342
343	case CLK_TYPE_R8A77970_SD0H:
344		return rcar_clk_get_rate64_div_table(core->parent,
345						     gen3_clk_get_rate64(&parent),
346						     priv->base + core->offset,
347						     CPG_SDCKCR_SDHFC_MASK,
348						     r8a77970_cpg_sd0h_div_table, "SDH");
349
350	case CLK_TYPE_GEN3_SD:
351		fallthrough;
352	case CLK_TYPE_GEN4_SD:
353		return rcar_clk_get_rate64_sd(core->parent,
354					      gen3_clk_get_rate64(&parent),
355					      priv->base + core->offset);
356
357	case CLK_TYPE_R8A77970_SD0:
358		return rcar_clk_get_rate64_div_table(core->parent,
359						     gen3_clk_get_rate64(&parent),
360						     priv->base + core->offset,
361						     CPG_SDCKCR_SD0FC_MASK,
362						     r8a77970_cpg_sd0_div_table, "SD");
363
364	case CLK_TYPE_GEN3_RPCSRC:
365		return rcar_clk_get_rate64_div_table(core->parent,
366						     gen3_clk_get_rate64(&parent),
367						     priv->base + CPG_RPCCKCR,
368						     CPG_RPCCKCR_DIV_POST_MASK,
369						     gen3_cpg_rpcsrc_div_table,
370						     "RPCSRC");
371
372	case CLK_TYPE_GEN4_RPCSRC:
373		return rcar_clk_get_rate64_div_table(core->parent,
374						     gen3_clk_get_rate64(&parent),
375						     priv->base + CPG_RPCCKCR,
376						     CPG_RPCCKCR_DIV_POST_MASK,
377						     gen4_cpg_rpcsrc_div_table,
378						     "RPCSRC");
379
380	case CLK_TYPE_GEN3_D3_RPCSRC:
381	case CLK_TYPE_GEN3_E3_RPCSRC:
382		/*
383		 * Register RPCSRC as fixed factor clock based on the
384		 * MD[4:1] pins and CPG_RPCCKCR[4:3] register value for
385		 * which has been set prior to booting the kernel.
386		 */
387		value = (readl(priv->base + CPG_RPCCKCR) & GENMASK(4, 3)) >> 3;
388
389		switch (value) {
390		case 0:
391			div = 5;
392			break;
393		case 1:
394			div = 3;
395			break;
396		case 2:
397			div = core->div;
398			break;
399		case 3:
400		default:
401			div = 2;
402			break;
403		}
404
405		rate = gen3_clk_get_rate64(&parent) / div;
406		debug("%s[%i] E3/D3 RPCSRC clk: parent=%i div=%u => rate=%llu\n",
407		      __func__, __LINE__, (core->parent >> 16) & 0xffff, div, rate);
408
409		return rate;
410
411	case CLK_TYPE_GEN3_RPC:
412	case CLK_TYPE_GEN4_RPC:
413		return rcar_clk_get_rate64_rpc(core->parent,
414					       gen3_clk_get_rate64(&parent),
415					       priv->base + CPG_RPCCKCR);
416
417	case CLK_TYPE_GEN3_RPCD2:
418	case CLK_TYPE_GEN4_RPCD2:
419		return rcar_clk_get_rate64_rpcd2(core->parent,
420						 gen3_clk_get_rate64(&parent));
421
422	}
423
424	printf("%s[%i] unknown fail\n", __func__, __LINE__);
425
426	return -ENOENT;
427}
428
429static ulong gen3_clk_get_rate(struct clk *clk)
430{
431	return gen3_clk_get_rate64(clk);
432}
433
434static ulong gen3_clk_set_rate(struct clk *clk, ulong rate)
435{
436	/* Force correct SD-IF divider configuration if applicable */
437	gen3_clk_setup_sdif_div(clk, rate);
438	return gen3_clk_get_rate64(clk);
439}
440
441static int gen3_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
442{
443	if (args->args_count != 2) {
444		debug("Invalid args_count: %d\n", args->args_count);
445		return -EINVAL;
446	}
447
448	clk->id = (args->args[0] << 16) | args->args[1];
449
450	return 0;
451}
452
453const struct clk_ops gen3_clk_ops = {
454	.enable		= gen3_clk_enable,
455	.disable	= gen3_clk_disable,
456	.get_rate	= gen3_clk_get_rate,
457	.set_rate	= gen3_clk_set_rate,
458	.of_xlate	= gen3_clk_of_xlate,
459};
460
461static int gen3_clk_probe(struct udevice *dev)
462{
463	struct gen3_clk_priv *priv = dev_get_priv(dev);
464	struct cpg_mssr_info *info =
465		(struct cpg_mssr_info *)dev_get_driver_data(dev);
466	const void *pll_config;
467	fdt_addr_t rst_base;
468	int ret;
469
470	priv->base = dev_read_addr_ptr(dev);
471	if (!priv->base)
472		return -EINVAL;
473
474	priv->info = info;
475	ret = fdt_node_offset_by_compatible(gd->fdt_blob, -1, info->reset_node);
476	if (ret < 0)
477		return ret;
478
479	rst_base = fdtdec_get_addr(gd->fdt_blob, ret, "reg");
480	if (rst_base == FDT_ADDR_T_NONE)
481		return -EINVAL;
482
483	priv->cpg_mode = readl(rst_base + info->reset_modemr_offset);
484
485	pll_config = info->get_pll_config(priv->cpg_mode);
486
487	if (info->reg_layout == CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3) {
488		priv->info->status_regs = mstpsr;
489		priv->info->control_regs = smstpcr;
490		priv->info->reset_regs = srcr;
491		priv->info->reset_clear_regs = srstclr;
492		priv->gen3_cpg_pll_config = pll_config;
493		if (!priv->gen3_cpg_pll_config->extal_div)
494			return -EINVAL;
495	} else if (info->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) {
496		priv->info->status_regs = mstpsr_for_gen4;
497		priv->info->control_regs = mstpcr_for_gen4;
498		priv->info->reset_regs = srcr_for_gen4;
499		priv->info->reset_clear_regs = srstclr_for_gen4;
500		priv->gen4_cpg_pll_config = pll_config;
501		if (!priv->gen4_cpg_pll_config->extal_div)
502			return -EINVAL;
503	} else {
504		return -EINVAL;
505	}
506
507	ret = clk_get_by_name(dev, "extal", &priv->clk_extal);
508	if (ret < 0)
509		return ret;
510
511	if (info->extalr_node) {
512		ret = clk_get_by_name(dev, info->extalr_node, &priv->clk_extalr);
513		if (ret < 0)
514			return ret;
515	}
516
517	return 0;
518}
519
520static int gen3_clk_remove(struct udevice *dev)
521{
522	struct gen3_clk_priv *priv = dev_get_priv(dev);
523
524	return renesas_clk_remove(priv->base, priv->info);
525}
526
527U_BOOT_DRIVER(clk_gen3) = {
528	.name		= "clk_gen3",
529	.id		= UCLASS_CLK,
530	.priv_auto	= sizeof(struct gen3_clk_priv),
531	.ops		= &gen3_clk_ops,
532	.probe		= gen3_clk_probe,
533	.remove		= gen3_clk_remove,
534	.flags          = DM_FLAG_OS_PREPARE | DM_FLAG_VITAL,
535};
536
537static int gen3_reset_assert(struct reset_ctl *reset_ctl)
538{
539	struct udevice *cdev = (struct udevice *)dev_get_driver_data(reset_ctl->dev);
540	struct gen3_clk_priv *priv = dev_get_priv(cdev);
541	unsigned int packed_id = MOD_CLK_PACK(reset_ctl->id);
542	unsigned int reg = packed_id / 32;
543	unsigned int bit = packed_id % 32;
544	u32 bitmask = BIT(bit);
545
546	writel(bitmask, priv->base + priv->info->reset_regs[reg]);
547
548	return 0;
549}
550
551static int gen3_reset_deassert(struct reset_ctl *reset_ctl)
552{
553	struct udevice *cdev = (struct udevice *)dev_get_driver_data(reset_ctl->dev);
554	struct gen3_clk_priv *priv = dev_get_priv(cdev);
555	unsigned int packed_id = MOD_CLK_PACK(reset_ctl->id);
556	unsigned int reg = packed_id / 32;
557	unsigned int bit = packed_id % 32;
558	u32 bitmask = BIT(bit);
559
560	writel(bitmask, priv->base + priv->info->reset_clear_regs[reg]);
561
562	return 0;
563}
564
565static const struct reset_ops rst_gen3_ops = {
566	.rst_assert = gen3_reset_assert,
567	.rst_deassert = gen3_reset_deassert,
568};
569
570U_BOOT_DRIVER(rst_gen3) = {
571	.name = "rst_gen3",
572	.id = UCLASS_RESET,
573	.ops = &rst_gen3_ops,
574	.flags = DM_FLAG_OS_PREPARE | DM_FLAG_VITAL,
575};
576
577int gen3_cpg_bind(struct udevice *parent)
578{
579	struct cpg_mssr_info *info =
580		(struct cpg_mssr_info *)dev_get_driver_data(parent);
581	struct udevice *cdev, *rdev;
582	struct driver *drv;
583	int ret;
584
585	drv = lists_driver_lookup_name("clk_gen3");
586	if (!drv)
587		return -ENOENT;
588
589	ret = device_bind_with_driver_data(parent, drv, "clk_gen3", (ulong)info,
590					   dev_ofnode(parent), &cdev);
591	if (ret)
592		return ret;
593
594	drv = lists_driver_lookup_name("rst_gen3");
595	if (!drv)
596		return -ENOENT;
597
598	ret = device_bind_with_driver_data(parent, drv, "rst_gen3", (ulong)cdev,
599					   dev_ofnode(parent), &rdev);
600	if (ret)
601		device_unbind(cdev);
602
603	return ret;
604}
605