Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Tegra124 DFLL FCPU clock source driver
0004  *
0005  * Copyright (C) 2012-2019 NVIDIA Corporation.  All rights reserved.
0006  *
0007  * Aleksandr Frid <afrid@nvidia.com>
0008  * Paul Walmsley <pwalmsley@nvidia.com>
0009  */
0010 
0011 #include <linux/cpu.h>
0012 #include <linux/err.h>
0013 #include <linux/kernel.h>
0014 #include <linux/init.h>
0015 #include <linux/of_device.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/regulator/consumer.h>
0018 #include <soc/tegra/fuse.h>
0019 
0020 #include "clk.h"
0021 #include "clk-dfll.h"
0022 #include "cvb.h"
0023 
0024 struct dfll_fcpu_data {
0025     const unsigned long *cpu_max_freq_table;
0026     unsigned int cpu_max_freq_table_size;
0027     const struct cvb_table *cpu_cvb_tables;
0028     unsigned int cpu_cvb_tables_size;
0029 };
0030 
0031 /* Maximum CPU frequency, indexed by CPU speedo id */
0032 static const unsigned long tegra124_cpu_max_freq_table[] = {
0033     [0] = 2014500000UL,
0034     [1] = 2320500000UL,
0035     [2] = 2116500000UL,
0036     [3] = 2524500000UL,
0037 };
0038 
0039 static const struct cvb_table tegra124_cpu_cvb_tables[] = {
0040     {
0041         .speedo_id = -1,
0042         .process_id = -1,
0043         .min_millivolts = 900,
0044         .max_millivolts = 1260,
0045         .speedo_scale = 100,
0046         .voltage_scale = 1000,
0047         .entries = {
0048             {  204000000UL, { 1112619, -29295, 402 } },
0049             {  306000000UL, { 1150460, -30585, 402 } },
0050             {  408000000UL, { 1190122, -31865, 402 } },
0051             {  510000000UL, { 1231606, -33155, 402 } },
0052             {  612000000UL, { 1274912, -34435, 402 } },
0053             {  714000000UL, { 1320040, -35725, 402 } },
0054             {  816000000UL, { 1366990, -37005, 402 } },
0055             {  918000000UL, { 1415762, -38295, 402 } },
0056             { 1020000000UL, { 1466355, -39575, 402 } },
0057             { 1122000000UL, { 1518771, -40865, 402 } },
0058             { 1224000000UL, { 1573009, -42145, 402 } },
0059             { 1326000000UL, { 1629068, -43435, 402 } },
0060             { 1428000000UL, { 1686950, -44715, 402 } },
0061             { 1530000000UL, { 1746653, -46005, 402 } },
0062             { 1632000000UL, { 1808179, -47285, 402 } },
0063             { 1734000000UL, { 1871526, -48575, 402 } },
0064             { 1836000000UL, { 1936696, -49855, 402 } },
0065             { 1938000000UL, { 2003687, -51145, 402 } },
0066             { 2014500000UL, { 2054787, -52095, 402 } },
0067             { 2116500000UL, { 2124957, -53385, 402 } },
0068             { 2218500000UL, { 2196950, -54665, 402 } },
0069             { 2320500000UL, { 2270765, -55955, 402 } },
0070             { 2422500000UL, { 2346401, -57235, 402 } },
0071             { 2524500000UL, { 2437299, -58535, 402 } },
0072             {          0UL, {       0,      0,   0 } },
0073         },
0074         .cpu_dfll_data = {
0075             .tune0_low = 0x005020ff,
0076             .tune0_high = 0x005040ff,
0077             .tune1 = 0x00000060,
0078         }
0079     },
0080 };
0081 
0082 static const unsigned long tegra210_cpu_max_freq_table[] = {
0083     [0] = 1912500000UL,
0084     [1] = 1912500000UL,
0085     [2] = 2218500000UL,
0086     [3] = 1785000000UL,
0087     [4] = 1632000000UL,
0088     [5] = 1912500000UL,
0089     [6] = 2014500000UL,
0090     [7] = 1734000000UL,
0091     [8] = 1683000000UL,
0092     [9] = 1555500000UL,
0093     [10] = 1504500000UL,
0094 };
0095 
0096 #define CPU_CVB_TABLE \
0097     .speedo_scale = 100,    \
0098     .voltage_scale = 1000,  \
0099     .entries = {        \
0100         {  204000000UL, { 1007452, -23865, 370 } }, \
0101         {  306000000UL, { 1052709, -24875, 370 } }, \
0102         {  408000000UL, { 1099069, -25895, 370 } }, \
0103         {  510000000UL, { 1146534, -26905, 370 } }, \
0104         {  612000000UL, { 1195102, -27915, 370 } }, \
0105         {  714000000UL, { 1244773, -28925, 370 } }, \
0106         {  816000000UL, { 1295549, -29935, 370 } }, \
0107         {  918000000UL, { 1347428, -30955, 370 } }, \
0108         { 1020000000UL, { 1400411, -31965, 370 } }, \
0109         { 1122000000UL, { 1454497, -32975, 370 } }, \
0110         { 1224000000UL, { 1509687, -33985, 370 } }, \
0111         { 1326000000UL, { 1565981, -35005, 370 } }, \
0112         { 1428000000UL, { 1623379, -36015, 370 } }, \
0113         { 1530000000UL, { 1681880, -37025, 370 } }, \
0114         { 1632000000UL, { 1741485, -38035, 370 } }, \
0115         { 1734000000UL, { 1802194, -39055, 370 } }, \
0116         { 1836000000UL, { 1864006, -40065, 370 } }, \
0117         { 1912500000UL, { 1910780, -40815, 370 } }, \
0118         { 2014500000UL, { 1227000,      0,   0 } }, \
0119         { 2218500000UL, { 1227000,      0,   0 } }, \
0120         {          0UL, {       0,      0,   0 } }, \
0121     }
0122 
0123 #define CPU_CVB_TABLE_XA \
0124     .speedo_scale = 100,    \
0125     .voltage_scale = 1000,  \
0126     .entries = {        \
0127         {  204000000UL, { 1250024, -39785, 565 } }, \
0128         {  306000000UL, { 1297556, -41145, 565 } }, \
0129         {  408000000UL, { 1346718, -42505, 565 } }, \
0130         {  510000000UL, { 1397511, -43855, 565 } }, \
0131         {  612000000UL, { 1449933, -45215, 565 } }, \
0132         {  714000000UL, { 1503986, -46575, 565 } }, \
0133         {  816000000UL, { 1559669, -47935, 565 } }, \
0134         {  918000000UL, { 1616982, -49295, 565 } }, \
0135         { 1020000000UL, { 1675926, -50645, 565 } }, \
0136         { 1122000000UL, { 1736500, -52005, 565 } }, \
0137         { 1224000000UL, { 1798704, -53365, 565 } }, \
0138         { 1326000000UL, { 1862538, -54725, 565 } }, \
0139         { 1428000000UL, { 1928003, -56085, 565 } }, \
0140         { 1530000000UL, { 1995097, -57435, 565 } }, \
0141         { 1606500000UL, { 2046149, -58445, 565 } }, \
0142         { 1632000000UL, { 2063822, -58795, 565 } }, \
0143         {          0UL, {       0,      0,   0 } }, \
0144     }
0145 
0146 #define CPU_CVB_TABLE_EUCM1 \
0147     .speedo_scale = 100,    \
0148     .voltage_scale = 1000,  \
0149     .entries = {        \
0150         {  204000000UL, {  734429, 0, 0 } }, \
0151         {  306000000UL, {  768191, 0, 0 } }, \
0152         {  408000000UL, {  801953, 0, 0 } }, \
0153         {  510000000UL, {  835715, 0, 0 } }, \
0154         {  612000000UL, {  869477, 0, 0 } }, \
0155         {  714000000UL, {  903239, 0, 0 } }, \
0156         {  816000000UL, {  937001, 0, 0 } }, \
0157         {  918000000UL, {  970763, 0, 0 } }, \
0158         { 1020000000UL, { 1004525, 0, 0 } }, \
0159         { 1122000000UL, { 1038287, 0, 0 } }, \
0160         { 1224000000UL, { 1072049, 0, 0 } }, \
0161         { 1326000000UL, { 1105811, 0, 0 } }, \
0162         { 1428000000UL, { 1130000, 0, 0 } }, \
0163         { 1555500000UL, { 1130000, 0, 0 } }, \
0164         { 1632000000UL, { 1170000, 0, 0 } }, \
0165         { 1734000000UL, { 1227500, 0, 0 } }, \
0166         {          0UL, {       0, 0, 0 } }, \
0167     }
0168 
0169 #define CPU_CVB_TABLE_EUCM2 \
0170     .speedo_scale = 100,    \
0171     .voltage_scale = 1000,  \
0172     .entries = {        \
0173         {  204000000UL, {  742283, 0, 0 } }, \
0174         {  306000000UL, {  776249, 0, 0 } }, \
0175         {  408000000UL, {  810215, 0, 0 } }, \
0176         {  510000000UL, {  844181, 0, 0 } }, \
0177         {  612000000UL, {  878147, 0, 0 } }, \
0178         {  714000000UL, {  912113, 0, 0 } }, \
0179         {  816000000UL, {  946079, 0, 0 } }, \
0180         {  918000000UL, {  980045, 0, 0 } }, \
0181         { 1020000000UL, { 1014011, 0, 0 } }, \
0182         { 1122000000UL, { 1047977, 0, 0 } }, \
0183         { 1224000000UL, { 1081943, 0, 0 } }, \
0184         { 1326000000UL, { 1090000, 0, 0 } }, \
0185         { 1479000000UL, { 1090000, 0, 0 } }, \
0186         { 1555500000UL, { 1162000, 0, 0 } }, \
0187         { 1683000000UL, { 1195000, 0, 0 } }, \
0188         {          0UL, {       0, 0, 0 } }, \
0189     }
0190 
0191 #define CPU_CVB_TABLE_EUCM2_JOINT_RAIL \
0192     .speedo_scale = 100,    \
0193     .voltage_scale = 1000,  \
0194     .entries = {        \
0195         {  204000000UL, {  742283, 0, 0 } }, \
0196         {  306000000UL, {  776249, 0, 0 } }, \
0197         {  408000000UL, {  810215, 0, 0 } }, \
0198         {  510000000UL, {  844181, 0, 0 } }, \
0199         {  612000000UL, {  878147, 0, 0 } }, \
0200         {  714000000UL, {  912113, 0, 0 } }, \
0201         {  816000000UL, {  946079, 0, 0 } }, \
0202         {  918000000UL, {  980045, 0, 0 } }, \
0203         { 1020000000UL, { 1014011, 0, 0 } }, \
0204         { 1122000000UL, { 1047977, 0, 0 } }, \
0205         { 1224000000UL, { 1081943, 0, 0 } }, \
0206         { 1326000000UL, { 1090000, 0, 0 } }, \
0207         { 1479000000UL, { 1090000, 0, 0 } }, \
0208         { 1504500000UL, { 1120000, 0, 0 } }, \
0209         {          0UL, {       0, 0, 0 } }, \
0210     }
0211 
0212 #define CPU_CVB_TABLE_ODN \
0213     .speedo_scale = 100,    \
0214     .voltage_scale = 1000,  \
0215     .entries = {        \
0216         {  204000000UL, {  721094, 0, 0 } }, \
0217         {  306000000UL, {  754040, 0, 0 } }, \
0218         {  408000000UL, {  786986, 0, 0 } }, \
0219         {  510000000UL, {  819932, 0, 0 } }, \
0220         {  612000000UL, {  852878, 0, 0 } }, \
0221         {  714000000UL, {  885824, 0, 0 } }, \
0222         {  816000000UL, {  918770, 0, 0 } }, \
0223         {  918000000UL, {  915716, 0, 0 } }, \
0224         { 1020000000UL, {  984662, 0, 0 } }, \
0225         { 1122000000UL, { 1017608, 0, 0 } }, \
0226         { 1224000000UL, { 1050554, 0, 0 } }, \
0227         { 1326000000UL, { 1083500, 0, 0 } }, \
0228         { 1428000000UL, { 1116446, 0, 0 } }, \
0229         { 1581000000UL, { 1130000, 0, 0 } }, \
0230         { 1683000000UL, { 1168000, 0, 0 } }, \
0231         { 1785000000UL, { 1227500, 0, 0 } }, \
0232         {          0UL, {       0, 0, 0 } }, \
0233     }
0234 
0235 static struct cvb_table tegra210_cpu_cvb_tables[] = {
0236     {
0237         .speedo_id = 10,
0238         .process_id = 0,
0239         .min_millivolts = 840,
0240         .max_millivolts = 1120,
0241         CPU_CVB_TABLE_EUCM2_JOINT_RAIL,
0242         .cpu_dfll_data = {
0243             .tune0_low = 0xffead0ff,
0244             .tune0_high = 0xffead0ff,
0245             .tune1 = 0x20091d9,
0246             .tune_high_min_millivolts = 864,
0247         }
0248     },
0249     {
0250         .speedo_id = 10,
0251         .process_id = 1,
0252         .min_millivolts = 840,
0253         .max_millivolts = 1120,
0254         CPU_CVB_TABLE_EUCM2_JOINT_RAIL,
0255         .cpu_dfll_data = {
0256             .tune0_low = 0xffead0ff,
0257             .tune0_high = 0xffead0ff,
0258             .tune1 = 0x20091d9,
0259             .tune_high_min_millivolts = 864,
0260         }
0261     },
0262     {
0263         .speedo_id = 9,
0264         .process_id = 0,
0265         .min_millivolts = 900,
0266         .max_millivolts = 1162,
0267         CPU_CVB_TABLE_EUCM2,
0268         .cpu_dfll_data = {
0269             .tune0_low = 0xffead0ff,
0270             .tune0_high = 0xffead0ff,
0271             .tune1 = 0x20091d9,
0272         }
0273     },
0274     {
0275         .speedo_id = 9,
0276         .process_id = 1,
0277         .min_millivolts = 900,
0278         .max_millivolts = 1162,
0279         CPU_CVB_TABLE_EUCM2,
0280         .cpu_dfll_data = {
0281             .tune0_low = 0xffead0ff,
0282             .tune0_high = 0xffead0ff,
0283             .tune1 = 0x20091d9,
0284         }
0285     },
0286     {
0287         .speedo_id = 8,
0288         .process_id = 0,
0289         .min_millivolts = 900,
0290         .max_millivolts = 1195,
0291         CPU_CVB_TABLE_EUCM2,
0292         .cpu_dfll_data = {
0293             .tune0_low = 0xffead0ff,
0294             .tune0_high = 0xffead0ff,
0295             .tune1 = 0x20091d9,
0296         }
0297     },
0298     {
0299         .speedo_id = 8,
0300         .process_id = 1,
0301         .min_millivolts = 900,
0302         .max_millivolts = 1195,
0303         CPU_CVB_TABLE_EUCM2,
0304         .cpu_dfll_data = {
0305             .tune0_low = 0xffead0ff,
0306             .tune0_high = 0xffead0ff,
0307             .tune1 = 0x20091d9,
0308         }
0309     },
0310     {
0311         .speedo_id = 7,
0312         .process_id = 0,
0313         .min_millivolts = 841,
0314         .max_millivolts = 1227,
0315         CPU_CVB_TABLE_EUCM1,
0316         .cpu_dfll_data = {
0317             .tune0_low = 0xffead0ff,
0318             .tune0_high = 0xffead0ff,
0319             .tune1 = 0x20091d9,
0320             .tune_high_min_millivolts = 864,
0321         }
0322     },
0323     {
0324         .speedo_id = 7,
0325         .process_id = 1,
0326         .min_millivolts = 841,
0327         .max_millivolts = 1227,
0328         CPU_CVB_TABLE_EUCM1,
0329         .cpu_dfll_data = {
0330             .tune0_low = 0xffead0ff,
0331             .tune0_high = 0xffead0ff,
0332             .tune1 = 0x20091d9,
0333             .tune_high_min_millivolts = 864,
0334         }
0335     },
0336     {
0337         .speedo_id = 6,
0338         .process_id = 0,
0339         .min_millivolts = 870,
0340         .max_millivolts = 1150,
0341         CPU_CVB_TABLE,
0342         .cpu_dfll_data = {
0343             .tune0_low = 0xffead0ff,
0344             .tune1 = 0x20091d9,
0345         }
0346     },
0347     {
0348         .speedo_id = 6,
0349         .process_id = 1,
0350         .min_millivolts = 870,
0351         .max_millivolts = 1150,
0352         CPU_CVB_TABLE,
0353         .cpu_dfll_data = {
0354             .tune0_low = 0xffead0ff,
0355             .tune1 = 0x25501d0,
0356         }
0357     },
0358     {
0359         .speedo_id = 5,
0360         .process_id = 0,
0361         .min_millivolts = 818,
0362         .max_millivolts = 1227,
0363         CPU_CVB_TABLE,
0364         .cpu_dfll_data = {
0365             .tune0_low = 0xffead0ff,
0366             .tune0_high = 0xffead0ff,
0367             .tune1 = 0x20091d9,
0368             .tune_high_min_millivolts = 864,
0369         }
0370     },
0371     {
0372         .speedo_id = 5,
0373         .process_id = 1,
0374         .min_millivolts = 818,
0375         .max_millivolts = 1227,
0376         CPU_CVB_TABLE,
0377         .cpu_dfll_data = {
0378             .tune0_low = 0xffead0ff,
0379             .tune0_high = 0xffead0ff,
0380             .tune1 = 0x25501d0,
0381             .tune_high_min_millivolts = 864,
0382         }
0383     },
0384     {
0385         .speedo_id = 4,
0386         .process_id = -1,
0387         .min_millivolts = 918,
0388         .max_millivolts = 1113,
0389         CPU_CVB_TABLE_XA,
0390         .cpu_dfll_data = {
0391             .tune0_low = 0xffead0ff,
0392             .tune1 = 0x17711BD,
0393         }
0394     },
0395     {
0396         .speedo_id = 3,
0397         .process_id = 0,
0398         .min_millivolts = 825,
0399         .max_millivolts = 1227,
0400         CPU_CVB_TABLE_ODN,
0401         .cpu_dfll_data = {
0402             .tune0_low = 0xffead0ff,
0403             .tune0_high = 0xffead0ff,
0404             .tune1 = 0x20091d9,
0405             .tune_high_min_millivolts = 864,
0406         }
0407     },
0408     {
0409         .speedo_id = 3,
0410         .process_id = 1,
0411         .min_millivolts = 825,
0412         .max_millivolts = 1227,
0413         CPU_CVB_TABLE_ODN,
0414         .cpu_dfll_data = {
0415             .tune0_low = 0xffead0ff,
0416             .tune0_high = 0xffead0ff,
0417             .tune1 = 0x25501d0,
0418             .tune_high_min_millivolts = 864,
0419         }
0420     },
0421     {
0422         .speedo_id = 2,
0423         .process_id = 0,
0424         .min_millivolts = 870,
0425         .max_millivolts = 1227,
0426         CPU_CVB_TABLE,
0427         .cpu_dfll_data = {
0428             .tune0_low = 0xffead0ff,
0429             .tune1 = 0x20091d9,
0430         }
0431     },
0432     {
0433         .speedo_id = 2,
0434         .process_id = 1,
0435         .min_millivolts = 870,
0436         .max_millivolts = 1227,
0437         CPU_CVB_TABLE,
0438         .cpu_dfll_data = {
0439             .tune0_low = 0xffead0ff,
0440             .tune1 = 0x25501d0,
0441         }
0442     },
0443     {
0444         .speedo_id = 1,
0445         .process_id = 0,
0446         .min_millivolts = 837,
0447         .max_millivolts = 1227,
0448         CPU_CVB_TABLE,
0449         .cpu_dfll_data = {
0450             .tune0_low = 0xffead0ff,
0451             .tune0_high = 0xffead0ff,
0452             .tune1 = 0x20091d9,
0453             .tune_high_min_millivolts = 864,
0454         }
0455     },
0456     {
0457         .speedo_id = 1,
0458         .process_id = 1,
0459         .min_millivolts = 837,
0460         .max_millivolts = 1227,
0461         CPU_CVB_TABLE,
0462         .cpu_dfll_data = {
0463             .tune0_low = 0xffead0ff,
0464             .tune0_high = 0xffead0ff,
0465             .tune1 = 0x25501d0,
0466             .tune_high_min_millivolts = 864,
0467         }
0468     },
0469     {
0470         .speedo_id = 0,
0471         .process_id = 0,
0472         .min_millivolts = 850,
0473         .max_millivolts = 1170,
0474         CPU_CVB_TABLE,
0475         .cpu_dfll_data = {
0476             .tune0_low = 0xffead0ff,
0477             .tune0_high = 0xffead0ff,
0478             .tune1 = 0x20091d9,
0479             .tune_high_min_millivolts = 864,
0480         }
0481     },
0482     {
0483         .speedo_id = 0,
0484         .process_id = 1,
0485         .min_millivolts = 850,
0486         .max_millivolts = 1170,
0487         CPU_CVB_TABLE,
0488         .cpu_dfll_data = {
0489             .tune0_low = 0xffead0ff,
0490             .tune0_high = 0xffead0ff,
0491             .tune1 = 0x25501d0,
0492             .tune_high_min_millivolts = 864,
0493         }
0494     },
0495 };
0496 
0497 static const struct dfll_fcpu_data tegra124_dfll_fcpu_data = {
0498     .cpu_max_freq_table = tegra124_cpu_max_freq_table,
0499     .cpu_max_freq_table_size = ARRAY_SIZE(tegra124_cpu_max_freq_table),
0500     .cpu_cvb_tables = tegra124_cpu_cvb_tables,
0501     .cpu_cvb_tables_size = ARRAY_SIZE(tegra124_cpu_cvb_tables)
0502 };
0503 
0504 static const struct dfll_fcpu_data tegra210_dfll_fcpu_data = {
0505     .cpu_max_freq_table = tegra210_cpu_max_freq_table,
0506     .cpu_max_freq_table_size = ARRAY_SIZE(tegra210_cpu_max_freq_table),
0507     .cpu_cvb_tables = tegra210_cpu_cvb_tables,
0508     .cpu_cvb_tables_size = ARRAY_SIZE(tegra210_cpu_cvb_tables),
0509 };
0510 
0511 static const struct of_device_id tegra124_dfll_fcpu_of_match[] = {
0512     {
0513         .compatible = "nvidia,tegra124-dfll",
0514         .data = &tegra124_dfll_fcpu_data,
0515     },
0516     {
0517         .compatible = "nvidia,tegra210-dfll",
0518         .data = &tegra210_dfll_fcpu_data
0519     },
0520     { },
0521 };
0522 
0523 static void get_alignment_from_dt(struct device *dev,
0524                   struct rail_alignment *align)
0525 {
0526     if (of_property_read_u32(dev->of_node,
0527                  "nvidia,pwm-voltage-step-microvolts",
0528                  &align->step_uv))
0529         align->step_uv = 0;
0530 
0531     if (of_property_read_u32(dev->of_node,
0532                  "nvidia,pwm-min-microvolts",
0533                  &align->offset_uv))
0534         align->offset_uv = 0;
0535 }
0536 
0537 static int get_alignment_from_regulator(struct device *dev,
0538                      struct rail_alignment *align)
0539 {
0540     struct regulator *reg = regulator_get(dev, "vdd-cpu");
0541 
0542     if (IS_ERR(reg))
0543         return PTR_ERR(reg);
0544 
0545     align->offset_uv = regulator_list_voltage(reg, 0);
0546     align->step_uv = regulator_get_linear_step(reg);
0547 
0548     regulator_put(reg);
0549 
0550     return 0;
0551 }
0552 
0553 static int tegra124_dfll_fcpu_probe(struct platform_device *pdev)
0554 {
0555     int process_id, speedo_id, speedo_value, err;
0556     struct tegra_dfll_soc_data *soc;
0557     const struct dfll_fcpu_data *fcpu_data;
0558     struct rail_alignment align;
0559 
0560     fcpu_data = of_device_get_match_data(&pdev->dev);
0561     if (!fcpu_data)
0562         return -ENODEV;
0563 
0564     process_id = tegra_sku_info.cpu_process_id;
0565     speedo_id = tegra_sku_info.cpu_speedo_id;
0566     speedo_value = tegra_sku_info.cpu_speedo_value;
0567 
0568     if (speedo_id >= fcpu_data->cpu_max_freq_table_size) {
0569         dev_err(&pdev->dev, "unknown max CPU freq for speedo_id=%d\n",
0570             speedo_id);
0571         return -ENODEV;
0572     }
0573 
0574     soc = devm_kzalloc(&pdev->dev, sizeof(*soc), GFP_KERNEL);
0575     if (!soc)
0576         return -ENOMEM;
0577 
0578     soc->dev = get_cpu_device(0);
0579     if (!soc->dev) {
0580         dev_err(&pdev->dev, "no CPU0 device\n");
0581         return -ENODEV;
0582     }
0583 
0584     if (of_property_read_bool(pdev->dev.of_node, "nvidia,pwm-to-pmic")) {
0585         get_alignment_from_dt(&pdev->dev, &align);
0586     } else {
0587         err = get_alignment_from_regulator(&pdev->dev, &align);
0588         if (err)
0589             return err;
0590     }
0591 
0592     soc->max_freq = fcpu_data->cpu_max_freq_table[speedo_id];
0593 
0594     soc->cvb = tegra_cvb_add_opp_table(soc->dev, fcpu_data->cpu_cvb_tables,
0595                        fcpu_data->cpu_cvb_tables_size,
0596                        &align, process_id, speedo_id,
0597                        speedo_value, soc->max_freq);
0598     soc->alignment = align;
0599 
0600     if (IS_ERR(soc->cvb)) {
0601         dev_err(&pdev->dev, "couldn't add OPP table: %ld\n",
0602             PTR_ERR(soc->cvb));
0603         return PTR_ERR(soc->cvb);
0604     }
0605 
0606     err = tegra_dfll_register(pdev, soc);
0607     if (err < 0) {
0608         tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq);
0609         return err;
0610     }
0611 
0612     return 0;
0613 }
0614 
0615 static int tegra124_dfll_fcpu_remove(struct platform_device *pdev)
0616 {
0617     struct tegra_dfll_soc_data *soc;
0618 
0619     soc = tegra_dfll_unregister(pdev);
0620     if (IS_ERR(soc)) {
0621         dev_err(&pdev->dev, "failed to unregister DFLL: %ld\n",
0622             PTR_ERR(soc));
0623         return PTR_ERR(soc);
0624     }
0625 
0626     tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq);
0627 
0628     return 0;
0629 }
0630 
0631 static const struct dev_pm_ops tegra124_dfll_pm_ops = {
0632     SET_RUNTIME_PM_OPS(tegra_dfll_runtime_suspend,
0633                tegra_dfll_runtime_resume, NULL)
0634     SET_SYSTEM_SLEEP_PM_OPS(tegra_dfll_suspend, tegra_dfll_resume)
0635 };
0636 
0637 static struct platform_driver tegra124_dfll_fcpu_driver = {
0638     .probe = tegra124_dfll_fcpu_probe,
0639     .remove = tegra124_dfll_fcpu_remove,
0640     .driver = {
0641         .name = "tegra124-dfll",
0642         .of_match_table = tegra124_dfll_fcpu_of_match,
0643         .pm = &tegra124_dfll_pm_ops,
0644     },
0645 };
0646 builtin_platform_driver(tegra124_dfll_fcpu_driver);