c0c46861c623a1f7c59788cde382ae79f0409bf7
[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-2012, NVIDIA Corporation. All rights reserved.
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 <linux/bug.h>                  /* For BUG_ON.  */
25
26 #include <mach/iomap.h>
27 #include <mach/tegra_fuse.h>
28 #include <mach/hardware.h>
29 #include <linux/module.h>
30 #include <linux/moduleparam.h>
31
32 #include "fuse.h"
33
34 #define CORE_PROCESS_CORNERS_NUM        1
35 #define CPU_PROCESS_CORNERS_NUM 7
36
37 #define FUSE_SPEEDO_CALIB_0     0x114
38 #define FUSE_PACKAGE_INFO       0X1FC
39 #define FUSE_TEST_PROG_VER      0X128
40 #define FUSE_SPARE_BIT_58       0x32c
41 #define FUSE_SPARE_BIT_59       0x330
42 #define FUSE_SPARE_BIT_60       0x334
43 #define FUSE_SPARE_BIT_61       0x338
44 #define FUSE_SPARE_BIT_62       0x33c
45 #define FUSE_SPARE_BIT_63       0x340
46 #define FUSE_SPARE_BIT_64       0x344
47 #define FUSE_SPARE_BIT_65       0x348
48
49 #define G_SPEEDO_BIT_MINUS1     FUSE_SPARE_BIT_58
50 #define G_SPEEDO_BIT_MINUS1_R   FUSE_SPARE_BIT_59
51 #define G_SPEEDO_BIT_MINUS2     FUSE_SPARE_BIT_60
52 #define G_SPEEDO_BIT_MINUS2_R   FUSE_SPARE_BIT_61
53 #define LP_SPEEDO_BIT_MINUS1    FUSE_SPARE_BIT_62
54 #define LP_SPEEDO_BIT_MINUS1_R  FUSE_SPARE_BIT_63
55 #define LP_SPEEDO_BIT_MINUS2    FUSE_SPARE_BIT_64
56 #define LP_SPEEDO_BIT_MINUS2_R  FUSE_SPARE_BIT_65
57
58 /* Maximum speedo levels for each core process corner */
59 static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = {
60 /* proc_id 0 */
61         {180}, /* [0]: soc_speedo_id 0: any A01 */
62
63 /* T30 family */
64         {170}, /* [1]: soc_speedo_id 1: AP30 */
65         {195}, /* [2]: soc_speedo_id 2: T30  */
66         {180}, /* [3]: soc_speedo_id 2: T30S */
67
68 /* Characterization SKUs */
69         {168}, /* [4]: soc_speedo_id 1: AP30 char */
70         {192}, /* [5]: soc_speedo_id 2: T30  char */
71         {180}, /* [6]: soc_speedo_id 2: T30S char */
72
73 /* T33 family */
74         {170}, /* [7]: soc_speedo_id = 1 - AP33 */
75         {195}, /* [8]: soc_speedo_id = 2 - T33  */
76         {180}, /* [9]: soc_speedo_id = 2 - T33S/AP37 */
77
78 /* T30 'L' family */
79         {180}, /* [10]: soc_speedo_id 1: T30L */
80         {180}, /* [11]: soc_speedo_id 1: T30SL */
81
82 /* T30 Automotives */
83         {185}, /* [12]: soc_speedo_id = 3 - Automotives */
84         {185}, /* [13]: soc_speedo_id = 3 - Automotives */
85
86 /* T37 Family*/
87         {210}, /* [14]: soc_speedo_id 2: T37 */
88 };
89
90 /* Maximum speedo levels for each CPU process corner */
91 static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
92 /* proc_id 0    1    2    3    4*/
93         {306, 338, 360, 376, UINT_MAX}, /* [0]: cpu_speedo_id 0: any A01 */
94
95 /* T30 family */
96         {295, 336, 358, 375, UINT_MAX}, /* [1]: cpu_speedo_id 1: AP30 */
97         {325, 325, 358, 375, UINT_MAX}, /* [2]: cpu_speedo_id 2: T30  */
98         {325, 325, 358, 375, UINT_MAX}, /* [3]: cpu_speedo_id 3: T30S */
99
100 /* Characterization SKUs */
101         {292, 324, 348, 364, UINT_MAX}, /* [4]: cpu_speedo_id 1: AP30char */
102         {324, 324, 348, 364, UINT_MAX}, /* [5]: cpu_speedo_id 2: T30char  */
103         {324, 324, 348, 364, UINT_MAX}, /* [6]: cpu_speedo_id 3: T30Schar */
104
105 /* T33 family */
106         {295, 336, 358, 375, UINT_MAX},      /* [7]: cpu_speedo_id: 4: AP33 */
107         {358, 358, 358, 358, 397, UINT_MAX}, /* [8]: cpu_speedo_id: 5: T33  */
108         {364, 364, 364, 364, 397, UINT_MAX}, /* [9]: cpu_speedo_id: 6/12: T33S/AP37 */
109
110 /* T30 'L' family */
111         {295, 336, 358, 375, 391, UINT_MAX}, /* [10]: cpu_speedo_id 7: T30L  */
112         {295, 336, 358, 375, 391, UINT_MAX}, /* [11]: cpu_speedo_id 8: T30SL */
113
114 /* T30 Automotives */
115         /* threshold_index 12: cpu_speedo_id 9 & 10
116          * 0,1,2 values correspond to speedo_id  9/14
117          * 3,4,5 values correspond to speedo_id 10/15*/
118         {300, 311, 360, 371, 381, 415, 431},
119         {300, 311, 410, 431, UINT_MAX}, /* [13]: cpu_speedo_id 11: T30 auto */
120
121 /* T37 family */
122         {358, 358, 358, 358, 397, UINT_MAX}, /* [14]: cpu_speedo_id 13: T37 */
123 };
124
125 /*
126  * Common speedo_value array threshold index for both core_process_speedos and
127  * cpu_process_speedos arrays. Make sure these two arrays are always in synch.
128  */
129 static int threshold_index;
130
131 static int cpu_process_id;
132 static int core_process_id;
133 static int cpu_speedo_id;
134 static int soc_speedo_id;
135 static int package_id;
136 /*
137  * Only AP37 supports App Profile
138  * This informs user space of support without exposing cpu id's
139  */
140 static int enable_app_profiles;
141
142 static void fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp)
143 {
144         u32 reg;
145         int ate_ver, bit_minus1, bit_minus2;
146
147         BUG_ON(!speedo_g || !speedo_lp);
148         reg = tegra_fuse_readl(FUSE_SPEEDO_CALIB_0);
149
150         /* Speedo LP = Lower 16-bits Multiplied by 4 */
151         *speedo_lp = (reg & 0xFFFF) * 4;
152
153         /* Speedo G = Upper 16-bits Multiplied by 4 */
154         *speedo_g = ((reg >> 16) & 0xFFFF) * 4;
155
156         if (tegra_fuse_get_revision(&ate_ver))
157                 return;
158         pr_info("%s: ATE prog ver %d.%d\n", __func__, ate_ver/10, ate_ver%10);
159
160         pr_debug("CPU speedo base value %u (0x%3x)\n", *speedo_g, *speedo_g);
161         pr_debug("Core speedo base value %u (0x%3x)\n", *speedo_lp, *speedo_lp);
162
163         if (ate_ver >= 26) {
164                 /* read lower 2 bits of LP speedo from spare fuses */
165                 bit_minus1 = tegra_fuse_readl(LP_SPEEDO_BIT_MINUS1) & 0x1;
166                 bit_minus1 |= tegra_fuse_readl(LP_SPEEDO_BIT_MINUS1_R) & 0x1;
167                 bit_minus2 = tegra_fuse_readl(LP_SPEEDO_BIT_MINUS2) & 0x1;
168                 bit_minus2 |= tegra_fuse_readl(LP_SPEEDO_BIT_MINUS2_R) & 0x1;
169                 *speedo_lp |= (bit_minus1 << 1) | bit_minus2;
170
171                 /* read lower 2 bits of G speedo from spare fuses */
172                 bit_minus1 = tegra_fuse_readl(G_SPEEDO_BIT_MINUS1) & 0x1;
173                 bit_minus1 |= tegra_fuse_readl(G_SPEEDO_BIT_MINUS1_R) & 0x1;
174                 bit_minus2 = tegra_fuse_readl(G_SPEEDO_BIT_MINUS2) & 0x1;
175                 bit_minus2 |= tegra_fuse_readl(G_SPEEDO_BIT_MINUS2_R) & 0x1;
176                 *speedo_g |= (bit_minus1 << 1) | bit_minus2;
177         } else {
178                 /* set lower 2 bits for speedo ate-ver independent comparison */
179                 *speedo_lp |= 0x3;
180                 *speedo_g |= 0x3;
181         }
182 }
183
184 static void rev_sku_to_speedo_ids(int rev, int sku)
185 {
186         switch (rev) {
187         case TEGRA_REVISION_A01: /* any A01 */
188                 cpu_speedo_id = 0;
189                 soc_speedo_id = 0;
190                 threshold_index = 0;
191                 break;
192
193         case TEGRA_REVISION_A02:
194         case TEGRA_REVISION_A03:
195                 switch (sku) {
196                 case 0x87: /* AP30 */
197                 case 0x82: /* T30V */
198                         cpu_speedo_id = 1;
199                         soc_speedo_id = 1;
200                         threshold_index = 1;
201                         break;
202
203                 case 0x81: /* T30 */
204                         switch (package_id) {
205                         case 1: /* MID => T30 */
206                                 cpu_speedo_id = 2;
207                                 soc_speedo_id = 2;
208                                 threshold_index = 2;
209                                 break;
210                         case 2: /* DSC => AP33 */
211                                 cpu_speedo_id = 4;
212                                 soc_speedo_id = 1;
213                                 threshold_index = 7;
214                                 break;
215                         default:
216                                 pr_err("Tegra3 Rev-A02: Reserved pkg: %d\n",
217                                        package_id);
218                                 BUG();
219                                 break;
220                         }
221                         break;
222
223                 case 0x80: /* T33 or T33S */
224                         switch (package_id) {
225                         case 1: /* MID => T33 */
226                                 cpu_speedo_id = 5;
227                                 soc_speedo_id = 2;
228                                 threshold_index = 8;
229                                 break;
230                         case 2: /* DSC => T33S */
231                                 cpu_speedo_id = 6;
232                                 soc_speedo_id = 2;
233                                 threshold_index = 9;
234                                 break;
235                         default:
236                                 pr_err("Tegra3 Rev-A02: Reserved pkg: %d\n",
237                                        package_id);
238                                 BUG();
239                                 break;
240                         }
241                         break;
242
243                 case 0x83: /* T30L or T30S */
244                         switch (package_id) {
245                         case 1: /* MID => T30L */
246                                 cpu_speedo_id = 7;
247                                 soc_speedo_id = 1;
248                                 threshold_index = 10;
249                                 break;
250                         case 2: /* DSC => T30S */
251                                 cpu_speedo_id = 3;
252                                 soc_speedo_id = 2;
253                                 threshold_index = 3;
254                                 break;
255                         default:
256                                 pr_err("Tegra3 Rev-A02: Reserved pkg: %d\n",
257                                        package_id);
258                                 BUG();
259                                 break;
260                         }
261                         break;
262
263                 case 0x8F: /* T30SL */
264                         cpu_speedo_id = 8;
265                         soc_speedo_id = 1;
266                         threshold_index = 11;
267                         break;
268
269                 case 0xA0: /* T37 or A37 */
270                         switch (package_id) {
271                         case 1: /* MID => T37 */
272                                 cpu_speedo_id = 13;
273                                 soc_speedo_id = 2;
274                                 threshold_index = 14;
275                                 break;
276                         case 2: /* DSC => AP37 */
277                                 cpu_speedo_id = 12;
278                                 soc_speedo_id = 2;
279                                 threshold_index = 9;
280                                 enable_app_profiles = 1;
281                                 break;
282                         default:
283                                 pr_err("Tegra3 Rev-A02: Reserved pkg: %d\n",
284                                                 package_id);
285                                 BUG();
286                                 break;
287                         }
288                         break;
289
290 /* Characterization SKUs */
291                 case 0x08: /* AP30 char */
292                         cpu_speedo_id = 1;
293                         soc_speedo_id = 1;
294                         threshold_index = 4;
295                         break;
296                 case 0x02: /* T30 char */
297                         cpu_speedo_id = 2;
298                         soc_speedo_id = 2;
299                         threshold_index = 5;
300                         break;
301                 case 0x04: /* T30S char */
302                         cpu_speedo_id = 3;
303                         soc_speedo_id = 2;
304                         threshold_index = 6;
305                         break;
306
307                 case 0x91: /* T30AGS-Ax */
308                 case 0xb0: /* T30IQS-Ax */
309                 case 0xb1: /* T30MQS-Ax */
310                 case 0x90: /* T30AQS-Ax */
311                         soc_speedo_id = 3;
312                         threshold_index = 12;
313                         break;
314                 case 0x93: /* T30AG-Ax */
315                         cpu_speedo_id = 11;
316                         soc_speedo_id = 3;
317                         threshold_index = 13;
318                         break;
319                 case 0:    /* ENG - check package_id */
320                         pr_info("Tegra3 ENG SKU: Checking package_id\n");
321                         switch (package_id) {
322                         case 1: /* MID => assume T30 */
323                                 cpu_speedo_id = 2;
324                                 soc_speedo_id = 2;
325                                 threshold_index = 2;
326                                 break;
327                         case 2: /* DSC => assume T30S */
328                                 cpu_speedo_id = 3;
329                                 soc_speedo_id = 2;
330                                 threshold_index = 3;
331                                 break;
332                         default:
333                                 pr_err("Tegra3 Rev-A02: Reserved pkg: %d\n",
334                                        package_id);
335                                 BUG();
336                                 break;
337                         }
338                         break;
339
340                 default:
341                         /* FIXME: replace with BUG() when all SKU's valid */
342                         pr_err("Tegra3 Rev-A02: Unknown SKU %d\n", sku);
343                         cpu_speedo_id = 0;
344                         soc_speedo_id = 0;
345                         threshold_index = 0;
346                         break;
347                 }
348                 break;
349         default:
350                 BUG();
351                 break;
352         }
353 }
354
355 void tegra_init_speedo_data(void)
356 {
357         u32 cpu_speedo_val, core_speedo_val;
358         int iv;
359         int fuse_sku = tegra_sku_id;
360         int sku_override = tegra_get_sku_override();
361         int new_sku = fuse_sku;
362
363         /* Package info: 4 bits - 0,3:reserved 1:MID 2:DSC */
364         package_id = tegra_fuse_readl(FUSE_PACKAGE_INFO) & 0x0F;
365
366         /* Arrays must be of equal size - each index corresponds to a SKU */
367         BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
368                ARRAY_SIZE(core_process_speedos));
369
370         /* SKU Overrides
371         * T33   => T30, T30L
372         * T33S  => T30S, T30SL
373         * T30   => T30L
374         * T30S  => T30SL
375         * AP33  => AP30
376         */
377         switch (sku_override) {
378         case 1:
379                 /* Base sku override */
380                 if (fuse_sku == 0x80) {
381                         if (package_id == 1) {
382                                 /* T33 to T30 */
383                                 pr_info("%s: SKU OR: T33->T30\n", __func__);
384                                 new_sku = 0x81;
385                         } else if (package_id == 2) {
386                                 /* T33S->T30S */
387                                 pr_info("%s: SKU OR: T33S->T30S\n", __func__);
388                                 new_sku = 0x83;
389                         }
390                 } else if (fuse_sku == 0x81) {
391                         if (package_id == 2) {
392                                 /* AP33->AP30 */
393                                 pr_info("%s: SKU OR: AP33->AP30\n", __func__);
394                                 new_sku = 0x87;
395                         }
396                 }
397                 break;
398         case 2:
399                 /* L sku override */
400                 if (fuse_sku == 0x80) {
401                         if (package_id == 1) {
402                                 /* T33->T30L */
403                                 pr_info("%s: SKU OR: T33->T30L\n", __func__);
404                                 new_sku = 0x83;
405                         } else if (package_id == 2) {
406                                 /* T33S->T33SL */
407                                 pr_info("%s: SKU OR: T33S->T30SL\n", __func__);
408                                 new_sku = 0x8f;
409                         }
410                 } else if (fuse_sku == 0x81) {
411                         if (package_id == 1) {
412                                 pr_info("%s: SKU OR: T30->T30L\n", __func__);
413                                 /* T30->T30L */
414                                 new_sku = 0x83;
415                         }
416                 } else if (fuse_sku == 0x83) {
417                         if (package_id == 2) {
418                                 pr_info("%s: SKU OR: T30S->T30SL\n", __func__);
419                                 /* T30S to T30SL */
420                                 new_sku = 0x8f;
421                         }
422                 }
423                 break;
424         default:
425                 /* no override */
426                 break;
427         }
428
429         rev_sku_to_speedo_ids(tegra_revision, new_sku);
430         BUG_ON(threshold_index >= ARRAY_SIZE(cpu_process_speedos));
431
432         fuse_speedo_calib(&cpu_speedo_val, &core_speedo_val);
433         pr_debug("%s CPU speedo value %u\n", __func__, cpu_speedo_val);
434         pr_debug("%s Core speedo value %u\n", __func__, core_speedo_val);
435
436         for (iv = 0; iv < CPU_PROCESS_CORNERS_NUM; iv++) {
437                 if (cpu_speedo_val <
438                     cpu_process_speedos[threshold_index][iv]) {
439                         break;
440                 }
441         }
442         cpu_process_id = iv -1;
443
444         if (cpu_process_id == -1) {
445                 pr_err("****************************************************");
446                 pr_err("****************************************************");
447                 pr_err("* tegra3_speedo: CPU speedo value %3d out of range *",
448                        cpu_speedo_val);
449                 pr_err("****************************************************");
450                 pr_err("****************************************************");
451
452                 cpu_process_id = INVALID_PROCESS_ID;
453                 cpu_speedo_id = 1;
454         }
455
456         for (iv = 0; iv < CORE_PROCESS_CORNERS_NUM; iv++) {
457                 if (core_speedo_val <
458                     core_process_speedos[threshold_index][iv]) {
459                         break;
460                 }
461         }
462         core_process_id = iv -1;
463
464         if (core_process_id == -1) {
465                 pr_err("****************************************************");
466                 pr_err("****************************************************");
467                 pr_err("* tegra3_speedo: CORE speedo value %3d out of range *",
468                        core_speedo_val);
469                 pr_err("****************************************************");
470                 pr_err("****************************************************");
471
472                 core_process_id = INVALID_PROCESS_ID;
473                 soc_speedo_id = 1;
474         }
475         if (threshold_index == 12 && cpu_process_id != INVALID_PROCESS_ID) {
476                 if (cpu_process_id <= 2) {
477                         switch(fuse_sku) {
478                         case 0xb0:
479                         case 0xb1:
480                                 cpu_speedo_id = 9;
481                                 break;
482                         case 0x90:
483                         case 0x91:
484                                 cpu_speedo_id = 14;
485                         default:
486                                 break;
487                         }
488                 } else if (cpu_process_id >= 3 && cpu_process_id < 6) {
489                         switch(fuse_sku) {
490                         case 0xb0:
491                         case 0xb1:
492                                 cpu_speedo_id = 10;
493                                 break;
494                         case 0x90:
495                         case 0x91:
496                                 cpu_speedo_id = 15;
497                         default:
498                                 break;
499                         }
500                 }
501         }
502         pr_info("Tegra3: CPU Speedo ID %d, Soc Speedo ID %d",
503                  cpu_speedo_id, soc_speedo_id);
504 }
505
506 int tegra_cpu_process_id(void)
507 {
508         /* FIXME: remove when ready to deprecate invalid process-id boards */
509         if (cpu_process_id == INVALID_PROCESS_ID)
510                 return 0;
511         else
512                 return cpu_process_id;
513 }
514
515 int tegra_core_process_id(void)
516 {
517         /* FIXME: remove when ready to deprecate invalid process-id boards */
518         if (core_process_id == INVALID_PROCESS_ID)
519                 return 0;
520         else
521                 return core_process_id;
522 }
523
524 int tegra_cpu_speedo_id(void)
525 {
526         return cpu_speedo_id;
527 }
528
529 int tegra_soc_speedo_id(void)
530 {
531         return soc_speedo_id;
532 }
533
534 int tegra_package_id(void)
535 {
536         return package_id;
537 }
538
539 /*
540  * CPU and core nominal voltage levels as determined by chip SKU and speedo
541  * (not final - can be lowered by dvfs tables and rail dependencies; the
542  * latter is resolved by the dvfs code)
543  */
544 static const int cpu_speedo_nominal_millivolts[] =
545 /* speedo_id 0,    1,    2,    3,    4,    5,    6,    7,    8,   9,  10,  11,   12,    13,  14,  15 */
546         { 1125, 1150, 1150, 1150, 1237, 1237, 1237, 1150, 1150, 1007, 916, 850, 1237, 1237, 950, 900};
547
548 int tegra_cpu_speedo_mv(void)
549 {
550         return cpu_speedo_nominal_millivolts[cpu_speedo_id];
551 }
552
553 int tegra_core_speedo_mv(void)
554 {
555         switch (soc_speedo_id) {
556         case 0:
557                 return 1200;
558         case 1:
559                 if ((cpu_speedo_id != 7) && (cpu_speedo_id != 8))
560                         return 1200;
561                 /* fall thru for T30L or T30SL */
562         case 2:
563                 if (cpu_speedo_id != 13)
564                         return 1300;
565                 /* T37 */
566                 return 1350;
567         case 3:
568                 return 1250;
569         default:
570                 BUG();
571         }
572 }
573
574 static int get_enable_app_profiles(char *val, const struct kernel_param *kp)
575 {
576         return param_get_uint(val, kp);
577 }
578
579 static struct kernel_param_ops tegra_profiles_ops = {
580         .get = get_enable_app_profiles,
581 };
582
583 module_param_cb(tegra_enable_app_profiles,
584         &tegra_profiles_ops, &enable_app_profiles, 0444);