File Index
Files and directories
Sign in
FILE

clk-tegra124-dfll-fcpu.c

File preview with syntax highlighting.

linux-6.19.14/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c C
  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
 24struct 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 */
 32static 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
 71static 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 */
125static const unsigned long tegra124_cpu_max_freq_table[] = {
126	[0] = 2014500000UL,
127	[1] = 2320500000UL,
128	[2] = 2116500000UL,
129	[3] = 2524500000UL,
130};
131
132static 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
175static 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
328static 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
590static 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
597static 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
604static 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
611static 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
627static 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
641static 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
657static 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
719static 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
734static 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
740static 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};
749builtin_platform_driver(tegra124_dfll_fcpu_driver);
~/ Read-only file preview.