1 // SPDX-License-Identifier: GPL-2.0+ or BSD-3-Clause
2 /*
3 * Copyright (C) 2021 Microchip
4 */
5
6 #include <dt-bindings/clock/at91.h>
7 #include <io.h>
8 #include <kernel/panic.h>
9 #include <kernel/pm.h>
10 #include <malloc.h>
11 #include <string.h>
12 #include <trace.h>
13 #include <types_ext.h>
14
15 #include "at91_clk.h"
16
17 #define PMC_MAX_IDS 128
18 #define PMC_MAX_PCKS 8
19
pmc_clk_get_by_id(struct pmc_clk * clks,unsigned int nclk,unsigned int id)20 static struct clk *pmc_clk_get_by_id(struct pmc_clk *clks, unsigned int nclk,
21 unsigned int id)
22 {
23 unsigned int i = 0;
24
25 for (i = 0; i < nclk; i++) {
26 if (clks[i].clk && clks[i].id == id)
27 return clks[i].clk;
28 }
29
30 return NULL;
31 }
32
pmc_clk_get_by_name(struct pmc_clk * clks,unsigned int nclk,const char * name)33 struct clk *pmc_clk_get_by_name(struct pmc_clk *clks, unsigned int nclk,
34 const char *name)
35 {
36 unsigned int i = 0;
37
38 for (i = 0; i < nclk; i++)
39 if (strcmp(clks[i].clk->name, name) == 0)
40 return clks[i].clk;
41
42 return NULL;
43 }
44
clk_dt_pmc_get(struct dt_driver_phandle_args * clkspec,void * data,TEE_Result * res)45 struct clk *clk_dt_pmc_get(struct dt_driver_phandle_args *clkspec, void *data,
46 TEE_Result *res)
47 {
48 unsigned int type = clkspec->args[0];
49 unsigned int idx = clkspec->args[1];
50 struct pmc_data *pmc_data = data;
51 struct pmc_clk *clks = NULL;
52 struct clk *clk = NULL;
53 unsigned int nclk = 0;
54 *res = TEE_ERROR_GENERIC;
55
56 if (clkspec->args_count != 2) {
57 *res = TEE_ERROR_BAD_PARAMETERS;
58 return NULL;
59 }
60
61 switch (type) {
62 case PMC_TYPE_CORE:
63 nclk = pmc_data->ncore;
64 clks = pmc_data->chws;
65 break;
66 case PMC_TYPE_SYSTEM:
67 nclk = pmc_data->nsystem;
68 clks = pmc_data->shws;
69 break;
70 case PMC_TYPE_PERIPHERAL:
71 nclk = pmc_data->nperiph;
72 clks = pmc_data->phws;
73 break;
74 case PMC_TYPE_GCK:
75 nclk = pmc_data->ngck;
76 clks = pmc_data->ghws;
77 break;
78 case PMC_TYPE_PROGRAMMABLE:
79 nclk = pmc_data->npck;
80 clks = pmc_data->pchws;
81 break;
82 default:
83 return NULL;
84 }
85
86 clk = pmc_clk_get_by_id(clks, nclk, idx);
87 if (clk)
88 *res = TEE_SUCCESS;
89
90 return clk;
91 }
92
pmc_data_allocate(unsigned int ncore,unsigned int nsystem,unsigned int nperiph,unsigned int ngck,unsigned int npck)93 struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
94 unsigned int nperiph, unsigned int ngck,
95 unsigned int npck)
96 {
97 unsigned int num_clks = ncore + nsystem + nperiph + ngck + npck;
98 unsigned int alloc_size = sizeof(struct pmc_data) +
99 num_clks * sizeof(struct pmc_clk);
100 struct pmc_data *pmc_data = NULL;
101
102 pmc_data = calloc(1, alloc_size);
103 if (!pmc_data)
104 return NULL;
105
106 pmc_data->ncore = ncore;
107 pmc_data->chws = pmc_data->hwtable;
108
109 pmc_data->nsystem = nsystem;
110 pmc_data->shws = pmc_data->chws + ncore;
111
112 pmc_data->nperiph = nperiph;
113 pmc_data->phws = pmc_data->shws + nsystem;
114
115 pmc_data->ngck = ngck;
116 pmc_data->ghws = pmc_data->phws + nperiph;
117
118 pmc_data->npck = npck;
119 pmc_data->pchws = pmc_data->ghws + ngck;
120
121 return pmc_data;
122 }
123
124 #ifdef CFG_PM_ARM32
125 static uint8_t registered_ids[PMC_MAX_IDS];
126 static uint8_t registered_pcks[PMC_MAX_PCKS];
127
128 static struct
129 {
130 uint32_t scsr;
131 uint32_t pcsr0;
132 uint32_t uckr;
133 uint32_t mor;
134 uint32_t mcfr;
135 uint32_t pllar;
136 uint32_t mckr;
137 uint32_t usb;
138 uint32_t imr;
139 uint32_t pcsr1;
140 uint32_t pcr[PMC_MAX_IDS];
141 uint32_t audio_pll0;
142 uint32_t audio_pll1;
143 uint32_t pckr[PMC_MAX_PCKS];
144 } pmc_cache;
145
146 /*
147 * As Peripheral ID 0 is invalid on AT91 chips, the identifier is stored
148 * without alteration in the table, and 0 is for unused clocks.
149 */
pmc_register_id(uint8_t id)150 void pmc_register_id(uint8_t id)
151 {
152 int i = 0;
153
154 for (i = 0; i < PMC_MAX_IDS; i++) {
155 if (registered_ids[i] == 0) {
156 registered_ids[i] = id;
157 return;
158 }
159 if (registered_ids[i] == id)
160 return;
161 }
162
163 panic("Invalid clock ID");
164 }
165
166 /*
167 * As Programmable Clock 0 is valid on AT91 chips, there is an offset
168 * of 1 between the stored value and the real clock ID.
169 */
pmc_register_pck(uint8_t pck)170 void pmc_register_pck(uint8_t pck)
171 {
172 int i = 0;
173
174 for (i = 0; i < PMC_MAX_PCKS; i++) {
175 if (registered_pcks[i] == 0) {
176 registered_pcks[i] = pck + 1;
177 return;
178 }
179 if (registered_pcks[i] == pck + 1)
180 return;
181 }
182
183 panic("Invalid clock ID");
184 }
185
pmc_suspend(void)186 static void pmc_suspend(void)
187 {
188 int i = 0;
189 uint8_t num = 0;
190 vaddr_t pmc_base = at91_pmc_get_base();
191
192 pmc_cache.scsr = io_read32(pmc_base + AT91_PMC_SCSR);
193 pmc_cache.pcsr0 = io_read32(pmc_base + AT91_PMC_PCSR);
194 pmc_cache.uckr = io_read32(pmc_base + AT91_CKGR_UCKR);
195 pmc_cache.mor = io_read32(pmc_base + AT91_CKGR_MOR);
196 pmc_cache.mcfr = io_read32(pmc_base + AT91_CKGR_MCFR);
197 pmc_cache.pllar = io_read32(pmc_base + AT91_CKGR_PLLAR);
198 pmc_cache.mckr = io_read32(pmc_base + AT91_PMC_MCKR);
199 pmc_cache.usb = io_read32(pmc_base + AT91_PMC_USB);
200 pmc_cache.imr = io_read32(pmc_base + AT91_PMC_IMR);
201 pmc_cache.pcsr1 = io_read32(pmc_base + AT91_PMC_PCSR1);
202
203 for (i = 0; registered_ids[i]; i++) {
204 io_write32(pmc_base + AT91_PMC_PCR,
205 registered_ids[i] & AT91_PMC_PCR_PID_MASK);
206 pmc_cache.pcr[registered_ids[i]] = io_read32(pmc_base +
207 AT91_PMC_PCR);
208 }
209 for (i = 0; registered_pcks[i]; i++) {
210 num = registered_pcks[i] - 1;
211 pmc_cache.pckr[num] = io_read32(pmc_base + AT91_PMC_PCKR(num));
212 }
213 }
214
pmc_ready(vaddr_t pmc_base,unsigned int mask)215 static bool pmc_ready(vaddr_t pmc_base, unsigned int mask)
216 {
217 uint32_t status = 0;
218
219 status = io_read32(pmc_base + AT91_PMC_SR);
220
221 return (status & mask) == mask;
222 }
223
pmc_resume(void)224 static void pmc_resume(void)
225 {
226 int i = 0;
227 uint8_t num = 0;
228 uint32_t tmp = 0;
229 vaddr_t pmc_base = at91_pmc_get_base();
230 uint32_t mask = AT91_PMC_MCKRDY | AT91_PMC_LOCKA;
231
232 tmp = io_read32(pmc_base + AT91_PMC_MCKR);
233 if (pmc_cache.mckr != tmp)
234 panic("MCKR was not configured properly by the previous bootstage");
235 tmp = io_read32(pmc_base + AT91_CKGR_PLLAR);
236 if (pmc_cache.pllar != tmp)
237 panic("PLLAR was not configured properly by the previous bootstage");
238
239 io_write32(pmc_base + AT91_PMC_SCER, pmc_cache.scsr);
240 io_write32(pmc_base + AT91_PMC_PCER, pmc_cache.pcsr0);
241 io_write32(pmc_base + AT91_CKGR_UCKR, pmc_cache.uckr);
242 io_write32(pmc_base + AT91_CKGR_MOR, pmc_cache.mor);
243 io_write32(pmc_base + AT91_CKGR_MCFR, pmc_cache.mcfr);
244 io_write32(pmc_base + AT91_PMC_USB, pmc_cache.usb);
245 io_write32(pmc_base + AT91_PMC_IMR, pmc_cache.imr);
246 io_write32(pmc_base + AT91_PMC_PCER1, pmc_cache.pcsr1);
247
248 for (i = 0; registered_ids[i]; i++) {
249 io_write32(pmc_base + AT91_PMC_PCR,
250 pmc_cache.pcr[registered_ids[i]] | AT91_PMC_PCR_CMD);
251 }
252 for (i = 0; registered_pcks[i]; i++) {
253 num = registered_pcks[i] - 1;
254 io_write32(pmc_base + AT91_PMC_PCKR(num), pmc_cache.pckr[num]);
255 }
256
257 if (pmc_cache.uckr & AT91_PMC_UPLLEN)
258 mask |= AT91_PMC_LOCKU;
259
260 while (!pmc_ready(pmc_base, mask))
261 ;
262 }
263
pmc_pm(enum pm_op op,uint32_t pm_hint __unused,const struct pm_callback_handle * hdl __unused)264 static TEE_Result pmc_pm(enum pm_op op, uint32_t pm_hint __unused,
265 const struct pm_callback_handle *hdl __unused)
266 {
267 switch (op) {
268 case PM_OP_RESUME:
269 pmc_resume();
270 break;
271 case PM_OP_SUSPEND:
272 pmc_suspend();
273 break;
274 default:
275 panic("Invalid PM operation");
276 }
277
278 return TEE_SUCCESS;
279 }
280
pmc_register_pm(void)281 void pmc_register_pm(void)
282 {
283 /*
284 * We register the clock as a core service since clocks must be
285 * re-enable prior to accessing devices
286 */
287 register_pm_core_service_cb(pmc_pm, NULL, "pmc");
288 }
289
290 #endif
291