1 // SPDX-License-Identifier: GPL-2.0+ or BSD-3-Clause
2 /*
3  *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
4  *  Copyright (C) 2021 Microchip
5  */
6 
7 #include <io.h>
8 #include <kernel/delay.h>
9 #include <kernel/panic.h>
10 #include <mm/core_memprot.h>
11 #include <types_ext.h>
12 
13 #include "at91_clk.h"
14 
15 #define SLOW_CLOCK_FREQ		32768
16 #define MAINF_DIV		16
17 #define USEC_PER_SEC		1000000L
18 #define MAINF_LOOP_MIN_WAIT	(USEC_PER_SEC / SLOW_CLOCK_FREQ)
19 
20 #define OSC_READY_TIMEOUT_US	1000
21 
22 #define MOR_KEY_MASK		(0xFF << 16)
23 
24 #define CLK_MAIN_PARENT_SELECT(s)	(((s) & \
25 					(AT91_PMC_MOSCEN | \
26 					AT91_PMC_OSCBYPASS)) ? 1 : 0)
27 
28 /*
29  * Main RC Oscillator
30  */
31 
32 struct main_rc_osc {
33 	unsigned long freq;
34 	vaddr_t base;
35 };
36 
pmc_main_rc_osc_ready(struct main_rc_osc * osc)37 static bool pmc_main_rc_osc_ready(struct main_rc_osc *osc)
38 {
39 	uint32_t status = io_read32(osc->base + AT91_PMC_SR);
40 
41 	return status & AT91_PMC_MOSCRCS;
42 }
43 
pmc_main_rc_osc_enable(struct clk * clk)44 static TEE_Result pmc_main_rc_osc_enable(struct clk *clk)
45 {
46 	struct main_rc_osc *osc = clk->priv;
47 	uint32_t mor = io_read32(osc->base + AT91_CKGR_MOR);
48 
49 	/* Enable the oscillator if not */
50 	if (!(mor & AT91_PMC_MOSCRCEN)) {
51 		io_clrsetbits32(osc->base + AT91_CKGR_MOR,
52 				MOR_KEY_MASK | AT91_PMC_MOSCRCEN,
53 				AT91_PMC_MOSCRCEN | AT91_PMC_KEY);
54 	}
55 
56 	while (!pmc_main_rc_osc_ready(osc))
57 		;
58 
59 	return TEE_SUCCESS;
60 }
61 
pmc_main_rc_osc_disable(struct clk * clk)62 static void pmc_main_rc_osc_disable(struct clk *clk)
63 {
64 	struct main_rc_osc *osc = clk->priv;
65 	uint32_t mor = io_read32(osc->base + AT91_CKGR_MOR);
66 
67 	if (!(mor & AT91_PMC_MOSCRCEN))
68 		return;
69 
70 	io_clrsetbits32(osc->base + AT91_CKGR_MOR,
71 			MOR_KEY_MASK | AT91_PMC_MOSCRCEN, AT91_PMC_KEY);
72 }
73 
74 static unsigned long
pmc_main_rc_osc_get_rate(struct clk * clk,unsigned long parent_rate __unused)75 pmc_main_rc_osc_get_rate(struct clk *clk, unsigned long parent_rate __unused)
76 {
77 	struct main_rc_osc *osc = clk->priv;
78 
79 	return osc->freq;
80 }
81 
82 static const struct clk_ops pmc_main_rc_osc_clk_ops = {
83 	.enable = pmc_main_rc_osc_enable,
84 	.disable = pmc_main_rc_osc_disable,
85 	.get_rate = pmc_main_rc_osc_get_rate,
86 };
87 
pmc_register_main_rc_osc(struct pmc_data * pmc,const char * name,unsigned long freq)88 struct clk *pmc_register_main_rc_osc(struct pmc_data *pmc, const char *name,
89 				     unsigned long freq)
90 {
91 	struct clk *clk = NULL;
92 	struct main_rc_osc *osc = NULL;
93 
94 	clk = clk_alloc(name, &pmc_main_rc_osc_clk_ops, NULL, 0);
95 	if (!clk)
96 		return NULL;
97 
98 	osc = calloc(1, sizeof(*osc));
99 	if (!osc) {
100 		clk_free(clk);
101 		return NULL;
102 	}
103 
104 	osc->freq = freq;
105 	osc->base = pmc->base;
106 
107 	clk->priv = osc;
108 
109 	if (clk_register(clk)) {
110 		free(osc);
111 		clk_free(clk);
112 		return NULL;
113 	}
114 
115 	return clk;
116 }
117 
118 /*
119  * Main Oscillator
120  */
pmc_main_osc_ready(struct pmc_data * pmc)121 static bool pmc_main_osc_ready(struct pmc_data *pmc)
122 {
123 	uint32_t status = io_read32(pmc->base + AT91_PMC_SR);
124 
125 	return status & AT91_PMC_MOSCS;
126 }
127 
pmc_main_osc_enable(struct clk * clk)128 static TEE_Result pmc_main_osc_enable(struct clk *clk)
129 {
130 	struct pmc_data *pmc = clk->priv;
131 	uint32_t mor = io_read32(pmc->base + AT91_CKGR_MOR);
132 
133 	mor &= ~MOR_KEY_MASK;
134 
135 	if (mor & AT91_PMC_OSCBYPASS)
136 		return TEE_SUCCESS;
137 
138 	if (!(mor & AT91_PMC_MOSCEN)) {
139 		mor |= AT91_PMC_MOSCEN | AT91_PMC_KEY;
140 		io_write32(pmc->base + AT91_CKGR_MOR, mor);
141 	}
142 
143 	while (!pmc_main_osc_ready(pmc))
144 		;
145 
146 	return TEE_SUCCESS;
147 }
148 
pmc_main_osc_disable(struct clk * clk)149 static void pmc_main_osc_disable(struct clk *clk)
150 {
151 	struct pmc_data *pmc = clk->priv;
152 	uint32_t mor = io_read32(pmc->base + AT91_CKGR_MOR);
153 
154 	if (mor & AT91_PMC_OSCBYPASS)
155 		return;
156 
157 	if (!(mor & AT91_PMC_MOSCEN))
158 		return;
159 
160 	mor &= ~(AT91_PMC_KEY | AT91_PMC_MOSCEN);
161 	io_write32(pmc->base + AT91_CKGR_MOR, mor | AT91_PMC_KEY);
162 }
163 
164 static const struct clk_ops pmc_main_osc_clk_ops = {
165 	.enable = pmc_main_osc_enable,
166 	.disable = pmc_main_osc_disable,
167 };
168 
pmc_register_main_osc(struct pmc_data * pmc,const char * name,struct clk * parent,bool bypass)169 struct clk *pmc_register_main_osc(struct pmc_data *pmc, const char *name,
170 				  struct clk *parent, bool bypass)
171 {
172 	struct clk *clk = NULL;
173 
174 	clk = clk_alloc(name, &pmc_main_osc_clk_ops, &parent, 1);
175 	if (!clk)
176 		panic();
177 
178 	clk->priv = pmc;
179 
180 	if (bypass)
181 		io_clrsetbits32(pmc->base + AT91_CKGR_MOR,
182 				MOR_KEY_MASK | AT91_PMC_OSCBYPASS,
183 				AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
184 
185 	if (clk_register(clk)) {
186 		clk_free(clk);
187 		return NULL;
188 	}
189 
190 	return clk;
191 }
192 
193 /*
194  * Main Clock
195  */
clk_main_probe_frequency(vaddr_t base)196 static TEE_Result clk_main_probe_frequency(vaddr_t base)
197 {
198 	while (!(io_read32(base + AT91_CKGR_MCFR) & AT91_PMC_MAINRDY))
199 		;
200 
201 	return TEE_SUCCESS;
202 }
203 
clk_main_get_rate(vaddr_t base,unsigned long parent_rate)204 static unsigned long clk_main_get_rate(vaddr_t base,
205 				       unsigned long parent_rate)
206 {
207 	uint32_t mcfr = 0;
208 
209 	if (parent_rate)
210 		return parent_rate;
211 
212 	IMSG("Main crystal frequency not set, using approximate value");
213 	mcfr = io_read32(base + AT91_CKGR_MCFR);
214 	if (!(mcfr & AT91_PMC_MAINRDY))
215 		return 0;
216 
217 	return ((mcfr & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV;
218 }
219 
clk_sam9x5_main_ready(vaddr_t base)220 static bool clk_sam9x5_main_ready(vaddr_t base)
221 {
222 	uint32_t status = io_read32(base + AT91_PMC_SR);
223 
224 	return status & AT91_PMC_MOSCSELS;
225 }
226 
clk_sam9x5_main_enable(struct clk * clk)227 static TEE_Result clk_sam9x5_main_enable(struct clk *clk)
228 {
229 	struct pmc_data *pmc = clk->priv;
230 
231 	while (!clk_sam9x5_main_ready(pmc->base))
232 		;
233 
234 	return clk_main_probe_frequency(pmc->base);
235 }
236 
clk_sam9x5_main_get_rate(struct clk * clk,unsigned long parent_rate)237 static unsigned long clk_sam9x5_main_get_rate(struct clk *clk,
238 					      unsigned long parent_rate)
239 {
240 	struct pmc_data *pmc = clk->priv;
241 
242 	return clk_main_get_rate(pmc->base, parent_rate);
243 }
244 
clk_sam9x5_main_set_parent(struct clk * clk,size_t index)245 static TEE_Result clk_sam9x5_main_set_parent(struct clk *clk, size_t index)
246 {
247 	struct pmc_data *pmc = clk->priv;
248 	uint32_t tmp = 0;
249 
250 	if (index > 1)
251 		return TEE_ERROR_BAD_PARAMETERS;
252 
253 	tmp = io_read32(pmc->base + AT91_CKGR_MOR);
254 
255 	if (index && !(tmp & AT91_PMC_MOSCSEL))
256 		tmp = AT91_PMC_MOSCSEL;
257 	else if (!index && (tmp & AT91_PMC_MOSCSEL))
258 		tmp = 0;
259 	else
260 		return TEE_SUCCESS;
261 
262 	io_clrsetbits32(pmc->base + AT91_CKGR_MOR,
263 			AT91_PMC_MOSCSEL | MOR_KEY_MASK,
264 			tmp | AT91_PMC_KEY);
265 
266 	while (!clk_sam9x5_main_ready(pmc->base))
267 		;
268 
269 	return TEE_SUCCESS;
270 }
271 
clk_sam9x5_main_get_parent(struct clk * clk)272 static size_t clk_sam9x5_main_get_parent(struct clk *clk)
273 {
274 	struct pmc_data *pmc = clk->priv;
275 	uint32_t status = io_read32(pmc->base + AT91_CKGR_MOR);
276 
277 	return CLK_MAIN_PARENT_SELECT(status);
278 }
279 
280 static const struct clk_ops sam9x5_main_ops = {
281 	.enable = clk_sam9x5_main_enable,
282 	.get_rate = clk_sam9x5_main_get_rate,
283 	.set_parent = clk_sam9x5_main_set_parent,
284 	.get_parent = clk_sam9x5_main_get_parent,
285 };
286 
287 struct clk *
at91_clk_register_sam9x5_main(struct pmc_data * pmc,const char * name,struct clk ** parent_clocks,unsigned int num_parents)288 at91_clk_register_sam9x5_main(struct pmc_data *pmc,
289 			      const char *name,
290 			      struct clk **parent_clocks,
291 			      unsigned int num_parents)
292 {
293 	struct clk *clk = NULL;
294 
295 	if (!name)
296 		return NULL;
297 
298 	if (!parent_clocks || !num_parents)
299 		return NULL;
300 
301 	clk = clk_alloc(name, &sam9x5_main_ops, parent_clocks, num_parents);
302 	if (!clk)
303 		return NULL;
304 
305 	clk->flags = CLK_SET_PARENT_GATE;
306 	clk->priv = pmc;
307 
308 	if (clk_register(clk)) {
309 		clk_free(clk);
310 		return NULL;
311 	}
312 
313 	return clk;
314 }
315