1 /* SPDX-License-Identifier: GPL-2.0+ or BSD-3-Clause */
2 /*
3 * include/linux/clk/at91_pmc.h
4 *
5 * Copyright (C) 2005 Ivan Kokshaysky
6 * Copyright (C) SAN People
7 * Copyright (C) 2021 Microchip
8 *
9 * Power Management Controller (PMC) - System peripherals registers.
10 * Based on AT91RM9200 datasheet revision E.
11 */
12
13 #ifndef AT91_CLK_H
14 #define AT91_CLK_H
15
16 #include <drivers/clk.h>
17 #include <drivers/clk_dt.h>
18
19 #include "at91_pmc.h"
20
21 #define ffs(x) __builtin_ffs(x)
22
23 #define field_get(_mask, _reg) \
24 ({ \
25 typeof(_mask) __mask = _mask; \
26 \
27 (((_reg) & (__mask)) >> (ffs(__mask) - 1)); \
28 })
29 #define field_prep(_mask, _val) \
30 ({ \
31 typeof(_mask) __mask = _mask; \
32 \
33 (((_val) << (ffs(__mask) - 1)) & (__mask)); \
34 })
35
36 struct clk_range {
37 unsigned long min;
38 unsigned long max;
39 };
40
41 #define CLK_RANGE(MIN, MAX) {.min = MIN, .max = MAX,}
42
43 struct pmc_clk {
44 struct clk *clk;
45 uint8_t id;
46 };
47
48 struct pmc_data {
49 vaddr_t base;
50 unsigned int ncore;
51 struct pmc_clk *chws;
52 unsigned int nsystem;
53 struct pmc_clk *shws;
54 unsigned int nperiph;
55 struct pmc_clk *phws;
56 unsigned int ngck;
57 struct pmc_clk *ghws;
58 unsigned int npck;
59 struct pmc_clk *pchws;
60
61 struct pmc_clk hwtable[];
62 };
63
64 /* PLL */
65 struct clk_pll_layout {
66 uint32_t pllr_mask;
67 uint32_t mul_mask;
68 uint32_t frac_mask;
69 uint32_t div_mask;
70 uint32_t endiv_mask;
71 uint8_t mul_shift;
72 uint8_t frac_shift;
73 uint8_t div_shift;
74 uint8_t endiv_shift;
75 };
76
77 struct clk_pcr_layout {
78 uint32_t offset;
79 uint32_t cmd;
80 uint32_t div_mask;
81 uint32_t gckcss_mask;
82 uint32_t pid_mask;
83 };
84
85 struct clk_pll_charac {
86 struct clk_range input;
87 int num_output;
88 const struct clk_range *output;
89 uint16_t *icpll;
90 uint8_t *out;
91 uint8_t upll : 1;
92 };
93
94 extern const struct clk_pll_layout sama5d3_pll_layout;
95
96 /* Master */
97 struct clk_master_charac {
98 struct clk_range output;
99 uint32_t divisors[5];
100 uint8_t have_div3_pres;
101 };
102
103 struct clk_master_layout {
104 uint32_t offset;
105 uint32_t mask;
106 uint8_t pres_shift;
107 };
108
109 struct clk_programmable_layout {
110 uint8_t pres_mask;
111 uint8_t pres_shift;
112 uint8_t css_mask;
113 uint8_t have_slck_mck;
114 uint8_t is_pres_direct;
115 };
116
117 extern const struct clk_master_layout at91sam9x5_master_layout;
118
119 vaddr_t at91_pmc_get_base(void);
120
121 TEE_Result at91_pmc_clk_get(unsigned int type, unsigned int idx,
122 struct clk **clk);
123
124 TEE_Result pmc_clk_get(struct pmc_data *pmc, unsigned int type,
125 unsigned int idx, struct clk **clk);
126
127 struct clk *at91_sckc_clk_get(void);
128
129 struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
130 unsigned int nperiph, unsigned int ngck,
131 unsigned int npck);
132
133 TEE_Result clk_dt_pmc_get(struct dt_pargs *args, void *data, struct clk **clk);
134
135 struct clk *pmc_clk_get_by_name(struct pmc_clk *clks, unsigned int nclk,
136 const char *name);
137
138 /* Main clock */
139 struct clk *pmc_register_main_rc_osc(struct pmc_data *pmc, const char *name,
140 unsigned long freq);
141
142 struct clk *pmc_register_main_osc(struct pmc_data *pmc, const char *name,
143 struct clk *parent, bool bypass);
144
145 struct clk *at91_clk_register_sam9x5_main(struct pmc_data *pmc,
146 const char *name,
147 struct clk **parent_clocks,
148 unsigned int num_parents);
149
150 /* PLL */
151 struct clk *
152 at91_clk_register_pll(struct pmc_data *pmc, const char *name,
153 struct clk *parent, uint8_t id,
154 const struct clk_pll_layout *layout,
155 const struct clk_pll_charac *charac);
156
157 struct clk *
158 at91_clk_register_plldiv(struct pmc_data *pmc, const char *name,
159 struct clk *parent);
160
161 struct clk *sam9x60_clk_register_frac_pll(struct pmc_data *pmc,
162 const char *name,
163 struct clk *parent,
164 uint8_t id,
165 const struct clk_pll_charac *charac,
166 const struct clk_pll_layout *layout,
167 uint32_t flags);
168
169 struct clk *sam9x60_clk_register_div_pll(struct pmc_data *pmc,
170 const char *name,
171 struct clk *parent,
172 uint8_t id,
173 const struct clk_pll_charac *charac,
174 const struct clk_pll_layout *layout,
175 uint32_t flags,
176 uint32_t safe_div);
177
178 /* UTMI */
179 struct clk *
180 at91_clk_register_utmi(struct pmc_data *pmc, const char *name,
181 struct clk *parent);
182
183 struct clk *at91_clk_sama7g5_register_utmi(struct pmc_data *pmc,
184 const char *name,
185 struct clk *parent);
186
187 struct clk *sama7_utmi_clk_register(const char *name,
188 struct clk *parent,
189 uint8_t id);
190
191 /* Master */
192 struct clk *
193 at91_clk_register_master_pres(struct pmc_data *pmc,
194 const char *name, int num_parents,
195 struct clk **parents,
196 const struct clk_master_layout *layout,
197 const struct clk_master_charac *charac,
198 int chg_pid);
199
200 struct clk *
201 at91_clk_register_master_div(struct pmc_data *pmc,
202 const char *name, struct clk *parent,
203 const struct clk_master_layout *layout,
204 const struct clk_master_charac *charac);
205
206 /*
207 * @mux_table: when @mux_table is not NULL it shall hold @num_parents cells
208 */
209 struct clk *at91_clk_sama7g5_register_master(struct pmc_data *pmc,
210 const char *name,
211 int num_parents,
212 struct clk **parent,
213 uint32_t *mux_table,
214 uint8_t id,
215 int chg_pid);
216
217 /* H32MX */
218 struct clk *
219 at91_clk_register_h32mx(struct pmc_data *pmc, const char *name,
220 struct clk *parent);
221
222 /* USB */
223 struct clk *
224 at91sam9x5_clk_register_usb(struct pmc_data *pmc, const char *name,
225 struct clk **parents, uint8_t num_parents);
226
227 /* Programmable */
228 struct clk *
229 at91_clk_register_programmable(struct pmc_data *pmc,
230 const char *name, struct clk **parents,
231 uint8_t num_parents, uint8_t id,
232 const struct clk_programmable_layout *layout);
233
234 struct clk *
235 at91_clk_register_system(struct pmc_data *pmc, const char *name,
236 struct clk *parent, uint8_t id);
237
238 struct clk *
239 at91_clk_register_sam9x5_periph(struct pmc_data *pmc,
240 const struct clk_pcr_layout *layout,
241 const char *name, struct clk *parent,
242 uint32_t id, const struct clk_range *range);
243
244 struct clk *
245 at91_clk_register_generated(struct pmc_data *pmc,
246 const struct clk_pcr_layout *layout,
247 const char *name, struct clk **parents,
248 uint32_t *mux_table,
249 uint8_t num_parents, uint8_t id,
250 const struct clk_range *range,
251 int chg_pid);
252
253 struct clk *
254 at91_clk_i2s_mux_register(const char *name, struct clk **parents,
255 unsigned int num_parents, uint8_t bus_id);
256
257 /* Audio PLL */
258 struct clk *
259 at91_clk_register_audio_pll_frac(struct pmc_data *pmc, const char *name,
260 struct clk *parent);
261
262 struct clk *
263 at91_clk_register_audio_pll_pad(struct pmc_data *pmc, const char *name,
264 struct clk *parent);
265
266 struct clk *
267 at91_clk_register_audio_pll_pmc(struct pmc_data *pmc, const char *name,
268 struct clk *parent);
269
270 /* CPU OPP (Operation Performance Points) */
271 struct clk *at91_cpu_opp_clk_get(void);
272
273 TEE_Result at91_clk_register_cpu_opp(const void *fdt, int node,
274 struct clk *clk);
275
276 void sam_set_clock_range(unsigned int pmc_type, unsigned int pmc_id,
277 const struct clk_range *range);
278
279 #ifdef CFG_PM_ARM32
280 void pmc_register_id(uint8_t id);
281 void pmc_register_pck(uint8_t pck);
282 void pmc_register_pm(void);
283 #else
pmc_register_id(uint8_t id __unused)284 static inline void pmc_register_id(uint8_t id __unused) {}
pmc_register_pck(uint8_t pck __unused)285 static inline void pmc_register_pck(uint8_t pck __unused) {}
pmc_register_pm(void)286 static inline void pmc_register_pm(void) {}
287 #endif
288
289 #endif
290