Mention branches and keyring.
[releases.git] / tegra / fuse / speedo-tegra30.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2012-2014, NVIDIA CORPORATION.  All rights reserved.
4  */
5
6 #include <linux/bug.h>
7 #include <linux/device.h>
8 #include <linux/kernel.h>
9
10 #include <soc/tegra/fuse.h>
11
12 #include "fuse.h"
13
14 #define SOC_PROCESS_CORNERS     1
15 #define CPU_PROCESS_CORNERS     6
16
17 #define FUSE_SPEEDO_CALIB_0     0x14
18 #define FUSE_PACKAGE_INFO       0XFC
19 #define FUSE_TEST_PROG_VER      0X28
20
21 #define G_SPEEDO_BIT_MINUS1     58
22 #define G_SPEEDO_BIT_MINUS1_R   59
23 #define G_SPEEDO_BIT_MINUS2     60
24 #define G_SPEEDO_BIT_MINUS2_R   61
25 #define LP_SPEEDO_BIT_MINUS1    62
26 #define LP_SPEEDO_BIT_MINUS1_R  63
27 #define LP_SPEEDO_BIT_MINUS2    64
28 #define LP_SPEEDO_BIT_MINUS2_R  65
29
30 enum {
31         THRESHOLD_INDEX_0,
32         THRESHOLD_INDEX_1,
33         THRESHOLD_INDEX_2,
34         THRESHOLD_INDEX_3,
35         THRESHOLD_INDEX_4,
36         THRESHOLD_INDEX_5,
37         THRESHOLD_INDEX_6,
38         THRESHOLD_INDEX_7,
39         THRESHOLD_INDEX_8,
40         THRESHOLD_INDEX_9,
41         THRESHOLD_INDEX_10,
42         THRESHOLD_INDEX_11,
43         THRESHOLD_INDEX_COUNT,
44 };
45
46 static const u32 __initconst soc_process_speedos[][SOC_PROCESS_CORNERS] = {
47         {180},
48         {170},
49         {195},
50         {180},
51         {168},
52         {192},
53         {180},
54         {170},
55         {195},
56         {180},
57         {180},
58         {180},
59 };
60
61 static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = {
62         {306, 338, 360, 376, UINT_MAX},
63         {295, 336, 358, 375, UINT_MAX},
64         {325, 325, 358, 375, UINT_MAX},
65         {325, 325, 358, 375, UINT_MAX},
66         {292, 324, 348, 364, UINT_MAX},
67         {324, 324, 348, 364, UINT_MAX},
68         {324, 324, 348, 364, UINT_MAX},
69         {295, 336, 358, 375, UINT_MAX},
70         {358, 358, 358, 358, 397, UINT_MAX},
71         {364, 364, 364, 364, 397, UINT_MAX},
72         {295, 336, 358, 375, 391, UINT_MAX},
73         {295, 336, 358, 375, 391, UINT_MAX},
74 };
75
76 static int threshold_index __initdata;
77
78 static void __init fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp)
79 {
80         u32 reg;
81         int ate_ver;
82         int bit_minus1;
83         int bit_minus2;
84
85         reg = tegra_fuse_read_early(FUSE_SPEEDO_CALIB_0);
86
87         *speedo_lp = (reg & 0xFFFF) * 4;
88         *speedo_g = ((reg >> 16) & 0xFFFF) * 4;
89
90         ate_ver = tegra_fuse_read_early(FUSE_TEST_PROG_VER);
91         pr_debug("Tegra ATE prog ver %d.%d\n", ate_ver/10, ate_ver%10);
92
93         if (ate_ver >= 26) {
94                 bit_minus1 = tegra_fuse_read_spare(LP_SPEEDO_BIT_MINUS1);
95                 bit_minus1 |= tegra_fuse_read_spare(LP_SPEEDO_BIT_MINUS1_R);
96                 bit_minus2 = tegra_fuse_read_spare(LP_SPEEDO_BIT_MINUS2);
97                 bit_minus2 |= tegra_fuse_read_spare(LP_SPEEDO_BIT_MINUS2_R);
98                 *speedo_lp |= (bit_minus1 << 1) | bit_minus2;
99
100                 bit_minus1 = tegra_fuse_read_spare(G_SPEEDO_BIT_MINUS1);
101                 bit_minus1 |= tegra_fuse_read_spare(G_SPEEDO_BIT_MINUS1_R);
102                 bit_minus2 = tegra_fuse_read_spare(G_SPEEDO_BIT_MINUS2);
103                 bit_minus2 |= tegra_fuse_read_spare(G_SPEEDO_BIT_MINUS2_R);
104                 *speedo_g |= (bit_minus1 << 1) | bit_minus2;
105         } else {
106                 *speedo_lp |= 0x3;
107                 *speedo_g |= 0x3;
108         }
109 }
110
111 static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info)
112 {
113         int package_id = tegra_fuse_read_early(FUSE_PACKAGE_INFO) & 0x0F;
114
115         switch (sku_info->revision) {
116         case TEGRA_REVISION_A01:
117                 sku_info->cpu_speedo_id = 0;
118                 sku_info->soc_speedo_id = 0;
119                 threshold_index = THRESHOLD_INDEX_0;
120                 break;
121         case TEGRA_REVISION_A02:
122         case TEGRA_REVISION_A03:
123                 switch (sku_info->sku_id) {
124                 case 0x87:
125                 case 0x82:
126                         sku_info->cpu_speedo_id = 1;
127                         sku_info->soc_speedo_id = 1;
128                         threshold_index = THRESHOLD_INDEX_1;
129                         break;
130                 case 0x81:
131                         switch (package_id) {
132                         case 1:
133                                 sku_info->cpu_speedo_id = 2;
134                                 sku_info->soc_speedo_id = 2;
135                                 threshold_index = THRESHOLD_INDEX_2;
136                                 break;
137                         case 2:
138                                 sku_info->cpu_speedo_id = 4;
139                                 sku_info->soc_speedo_id = 1;
140                                 threshold_index = THRESHOLD_INDEX_7;
141                                 break;
142                         default:
143                                 pr_err("Tegra Unknown pkg %d\n", package_id);
144                                 break;
145                         }
146                         break;
147                 case 0x80:
148                         switch (package_id) {
149                         case 1:
150                                 sku_info->cpu_speedo_id = 5;
151                                 sku_info->soc_speedo_id = 2;
152                                 threshold_index = THRESHOLD_INDEX_8;
153                                 break;
154                         case 2:
155                                 sku_info->cpu_speedo_id = 6;
156                                 sku_info->soc_speedo_id = 2;
157                                 threshold_index = THRESHOLD_INDEX_9;
158                                 break;
159                         default:
160                                 pr_err("Tegra Unknown pkg %d\n", package_id);
161                                 break;
162                         }
163                         break;
164                 case 0x83:
165                         switch (package_id) {
166                         case 1:
167                                 sku_info->cpu_speedo_id = 7;
168                                 sku_info->soc_speedo_id = 1;
169                                 threshold_index = THRESHOLD_INDEX_10;
170                                 break;
171                         case 2:
172                                 sku_info->cpu_speedo_id = 3;
173                                 sku_info->soc_speedo_id = 2;
174                                 threshold_index = THRESHOLD_INDEX_3;
175                                 break;
176                         default:
177                                 pr_err("Tegra Unknown pkg %d\n", package_id);
178                                 break;
179                         }
180                         break;
181                 case 0x8F:
182                         sku_info->cpu_speedo_id = 8;
183                         sku_info->soc_speedo_id = 1;
184                         threshold_index = THRESHOLD_INDEX_11;
185                         break;
186                 case 0x08:
187                         sku_info->cpu_speedo_id = 1;
188                         sku_info->soc_speedo_id = 1;
189                         threshold_index = THRESHOLD_INDEX_4;
190                         break;
191                 case 0x02:
192                         sku_info->cpu_speedo_id = 2;
193                         sku_info->soc_speedo_id = 2;
194                         threshold_index = THRESHOLD_INDEX_5;
195                         break;
196                 case 0x04:
197                         sku_info->cpu_speedo_id = 3;
198                         sku_info->soc_speedo_id = 2;
199                         threshold_index = THRESHOLD_INDEX_6;
200                         break;
201                 case 0:
202                         switch (package_id) {
203                         case 1:
204                                 sku_info->cpu_speedo_id = 2;
205                                 sku_info->soc_speedo_id = 2;
206                                 threshold_index = THRESHOLD_INDEX_2;
207                                 break;
208                         case 2:
209                                 sku_info->cpu_speedo_id = 3;
210                                 sku_info->soc_speedo_id = 2;
211                                 threshold_index = THRESHOLD_INDEX_3;
212                                 break;
213                         default:
214                                 pr_err("Tegra Unknown pkg %d\n", package_id);
215                                 break;
216                         }
217                         break;
218                 default:
219                         pr_warn("Tegra Unknown SKU %d\n", sku_info->sku_id);
220                         sku_info->cpu_speedo_id = 0;
221                         sku_info->soc_speedo_id = 0;
222                         threshold_index = THRESHOLD_INDEX_0;
223                         break;
224                 }
225                 break;
226         default:
227                 pr_warn("Tegra Unknown chip rev %d\n", sku_info->revision);
228                 sku_info->cpu_speedo_id = 0;
229                 sku_info->soc_speedo_id = 0;
230                 threshold_index = THRESHOLD_INDEX_0;
231                 break;
232         }
233 }
234
235 void __init tegra30_init_speedo_data(struct tegra_sku_info *sku_info)
236 {
237         u32 cpu_speedo_val;
238         u32 soc_speedo_val;
239         int i;
240
241         BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
242                         THRESHOLD_INDEX_COUNT);
243         BUILD_BUG_ON(ARRAY_SIZE(soc_process_speedos) !=
244                         THRESHOLD_INDEX_COUNT);
245
246
247         rev_sku_to_speedo_ids(sku_info);
248         fuse_speedo_calib(&cpu_speedo_val, &soc_speedo_val);
249         pr_debug("Tegra CPU speedo value %u\n", cpu_speedo_val);
250         pr_debug("Tegra Core speedo value %u\n", soc_speedo_val);
251
252         for (i = 0; i < CPU_PROCESS_CORNERS; i++) {
253                 if (cpu_speedo_val < cpu_process_speedos[threshold_index][i])
254                         break;
255         }
256         sku_info->cpu_process_id = i - 1;
257
258         if (sku_info->cpu_process_id == -1) {
259                 pr_warn("Tegra CPU speedo value %3d out of range",
260                          cpu_speedo_val);
261                 sku_info->cpu_process_id = 0;
262                 sku_info->cpu_speedo_id = 1;
263         }
264
265         for (i = 0; i < SOC_PROCESS_CORNERS; i++) {
266                 if (soc_speedo_val < soc_process_speedos[threshold_index][i])
267                         break;
268         }
269         sku_info->soc_process_id = i - 1;
270
271         if (sku_info->soc_process_id == -1) {
272                 pr_warn("Tegra SoC speedo value %3d out of range",
273                         soc_speedo_val);
274                 sku_info->soc_process_id = 0;
275                 sku_info->soc_speedo_id = 1;
276         }
277 }