Commit | Line | Data |
---|---|---|
62a8a094 TT |
1 | /* |
2 | * Tegra124 DFLL FCPU clock source driver | |
3 | * | |
b0dcfb78 | 4 | * Copyright (C) 2012-2019 NVIDIA Corporation. All rights reserved. |
62a8a094 TT |
5 | * |
6 | * Aleksandr Frid <afrid@nvidia.com> | |
7 | * Paul Walmsley <pwalmsley@nvidia.com> | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or modify | |
10 | * it under the terms of the GNU General Public License version 2 as | |
11 | * published by the Free Software Foundation. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | |
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
16 | * more details. | |
17 | * | |
18 | */ | |
19 | ||
20 | #include <linux/cpu.h> | |
21 | #include <linux/err.h> | |
22 | #include <linux/kernel.h> | |
33996b02 | 23 | #include <linux/init.h> |
b0dcfb78 | 24 | #include <linux/of_device.h> |
62a8a094 | 25 | #include <linux/platform_device.h> |
b3cf8d06 | 26 | #include <linux/regulator/consumer.h> |
62a8a094 TT |
27 | #include <soc/tegra/fuse.h> |
28 | ||
29 | #include "clk.h" | |
30 | #include "clk-dfll.h" | |
31 | #include "cvb.h" | |
32 | ||
b0dcfb78 PDS |
33 | struct dfll_fcpu_data { |
34 | const unsigned long *cpu_max_freq_table; | |
35 | unsigned int cpu_max_freq_table_size; | |
36 | const struct cvb_table *cpu_cvb_tables; | |
37 | unsigned int cpu_cvb_tables_size; | |
38 | }; | |
39 | ||
62a8a094 | 40 | /* Maximum CPU frequency, indexed by CPU speedo id */ |
b0dcfb78 | 41 | static const unsigned long tegra124_cpu_max_freq_table[] = { |
62a8a094 TT |
42 | [0] = 2014500000UL, |
43 | [1] = 2320500000UL, | |
44 | [2] = 2116500000UL, | |
45 | [3] = 2524500000UL, | |
46 | }; | |
47 | ||
48 | static const struct cvb_table tegra124_cpu_cvb_tables[] = { | |
49 | { | |
50 | .speedo_id = -1, | |
51 | .process_id = -1, | |
52 | .min_millivolts = 900, | |
53 | .max_millivolts = 1260, | |
62a8a094 TT |
54 | .speedo_scale = 100, |
55 | .voltage_scale = 1000, | |
e8f6a68c | 56 | .entries = { |
2690e912 TR |
57 | { 204000000UL, { 1112619, -29295, 402 } }, |
58 | { 306000000UL, { 1150460, -30585, 402 } }, | |
59 | { 408000000UL, { 1190122, -31865, 402 } }, | |
60 | { 510000000UL, { 1231606, -33155, 402 } }, | |
61 | { 612000000UL, { 1274912, -34435, 402 } }, | |
62 | { 714000000UL, { 1320040, -35725, 402 } }, | |
63 | { 816000000UL, { 1366990, -37005, 402 } }, | |
64 | { 918000000UL, { 1415762, -38295, 402 } }, | |
65 | { 1020000000UL, { 1466355, -39575, 402 } }, | |
66 | { 1122000000UL, { 1518771, -40865, 402 } }, | |
67 | { 1224000000UL, { 1573009, -42145, 402 } }, | |
68 | { 1326000000UL, { 1629068, -43435, 402 } }, | |
69 | { 1428000000UL, { 1686950, -44715, 402 } }, | |
70 | { 1530000000UL, { 1746653, -46005, 402 } }, | |
71 | { 1632000000UL, { 1808179, -47285, 402 } }, | |
72 | { 1734000000UL, { 1871526, -48575, 402 } }, | |
73 | { 1836000000UL, { 1936696, -49855, 402 } }, | |
74 | { 1938000000UL, { 2003687, -51145, 402 } }, | |
75 | { 2014500000UL, { 2054787, -52095, 402 } }, | |
76 | { 2116500000UL, { 2124957, -53385, 402 } }, | |
77 | { 2218500000UL, { 2196950, -54665, 402 } }, | |
78 | { 2320500000UL, { 2270765, -55955, 402 } }, | |
79 | { 2422500000UL, { 2346401, -57235, 402 } }, | |
80 | { 2524500000UL, { 2437299, -58535, 402 } }, | |
81 | { 0UL, { 0, 0, 0 } }, | |
62a8a094 TT |
82 | }, |
83 | .cpu_dfll_data = { | |
84 | .tune0_low = 0x005020ff, | |
85 | .tune0_high = 0x005040ff, | |
86 | .tune1 = 0x00000060, | |
87 | } | |
88 | }, | |
89 | }; | |
90 | ||
2b2dbc2f JL |
91 | static const unsigned long tegra210_cpu_max_freq_table[] = { |
92 | [0] = 1912500000UL, | |
93 | [1] = 1912500000UL, | |
94 | [2] = 2218500000UL, | |
95 | [3] = 1785000000UL, | |
96 | [4] = 1632000000UL, | |
97 | [5] = 1912500000UL, | |
98 | [6] = 2014500000UL, | |
99 | [7] = 1734000000UL, | |
100 | [8] = 1683000000UL, | |
101 | [9] = 1555500000UL, | |
102 | [10] = 1504500000UL, | |
103 | }; | |
104 | ||
105 | #define CPU_CVB_TABLE \ | |
106 | .speedo_scale = 100, \ | |
107 | .voltage_scale = 1000, \ | |
108 | .entries = { \ | |
109 | { 204000000UL, { 1007452, -23865, 370 } }, \ | |
110 | { 306000000UL, { 1052709, -24875, 370 } }, \ | |
111 | { 408000000UL, { 1099069, -25895, 370 } }, \ | |
112 | { 510000000UL, { 1146534, -26905, 370 } }, \ | |
113 | { 612000000UL, { 1195102, -27915, 370 } }, \ | |
114 | { 714000000UL, { 1244773, -28925, 370 } }, \ | |
115 | { 816000000UL, { 1295549, -29935, 370 } }, \ | |
116 | { 918000000UL, { 1347428, -30955, 370 } }, \ | |
117 | { 1020000000UL, { 1400411, -31965, 370 } }, \ | |
118 | { 1122000000UL, { 1454497, -32975, 370 } }, \ | |
119 | { 1224000000UL, { 1509687, -33985, 370 } }, \ | |
120 | { 1326000000UL, { 1565981, -35005, 370 } }, \ | |
121 | { 1428000000UL, { 1623379, -36015, 370 } }, \ | |
122 | { 1530000000UL, { 1681880, -37025, 370 } }, \ | |
123 | { 1632000000UL, { 1741485, -38035, 370 } }, \ | |
124 | { 1734000000UL, { 1802194, -39055, 370 } }, \ | |
125 | { 1836000000UL, { 1864006, -40065, 370 } }, \ | |
126 | { 1912500000UL, { 1910780, -40815, 370 } }, \ | |
127 | { 2014500000UL, { 1227000, 0, 0 } }, \ | |
128 | { 2218500000UL, { 1227000, 0, 0 } }, \ | |
129 | { 0UL, { 0, 0, 0 } }, \ | |
130 | } | |
131 | ||
132 | #define CPU_CVB_TABLE_XA \ | |
133 | .speedo_scale = 100, \ | |
134 | .voltage_scale = 1000, \ | |
135 | .entries = { \ | |
136 | { 204000000UL, { 1250024, -39785, 565 } }, \ | |
137 | { 306000000UL, { 1297556, -41145, 565 } }, \ | |
138 | { 408000000UL, { 1346718, -42505, 565 } }, \ | |
139 | { 510000000UL, { 1397511, -43855, 565 } }, \ | |
140 | { 612000000UL, { 1449933, -45215, 565 } }, \ | |
141 | { 714000000UL, { 1503986, -46575, 565 } }, \ | |
142 | { 816000000UL, { 1559669, -47935, 565 } }, \ | |
143 | { 918000000UL, { 1616982, -49295, 565 } }, \ | |
144 | { 1020000000UL, { 1675926, -50645, 565 } }, \ | |
145 | { 1122000000UL, { 1736500, -52005, 565 } }, \ | |
146 | { 1224000000UL, { 1798704, -53365, 565 } }, \ | |
147 | { 1326000000UL, { 1862538, -54725, 565 } }, \ | |
148 | { 1428000000UL, { 1928003, -56085, 565 } }, \ | |
149 | { 1530000000UL, { 1995097, -57435, 565 } }, \ | |
150 | { 1606500000UL, { 2046149, -58445, 565 } }, \ | |
151 | { 1632000000UL, { 2063822, -58795, 565 } }, \ | |
152 | { 0UL, { 0, 0, 0 } }, \ | |
153 | } | |
154 | ||
155 | #define CPU_CVB_TABLE_EUCM1 \ | |
156 | .speedo_scale = 100, \ | |
157 | .voltage_scale = 1000, \ | |
158 | .entries = { \ | |
159 | { 204000000UL, { 734429, 0, 0 } }, \ | |
160 | { 306000000UL, { 768191, 0, 0 } }, \ | |
161 | { 408000000UL, { 801953, 0, 0 } }, \ | |
162 | { 510000000UL, { 835715, 0, 0 } }, \ | |
163 | { 612000000UL, { 869477, 0, 0 } }, \ | |
164 | { 714000000UL, { 903239, 0, 0 } }, \ | |
165 | { 816000000UL, { 937001, 0, 0 } }, \ | |
166 | { 918000000UL, { 970763, 0, 0 } }, \ | |
167 | { 1020000000UL, { 1004525, 0, 0 } }, \ | |
168 | { 1122000000UL, { 1038287, 0, 0 } }, \ | |
169 | { 1224000000UL, { 1072049, 0, 0 } }, \ | |
170 | { 1326000000UL, { 1105811, 0, 0 } }, \ | |
171 | { 1428000000UL, { 1130000, 0, 0 } }, \ | |
172 | { 1555500000UL, { 1130000, 0, 0 } }, \ | |
173 | { 1632000000UL, { 1170000, 0, 0 } }, \ | |
174 | { 1734000000UL, { 1227500, 0, 0 } }, \ | |
175 | { 0UL, { 0, 0, 0 } }, \ | |
176 | } | |
177 | ||
178 | #define CPU_CVB_TABLE_EUCM2 \ | |
179 | .speedo_scale = 100, \ | |
180 | .voltage_scale = 1000, \ | |
181 | .entries = { \ | |
182 | { 204000000UL, { 742283, 0, 0 } }, \ | |
183 | { 306000000UL, { 776249, 0, 0 } }, \ | |
184 | { 408000000UL, { 810215, 0, 0 } }, \ | |
185 | { 510000000UL, { 844181, 0, 0 } }, \ | |
186 | { 612000000UL, { 878147, 0, 0 } }, \ | |
187 | { 714000000UL, { 912113, 0, 0 } }, \ | |
188 | { 816000000UL, { 946079, 0, 0 } }, \ | |
189 | { 918000000UL, { 980045, 0, 0 } }, \ | |
190 | { 1020000000UL, { 1014011, 0, 0 } }, \ | |
191 | { 1122000000UL, { 1047977, 0, 0 } }, \ | |
192 | { 1224000000UL, { 1081943, 0, 0 } }, \ | |
193 | { 1326000000UL, { 1090000, 0, 0 } }, \ | |
194 | { 1479000000UL, { 1090000, 0, 0 } }, \ | |
195 | { 1555500000UL, { 1162000, 0, 0 } }, \ | |
196 | { 1683000000UL, { 1195000, 0, 0 } }, \ | |
197 | { 0UL, { 0, 0, 0 } }, \ | |
198 | } | |
199 | ||
200 | #define CPU_CVB_TABLE_EUCM2_JOINT_RAIL \ | |
201 | .speedo_scale = 100, \ | |
202 | .voltage_scale = 1000, \ | |
203 | .entries = { \ | |
204 | { 204000000UL, { 742283, 0, 0 } }, \ | |
205 | { 306000000UL, { 776249, 0, 0 } }, \ | |
206 | { 408000000UL, { 810215, 0, 0 } }, \ | |
207 | { 510000000UL, { 844181, 0, 0 } }, \ | |
208 | { 612000000UL, { 878147, 0, 0 } }, \ | |
209 | { 714000000UL, { 912113, 0, 0 } }, \ | |
210 | { 816000000UL, { 946079, 0, 0 } }, \ | |
211 | { 918000000UL, { 980045, 0, 0 } }, \ | |
212 | { 1020000000UL, { 1014011, 0, 0 } }, \ | |
213 | { 1122000000UL, { 1047977, 0, 0 } }, \ | |
214 | { 1224000000UL, { 1081943, 0, 0 } }, \ | |
215 | { 1326000000UL, { 1090000, 0, 0 } }, \ | |
216 | { 1479000000UL, { 1090000, 0, 0 } }, \ | |
217 | { 1504500000UL, { 1120000, 0, 0 } }, \ | |
218 | { 0UL, { 0, 0, 0 } }, \ | |
219 | } | |
220 | ||
221 | #define CPU_CVB_TABLE_ODN \ | |
222 | .speedo_scale = 100, \ | |
223 | .voltage_scale = 1000, \ | |
224 | .entries = { \ | |
225 | { 204000000UL, { 721094, 0, 0 } }, \ | |
226 | { 306000000UL, { 754040, 0, 0 } }, \ | |
227 | { 408000000UL, { 786986, 0, 0 } }, \ | |
228 | { 510000000UL, { 819932, 0, 0 } }, \ | |
229 | { 612000000UL, { 852878, 0, 0 } }, \ | |
230 | { 714000000UL, { 885824, 0, 0 } }, \ | |
231 | { 816000000UL, { 918770, 0, 0 } }, \ | |
232 | { 918000000UL, { 915716, 0, 0 } }, \ | |
233 | { 1020000000UL, { 984662, 0, 0 } }, \ | |
234 | { 1122000000UL, { 1017608, 0, 0 } }, \ | |
235 | { 1224000000UL, { 1050554, 0, 0 } }, \ | |
236 | { 1326000000UL, { 1083500, 0, 0 } }, \ | |
237 | { 1428000000UL, { 1116446, 0, 0 } }, \ | |
238 | { 1581000000UL, { 1130000, 0, 0 } }, \ | |
239 | { 1683000000UL, { 1168000, 0, 0 } }, \ | |
240 | { 1785000000UL, { 1227500, 0, 0 } }, \ | |
241 | { 0UL, { 0, 0, 0 } }, \ | |
242 | } | |
243 | ||
244 | struct cvb_table tegra210_cpu_cvb_tables[] = { | |
245 | { | |
246 | .speedo_id = 10, | |
247 | .process_id = 0, | |
248 | .min_millivolts = 840, | |
249 | .max_millivolts = 1120, | |
250 | CPU_CVB_TABLE_EUCM2_JOINT_RAIL, | |
251 | .cpu_dfll_data = { | |
252 | .tune0_low = 0xffead0ff, | |
253 | .tune0_high = 0xffead0ff, | |
254 | .tune1 = 0x20091d9, | |
255 | .tune_high_min_millivolts = 864, | |
256 | } | |
257 | }, | |
258 | { | |
259 | .speedo_id = 10, | |
260 | .process_id = 1, | |
261 | .min_millivolts = 840, | |
262 | .max_millivolts = 1120, | |
263 | CPU_CVB_TABLE_EUCM2_JOINT_RAIL, | |
264 | .cpu_dfll_data = { | |
265 | .tune0_low = 0xffead0ff, | |
266 | .tune0_high = 0xffead0ff, | |
267 | .tune1 = 0x20091d9, | |
268 | .tune_high_min_millivolts = 864, | |
269 | } | |
270 | }, | |
271 | { | |
272 | .speedo_id = 9, | |
273 | .process_id = 0, | |
274 | .min_millivolts = 900, | |
275 | .max_millivolts = 1162, | |
276 | CPU_CVB_TABLE_EUCM2, | |
277 | .cpu_dfll_data = { | |
278 | .tune0_low = 0xffead0ff, | |
279 | .tune0_high = 0xffead0ff, | |
280 | .tune1 = 0x20091d9, | |
281 | } | |
282 | }, | |
283 | { | |
284 | .speedo_id = 9, | |
285 | .process_id = 1, | |
286 | .min_millivolts = 900, | |
287 | .max_millivolts = 1162, | |
288 | CPU_CVB_TABLE_EUCM2, | |
289 | .cpu_dfll_data = { | |
290 | .tune0_low = 0xffead0ff, | |
291 | .tune0_high = 0xffead0ff, | |
292 | .tune1 = 0x20091d9, | |
293 | } | |
294 | }, | |
295 | { | |
296 | .speedo_id = 8, | |
297 | .process_id = 0, | |
298 | .min_millivolts = 900, | |
299 | .max_millivolts = 1195, | |
300 | CPU_CVB_TABLE_EUCM2, | |
301 | .cpu_dfll_data = { | |
302 | .tune0_low = 0xffead0ff, | |
303 | .tune0_high = 0xffead0ff, | |
304 | .tune1 = 0x20091d9, | |
305 | } | |
306 | }, | |
307 | { | |
308 | .speedo_id = 8, | |
309 | .process_id = 1, | |
310 | .min_millivolts = 900, | |
311 | .max_millivolts = 1195, | |
312 | CPU_CVB_TABLE_EUCM2, | |
313 | .cpu_dfll_data = { | |
314 | .tune0_low = 0xffead0ff, | |
315 | .tune0_high = 0xffead0ff, | |
316 | .tune1 = 0x20091d9, | |
317 | } | |
318 | }, | |
319 | { | |
320 | .speedo_id = 7, | |
321 | .process_id = 0, | |
322 | .min_millivolts = 841, | |
323 | .max_millivolts = 1227, | |
324 | CPU_CVB_TABLE_EUCM1, | |
325 | .cpu_dfll_data = { | |
326 | .tune0_low = 0xffead0ff, | |
327 | .tune0_high = 0xffead0ff, | |
328 | .tune1 = 0x20091d9, | |
329 | .tune_high_min_millivolts = 864, | |
330 | } | |
331 | }, | |
332 | { | |
333 | .speedo_id = 7, | |
334 | .process_id = 1, | |
335 | .min_millivolts = 841, | |
336 | .max_millivolts = 1227, | |
337 | CPU_CVB_TABLE_EUCM1, | |
338 | .cpu_dfll_data = { | |
339 | .tune0_low = 0xffead0ff, | |
340 | .tune0_high = 0xffead0ff, | |
341 | .tune1 = 0x20091d9, | |
342 | .tune_high_min_millivolts = 864, | |
343 | } | |
344 | }, | |
345 | { | |
346 | .speedo_id = 6, | |
347 | .process_id = 0, | |
348 | .min_millivolts = 870, | |
349 | .max_millivolts = 1150, | |
350 | CPU_CVB_TABLE, | |
351 | .cpu_dfll_data = { | |
352 | .tune0_low = 0xffead0ff, | |
353 | .tune1 = 0x20091d9, | |
354 | } | |
355 | }, | |
356 | { | |
357 | .speedo_id = 6, | |
358 | .process_id = 1, | |
359 | .min_millivolts = 870, | |
360 | .max_millivolts = 1150, | |
361 | CPU_CVB_TABLE, | |
362 | .cpu_dfll_data = { | |
363 | .tune0_low = 0xffead0ff, | |
364 | .tune1 = 0x25501d0, | |
365 | } | |
366 | }, | |
367 | { | |
368 | .speedo_id = 5, | |
369 | .process_id = 0, | |
370 | .min_millivolts = 818, | |
371 | .max_millivolts = 1227, | |
372 | CPU_CVB_TABLE, | |
373 | .cpu_dfll_data = { | |
374 | .tune0_low = 0xffead0ff, | |
375 | .tune0_high = 0xffead0ff, | |
376 | .tune1 = 0x20091d9, | |
377 | .tune_high_min_millivolts = 864, | |
378 | } | |
379 | }, | |
380 | { | |
381 | .speedo_id = 5, | |
382 | .process_id = 1, | |
383 | .min_millivolts = 818, | |
384 | .max_millivolts = 1227, | |
385 | CPU_CVB_TABLE, | |
386 | .cpu_dfll_data = { | |
387 | .tune0_low = 0xffead0ff, | |
388 | .tune0_high = 0xffead0ff, | |
389 | .tune1 = 0x25501d0, | |
390 | .tune_high_min_millivolts = 864, | |
391 | } | |
392 | }, | |
393 | { | |
394 | .speedo_id = 4, | |
395 | .process_id = -1, | |
396 | .min_millivolts = 918, | |
397 | .max_millivolts = 1113, | |
398 | CPU_CVB_TABLE_XA, | |
399 | .cpu_dfll_data = { | |
400 | .tune0_low = 0xffead0ff, | |
401 | .tune1 = 0x17711BD, | |
402 | } | |
403 | }, | |
404 | { | |
405 | .speedo_id = 3, | |
406 | .process_id = 0, | |
407 | .min_millivolts = 825, | |
408 | .max_millivolts = 1227, | |
409 | CPU_CVB_TABLE_ODN, | |
410 | .cpu_dfll_data = { | |
411 | .tune0_low = 0xffead0ff, | |
412 | .tune0_high = 0xffead0ff, | |
413 | .tune1 = 0x20091d9, | |
414 | .tune_high_min_millivolts = 864, | |
415 | } | |
416 | }, | |
417 | { | |
418 | .speedo_id = 3, | |
419 | .process_id = 1, | |
420 | .min_millivolts = 825, | |
421 | .max_millivolts = 1227, | |
422 | CPU_CVB_TABLE_ODN, | |
423 | .cpu_dfll_data = { | |
424 | .tune0_low = 0xffead0ff, | |
425 | .tune0_high = 0xffead0ff, | |
426 | .tune1 = 0x25501d0, | |
427 | .tune_high_min_millivolts = 864, | |
428 | } | |
429 | }, | |
430 | { | |
431 | .speedo_id = 2, | |
432 | .process_id = 0, | |
433 | .min_millivolts = 870, | |
434 | .max_millivolts = 1227, | |
435 | CPU_CVB_TABLE, | |
436 | .cpu_dfll_data = { | |
437 | .tune0_low = 0xffead0ff, | |
438 | .tune1 = 0x20091d9, | |
439 | } | |
440 | }, | |
441 | { | |
442 | .speedo_id = 2, | |
443 | .process_id = 1, | |
444 | .min_millivolts = 870, | |
445 | .max_millivolts = 1227, | |
446 | CPU_CVB_TABLE, | |
447 | .cpu_dfll_data = { | |
448 | .tune0_low = 0xffead0ff, | |
449 | .tune1 = 0x25501d0, | |
450 | } | |
451 | }, | |
452 | { | |
453 | .speedo_id = 1, | |
454 | .process_id = 0, | |
455 | .min_millivolts = 837, | |
456 | .max_millivolts = 1227, | |
457 | CPU_CVB_TABLE, | |
458 | .cpu_dfll_data = { | |
459 | .tune0_low = 0xffead0ff, | |
460 | .tune0_high = 0xffead0ff, | |
461 | .tune1 = 0x20091d9, | |
462 | .tune_high_min_millivolts = 864, | |
463 | } | |
464 | }, | |
465 | { | |
466 | .speedo_id = 1, | |
467 | .process_id = 1, | |
468 | .min_millivolts = 837, | |
469 | .max_millivolts = 1227, | |
470 | CPU_CVB_TABLE, | |
471 | .cpu_dfll_data = { | |
472 | .tune0_low = 0xffead0ff, | |
473 | .tune0_high = 0xffead0ff, | |
474 | .tune1 = 0x25501d0, | |
475 | .tune_high_min_millivolts = 864, | |
476 | } | |
477 | }, | |
478 | { | |
479 | .speedo_id = 0, | |
480 | .process_id = 0, | |
481 | .min_millivolts = 850, | |
482 | .max_millivolts = 1170, | |
483 | CPU_CVB_TABLE, | |
484 | .cpu_dfll_data = { | |
485 | .tune0_low = 0xffead0ff, | |
486 | .tune0_high = 0xffead0ff, | |
487 | .tune1 = 0x20091d9, | |
488 | .tune_high_min_millivolts = 864, | |
489 | } | |
490 | }, | |
491 | { | |
492 | .speedo_id = 0, | |
493 | .process_id = 1, | |
494 | .min_millivolts = 850, | |
495 | .max_millivolts = 1170, | |
496 | CPU_CVB_TABLE, | |
497 | .cpu_dfll_data = { | |
498 | .tune0_low = 0xffead0ff, | |
499 | .tune0_high = 0xffead0ff, | |
500 | .tune1 = 0x25501d0, | |
501 | .tune_high_min_millivolts = 864, | |
502 | } | |
503 | }, | |
504 | }; | |
505 | ||
b0dcfb78 PDS |
506 | static const struct dfll_fcpu_data tegra124_dfll_fcpu_data = { |
507 | .cpu_max_freq_table = tegra124_cpu_max_freq_table, | |
508 | .cpu_max_freq_table_size = ARRAY_SIZE(tegra124_cpu_max_freq_table), | |
509 | .cpu_cvb_tables = tegra124_cpu_cvb_tables, | |
510 | .cpu_cvb_tables_size = ARRAY_SIZE(tegra124_cpu_cvb_tables) | |
511 | }; | |
512 | ||
2b2dbc2f JL |
513 | static const struct dfll_fcpu_data tegra210_dfll_fcpu_data = { |
514 | .cpu_max_freq_table = tegra210_cpu_max_freq_table, | |
515 | .cpu_max_freq_table_size = ARRAY_SIZE(tegra210_cpu_max_freq_table), | |
516 | .cpu_cvb_tables = tegra210_cpu_cvb_tables, | |
517 | .cpu_cvb_tables_size = ARRAY_SIZE(tegra210_cpu_cvb_tables), | |
518 | }; | |
519 | ||
b0dcfb78 PDS |
520 | static const struct of_device_id tegra124_dfll_fcpu_of_match[] = { |
521 | { | |
522 | .compatible = "nvidia,tegra124-dfll", | |
523 | .data = &tegra124_dfll_fcpu_data, | |
524 | }, | |
2b2dbc2f JL |
525 | { |
526 | .compatible = "nvidia,tegra210-dfll", | |
527 | .data = &tegra210_dfll_fcpu_data | |
528 | }, | |
b0dcfb78 PDS |
529 | { }, |
530 | }; | |
531 | ||
b3cf8d06 JL |
532 | static void get_alignment_from_dt(struct device *dev, |
533 | struct rail_alignment *align) | |
534 | { | |
535 | if (of_property_read_u32(dev->of_node, | |
536 | "nvidia,pwm-voltage-step-microvolts", | |
537 | &align->step_uv)) | |
538 | align->step_uv = 0; | |
539 | ||
540 | if (of_property_read_u32(dev->of_node, | |
541 | "nvidia,pwm-min-microvolts", | |
542 | &align->offset_uv)) | |
543 | align->offset_uv = 0; | |
544 | } | |
545 | ||
546 | static int get_alignment_from_regulator(struct device *dev, | |
547 | struct rail_alignment *align) | |
548 | { | |
549 | struct regulator *reg = devm_regulator_get(dev, "vdd-cpu"); | |
550 | ||
551 | if (IS_ERR(reg)) | |
552 | return PTR_ERR(reg); | |
553 | ||
554 | align->offset_uv = regulator_list_voltage(reg, 0); | |
555 | align->step_uv = regulator_get_linear_step(reg); | |
556 | ||
557 | devm_regulator_put(reg); | |
558 | ||
559 | return 0; | |
560 | } | |
561 | ||
62a8a094 TT |
562 | static int tegra124_dfll_fcpu_probe(struct platform_device *pdev) |
563 | { | |
f7c42d98 | 564 | int process_id, speedo_id, speedo_value, err; |
62a8a094 | 565 | struct tegra_dfll_soc_data *soc; |
b0dcfb78 | 566 | const struct dfll_fcpu_data *fcpu_data; |
b3cf8d06 | 567 | struct rail_alignment align; |
b0dcfb78 PDS |
568 | |
569 | fcpu_data = of_device_get_match_data(&pdev->dev); | |
570 | if (!fcpu_data) | |
571 | return -ENODEV; | |
62a8a094 TT |
572 | |
573 | process_id = tegra_sku_info.cpu_process_id; | |
574 | speedo_id = tegra_sku_info.cpu_speedo_id; | |
575 | speedo_value = tegra_sku_info.cpu_speedo_value; | |
576 | ||
b0dcfb78 | 577 | if (speedo_id >= fcpu_data->cpu_max_freq_table_size) { |
62a8a094 TT |
578 | dev_err(&pdev->dev, "unknown max CPU freq for speedo_id=%d\n", |
579 | speedo_id); | |
580 | return -ENODEV; | |
581 | } | |
582 | ||
583 | soc = devm_kzalloc(&pdev->dev, sizeof(*soc), GFP_KERNEL); | |
584 | if (!soc) | |
585 | return -ENOMEM; | |
586 | ||
587 | soc->dev = get_cpu_device(0); | |
588 | if (!soc->dev) { | |
589 | dev_err(&pdev->dev, "no CPU0 device\n"); | |
590 | return -ENODEV; | |
591 | } | |
592 | ||
b3cf8d06 JL |
593 | if (of_property_read_bool(pdev->dev.of_node, "nvidia,pwm-to-pmic")) { |
594 | get_alignment_from_dt(&pdev->dev, &align); | |
595 | } else { | |
596 | err = get_alignment_from_regulator(&pdev->dev, &align); | |
597 | if (err) | |
598 | return err; | |
599 | } | |
600 | ||
b0dcfb78 | 601 | soc->max_freq = fcpu_data->cpu_max_freq_table[speedo_id]; |
f7c42d98 | 602 | |
b0dcfb78 PDS |
603 | soc->cvb = tegra_cvb_add_opp_table(soc->dev, fcpu_data->cpu_cvb_tables, |
604 | fcpu_data->cpu_cvb_tables_size, | |
b3cf8d06 JL |
605 | &align, process_id, speedo_id, |
606 | speedo_value, soc->max_freq); | |
607 | soc->alignment = align; | |
f7c42d98 | 608 | |
27ed2f7e TR |
609 | if (IS_ERR(soc->cvb)) { |
610 | dev_err(&pdev->dev, "couldn't add OPP table: %ld\n", | |
611 | PTR_ERR(soc->cvb)); | |
612 | return PTR_ERR(soc->cvb); | |
62a8a094 TT |
613 | } |
614 | ||
f7c42d98 TR |
615 | err = tegra_dfll_register(pdev, soc); |
616 | if (err < 0) { | |
617 | tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq); | |
618 | return err; | |
619 | } | |
620 | ||
f7c42d98 TR |
621 | return 0; |
622 | } | |
623 | ||
624 | static int tegra124_dfll_fcpu_remove(struct platform_device *pdev) | |
625 | { | |
1752c9ee | 626 | struct tegra_dfll_soc_data *soc; |
f7c42d98 | 627 | |
1752c9ee | 628 | soc = tegra_dfll_unregister(pdev); |
d39eca54 | 629 | if (IS_ERR(soc)) { |
1752c9ee NC |
630 | dev_err(&pdev->dev, "failed to unregister DFLL: %ld\n", |
631 | PTR_ERR(soc)); | |
d39eca54 DC |
632 | return PTR_ERR(soc); |
633 | } | |
f7c42d98 TR |
634 | |
635 | tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq); | |
62a8a094 | 636 | |
f7c42d98 | 637 | return 0; |
62a8a094 TT |
638 | } |
639 | ||
62a8a094 TT |
640 | static const struct dev_pm_ops tegra124_dfll_pm_ops = { |
641 | SET_RUNTIME_PM_OPS(tegra_dfll_runtime_suspend, | |
642 | tegra_dfll_runtime_resume, NULL) | |
643 | }; | |
644 | ||
645 | static struct platform_driver tegra124_dfll_fcpu_driver = { | |
646 | .probe = tegra124_dfll_fcpu_probe, | |
f7c42d98 | 647 | .remove = tegra124_dfll_fcpu_remove, |
62a8a094 TT |
648 | .driver = { |
649 | .name = "tegra124-dfll", | |
650 | .of_match_table = tegra124_dfll_fcpu_of_match, | |
651 | .pm = &tegra124_dfll_pm_ops, | |
652 | }, | |
653 | }; | |
6f877e79 | 654 | builtin_platform_driver(tegra124_dfll_fcpu_driver); |