1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Main 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-main.c from Linux.
10  */
11 
12 #include <asm/processor.h>
13 #include <common.h>
14 #include <clk-uclass.h>
15 #include <dm.h>
16 #include <linux/clk-provider.h>
17 #include <linux/clk/at91_pmc.h>
18 #include <linux/delay.h>
19 #include <linux/io.h>
20 #include "pmc.h"
21 
22 #define UBOOT_DM_CLK_AT91_MAIN_RC		"at91-main-rc-clk"
23 #define UBOOT_DM_CLK_AT91_MAIN_OSC		"at91-main-osc-clk"
24 #define UBOOT_DM_CLK_AT91_RM9200_MAIN		"at91-rm9200-main-clk"
25 #define UBOOT_DM_CLK_AT91_SAM9X5_MAIN		"at91-sam9x5-main-clk"
26 
27 #define MOR_KEY_MASK		GENMASK(23, 16)
28 #define USEC_PER_SEC		1000000UL
29 #define SLOW_CLOCK_FREQ		32768
30 
31 #define clk_main_parent_select(s)	(((s) & \
32 					(AT91_PMC_MOSCEN | \
33 					AT91_PMC_OSCBYPASS)) ? 1 : 0)
34 
35 struct clk_main_rc {
36 	void __iomem	*reg;
37 	struct clk	clk;
38 };
39 
40 #define to_clk_main_rc(_clk) container_of(_clk, struct clk_main_rc, clk)
41 
42 struct clk_main_osc {
43 	void __iomem	*reg;
44 	struct clk	clk;
45 };
46 
47 #define to_clk_main_osc(_clk) container_of(_clk, struct clk_main_osc, clk)
48 
49 struct clk_main {
50 	void __iomem		*reg;
51 	const unsigned int	*clk_mux_table;
52 	const char * const	*parent_names;
53 	unsigned int		num_parents;
54 	int			type;
55 	struct clk		clk;
56 };
57 
58 #define to_clk_main(_clk) container_of(_clk, struct clk_main, clk)
59 
main_rc_enable(struct clk * clk)60 static int main_rc_enable(struct clk *clk)
61 {
62 	struct clk_main_rc *main_rc = to_clk_main_rc(clk);
63 	void __iomem *reg = main_rc->reg;
64 	unsigned int val;
65 
66 	pmc_read(reg, AT91_CKGR_MOR, &val);
67 
68 	if (!(val & AT91_PMC_MOSCRCEN)) {
69 		pmc_update_bits(reg, AT91_CKGR_MOR,
70 				MOR_KEY_MASK | AT91_PMC_MOSCRCEN,
71 				AT91_PMC_KEY | AT91_PMC_MOSCRCEN);
72 	}
73 
74 	pmc_read(reg, AT91_PMC_SR, &val);
75 	while (!(val & AT91_PMC_MOSCRCS)) {
76 		pmc_read(reg, AT91_PMC_SR, &val);
77 		debug("waiting for main rc...\n");
78 		cpu_relax();
79 	}
80 
81 	return 0;
82 }
83 
main_rc_disable(struct clk * clk)84 static int main_rc_disable(struct clk *clk)
85 {
86 	struct clk_main_rc *main_rc = to_clk_main_rc(clk);
87 	struct reg *reg = main_rc->reg;
88 	unsigned int val;
89 
90 	pmc_read(reg, AT91_CKGR_MOR, &val);
91 
92 	if (!(val & AT91_PMC_MOSCRCEN))
93 		return 0;
94 
95 	pmc_update_bits(reg, AT91_CKGR_MOR, MOR_KEY_MASK | AT91_PMC_MOSCRCEN,
96 			AT91_PMC_KEY);
97 
98 	return 0;
99 }
100 
101 static const struct clk_ops main_rc_clk_ops = {
102 	.enable = main_rc_enable,
103 	.disable = main_rc_disable,
104 	.get_rate = clk_generic_get_rate,
105 };
106 
at91_clk_main_rc(void __iomem * reg,const char * name,const char * parent_name)107 struct clk *at91_clk_main_rc(void __iomem *reg, const char *name,
108 			     const char *parent_name)
109 {
110 	struct clk_main_rc *main_rc;
111 	struct clk *clk;
112 	int ret;
113 
114 	if (!reg || !name || !parent_name)
115 		return ERR_PTR(-EINVAL);
116 
117 	main_rc = kzalloc(sizeof(*main_rc), GFP_KERNEL);
118 	if (!main_rc)
119 		return ERR_PTR(-ENOMEM);
120 
121 	main_rc->reg = reg;
122 	clk = &main_rc->clk;
123 
124 	ret = clk_register(clk, UBOOT_DM_CLK_AT91_MAIN_RC, name,
125 			   parent_name);
126 	if (ret) {
127 		kfree(main_rc);
128 		clk = ERR_PTR(ret);
129 	}
130 
131 	return clk;
132 }
133 
134 U_BOOT_DRIVER(at91_main_rc_clk) = {
135 	.name = UBOOT_DM_CLK_AT91_MAIN_RC,
136 	.id = UCLASS_CLK,
137 	.ops = &main_rc_clk_ops,
138 	.flags = DM_FLAG_PRE_RELOC,
139 };
140 
clk_main_osc_enable(struct clk * clk)141 static int clk_main_osc_enable(struct clk *clk)
142 {
143 	struct clk_main_osc *main = to_clk_main_osc(clk);
144 	void __iomem *reg = main->reg;
145 	unsigned int val;
146 
147 	pmc_read(reg, AT91_CKGR_MOR, &val);
148 	val &= ~MOR_KEY_MASK;
149 
150 	if (val & AT91_PMC_OSCBYPASS)
151 		return 0;
152 
153 	if (!(val & AT91_PMC_MOSCEN)) {
154 		val |= AT91_PMC_MOSCEN | AT91_PMC_KEY;
155 		pmc_write(reg, AT91_CKGR_MOR, val);
156 	}
157 
158 	pmc_read(reg, AT91_PMC_SR, &val);
159 	while (!(val & AT91_PMC_MOSCS)) {
160 		pmc_read(reg, AT91_PMC_SR, &val);
161 		debug("waiting for main osc..\n");
162 		cpu_relax();
163 	}
164 
165 	return 0;
166 }
167 
clk_main_osc_disable(struct clk * clk)168 static int clk_main_osc_disable(struct clk *clk)
169 {
170 	struct clk_main_osc *main = to_clk_main_osc(clk);
171 	void __iomem *reg = main->reg;
172 	unsigned int val;
173 
174 	pmc_read(reg, AT91_CKGR_MOR, &val);
175 	if (val & AT91_PMC_OSCBYPASS)
176 		return 0;
177 
178 	if (!(val & AT91_PMC_MOSCEN))
179 		return 0;
180 
181 	val &= ~(AT91_PMC_KEY | AT91_PMC_MOSCEN);
182 	pmc_write(reg, AT91_CKGR_MOR, val | AT91_PMC_KEY);
183 
184 	return 0;
185 }
186 
187 static const struct clk_ops main_osc_clk_ops = {
188 	.enable = clk_main_osc_enable,
189 	.disable = clk_main_osc_disable,
190 	.get_rate = clk_generic_get_rate,
191 };
192 
at91_clk_main_osc(void __iomem * reg,const char * name,const char * parent_name,bool bypass)193 struct clk *at91_clk_main_osc(void __iomem *reg, const char *name,
194 			      const char *parent_name, bool bypass)
195 {
196 	struct clk_main_osc *main;
197 	struct clk *clk;
198 	int ret;
199 
200 	if (!reg || !name || !parent_name)
201 		return ERR_PTR(-EINVAL);
202 
203 	main = kzalloc(sizeof(*main), GFP_KERNEL);
204 	if (!main)
205 		return ERR_PTR(-ENOMEM);
206 
207 	main->reg = reg;
208 	clk = &main->clk;
209 
210 	if (bypass) {
211 		pmc_update_bits(reg, AT91_CKGR_MOR,
212 				MOR_KEY_MASK | AT91_PMC_OSCBYPASS,
213 				AT91_PMC_KEY | AT91_PMC_OSCBYPASS);
214 	}
215 
216 	ret = clk_register(clk, UBOOT_DM_CLK_AT91_MAIN_OSC, name, parent_name);
217 	if (ret) {
218 		kfree(main);
219 		clk = ERR_PTR(ret);
220 	}
221 
222 	return clk;
223 }
224 
225 U_BOOT_DRIVER(at91_main_osc_clk) = {
226 	.name = UBOOT_DM_CLK_AT91_MAIN_OSC,
227 	.id = UCLASS_CLK,
228 	.ops = &main_osc_clk_ops,
229 	.flags = DM_FLAG_PRE_RELOC,
230 };
231 
clk_main_probe_frequency(void __iomem * reg)232 static int clk_main_probe_frequency(void __iomem *reg)
233 {
234 	unsigned int cycles = 16;
235 	unsigned int cycle = DIV_ROUND_UP(USEC_PER_SEC, SLOW_CLOCK_FREQ);
236 	unsigned int mcfr;
237 
238 	while (cycles--) {
239 		pmc_read(reg, AT91_CKGR_MCFR, &mcfr);
240 		if (mcfr & AT91_PMC_MAINRDY)
241 			return 0;
242 		udelay(cycle);
243 	}
244 
245 	return -ETIMEDOUT;
246 }
247 
clk_rm9200_main_enable(struct clk * clk)248 static int clk_rm9200_main_enable(struct clk *clk)
249 {
250 	struct clk_main *main = to_clk_main(clk);
251 
252 	return clk_main_probe_frequency(main->reg);
253 }
254 
255 static const struct clk_ops rm9200_main_clk_ops = {
256 	.enable = clk_rm9200_main_enable,
257 };
258 
at91_clk_rm9200_main(void __iomem * reg,const char * name,const char * parent_name)259 struct clk *at91_clk_rm9200_main(void __iomem *reg, const char *name,
260 				 const char *parent_name)
261 {
262 	struct clk_main *main;
263 	struct clk *clk;
264 	int ret;
265 
266 	if (!reg || !name || !parent_name)
267 		return ERR_PTR(-EINVAL);
268 
269 	main = kzalloc(sizeof(*main), GFP_KERNEL);
270 	if (!main)
271 		return ERR_PTR(-ENOMEM);
272 
273 	main->reg = reg;
274 	clk = &main->clk;
275 
276 	ret = clk_register(clk, UBOOT_DM_CLK_AT91_RM9200_MAIN, name,
277 			   parent_name);
278 	if (ret) {
279 		kfree(main);
280 		clk = ERR_PTR(ret);
281 	}
282 
283 	return clk;
284 }
285 
286 U_BOOT_DRIVER(at91_rm9200_main_clk) = {
287 	.name = UBOOT_DM_CLK_AT91_RM9200_MAIN,
288 	.id = UCLASS_CLK,
289 	.ops = &rm9200_main_clk_ops,
290 	.flags = DM_FLAG_PRE_RELOC,
291 };
292 
clk_sam9x5_main_ready(void __iomem * reg)293 static inline bool clk_sam9x5_main_ready(void __iomem *reg)
294 {
295 	unsigned int val;
296 
297 	pmc_read(reg, AT91_PMC_SR, &val);
298 
299 	return !!(val & AT91_PMC_MOSCSELS);
300 }
301 
clk_sam9x5_main_enable(struct clk * clk)302 static int clk_sam9x5_main_enable(struct clk *clk)
303 {
304 	struct clk_main *main = to_clk_main(clk);
305 	void __iomem *reg = main->reg;
306 
307 	while (!clk_sam9x5_main_ready(reg)) {
308 		debug("waiting for main...");
309 		cpu_relax();
310 	}
311 
312 	return clk_main_probe_frequency(reg);
313 }
314 
clk_sam9x5_main_set_parent(struct clk * clk,struct clk * parent)315 static int clk_sam9x5_main_set_parent(struct clk *clk, struct clk *parent)
316 {
317 	struct clk_main *main = to_clk_main(clk);
318 	void __iomem *reg = main->reg;
319 	unsigned int tmp, index;
320 
321 	index = at91_clk_mux_val_to_index(main->clk_mux_table,
322 			main->num_parents, AT91_CLK_ID_TO_DID(parent->id));
323 	if (index < 0)
324 		return index;
325 
326 	pmc_read(reg, AT91_CKGR_MOR, &tmp);
327 	tmp &= ~MOR_KEY_MASK;
328 	tmp |= AT91_PMC_KEY;
329 
330 	if (index && !(tmp & AT91_PMC_MOSCSEL))
331 		pmc_write(reg, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL);
332 	else if (!index && (tmp & AT91_PMC_MOSCSEL))
333 		pmc_write(reg, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL);
334 
335 	while (!clk_sam9x5_main_ready(reg))
336 		cpu_relax();
337 
338 	return 0;
339 }
340 
341 static const struct clk_ops sam9x5_main_clk_ops = {
342 	.enable = clk_sam9x5_main_enable,
343 	.set_parent = clk_sam9x5_main_set_parent,
344 	.get_rate = clk_generic_get_rate,
345 };
346 
at91_clk_sam9x5_main(void __iomem * reg,const char * name,const char * const * parent_names,int num_parents,const u32 * clk_mux_table,int type)347 struct clk *at91_clk_sam9x5_main(void __iomem *reg, const char *name,
348 				 const char * const *parent_names,
349 				 int num_parents, const u32 *clk_mux_table,
350 				 int type)
351 {
352 	struct clk *clk = ERR_PTR(-ENOMEM);
353 	struct clk_main *main = NULL;
354 	unsigned int val;
355 	int ret;
356 
357 	if (!reg || !name || !parent_names || !num_parents || !clk_mux_table)
358 		return ERR_PTR(-EINVAL);
359 
360 	main = kzalloc(sizeof(*main), GFP_KERNEL);
361 	if (!main)
362 		return ERR_PTR(-ENOMEM);
363 
364 	main->reg = reg;
365 	main->parent_names = parent_names;
366 	main->num_parents = num_parents;
367 	main->clk_mux_table = clk_mux_table;
368 	main->type = type;
369 	clk = &main->clk;
370 	clk->flags = CLK_GET_RATE_NOCACHE;
371 	pmc_read(reg, AT91_CKGR_MOR, &val);
372 	ret = clk_register(clk, UBOOT_DM_CLK_AT91_SAM9X5_MAIN, name,
373 			   main->parent_names[clk_main_parent_select(val)]);
374 	if (ret) {
375 		kfree(main);
376 		clk = ERR_PTR(ret);
377 	}
378 
379 	return clk;
380 }
381 
382 U_BOOT_DRIVER(at91_sam9x5_main_clk) = {
383 	.name = UBOOT_DM_CLK_AT91_SAM9X5_MAIN,
384 	.id = UCLASS_CLK,
385 	.ops = &sam9x5_main_clk_ops,
386 	.flags = DM_FLAG_PRE_RELOC,
387 };
388