ARM: tegra: dvfs: Update Tegra3 xL speedo/nominal voltage
[linux-2.6.git] / arch / arm / mach-tegra / tegra3_speedo.c
1 /*
2  * arch/arm/mach-tegra/tegra3_speedo.c
3  *
4  * Copyright (c) 2011, NVIDIA Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20
21 #include <linux/kernel.h>
22 #include <linux/io.h>
23 #include <linux/err.h>
24 #include <mach/iomap.h>
25
26 #include "fuse.h"
27
28 #define CORE_PROCESS_CORNERS_NUM        1
29 #define CPU_PROCESS_CORNERS_NUM         5
30
31 #define FUSE_SPEEDO_CALIB_0     0x114
32 #define FUSE_PACKAGE_INFO       0X1FC
33
34 /* Maximum speedo levels for each core process corner */
35 static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = {
36 /* proc_id 0 */
37         {180}, /* [0]: soc_speedo_id 0: any A01 */
38
39 /* T30 family */
40         {180}, /* [1]: soc_speedo_id 1: AP30 */
41         {204}, /* [2]: soc_speedo_id 2: T30  */
42         {192}, /* [3]: soc_speedo_id 2: T30S */
43
44 /* Characterization SKUs */
45         {168}, /* [4]: soc_speedo_id 1: AP30 char */
46         {192}, /* [5]: soc_speedo_id 2: T30  char */
47         {184}, /* [6]: soc_speedo_id 2: T30S char */
48
49 /* T33 family */
50         {180}, /* [7]: soc_speedo_id = 1 - AP33 */
51         {208}, /* [8]: soc_speedo_id = 2 - T33  */
52         {192}, /* [9]: soc_speedo_id = 2 - T33S */
53
54 /* T30 'L' family */
55         {192}, /* [10]: soc_speedo_id 1: T30L */
56         {192}, /* [11]: soc_speedo_id 1: T30SL */
57 };
58
59 /* Maximum speedo levels for each CPU process corner */
60 static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
61 /* proc_id 0    1    2    3    4*/
62         {306, 338, 360, 376, UINT_MAX}, /* [0]: cpu_speedo_id 0: any A01 */
63
64 /* T30 family */
65         {304, 336, 359, 375, UINT_MAX}, /* [1]: cpu_speedo_id 1: AP30 */
66         {336, 336, 359, 375, UINT_MAX}, /* [2]: cpu_speedo_id 2: T30  */
67         {336, 336, 359, 375, UINT_MAX}, /* [3]: cpu_speedo_id 3: T30S */
68
69 /* Characterization SKUs */
70         {292, 324, 348, 364, UINT_MAX}, /* [4]: cpu_speedo_id 1: AP30char */
71         {324, 324, 348, 364, UINT_MAX}, /* [5]: cpu_speedo_id 2: T30char  */
72         {324, 324, 348, 364, UINT_MAX}, /* [6]: cpu_speedo_id 3: T30Schar */
73
74 /* T33 family */
75         {305, 337, 359, 376, UINT_MAX}, /* [7]: cpu_speedo_id = 4 - AP33 */
76         {368, 368, 368, 368, 392},      /* [8]: cpu_speedo_id = 5 - T33  */
77         {376, 376, 376, 376, 392},      /* [9]: cpu_speedo_id = 6 - T33S */
78
79 /* T30 'L' family */
80         {305, 337, 359, 376, 392},      /* [10]: cpu_speedo_id 7: T30L  */
81         {305, 337, 359, 376, 392},      /* [11]: cpu_speedo_id 8: T30SL */
82 };
83
84 /*
85  * Common speedo_value array threshold index for both core_process_speedos and
86  * cpu_process_speedos arrays. Make sure these two arrays are always in synch.
87  */
88 static int threshold_index;
89
90 static int cpu_process_id;
91 static int core_process_id;
92 static int cpu_speedo_id;
93 static int soc_speedo_id;
94 static int package_id;
95
96 static void fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp)
97 {
98         u32 reg;
99
100         BUG_ON(!speedo_g || !speedo_lp);
101         reg = tegra_fuse_readl(FUSE_SPEEDO_CALIB_0);
102
103         /* Speedo LP = Lower 16-bits Multiplied by 4 */
104         *speedo_lp = (reg & 0xFFFF) * 4;
105
106         /* Speedo G = Upper 16-bits Multiplied by 4 */
107         *speedo_g = ((reg >> 16) & 0xFFFF) * 4;
108 }
109
110 static void rev_sku_to_speedo_ids(int rev, int sku)
111 {
112         switch (rev) {
113         case TEGRA_REVISION_A01: /* any A01 */
114                 cpu_speedo_id = 0;
115                 soc_speedo_id = 0;
116                 threshold_index = 0;
117                 break;
118
119         case TEGRA_REVISION_A02:
120         case TEGRA_REVISION_A03:
121                 switch (sku) {
122                 case 0x87: /* AP30 */
123                 case 0x82: /* T30V */
124                         cpu_speedo_id = 1;
125                         soc_speedo_id = 1;
126                         threshold_index = 1;
127                         break;
128
129                 case 0x81: /* T30 */
130                         switch (package_id) {
131                         case 1: /* MID => T30 */
132                                 cpu_speedo_id = 2;
133                                 soc_speedo_id = 2;
134                                 threshold_index = 2;
135                                 break;
136                         case 2: /* DSC => AP33 */
137                                 cpu_speedo_id = 4;
138                                 soc_speedo_id = 1;
139                                 threshold_index = 7;
140                                 break;
141                         default:
142                                 pr_err("Tegra3 Rev-A02: Reserved pkg: %d\n",
143                                        package_id);
144                                 BUG();
145                                 break;
146                         }
147                         break;
148
149                 case 0x80: /* T33 or T33S */
150                         switch (package_id) {
151                         case 1: /* MID => T33 */
152                                 cpu_speedo_id = 5;
153                                 soc_speedo_id = 2;
154                                 threshold_index = 8;
155                                 break;
156                         case 2: /* DSC => T33S */
157                                 cpu_speedo_id = 6;
158                                 soc_speedo_id = 2;
159                                 threshold_index = 9;
160                                 break;
161                         default:
162                                 pr_err("Tegra3 Rev-A02: Reserved pkg: %d\n",
163                                        package_id);
164                                 BUG();
165                                 break;
166                         }
167                         break;
168
169                 case 0x83: /* T30L or T30S */
170                         switch (package_id) {
171                         case 1: /* MID => T30L */
172                                 cpu_speedo_id = 7;
173                                 soc_speedo_id = 1;
174                                 threshold_index = 10;
175                                 break;
176                         case 2: /* DSC => T30S */
177                                 cpu_speedo_id = 3;
178                                 soc_speedo_id = 2;
179                                 threshold_index = 3;
180                                 break;
181                         default:
182                                 pr_err("Tegra3 Rev-A02: Reserved pkg: %d\n",
183                                        package_id);
184                                 BUG();
185                                 break;
186                         }
187                         break;
188
189                 case 0x8F: /* T30SL */
190                         cpu_speedo_id = 8;
191                         soc_speedo_id = 1;
192                         threshold_index = 11;
193                         break;
194
195 /* Characterization SKUs */
196                 case 0x08: /* AP30 char */
197                         cpu_speedo_id = 1;
198                         soc_speedo_id = 1;
199                         threshold_index = 4;
200                         break;
201                 case 0x02: /* T30 char */
202                         cpu_speedo_id = 2;
203                         soc_speedo_id = 2;
204                         threshold_index = 5;
205                         break;
206                 case 0x04: /* T30S char */
207                         cpu_speedo_id = 3;
208                         soc_speedo_id = 2;
209                         threshold_index = 6;
210                         break;
211
212                 case 0:    /* ENG - check package_id */
213                         pr_info("Tegra3 ENG SKU: Checking package_id\n");
214                         switch (package_id) {
215                         case 1: /* MID => assume T30 */
216                                 cpu_speedo_id = 2;
217                                 soc_speedo_id = 2;
218                                 threshold_index = 2;
219                                 break;
220                         case 2: /* DSC => assume T30S */
221                                 cpu_speedo_id = 3;
222                                 soc_speedo_id = 2;
223                                 threshold_index = 3;
224                                 break;
225                         default:
226                                 pr_err("Tegra3 Rev-A02: Reserved pkg: %d\n",
227                                        package_id);
228                                 BUG();
229                                 break;
230                         }
231                         break;
232
233                 default:
234                         /* FIXME: replace with BUG() when all SKU's valid */
235                         pr_err("Tegra3 Rev-A02: Unknown SKU %d\n", sku);
236                         cpu_speedo_id = 0;
237                         soc_speedo_id = 0;
238                         threshold_index = 0;
239                         break;
240                 }
241                 break;
242         default:
243                 BUG();
244                 break;
245         }
246 }
247
248 void tegra_init_speedo_data(void)
249 {
250         u32 cpu_speedo_val, core_speedo_val;
251         int iv;
252
253         /* Package info: 4 bits - 0,3:reserved 1:MID 2:DSC */
254         package_id = tegra_fuse_readl(FUSE_PACKAGE_INFO) & 0x0F;
255
256         /* Arrays must be of equal size - each index corresponds to a SKU */
257         BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
258                ARRAY_SIZE(core_process_speedos));
259
260         rev_sku_to_speedo_ids(tegra_get_revision(), tegra_sku_id());
261         BUG_ON(threshold_index >= ARRAY_SIZE(cpu_process_speedos));
262
263         fuse_speedo_calib(&cpu_speedo_val, &core_speedo_val);
264         pr_debug("%s CPU speedo value %u\n", __func__, cpu_speedo_val);
265         pr_debug("%s Core speedo value %u\n", __func__, core_speedo_val);
266
267         for (iv = 0; iv < CPU_PROCESS_CORNERS_NUM; iv++) {
268                 if (cpu_speedo_val <
269                     cpu_process_speedos[threshold_index][iv]) {
270                         break;
271                 }
272         }
273         cpu_process_id = iv -1;
274
275         if (cpu_process_id == -1) {
276                 pr_err("****************************************************");
277                 pr_err("****************************************************");
278                 pr_err("* tegra3_speedo: CPU speedo value %3d out of range *",
279                        cpu_speedo_val);
280                 pr_err("****************************************************");
281                 pr_err("****************************************************");
282
283                 cpu_process_id = INVALID_PROCESS_ID;
284                 cpu_speedo_id = 1;
285         }
286
287         for (iv = 0; iv < CORE_PROCESS_CORNERS_NUM; iv++) {
288                 if (core_speedo_val <
289                     core_process_speedos[threshold_index][iv]) {
290                         break;
291                 }
292         }
293         core_process_id = iv -1;
294
295         if (core_process_id == -1) {
296                 pr_err("****************************************************");
297                 pr_err("****************************************************");
298                 pr_err("* tegra3_speedo: CORE speedo value %3d out of range *",
299                        core_speedo_val);
300                 pr_err("****************************************************");
301                 pr_err("****************************************************");
302
303                 core_process_id = INVALID_PROCESS_ID;
304                 soc_speedo_id = 1;
305         }
306
307         pr_info("Tegra3: CPU Speedo ID %d, Soc Speedo ID %d",
308                  cpu_speedo_id, soc_speedo_id);
309 }
310
311 int tegra_cpu_process_id(void)
312 {
313         /* FIXME: remove when ready to deprecate invalid process-id boards */
314         if (cpu_process_id == INVALID_PROCESS_ID)
315                 return 0;
316         else
317                 return cpu_process_id;
318 }
319
320 int tegra_core_process_id(void)
321 {
322         /* FIXME: remove when ready to deprecate invalid process-id boards */
323         if (core_process_id == INVALID_PROCESS_ID)
324                 return 0;
325         else
326                 return core_process_id;
327 }
328
329 int tegra_cpu_speedo_id(void)
330 {
331         return cpu_speedo_id;
332 }
333
334 int tegra_soc_speedo_id(void)
335 {
336         return soc_speedo_id;
337 }
338
339 int tegra_package_id(void)
340 {
341         return package_id;
342 }
343
344 /*
345  * CPU and core nominal voltage levels as determined by chip SKU and speedo
346  * (not final - can be lowered by dvfs tables and rail dependencies; the
347  * latter is resolved by the dvfs code)
348  */
349 static const int cpu_speedo_nominal_millivolts[] =
350 /* speedo_id 0,    1,    2,    3,    4,    5,    6,    7,    8 */
351         { 1125, 1150, 1150, 1150, 1237, 1237, 1237, 1150, 1150 };
352
353 int tegra_cpu_speedo_mv(void)
354 {
355         BUG_ON(cpu_speedo_id >= ARRAY_SIZE(cpu_speedo_nominal_millivolts));
356         return cpu_speedo_nominal_millivolts[cpu_speedo_id];
357 }
358
359 int tegra_core_speedo_mv(void)
360 {
361         switch (soc_speedo_id) {
362         case 0:
363                 return 1200;
364         case 1:
365                 if ((cpu_speedo_id != 7) && (cpu_speedo_id != 8))
366                         return 1200;
367                 /* fall thru for T30L or T30SL */
368         case 2:
369                 return 1300;
370         default:
371                 BUG();
372         }
373 }