1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * UTMI clock support for AT91 architectures.
4  *
5  * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
6  *
7  * Author: Claudiu Beznea <claudiu.beznea@microchip.com>
8  *
9  * Based on drivers/clk/at91/clk-utmi.c from Linux.
10  */
11 #include <asm/processor.h>
12 #include <common.h>
13 #include <clk-uclass.h>
14 #include <dm.h>
15 #include <linux/clk-provider.h>
16 #include <linux/clk/at91_pmc.h>
17 #include <mach/at91_sfr.h>
18 #include <regmap.h>
19 #include <syscon.h>
20 
21 #include "pmc.h"
22 
23 #define UBOOT_DM_CLK_AT91_UTMI			"at91-utmi-clk"
24 #define UBOOT_DM_CLK_AT91_SAMA7G5_UTMI		"at91-sama7g5-utmi-clk"
25 
26 /*
27  * The purpose of this clock is to generate a 480 MHz signal. A different
28  * rate can't be configured.
29  */
30 #define UTMI_RATE	480000000
31 
32 struct clk_utmi {
33 	void __iomem *base;
34 	struct regmap *regmap_sfr;
35 	struct clk clk;
36 };
37 
38 #define to_clk_utmi(_clk) container_of(_clk, struct clk_utmi, clk)
39 
clk_utmi_ready(struct regmap * regmap)40 static inline bool clk_utmi_ready(struct regmap *regmap)
41 {
42 	unsigned int status;
43 
44 	pmc_read(regmap, AT91_PMC_SR, &status);
45 
46 	return !!(status & AT91_PMC_LOCKU);
47 }
48 
clk_utmi_enable(struct clk * clk)49 static int clk_utmi_enable(struct clk *clk)
50 {
51 	struct clk_utmi *utmi = to_clk_utmi(clk);
52 	unsigned int uckr = AT91_PMC_UPLLEN | AT91_PMC_UPLLCOUNT |
53 			    AT91_PMC_BIASEN;
54 	unsigned int utmi_ref_clk_freq;
55 	ulong parent_rate = clk_get_parent_rate(clk);
56 
57 	/*
58 	 * If mainck rate is different from 12 MHz, we have to configure the
59 	 * FREQ field of the SFR_UTMICKTRIM register to generate properly
60 	 * the utmi clock.
61 	 */
62 	switch (parent_rate) {
63 	case 12000000:
64 		utmi_ref_clk_freq = 0;
65 		break;
66 	case 16000000:
67 		utmi_ref_clk_freq = 1;
68 		break;
69 	case 24000000:
70 		utmi_ref_clk_freq = 2;
71 		break;
72 	/*
73 	 * Not supported on SAMA5D2 but it's not an issue since MAINCK
74 	 * maximum value is 24 MHz.
75 	 */
76 	case 48000000:
77 		utmi_ref_clk_freq = 3;
78 		break;
79 	default:
80 		debug("UTMICK: unsupported mainck rate\n");
81 		return -EINVAL;
82 	}
83 
84 	if (utmi->regmap_sfr) {
85 		regmap_update_bits(utmi->regmap_sfr, AT91_SFR_UTMICKTRIM,
86 				   AT91_UTMICKTRIM_FREQ, utmi_ref_clk_freq);
87 	} else if (utmi_ref_clk_freq) {
88 		debug("UTMICK: sfr node required\n");
89 		return -EINVAL;
90 	}
91 
92 	pmc_update_bits(utmi->base, AT91_CKGR_UCKR, uckr, uckr);
93 
94 	while (!clk_utmi_ready(utmi->base)) {
95 		debug("waiting for utmi...\n");
96 		cpu_relax();
97 	}
98 
99 	return 0;
100 }
101 
clk_utmi_disable(struct clk * clk)102 static int clk_utmi_disable(struct clk *clk)
103 {
104 	struct clk_utmi *utmi = to_clk_utmi(clk);
105 
106 	pmc_update_bits(utmi->base, AT91_CKGR_UCKR, AT91_PMC_UPLLEN, 0);
107 
108 	return 0;
109 }
110 
clk_utmi_get_rate(struct clk * clk)111 static ulong clk_utmi_get_rate(struct clk *clk)
112 {
113 	/* UTMI clk rate is fixed. */
114 	return UTMI_RATE;
115 }
116 
117 static const struct clk_ops utmi_ops = {
118 	.enable = clk_utmi_enable,
119 	.disable = clk_utmi_disable,
120 	.get_rate = clk_utmi_get_rate,
121 };
122 
at91_clk_register_utmi(void __iomem * base,struct udevice * dev,const char * name,const char * parent_name)123 struct clk *at91_clk_register_utmi(void __iomem *base, struct udevice *dev,
124 				   const char *name, const char *parent_name)
125 {
126 	struct udevice *syscon;
127 	struct clk_utmi *utmi;
128 	struct clk *clk;
129 	int ret;
130 
131 	if (!base || !dev || !name || !parent_name)
132 		return ERR_PTR(-EINVAL);
133 
134 	ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
135 					   "regmap-sfr", &syscon);
136 	if (ret)
137 		return ERR_PTR(ret);
138 
139 	utmi = kzalloc(sizeof(*utmi), GFP_KERNEL);
140 	if (!utmi)
141 		return ERR_PTR(-ENOMEM);
142 
143 	utmi->base = base;
144 	utmi->regmap_sfr = syscon_get_regmap(syscon);
145 	if (!utmi->regmap_sfr) {
146 		kfree(utmi);
147 		return ERR_PTR(-ENODEV);
148 	}
149 
150 	clk = &utmi->clk;
151 	clk->flags = CLK_GET_RATE_NOCACHE;
152 	ret = clk_register(clk, UBOOT_DM_CLK_AT91_UTMI, name, parent_name);
153 	if (ret) {
154 		kfree(utmi);
155 		clk = ERR_PTR(ret);
156 	}
157 
158 	return clk;
159 }
160 
161 U_BOOT_DRIVER(at91_utmi_clk) = {
162 	.name = UBOOT_DM_CLK_AT91_UTMI,
163 	.id = UCLASS_CLK,
164 	.ops = &utmi_ops,
165 	.flags = DM_FLAG_PRE_RELOC,
166 };
167 
clk_utmi_sama7g5_enable(struct clk * clk)168 static int clk_utmi_sama7g5_enable(struct clk *clk)
169 {
170 	struct clk_utmi *utmi = to_clk_utmi(clk);
171 	ulong parent_rate = clk_get_parent_rate(clk);
172 	unsigned int val;
173 
174 	switch (parent_rate) {
175 	case 16000000:
176 		val = 0;
177 		break;
178 	case 20000000:
179 		val = 2;
180 		break;
181 	case 24000000:
182 		val = 3;
183 		break;
184 	case 32000000:
185 		val = 5;
186 		break;
187 	default:
188 		debug("UTMICK: unsupported main_xtal rate\n");
189 		return -EINVAL;
190 	}
191 
192 	pmc_write(utmi->base, AT91_PMC_XTALF, val);
193 
194 	return 0;
195 }
196 
197 static const struct clk_ops sama7g5_utmi_ops = {
198 	.enable = clk_utmi_sama7g5_enable,
199 	.get_rate = clk_utmi_get_rate,
200 };
201 
at91_clk_sama7g5_register_utmi(void __iomem * base,const char * name,const char * parent_name)202 struct clk *at91_clk_sama7g5_register_utmi(void __iomem *base,
203 		const char *name, const char *parent_name)
204 {
205 	struct clk_utmi *utmi;
206 	struct clk *clk;
207 	int ret;
208 
209 	if (!base || !name || !parent_name)
210 		return ERR_PTR(-EINVAL);
211 
212 	utmi = kzalloc(sizeof(*utmi), GFP_KERNEL);
213 	if (!utmi)
214 		return ERR_PTR(-ENOMEM);
215 
216 	utmi->base = base;
217 
218 	clk = &utmi->clk;
219 	ret = clk_register(clk, UBOOT_DM_CLK_AT91_SAMA7G5_UTMI, name,
220 			   parent_name);
221 	if (ret) {
222 		kfree(utmi);
223 		clk = ERR_PTR(ret);
224 	}
225 
226 	return clk;
227 }
228 
229 U_BOOT_DRIVER(at91_sama7g5_utmi_clk) = {
230 	.name = UBOOT_DM_CLK_AT91_SAMA7G5_UTMI,
231 	.id = UCLASS_CLK,
232 	.ops = &sama7g5_utmi_ops,
233 	.flags = DM_FLAG_PRE_RELOC,
234 };
235