xref: /linux/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c (revision 522ba450b56fff29f868b1552bdc2965f55de7ed)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Tegra124 DFLL FCPU clock source driver
4  *
5  * Copyright (C) 2012-2019 NVIDIA Corporation.  All rights reserved.
6  *
7  * Aleksandr Frid <afrid@nvidia.com>
8  * Paul Walmsley <pwalmsley@nvidia.com>
9  */
10 
11 #include <linux/cpu.h>
12 #include <linux/err.h>
13 #include <linux/kernel.h>
14 #include <linux/init.h>
15 #include <linux/of.h>
16 #include <linux/platform_device.h>
17 #include <linux/regulator/consumer.h>
18 #include <soc/tegra/fuse.h>
19 
20 #include "clk.h"
21 #include "clk-dfll.h"
22 #include "cvb.h"
23 
24 struct dfll_fcpu_data {
25 	const unsigned long *cpu_max_freq_table;
26 	unsigned int cpu_max_freq_table_size;
27 	const struct cvb_table *cpu_cvb_tables;
28 	unsigned int cpu_cvb_tables_size;
29 };
30 
31 /* Maximum CPU frequency, indexed by CPU speedo id */
32 static const unsigned long tegra114_cpu_max_freq_table[] = {
33 	[0] = 2040000000UL,
34 	[1] = 1810500000UL,
35 	[2] = 1912500000UL,
36 	[3] = 1810500000UL,
37 };
38 
39 #define T114_CPU_CVB_TABLE \
40 	.min_millivolts = 1000, \
41 	.max_millivolts = 1320, \
42 	.speedo_scale = 100,    \
43 	.voltage_scale = 1000,  \
44 	.entries = {            \
45 		{  306000000UL, { 2190643, -141851, 3576 } }, \
46 		{  408000000UL, { 2250968, -144331, 3576 } }, \
47 		{  510000000UL, { 2313333, -146811, 3576 } }, \
48 		{  612000000UL, { 2377738, -149291, 3576 } }, \
49 		{  714000000UL, { 2444183, -151771, 3576 } }, \
50 		{  816000000UL, { 2512669, -154251, 3576 } }, \
51 		{  918000000UL, { 2583194, -156731, 3576 } }, \
52 		{ 1020000000UL, { 2655759, -159211, 3576 } }, \
53 		{ 1122000000UL, { 2730365, -161691, 3576 } }, \
54 		{ 1224000000UL, { 2807010, -164171, 3576 } }, \
55 		{ 1326000000UL, { 2885696, -166651, 3576 } }, \
56 		{ 1428000000UL, { 2966422, -169131, 3576 } }, \
57 		{ 1530000000UL, { 3049183, -171601, 3576 } }, \
58 		{ 1606500000UL, { 3112179, -173451, 3576 } }, \
59 		{ 1708500000UL, { 3198504, -175931, 3576 } }, \
60 		{ 1810500000UL, { 3304747, -179126, 3576 } }, \
61 		{ 1912500000UL, { 3395401, -181606, 3576 } }, \
62 		{          0UL, {       0,       0,    0 } }, \
63 	}, \
64 	.cpu_dfll_data = {      \
65 		.tune0_low = 0x00b0039d,          \
66 		.tune0_high = 0x00b0009d,         \
67 		.tune1 = 0x0000001f,              \
68 		.tune_high_min_millivolts = 1050, \
69 	}
70 
71 static const struct cvb_table tegra114_cpu_cvb_tables[] = {
72 	{
73 		.speedo_id = 0,
74 		.process_id = -1,
75 		.min_millivolts = 1000,
76 		.max_millivolts = 1250,
77 		.speedo_scale = 100,
78 		.voltage_scale = 100,
79 		.entries = {
80 			{  306000000UL, { 107330, -1569,   0 } },
81 			{  408000000UL, { 111250, -1666,   0 } },
82 			{  510000000UL, { 110000, -1460,   0 } },
83 			{  612000000UL, { 117290, -1745,   0 } },
84 			{  714000000UL, { 122700, -1910,   0 } },
85 			{  816000000UL, { 125620, -1945,   0 } },
86 			{  918000000UL, { 130560, -2076,   0 } },
87 			{ 1020000000UL, { 137280, -2303,   0 } },
88 			{ 1122000000UL, { 146440, -2660,   0 } },
89 			{ 1224000000UL, { 152190, -2825,   0 } },
90 			{ 1326000000UL, { 157520, -2953,   0 } },
91 			{ 1428000000UL, { 166100, -3261,   0 } },
92 			{ 1530000000UL, { 176410, -3647,   0 } },
93 			{ 1632000000UL, { 189620, -4186,   0 } },
94 			{ 1734000000UL, { 203190, -4725,   0 } },
95 			{ 1836000000UL, { 222670, -5573,   0 } },
96 			{ 1938000000UL, { 256210, -7165,   0 } },
97 			{ 2040000000UL, { 250050, -6544,   0 } },
98 			{          0UL, {      0,     0,   0 } },
99 		},
100 		.cpu_dfll_data = {
101 			.tune0_low = 0x00b0019d,
102 			.tune0_high = 0x00b0019d,
103 			.tune1 = 0x0000001f,
104 			.tune_high_min_millivolts = 1000,
105 		}
106 	},
107 	{
108 		.speedo_id = 1,
109 		.process_id = -1,
110 		T114_CPU_CVB_TABLE
111 	},
112 	{
113 		.speedo_id = 2,
114 		.process_id = -1,
115 		T114_CPU_CVB_TABLE
116 	},
117 	{
118 		.speedo_id = 3,
119 		.process_id = -1,
120 		T114_CPU_CVB_TABLE
121 	},
122 };
123 
124 /* Maximum CPU frequency, indexed by CPU speedo id */
125 static const unsigned long tegra124_cpu_max_freq_table[] = {
126 	[0] = 2014500000UL,
127 	[1] = 2320500000UL,
128 	[2] = 2116500000UL,
129 	[3] = 2524500000UL,
130 };
131 
132 static const struct cvb_table tegra124_cpu_cvb_tables[] = {
133 	{
134 		.speedo_id = -1,
135 		.process_id = -1,
136 		.min_millivolts = 900,
137 		.max_millivolts = 1260,
138 		.speedo_scale = 100,
139 		.voltage_scale = 1000,
140 		.entries = {
141 			{  204000000UL, { 1112619, -29295, 402 } },
142 			{  306000000UL, { 1150460, -30585, 402 } },
143 			{  408000000UL, { 1190122, -31865, 402 } },
144 			{  510000000UL, { 1231606, -33155, 402 } },
145 			{  612000000UL, { 1274912, -34435, 402 } },
146 			{  714000000UL, { 1320040, -35725, 402 } },
147 			{  816000000UL, { 1366990, -37005, 402 } },
148 			{  918000000UL, { 1415762, -38295, 402 } },
149 			{ 1020000000UL, { 1466355, -39575, 402 } },
150 			{ 1122000000UL, { 1518771, -40865, 402 } },
151 			{ 1224000000UL, { 1573009, -42145, 402 } },
152 			{ 1326000000UL, { 1629068, -43435, 402 } },
153 			{ 1428000000UL, { 1686950, -44715, 402 } },
154 			{ 1530000000UL, { 1746653, -46005, 402 } },
155 			{ 1632000000UL, { 1808179, -47285, 402 } },
156 			{ 1734000000UL, { 1871526, -48575, 402 } },
157 			{ 1836000000UL, { 1936696, -49855, 402 } },
158 			{ 1938000000UL, { 2003687, -51145, 402 } },
159 			{ 2014500000UL, { 2054787, -52095, 402 } },
160 			{ 2116500000UL, { 2124957, -53385, 402 } },
161 			{ 2218500000UL, { 2196950, -54665, 402 } },
162 			{ 2320500000UL, { 2270765, -55955, 402 } },
163 			{ 2422500000UL, { 2346401, -57235, 402 } },
164 			{ 2524500000UL, { 2437299, -58535, 402 } },
165 			{          0UL, {       0,      0,   0 } },
166 		},
167 		.cpu_dfll_data = {
168 			.tune0_low = 0x005020ff,
169 			.tune0_high = 0x005040ff,
170 			.tune1 = 0x00000060,
171 		}
172 	},
173 };
174 
175 static const unsigned long tegra210_cpu_max_freq_table[] = {
176 	[0] = 1912500000UL,
177 	[1] = 1912500000UL,
178 	[2] = 2218500000UL,
179 	[3] = 1785000000UL,
180 	[4] = 1632000000UL,
181 	[5] = 1912500000UL,
182 	[6] = 2014500000UL,
183 	[7] = 1734000000UL,
184 	[8] = 1683000000UL,
185 	[9] = 1555500000UL,
186 	[10] = 1504500000UL,
187 };
188 
189 #define TEGRA210_CPU_CVB_TABLE \
190 	.speedo_scale = 100,	\
191 	.voltage_scale = 1000,	\
192 	.entries = {		\
193 		{  204000000UL,	{ 1007452, -23865, 370 } }, \
194 		{  306000000UL,	{ 1052709, -24875, 370 } }, \
195 		{  408000000UL,	{ 1099069, -25895, 370 } }, \
196 		{  510000000UL,	{ 1146534, -26905, 370 } }, \
197 		{  612000000UL,	{ 1195102, -27915, 370 } }, \
198 		{  714000000UL,	{ 1244773, -28925, 370 } }, \
199 		{  816000000UL,	{ 1295549, -29935, 370 } }, \
200 		{  918000000UL,	{ 1347428, -30955, 370 } }, \
201 		{ 1020000000UL,	{ 1400411, -31965, 370 } }, \
202 		{ 1122000000UL,	{ 1454497, -32975, 370 } }, \
203 		{ 1224000000UL,	{ 1509687, -33985, 370 } }, \
204 		{ 1326000000UL,	{ 1565981, -35005, 370 } }, \
205 		{ 1428000000UL,	{ 1623379, -36015, 370 } }, \
206 		{ 1530000000UL,	{ 1681880, -37025, 370 } }, \
207 		{ 1632000000UL,	{ 1741485, -38035, 370 } }, \
208 		{ 1734000000UL,	{ 1802194, -39055, 370 } }, \
209 		{ 1836000000UL,	{ 1864006, -40065, 370 } }, \
210 		{ 1912500000UL,	{ 1910780, -40815, 370 } }, \
211 		{ 2014500000UL,	{ 1227000,      0,   0 } }, \
212 		{ 2218500000UL,	{ 1227000,      0,   0 } }, \
213 		{          0UL,	{       0,      0,   0 } }, \
214 	}
215 
216 #define TEGRA210_CPU_CVB_TABLE_XA \
217 	.speedo_scale = 100,	\
218 	.voltage_scale = 1000,	\
219 	.entries = {		\
220 		{  204000000UL,	{ 1250024, -39785, 565 } }, \
221 		{  306000000UL,	{ 1297556, -41145, 565 } }, \
222 		{  408000000UL,	{ 1346718, -42505, 565 } }, \
223 		{  510000000UL,	{ 1397511, -43855, 565 } }, \
224 		{  612000000UL,	{ 1449933, -45215, 565 } }, \
225 		{  714000000UL,	{ 1503986, -46575, 565 } }, \
226 		{  816000000UL,	{ 1559669, -47935, 565 } }, \
227 		{  918000000UL,	{ 1616982, -49295, 565 } }, \
228 		{ 1020000000UL,	{ 1675926, -50645, 565 } }, \
229 		{ 1122000000UL,	{ 1736500, -52005, 565 } }, \
230 		{ 1224000000UL,	{ 1798704, -53365, 565 } }, \
231 		{ 1326000000UL,	{ 1862538, -54725, 565 } }, \
232 		{ 1428000000UL,	{ 1928003, -56085, 565 } }, \
233 		{ 1530000000UL,	{ 1995097, -57435, 565 } }, \
234 		{ 1606500000UL,	{ 2046149, -58445, 565 } }, \
235 		{ 1632000000UL,	{ 2063822, -58795, 565 } }, \
236 		{          0UL,	{       0,      0,   0 } }, \
237 	}
238 
239 #define TEGRA210_CPU_CVB_TABLE_EUCM1 \
240 	.speedo_scale = 100,	\
241 	.voltage_scale = 1000,	\
242 	.entries = {		\
243 		{  204000000UL,	{  734429, 0, 0 } }, \
244 		{  306000000UL,	{  768191, 0, 0 } }, \
245 		{  408000000UL,	{  801953, 0, 0 } }, \
246 		{  510000000UL,	{  835715, 0, 0 } }, \
247 		{  612000000UL,	{  869477, 0, 0 } }, \
248 		{  714000000UL,	{  903239, 0, 0 } }, \
249 		{  816000000UL,	{  937001, 0, 0 } }, \
250 		{  918000000UL,	{  970763, 0, 0 } }, \
251 		{ 1020000000UL,	{ 1004525, 0, 0 } }, \
252 		{ 1122000000UL,	{ 1038287, 0, 0 } }, \
253 		{ 1224000000UL,	{ 1072049, 0, 0 } }, \
254 		{ 1326000000UL,	{ 1105811, 0, 0 } }, \
255 		{ 1428000000UL,	{ 1130000, 0, 0 } }, \
256 		{ 1555500000UL,	{ 1130000, 0, 0 } }, \
257 		{ 1632000000UL,	{ 1170000, 0, 0 } }, \
258 		{ 1734000000UL,	{ 1227500, 0, 0 } }, \
259 		{          0UL,	{       0, 0, 0 } }, \
260 	}
261 
262 #define TEGRA210_CPU_CVB_TABLE_EUCM2 \
263 	.speedo_scale = 100,	\
264 	.voltage_scale = 1000,	\
265 	.entries = {		\
266 		{  204000000UL,	{  742283, 0, 0 } }, \
267 		{  306000000UL,	{  776249, 0, 0 } }, \
268 		{  408000000UL,	{  810215, 0, 0 } }, \
269 		{  510000000UL,	{  844181, 0, 0 } }, \
270 		{  612000000UL,	{  878147, 0, 0 } }, \
271 		{  714000000UL,	{  912113, 0, 0 } }, \
272 		{  816000000UL,	{  946079, 0, 0 } }, \
273 		{  918000000UL,	{  980045, 0, 0 } }, \
274 		{ 1020000000UL,	{ 1014011, 0, 0 } }, \
275 		{ 1122000000UL,	{ 1047977, 0, 0 } }, \
276 		{ 1224000000UL,	{ 1081943, 0, 0 } }, \
277 		{ 1326000000UL,	{ 1090000, 0, 0 } }, \
278 		{ 1479000000UL,	{ 1090000, 0, 0 } }, \
279 		{ 1555500000UL,	{ 1162000, 0, 0 } }, \
280 		{ 1683000000UL,	{ 1195000, 0, 0 } }, \
281 		{          0UL,	{       0, 0, 0 } }, \
282 	}
283 
284 #define TEGRA210_CPU_CVB_TABLE_EUCM2_JOINT_RAIL \
285 	.speedo_scale = 100,	\
286 	.voltage_scale = 1000,	\
287 	.entries = {		\
288 		{  204000000UL,	{  742283, 0, 0 } }, \
289 		{  306000000UL,	{  776249, 0, 0 } }, \
290 		{  408000000UL,	{  810215, 0, 0 } }, \
291 		{  510000000UL,	{  844181, 0, 0 } }, \
292 		{  612000000UL,	{  878147, 0, 0 } }, \
293 		{  714000000UL,	{  912113, 0, 0 } }, \
294 		{  816000000UL,	{  946079, 0, 0 } }, \
295 		{  918000000UL,	{  980045, 0, 0 } }, \
296 		{ 1020000000UL,	{ 1014011, 0, 0 } }, \
297 		{ 1122000000UL,	{ 1047977, 0, 0 } }, \
298 		{ 1224000000UL,	{ 1081943, 0, 0 } }, \
299 		{ 1326000000UL,	{ 1090000, 0, 0 } }, \
300 		{ 1479000000UL,	{ 1090000, 0, 0 } }, \
301 		{ 1504500000UL,	{ 1120000, 0, 0 } }, \
302 		{          0UL,	{       0, 0, 0 } }, \
303 	}
304 
305 #define TEGRA210_CPU_CVB_TABLE_ODN \
306 	.speedo_scale = 100,	\
307 	.voltage_scale = 1000,	\
308 	.entries = {		\
309 		{  204000000UL,	{  721094, 0, 0 } }, \
310 		{  306000000UL,	{  754040, 0, 0 } }, \
311 		{  408000000UL,	{  786986, 0, 0 } }, \
312 		{  510000000UL,	{  819932, 0, 0 } }, \
313 		{  612000000UL,	{  852878, 0, 0 } }, \
314 		{  714000000UL,	{  885824, 0, 0 } }, \
315 		{  816000000UL,	{  918770, 0, 0 } }, \
316 		{  918000000UL,	{  915716, 0, 0 } }, \
317 		{ 1020000000UL,	{  984662, 0, 0 } }, \
318 		{ 1122000000UL,	{ 1017608, 0, 0 } }, \
319 		{ 1224000000UL,	{ 1050554, 0, 0 } }, \
320 		{ 1326000000UL,	{ 1083500, 0, 0 } }, \
321 		{ 1428000000UL,	{ 1116446, 0, 0 } }, \
322 		{ 1581000000UL,	{ 1130000, 0, 0 } }, \
323 		{ 1683000000UL,	{ 1168000, 0, 0 } }, \
324 		{ 1785000000UL,	{ 1227500, 0, 0 } }, \
325 		{          0UL,	{       0, 0, 0 } }, \
326 	}
327 
328 static struct cvb_table tegra210_cpu_cvb_tables[] = {
329 	{
330 		.speedo_id = 10,
331 		.process_id = 0,
332 		.min_millivolts = 840,
333 		.max_millivolts = 1120,
334 		TEGRA210_CPU_CVB_TABLE_EUCM2_JOINT_RAIL,
335 		.cpu_dfll_data = {
336 			.tune0_low = 0xffead0ff,
337 			.tune0_high = 0xffead0ff,
338 			.tune1 = 0x20091d9,
339 			.tune_high_min_millivolts = 864,
340 		}
341 	},
342 	{
343 		.speedo_id = 10,
344 		.process_id = 1,
345 		.min_millivolts = 840,
346 		.max_millivolts = 1120,
347 		TEGRA210_CPU_CVB_TABLE_EUCM2_JOINT_RAIL,
348 		.cpu_dfll_data = {
349 			.tune0_low = 0xffead0ff,
350 			.tune0_high = 0xffead0ff,
351 			.tune1 = 0x20091d9,
352 			.tune_high_min_millivolts = 864,
353 		}
354 	},
355 	{
356 		.speedo_id = 9,
357 		.process_id = 0,
358 		.min_millivolts = 900,
359 		.max_millivolts = 1162,
360 		TEGRA210_CPU_CVB_TABLE_EUCM2,
361 		.cpu_dfll_data = {
362 			.tune0_low = 0xffead0ff,
363 			.tune0_high = 0xffead0ff,
364 			.tune1 = 0x20091d9,
365 		}
366 	},
367 	{
368 		.speedo_id = 9,
369 		.process_id = 1,
370 		.min_millivolts = 900,
371 		.max_millivolts = 1162,
372 		TEGRA210_CPU_CVB_TABLE_EUCM2,
373 		.cpu_dfll_data = {
374 			.tune0_low = 0xffead0ff,
375 			.tune0_high = 0xffead0ff,
376 			.tune1 = 0x20091d9,
377 		}
378 	},
379 	{
380 		.speedo_id = 8,
381 		.process_id = 0,
382 		.min_millivolts = 900,
383 		.max_millivolts = 1195,
384 		TEGRA210_CPU_CVB_TABLE_EUCM2,
385 		.cpu_dfll_data = {
386 			.tune0_low = 0xffead0ff,
387 			.tune0_high = 0xffead0ff,
388 			.tune1 = 0x20091d9,
389 		}
390 	},
391 	{
392 		.speedo_id = 8,
393 		.process_id = 1,
394 		.min_millivolts = 900,
395 		.max_millivolts = 1195,
396 		TEGRA210_CPU_CVB_TABLE_EUCM2,
397 		.cpu_dfll_data = {
398 			.tune0_low = 0xffead0ff,
399 			.tune0_high = 0xffead0ff,
400 			.tune1 = 0x20091d9,
401 		}
402 	},
403 	{
404 		.speedo_id = 7,
405 		.process_id = 0,
406 		.min_millivolts = 841,
407 		.max_millivolts = 1227,
408 		TEGRA210_CPU_CVB_TABLE_EUCM1,
409 		.cpu_dfll_data = {
410 			.tune0_low = 0xffead0ff,
411 			.tune0_high = 0xffead0ff,
412 			.tune1 = 0x20091d9,
413 			.tune_high_min_millivolts = 864,
414 		}
415 	},
416 	{
417 		.speedo_id = 7,
418 		.process_id = 1,
419 		.min_millivolts = 841,
420 		.max_millivolts = 1227,
421 		TEGRA210_CPU_CVB_TABLE_EUCM1,
422 		.cpu_dfll_data = {
423 			.tune0_low = 0xffead0ff,
424 			.tune0_high = 0xffead0ff,
425 			.tune1 = 0x20091d9,
426 			.tune_high_min_millivolts = 864,
427 		}
428 	},
429 	{
430 		.speedo_id = 6,
431 		.process_id = 0,
432 		.min_millivolts = 870,
433 		.max_millivolts = 1150,
434 		TEGRA210_CPU_CVB_TABLE,
435 		.cpu_dfll_data = {
436 			.tune0_low = 0xffead0ff,
437 			.tune1 = 0x20091d9,
438 		}
439 	},
440 	{
441 		.speedo_id = 6,
442 		.process_id = 1,
443 		.min_millivolts = 870,
444 		.max_millivolts = 1150,
445 		TEGRA210_CPU_CVB_TABLE,
446 		.cpu_dfll_data = {
447 			.tune0_low = 0xffead0ff,
448 			.tune1 = 0x25501d0,
449 		}
450 	},
451 	{
452 		.speedo_id = 5,
453 		.process_id = 0,
454 		.min_millivolts = 818,
455 		.max_millivolts = 1227,
456 		TEGRA210_CPU_CVB_TABLE,
457 		.cpu_dfll_data = {
458 			.tune0_low = 0xffead0ff,
459 			.tune0_high = 0xffead0ff,
460 			.tune1 = 0x20091d9,
461 			.tune_high_min_millivolts = 864,
462 		}
463 	},
464 	{
465 		.speedo_id = 5,
466 		.process_id = 1,
467 		.min_millivolts = 818,
468 		.max_millivolts = 1227,
469 		TEGRA210_CPU_CVB_TABLE,
470 		.cpu_dfll_data = {
471 			.tune0_low = 0xffead0ff,
472 			.tune0_high = 0xffead0ff,
473 			.tune1 = 0x25501d0,
474 			.tune_high_min_millivolts = 864,
475 		}
476 	},
477 	{
478 		.speedo_id = 4,
479 		.process_id = -1,
480 		.min_millivolts = 918,
481 		.max_millivolts = 1113,
482 		TEGRA210_CPU_CVB_TABLE_XA,
483 		.cpu_dfll_data = {
484 			.tune0_low = 0xffead0ff,
485 			.tune1 = 0x17711BD,
486 		}
487 	},
488 	{
489 		.speedo_id = 3,
490 		.process_id = 0,
491 		.min_millivolts = 825,
492 		.max_millivolts = 1227,
493 		TEGRA210_CPU_CVB_TABLE_ODN,
494 		.cpu_dfll_data = {
495 			.tune0_low = 0xffead0ff,
496 			.tune0_high = 0xffead0ff,
497 			.tune1 = 0x20091d9,
498 			.tune_high_min_millivolts = 864,
499 		}
500 	},
501 	{
502 		.speedo_id = 3,
503 		.process_id = 1,
504 		.min_millivolts = 825,
505 		.max_millivolts = 1227,
506 		TEGRA210_CPU_CVB_TABLE_ODN,
507 		.cpu_dfll_data = {
508 			.tune0_low = 0xffead0ff,
509 			.tune0_high = 0xffead0ff,
510 			.tune1 = 0x25501d0,
511 			.tune_high_min_millivolts = 864,
512 		}
513 	},
514 	{
515 		.speedo_id = 2,
516 		.process_id = 0,
517 		.min_millivolts = 870,
518 		.max_millivolts = 1227,
519 		TEGRA210_CPU_CVB_TABLE,
520 		.cpu_dfll_data = {
521 			.tune0_low = 0xffead0ff,
522 			.tune1 = 0x20091d9,
523 		}
524 	},
525 	{
526 		.speedo_id = 2,
527 		.process_id = 1,
528 		.min_millivolts = 870,
529 		.max_millivolts = 1227,
530 		TEGRA210_CPU_CVB_TABLE,
531 		.cpu_dfll_data = {
532 			.tune0_low = 0xffead0ff,
533 			.tune1 = 0x25501d0,
534 		}
535 	},
536 	{
537 		.speedo_id = 1,
538 		.process_id = 0,
539 		.min_millivolts = 837,
540 		.max_millivolts = 1227,
541 		TEGRA210_CPU_CVB_TABLE,
542 		.cpu_dfll_data = {
543 			.tune0_low = 0xffead0ff,
544 			.tune0_high = 0xffead0ff,
545 			.tune1 = 0x20091d9,
546 			.tune_high_min_millivolts = 864,
547 		}
548 	},
549 	{
550 		.speedo_id = 1,
551 		.process_id = 1,
552 		.min_millivolts = 837,
553 		.max_millivolts = 1227,
554 		TEGRA210_CPU_CVB_TABLE,
555 		.cpu_dfll_data = {
556 			.tune0_low = 0xffead0ff,
557 			.tune0_high = 0xffead0ff,
558 			.tune1 = 0x25501d0,
559 			.tune_high_min_millivolts = 864,
560 		}
561 	},
562 	{
563 		.speedo_id = 0,
564 		.process_id = 0,
565 		.min_millivolts = 850,
566 		.max_millivolts = 1170,
567 		TEGRA210_CPU_CVB_TABLE,
568 		.cpu_dfll_data = {
569 			.tune0_low = 0xffead0ff,
570 			.tune0_high = 0xffead0ff,
571 			.tune1 = 0x20091d9,
572 			.tune_high_min_millivolts = 864,
573 		}
574 	},
575 	{
576 		.speedo_id = 0,
577 		.process_id = 1,
578 		.min_millivolts = 850,
579 		.max_millivolts = 1170,
580 		TEGRA210_CPU_CVB_TABLE,
581 		.cpu_dfll_data = {
582 			.tune0_low = 0xffead0ff,
583 			.tune0_high = 0xffead0ff,
584 			.tune1 = 0x25501d0,
585 			.tune_high_min_millivolts = 864,
586 		}
587 	},
588 };
589 
590 static const struct dfll_fcpu_data tegra114_dfll_fcpu_data = {
591 	.cpu_max_freq_table = tegra114_cpu_max_freq_table,
592 	.cpu_max_freq_table_size = ARRAY_SIZE(tegra114_cpu_max_freq_table),
593 	.cpu_cvb_tables = tegra114_cpu_cvb_tables,
594 	.cpu_cvb_tables_size = ARRAY_SIZE(tegra114_cpu_cvb_tables)
595 };
596 
597 static const struct dfll_fcpu_data tegra124_dfll_fcpu_data = {
598 	.cpu_max_freq_table = tegra124_cpu_max_freq_table,
599 	.cpu_max_freq_table_size = ARRAY_SIZE(tegra124_cpu_max_freq_table),
600 	.cpu_cvb_tables = tegra124_cpu_cvb_tables,
601 	.cpu_cvb_tables_size = ARRAY_SIZE(tegra124_cpu_cvb_tables)
602 };
603 
604 static const struct dfll_fcpu_data tegra210_dfll_fcpu_data = {
605 	.cpu_max_freq_table = tegra210_cpu_max_freq_table,
606 	.cpu_max_freq_table_size = ARRAY_SIZE(tegra210_cpu_max_freq_table),
607 	.cpu_cvb_tables = tegra210_cpu_cvb_tables,
608 	.cpu_cvb_tables_size = ARRAY_SIZE(tegra210_cpu_cvb_tables),
609 };
610 
611 static const struct of_device_id tegra124_dfll_fcpu_of_match[] = {
612 	{
613 		.compatible = "nvidia,tegra114-dfll",
614 		.data = &tegra114_dfll_fcpu_data,
615 	},
616 	{
617 		.compatible = "nvidia,tegra124-dfll",
618 		.data = &tegra124_dfll_fcpu_data,
619 	},
620 	{
621 		.compatible = "nvidia,tegra210-dfll",
622 		.data = &tegra210_dfll_fcpu_data
623 	},
624 	{ },
625 };
626 
get_alignment_from_dt(struct device * dev,struct rail_alignment * align)627 static void get_alignment_from_dt(struct device *dev,
628 				  struct rail_alignment *align)
629 {
630 	if (of_property_read_u32(dev->of_node,
631 				 "nvidia,pwm-voltage-step-microvolts",
632 				 &align->step_uv))
633 		align->step_uv = 0;
634 
635 	if (of_property_read_u32(dev->of_node,
636 				 "nvidia,pwm-min-microvolts",
637 				 &align->offset_uv))
638 		align->offset_uv = 0;
639 }
640 
get_alignment_from_regulator(struct device * dev,struct rail_alignment * align)641 static int get_alignment_from_regulator(struct device *dev,
642 					 struct rail_alignment *align)
643 {
644 	struct regulator *reg = regulator_get(dev, "vdd-cpu");
645 
646 	if (IS_ERR(reg))
647 		return PTR_ERR(reg);
648 
649 	align->offset_uv = regulator_list_voltage(reg, 0);
650 	align->step_uv = regulator_get_linear_step(reg);
651 
652 	regulator_put(reg);
653 
654 	return 0;
655 }
656 
tegra124_dfll_fcpu_probe(struct platform_device * pdev)657 static int tegra124_dfll_fcpu_probe(struct platform_device *pdev)
658 {
659 	int process_id, speedo_id, speedo_value, err;
660 	struct tegra_dfll_soc_data *soc;
661 	const struct dfll_fcpu_data *fcpu_data;
662 	struct rail_alignment align;
663 
664 	fcpu_data = of_device_get_match_data(&pdev->dev);
665 	if (!fcpu_data)
666 		return -ENODEV;
667 
668 	process_id = tegra_sku_info.cpu_process_id;
669 	speedo_id = tegra_sku_info.cpu_speedo_id;
670 	speedo_value = tegra_sku_info.cpu_speedo_value;
671 
672 	if (speedo_id >= fcpu_data->cpu_max_freq_table_size) {
673 		dev_err(&pdev->dev, "unknown max CPU freq for speedo_id=%d\n",
674 			speedo_id);
675 		return -ENODEV;
676 	}
677 
678 	soc = devm_kzalloc(&pdev->dev, sizeof(*soc), GFP_KERNEL);
679 	if (!soc)
680 		return -ENOMEM;
681 
682 	soc->dev = get_cpu_device(0);
683 	if (!soc->dev) {
684 		dev_err(&pdev->dev, "no CPU0 device\n");
685 		return -ENODEV;
686 	}
687 
688 	if (of_property_read_bool(pdev->dev.of_node, "nvidia,pwm-to-pmic")) {
689 		get_alignment_from_dt(&pdev->dev, &align);
690 	} else {
691 		err = get_alignment_from_regulator(&pdev->dev, &align);
692 		if (err)
693 			return err;
694 	}
695 
696 	soc->max_freq = fcpu_data->cpu_max_freq_table[speedo_id];
697 
698 	soc->cvb = tegra_cvb_add_opp_table(soc->dev, fcpu_data->cpu_cvb_tables,
699 					   fcpu_data->cpu_cvb_tables_size,
700 					   &align, process_id, speedo_id,
701 					   speedo_value, soc->max_freq);
702 	soc->alignment = align;
703 
704 	if (IS_ERR(soc->cvb)) {
705 		dev_err(&pdev->dev, "couldn't add OPP table: %ld\n",
706 			PTR_ERR(soc->cvb));
707 		return PTR_ERR(soc->cvb);
708 	}
709 
710 	err = tegra_dfll_register(pdev, soc);
711 	if (err < 0) {
712 		tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq);
713 		return err;
714 	}
715 
716 	return 0;
717 }
718 
tegra124_dfll_fcpu_remove(struct platform_device * pdev)719 static void tegra124_dfll_fcpu_remove(struct platform_device *pdev)
720 {
721 	struct tegra_dfll_soc_data *soc;
722 
723 	/*
724 	 * Note that exiting early here is dangerous as after this function
725 	 * returns *soc is freed.
726 	 */
727 	soc = tegra_dfll_unregister(pdev);
728 	if (IS_ERR(soc))
729 		return;
730 
731 	tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq);
732 }
733 
734 static const struct dev_pm_ops tegra124_dfll_pm_ops = {
735 	SET_RUNTIME_PM_OPS(tegra_dfll_runtime_suspend,
736 			   tegra_dfll_runtime_resume, NULL)
737 	SET_SYSTEM_SLEEP_PM_OPS(tegra_dfll_suspend, tegra_dfll_resume)
738 };
739 
740 static struct platform_driver tegra124_dfll_fcpu_driver = {
741 	.probe = tegra124_dfll_fcpu_probe,
742 	.remove = tegra124_dfll_fcpu_remove,
743 	.driver = {
744 		.name = "tegra124-dfll",
745 		.of_match_table = tegra124_dfll_fcpu_of_match,
746 		.pm = &tegra124_dfll_pm_ops,
747 	},
748 };
749 builtin_platform_driver(tegra124_dfll_fcpu_driver);
750