Ventana: KBC: Removing the KBC usage on ventana
[linux-2.6.git] / arch / arm / mach-tegra / fuse.c
1 /*
2  * arch/arm/mach-tegra/fuse.c
3  *
4  * Copyright (C) 2010 Google, Inc.
5  * Copyright (C) 2010-2011 NVIDIA Corp.
6  *
7  * Author:
8  *      Colin Cross <ccross@android.com>
9  *
10  * This software is licensed under the terms of the GNU General Public
11  * License version 2, as published by the Free Software Foundation, and
12  * may be copied, distributed, and modified under those terms.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  */
20
21 #include <linux/kernel.h>
22 #include <linux/io.h>
23 #include <linux/init.h>
24 #include <linux/string.h>
25 #include <linux/module.h>
26 #include <linux/moduleparam.h>
27
28 #include <mach/iomap.h>
29 #include <mach/tegra_fuse.h>
30
31 #include "fuse.h"
32 #include "apbio.h"
33
34 #define FUSE_SKU_INFO           0x110
35 #if defined(CONFIG_ARCH_TEGRA_2x_SOC)
36 #define FUSE_UID_LOW            0x108
37 #define FUSE_UID_HIGH           0x10c
38 #define FUSE_SPARE_BIT          0x200
39 #else
40 #define FUSE_VENDOR_CODE        0x200
41 #define FUSE_VENDOR_CODE_MASK   0xf
42 #define FUSE_FAB_CODE           0x204
43 #define FUSE_FAB_CODE_MASK      0x3f
44 #define FUSE_LOT_CODE_0         0x208
45 #define FUSE_LOT_CODE_1         0x20c
46 #define FUSE_WAFER_ID           0x210
47 #define FUSE_WAFER_ID_MASK      0x3f
48 #define FUSE_X_COORDINATE       0x214
49 #define FUSE_X_COORDINATE_MASK  0x1ff
50 #define FUSE_Y_COORDINATE       0x218
51 #define FUSE_Y_COORDINATE_MASK  0x1ff
52 #define FUSE_GPU_INFO           0x390
53 #define FUSE_GPU_INFO_MASK      (1<<2)
54 #define FUSE_SPARE_BIT          0x244
55 /* fuse registers used in public fuse data read API */
56 #define FUSE_TEST_PROGRAM_REVISION_0    0x128
57 /* fuse spare bits are used to get Tj-ADT values */
58 #define FUSE_SPARE_BIT_0_0      0x244
59 #define NUM_TSENSOR_SPARE_BITS  28
60 /* tsensor calibration register */
61 #define FUSE_TSENSOR_CALIB_0    0x198
62
63 #endif
64
65 struct tegra_id {
66         enum tegra_chipid chipid;
67         unsigned int major, minor, netlist, patch;
68         enum tegra_revision revision;
69         char *priv;
70 };
71
72 static struct tegra_id tegra_id;
73 static unsigned int tegra_chip_id;
74 static unsigned int tegra_chip_rev;
75
76 static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
77         [TEGRA_REVISION_UNKNOWN] = "unknown",
78         [TEGRA_REVISION_A01] = "A01",
79         [TEGRA_REVISION_A02] = "A02",
80         [TEGRA_REVISION_A03] = "A03",
81         [TEGRA_REVISION_A03p] = "A03 prime",
82 };
83
84 u32 tegra_fuse_readl(unsigned long offset)
85 {
86         return tegra_apb_readl(TEGRA_FUSE_BASE + offset);
87 }
88
89 void tegra_fuse_writel(u32 value, unsigned long offset)
90 {
91         tegra_apb_writel(value, TEGRA_FUSE_BASE + offset);
92 }
93
94 static inline bool get_spare_fuse(int bit)
95 {
96         return tegra_fuse_readl(FUSE_SPARE_BIT + bit * 4);
97 }
98
99 const char *tegra_get_revision_name(void)
100 {
101         return tegra_revision_name[tegra_get_revision()];
102 }
103
104 void tegra_init_fuse(void)
105 {
106         u32 reg = readl(IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48));
107         reg |= 1 << 28;
108         writel(reg, IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48));
109         tegra_init_speedo_data();
110
111         pr_info("Tegra Revision: %s "
112                 "SKU: 0x%x CPU Process: %d Core Process: %d\n",
113                 tegra_get_revision_name(), tegra_sku_id(),
114                 tegra_cpu_process_id(), tegra_core_process_id());
115 }
116
117 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
118 int tegra_fuse_get_revision(u32 *rev)
119 {
120         return -ENOENT;
121 }
122 EXPORT_SYMBOL(tegra_fuse_get_revision);
123
124 int tegra_fuse_get_tsensor_calibration_data(u32 *calib)
125 {
126         return -ENOENT;
127 }
128 EXPORT_SYMBOL(tegra_fuse_get_tsensor_calibration_data);
129
130 int tegra_fuse_get_tsensor_spare_bits(u32 *spare_bits)
131 {
132         return -ENOENT;
133 }
134 EXPORT_SYMBOL(tegra_fuse_get_tsensor_spare_bits);
135
136 #else
137
138 int tegra_fuse_get_revision(u32 *rev)
139 {
140         /* fuse revision */
141         *rev = tegra_fuse_readl(FUSE_TEST_PROGRAM_REVISION_0);
142         return 0;
143 }
144 EXPORT_SYMBOL(tegra_fuse_get_revision);
145
146 int tegra_fuse_get_tsensor_calibration_data(u32 *calib)
147 {
148         /* tsensor calibration fuse */
149         *calib = tegra_fuse_readl(FUSE_TSENSOR_CALIB_0);
150         return 0;
151 }
152 EXPORT_SYMBOL(tegra_fuse_get_tsensor_calibration_data);
153
154 int tegra_fuse_get_tsensor_spare_bits(u32 *spare_bits)
155 {
156         u32 value;
157         int i;
158
159         BUG_ON(NUM_TSENSOR_SPARE_BITS > (sizeof(u32) * 8));
160         if (!spare_bits)
161                 return -ENOMEM;
162         *spare_bits = 0;
163         /* spare bits 0-27 */
164         for (i = 0; i < NUM_TSENSOR_SPARE_BITS; i++) {
165                 value = tegra_fuse_readl(FUSE_SPARE_BIT_0_0 +
166                         (i << 2));
167                 if (value)
168                         *spare_bits |= BIT(i);
169         }
170         return 0;
171 }
172 EXPORT_SYMBOL(tegra_fuse_get_tsensor_spare_bits);
173 #endif
174
175 unsigned long long tegra_chip_uid(void)
176 {
177 #if defined(CONFIG_ARCH_TEGRA_2x_SOC)
178         unsigned long long lo, hi;
179
180         lo = tegra_fuse_readl(FUSE_UID_LOW);
181         hi = tegra_fuse_readl(FUSE_UID_HIGH);
182         return (hi << 32ull) | lo;
183 #else
184         u64 uid = 0ull;
185         u32 reg;
186         u32 cid;
187         u32 vendor;
188         u32 fab;
189         u32 lot;
190         u32 wafer;
191         u32 x;
192         u32 y;
193         u32 i;
194
195         /* This used to be so much easier in prior chips. Unfortunately, there
196            is no one-stop shopping for the unique id anymore. It must be
197            constructed from various bits of information burned into the fuses
198            during the manufacturing process. The 64-bit unique id is formed
199            by concatenating several bit fields. The notation used for the
200            various fields is <fieldname:size_in_bits> with the UID composed
201            thusly:
202
203            <CID:4><VENDOR:4><FAB:6><LOT:26><WAFER:6><X:9><Y:9>
204
205            Where:
206
207                 Field    Bits  Position Data
208                 -------  ----  -------- ----------------------------------------
209                 CID        4     60     Chip id (encoded as zero for T30)
210                 VENDOR     4     56     Vendor code
211                 FAB        6     50     FAB code
212                 LOT       26     24     Lot code (5-digit base-36-coded-decimal,
213                                         re-encoded to 26 bits binary)
214                 WAFER      6     18     Wafer id
215                 X          9      9     Wafer X-coordinate
216                 Y          9      0     Wafer Y-coordinate
217                 -------  ----
218                 Total     64
219         */
220
221         /* Get the chip id and encode each chip variant as a unique value. */
222         reg = readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE + 0x804));
223         reg = (reg & 0xFF00) >> 8;
224
225         switch (reg) {
226         case TEGRA_CHIPID_TEGRA3:
227                 cid = 0;
228                 break;
229
230         default:
231                 BUG();
232                 break;
233         }
234
235         vendor = tegra_fuse_readl(FUSE_VENDOR_CODE) & FUSE_VENDOR_CODE_MASK;
236         fab = tegra_fuse_readl(FUSE_FAB_CODE) & FUSE_FAB_CODE_MASK;
237
238         /* Lot code must be re-encoded from a 5 digit base-36 'BCD' number
239            to a binary number. */
240         lot = 0;
241         reg = tegra_fuse_readl(FUSE_LOT_CODE_1) << 2;
242
243         for (i = 0; i < 5; ++i) {
244                 u32 digit = (reg & 0xFC000000) >> 26;
245                 BUG_ON(digit >= 36);
246                 lot *= 36;
247                 lot += digit;
248                 reg <<= 6;
249         }
250
251         wafer = tegra_fuse_readl(FUSE_WAFER_ID) & FUSE_WAFER_ID_MASK;
252         x = tegra_fuse_readl(FUSE_X_COORDINATE) & FUSE_X_COORDINATE_MASK;
253         y = tegra_fuse_readl(FUSE_Y_COORDINATE) & FUSE_Y_COORDINATE_MASK;
254
255         uid = ((unsigned long long)cid  << 60ull)
256             | ((unsigned long long)vendor << 56ull)
257             | ((unsigned long long)fab << 50ull)
258             | ((unsigned long long)lot << 24ull)
259             | ((unsigned long long)wafer << 18ull)
260             | ((unsigned long long)x << 9ull)
261             | ((unsigned long long)y << 0ull);
262         return uid;
263 #endif
264 }
265
266 unsigned int tegra_spare_fuse(int bit)
267 {
268         BUG_ON(bit < 0 || bit > 61);
269         return tegra_fuse_readl(FUSE_SPARE_BIT + bit * 4);
270 }
271
272 int tegra_sku_id(void)
273 {
274         int sku_id;
275         u32 reg = tegra_fuse_readl(FUSE_SKU_INFO);
276         sku_id = reg & 0xFF;
277         return sku_id;
278 }
279
280 int tegra_gpu_register_sets(void)
281 {
282 #ifdef CONFIG_ARCH_TEGRA_DUAL_3D
283         u32 reg = readl(IO_TO_VIRT(TEGRA_CLK_RESET_BASE + FUSE_GPU_INFO));
284         if (reg & FUSE_GPU_INFO_MASK)
285                 return 1;
286         else
287                 return 2;
288 #else
289         return 1;
290 #endif
291 }
292
293 struct chip_revision {
294         enum tegra_chipid       chipid;
295         unsigned int            major;
296         unsigned int            minor;
297         char                    prime;
298         enum tegra_revision     revision;
299 };
300
301 #define CHIP_REVISION(id, m, n, p, rev) {       \
302         .chipid = TEGRA_CHIPID_##id,            \
303         .major = m,                             \
304         .minor = n,                             \
305         .prime = p,                             \
306         .revision = TEGRA_REVISION_##rev }
307
308 static struct chip_revision tegra_chip_revisions[] = {
309         CHIP_REVISION(TEGRA2, 1, 2, 0,   A02),
310         CHIP_REVISION(TEGRA2, 1, 3, 0,   A03),
311         CHIP_REVISION(TEGRA2, 1, 3, 'p', A03p),
312         CHIP_REVISION(TEGRA3, 1, 1, 0,   A01),
313         CHIP_REVISION(TEGRA3, 1, 2, 0,   A02),
314         CHIP_REVISION(TEGRA3, 1, 3, 0,   A03),
315 };
316
317 static enum tegra_revision tegra_decode_revision(const struct tegra_id *id)
318 {
319         enum tegra_revision revision = TEGRA_REVISION_UNKNOWN;
320
321 #if defined(CONFIG_TEGRA_SILICON_PLATFORM)
322         int i ;
323         char prime;
324
325         if (id->priv == NULL)
326                 prime = 0;
327         else
328                 prime = *(id->priv);
329
330         for (i = 0; i < ARRAY_SIZE(tegra_chip_revisions); i++) {
331                 if ((id->chipid != tegra_chip_revisions[i].chipid) ||
332                     (id->minor != tegra_chip_revisions[i].minor) ||
333                     (id->major != tegra_chip_revisions[i].major) ||
334                     (prime != tegra_chip_revisions[i].prime))
335                         continue;
336
337                 revision = tegra_chip_revisions[i].revision;
338                 break;
339         }
340
341 #elif defined(CONFIG_TEGRA_FPGA_PLATFORM)
342         if ((id->chipid & 0xf0) == TEGRA_CHIPID_TEGRA3) {
343                 if ((id->major == 0) && (id->minor == 1)) {
344                         unsigned int patch = id->patch & 0xF;
345                         if ((id->netlist == 12) && (patch == 12))
346                                 revision = TEGRA_REVISION_A01;
347                         else if ((id->netlist == 12) && (patch > 12))
348                                 revision = TEGRA_REVISION_A02;
349                         else if (id->netlist > 12)
350                                 revision = TEGRA_REVISION_A02;
351                 }
352         }
353 #endif
354
355         return revision;
356 }
357
358 static void tegra_set_tegraid(u32 chipid,
359                                         u32 major, u32 minor,
360                                         u32 nlist, u32 patch, const char *priv)
361 {
362         tegra_id.chipid  = (enum tegra_chipid) chipid;
363         tegra_id.major   = major;
364         tegra_id.minor   = minor;
365         tegra_id.netlist = nlist;
366         tegra_id.patch   = patch;
367         tegra_id.priv    = (char *)priv;
368         tegra_id.revision = tegra_decode_revision(&tegra_id);
369 }
370
371 static void tegra_get_tegraid_from_hw(void)
372 {
373         void __iomem *chip_id = IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804;
374         void __iomem *netlist = IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x860;
375         u32 cid = readl(chip_id);
376         u32 nlist = readl(netlist);
377         char *priv = NULL;
378
379 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
380         if (get_spare_fuse(18) || get_spare_fuse(19))
381                 priv = "p";
382 #endif
383         tegra_set_tegraid((cid >> 8) & 0xff,
384                           (cid >> 4) & 0xf,
385                           (cid >> 16) & 0xf,
386                           (nlist >> 0) & 0xffff,
387                           (nlist >> 16) & 0xffff,
388                           priv);
389 }
390
391 enum tegra_chipid tegra_get_chipid(void)
392 {
393         if (tegra_id.chipid == TEGRA_CHIPID_UNKNOWN) {
394                 /* Boot loader did not pass a valid chip ID.
395                  * Get it from hardware */
396                 tegra_get_tegraid_from_hw();
397         }
398
399         return tegra_id.chipid;
400 }
401
402 enum tegra_revision tegra_get_revision(void)
403 {
404         if (tegra_id.chipid == TEGRA_CHIPID_UNKNOWN) {
405                 /* Boot loader did not pass a valid chip ID.
406                  * Get it from hardware */
407                 tegra_get_tegraid_from_hw();
408         }
409
410         return tegra_id.revision;
411 }
412
413 static char chippriv[16]; /* Permanent buffer for private string */
414 static int __init tegra_bootloader_tegraid(char *str)
415 {
416         u32 id[5];
417         int i = 0;
418         char *priv = NULL;
419
420         do {
421                 id[i++] = simple_strtoul(str, &str, 16);
422         } while (*str++ && i < ARRAY_SIZE(id));
423
424         if (*(str - 1) == '.') {
425                 strncpy(chippriv, str, sizeof(chippriv) - 1);
426                 priv = chippriv;
427                 if (strlen(str) > sizeof(chippriv) - 1)
428                         pr_err("### tegraid.priv in kernel arg truncated\n");
429         }
430
431         while (i < ARRAY_SIZE(id))
432                 id[i++] = 0;
433
434         tegra_set_tegraid(id[0], id[1], id[2], id[3], id[4], priv);
435         return 0;
436 }
437
438 static unsigned int get_chip_id(char *val, struct kernel_param *kp)
439 {
440         tegra_chip_id = (unsigned int)tegra_get_chipid();
441         return param_get_uint(val, kp);
442 }
443 static unsigned int get_chip_rev(char *val, struct kernel_param *kp)
444 {
445         tegra_chip_rev = (unsigned int)tegra_get_revision();
446         return param_get_uint(val, kp);
447 }
448
449 module_param_call(tegra_chip_id, NULL, get_chip_id, &tegra_chip_id, 0444);
450 __MODULE_PARM_TYPE(tegra_chip_id, "uint");
451 module_param_call(tegra_chip_rev, NULL, get_chip_rev, &tegra_chip_rev, 0444);
452 __MODULE_PARM_TYPE(tegra_chip_rev, "uint");
453
454 /* tegraid=chipid.major.minor.netlist.patch[.priv] */
455 early_param("tegraid", tegra_bootloader_tegraid);