ARM: tegra: loki: fix build error due to warning
[linux-3.10.git] / arch / arm / mach-tegra / tegra12x_fuse_offsets.h
1 /*
2  * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
3  *
4  * this program is free software; you can redistribute it and/or modify
5  * it under the terms of the gnu general public license as published by
6  * the free software foundation; either version 2 of the license, or
7  * (at your option) any later version.
8  *
9  * this program is distributed in the hope that it will be useful, but without
10  * any warranty; without even the implied warranty of merchantability or
11  * fitness for a particular purpose.  see the gnu general public license for
12  * more details.
13  *
14  * you should have received a copy of the gnu general public license along
15  * with this program; if not, write to the free software foundation, inc.,
16  * 51 franklin street, fifth floor, boston, ma  02110-1301, usa.
17  */
18
19 #include <linux/tegra-soc.h>
20
21 #include <mach/tegra_fuse.h>
22
23 #include "apbio.h"
24 #include "fuse.h"
25 #include "iomap.h"
26
27 #ifndef __TEGRA12x_FUSE_OFFSETS_H
28 #define __TEGRA12x_FUSE_OFFSETS_H
29
30 /* private_key4 */
31 #define DEVKEY_START_OFFSET             0x2A
32 #define DEVKEY_START_BIT                12
33
34 /* arm_debug_dis */
35 #define JTAG_START_OFFSET               0x0
36 #define JTAG_START_BIT                  3
37
38 /* security_mode */
39 #define ODM_PROD_START_OFFSET           0x0
40 #define ODM_PROD_START_BIT              11
41
42 /* boot_device_info */
43 #define SB_DEVCFG_START_OFFSET          0x2C
44 #define SB_DEVCFG_START_BIT             12
45
46 /* reserved_sw[2:0] */
47 #define SB_DEVSEL_START_OFFSET          0x2C
48 #define SB_DEVSEL_START_BIT             28
49
50 /* private_key0 -> private_key3 (SBK) */
51 #define SBK_START_OFFSET                0x22
52 #define SBK_START_BIT                   12
53
54 /* reserved_sw[7:4] */
55 #define SW_RESERVED_START_OFFSET        0x2E
56 #define SW_RESERVED_START_BIT           0
57
58 /* reserved_sw[3] */
59 #define IGNORE_DEVSEL_START_OFFSET      0x2C
60 #define IGNORE_DEVSEL_START_BIT         31
61
62 /* public key */
63 #define PUBLIC_KEY_START_OFFSET         0x0A
64 #define PUBLIC_KEY_START_BIT            30
65
66 /* pkc_disable */
67 #define PKC_DISABLE_START_OFFSET        0x5A
68 #define PKC_DISABLE_START_BIT           9
69
70 /* video vp8 enable */
71 #define VP8_ENABLE_START_OFFSET         0x2E
72 #define VP8_ENABLE_START_BIT            4
73
74 /* odm lock */
75 #define ODM_LOCK_START_OFFSET           0x0
76 #define ODM_LOCK_START_BIT              6
77
78 /* reserved_odm0 -> reserved_odm7 */
79 #define ODM_RESERVED_DEVSEL_START_OFFSET        0x2E
80 #define ODM_RESERVED_START_BIT                  5
81
82 #define FUSE_VENDOR_CODE        0x200
83 #define FUSE_VENDOR_CODE_MASK   0xf
84 #define FUSE_FAB_CODE           0x204
85 #define FUSE_FAB_CODE_MASK      0x3f
86 #define FUSE_LOT_CODE_0         0x208
87 #define FUSE_LOT_CODE_1         0x20c
88 #define FUSE_WAFER_ID           0x210
89 #define FUSE_WAFER_ID_MASK      0x3f
90 #define FUSE_X_COORDINATE       0x214
91 #define FUSE_X_COORDINATE_MASK  0x1ff
92 #define FUSE_Y_COORDINATE       0x218
93 #define FUSE_Y_COORDINATE_MASK  0x1ff
94 #define FUSE_GPU_INFO           0x390
95 #define FUSE_GPU_INFO_MASK      (1<<2)
96 #define FUSE_SPARE_BIT          0x300
97 /* fuse registers used in public fuse data read API */
98 #define FUSE_FT_REV             0x128
99 #define FUSE_CP_REV             0x190
100 /* fuse spare bits are used to get Tj-ADT values */
101 #define NUM_TSENSOR_SPARE_BITS  28
102 /* tsensor calibration register */
103 #define FUSE_TSENSOR_CALIB_0    0x198
104 /* sparse realignment register */
105 #define FUSE_SPARE_REALIGNMENT_REG_0 0x2fc
106 /* tsensor8_calib */
107 #define FUSE_TSENSOR_CALIB_8 0x280
108
109 #define FUSE_BASE_CP_SHIFT      0
110 #define FUSE_BASE_CP_MASK       0x3ff
111 #define FUSE_BASE_FT_SHIFT      10
112 #define FUSE_BASE_FT_MASK       0x7ff
113 #define FUSE_SHIFT_CP_SHIFT     0
114 #define FUSE_SHIFT_CP_MASK      0x3f
115 #define FUSE_SHIFT_CP_BITS      6
116 #define FUSE_SHIFT_FT_SHIFT     21
117 #define FUSE_SHIFT_FT_MASK      0x1f
118 #define FUSE_SHIFT_FT_BITS      5
119
120 #define TEGRA_FUSE_SUPPLY       "vpp_fuse"
121
122 #define PGM_TIME_US 12
123
124 #define CHK_ERR(x) \
125 { \
126         if (x) { \
127                 pr_err("%s: sysfs_create_file fail(%d)!", __func__, x); \
128                 return x; \
129         } \
130 }
131
132 DEVICE_ATTR(public_key, 0440, tegra_fuse_show, tegra_fuse_store);
133 DEVICE_ATTR(pkc_disable, 0440, tegra_fuse_show, tegra_fuse_store);
134 DEVICE_ATTR(vp8_enable, 0440, tegra_fuse_show, tegra_fuse_store);
135 DEVICE_ATTR(odm_lock, 0440, tegra_fuse_show, tegra_fuse_store);
136
137 static inline int fuse_cp_rev_check(void)
138 {
139         u32 rev, rev_major, rev_minor;
140
141         rev = tegra_fuse_readl(FUSE_CP_REV);
142         rev_minor = rev & 0x1f;
143         rev_major = (rev >> 5) & 0x3f;
144         /* CP rev < 00.4 is unsupported */
145         if ((rev_major == 0) && (rev_minor < 4))
146                 return -EINVAL;
147
148         return 0;
149 }
150
151 static inline int fuse_ft_rev_check(void)
152 {
153         u32 rev, rev_major, rev_minor;
154
155         rev = tegra_fuse_readl(FUSE_FT_REV);
156         rev_minor = rev & 0x1f;
157         rev_major = (rev >> 5) & 0x3f;
158         /* FT rev < 00.5 is unsupported */
159         if ((rev_major == 0) && (rev_minor < 5))
160                 return -EINVAL;
161
162         return 0;
163 }
164
165 int tegra_fuse_get_tsensor_calibration_data(u32 *calib)
166 {
167         /* tsensor calibration fuse */
168         *calib = tegra_fuse_readl(FUSE_TSENSOR_CALIB_0);
169         return 0;
170 }
171
172 int tegra_fuse_get_tsensor_spare_bits(u32 *spare_bits)
173 {
174         u32 value;
175         int i;
176
177         BUG_ON(NUM_TSENSOR_SPARE_BITS > (sizeof(u32) * 8));
178         if (!spare_bits)
179                 return -ENOMEM;
180         *spare_bits = 0;
181         /* spare bits 0-27 */
182         for (i = 0; i < NUM_TSENSOR_SPARE_BITS; i++) {
183                 value = tegra_fuse_readl(FUSE_SPARE_BIT +
184                         (i << 2));
185                 if (value)
186                         *spare_bits |= BIT(i);
187         }
188         return 0;
189 }
190
191 unsigned long long tegra_chip_uid(void)
192 {
193
194         u64 uid = 0ull;
195         u32 reg;
196         u32 cid;
197         u32 vendor;
198         u32 fab;
199         u32 lot;
200         u32 wafer;
201         u32 x;
202         u32 y;
203         u32 i;
204
205         /* This used to be so much easier in prior chips. Unfortunately, there
206            is no one-stop shopping for the unique id anymore. It must be
207            constructed from various bits of information burned into the fuses
208            during the manufacturing process. The 64-bit unique id is formed
209            by concatenating several bit fields. The notation used for the
210            various fields is <fieldname:size_in_bits> with the UID composed
211            thusly:
212
213            <CID:4><VENDOR:4><FAB:6><LOT:26><WAFER:6><X:9><Y:9>
214
215            Where:
216
217                 Field    Bits  Position Data
218                 -------  ----  -------- ----------------------------------------
219                 CID        4     60     Chip id
220                 VENDOR     4     56     Vendor code
221                 FAB        6     50     FAB code
222                 LOT       26     24     Lot code (5-digit base-36-coded-decimal,
223                                         re-encoded to 26 bits binary)
224                 WAFER      6     18     Wafer id
225                 X          9      9     Wafer X-coordinate
226                 Y          9      0     Wafer Y-coordinate
227                 -------  ----
228                 Total     64
229         */
230
231         /* chip id is 3 for tegra 12x */
232         cid = 3;
233
234         vendor = tegra_fuse_readl(FUSE_VENDOR_CODE) & FUSE_VENDOR_CODE_MASK;
235         fab = tegra_fuse_readl(FUSE_FAB_CODE) & FUSE_FAB_CODE_MASK;
236
237         /* Lot code must be re-encoded from a 5 digit base-36 'BCD' number
238            to a binary number. */
239         lot = 0;
240         reg = tegra_fuse_readl(FUSE_LOT_CODE_0) << 2;
241
242         for (i = 0; i < 5; ++i) {
243                 u32 digit = (reg & 0xFC000000) >> 26;
244                 BUG_ON(digit >= 36);
245                 lot *= 36;
246                 lot += digit;
247                 reg <<= 6;
248         }
249
250         wafer = tegra_fuse_readl(FUSE_WAFER_ID) & FUSE_WAFER_ID_MASK;
251         x = tegra_fuse_readl(FUSE_X_COORDINATE) & FUSE_X_COORDINATE_MASK;
252         y = tegra_fuse_readl(FUSE_Y_COORDINATE) & FUSE_Y_COORDINATE_MASK;
253
254         uid = ((unsigned long long)cid  << 60ull)
255             | ((unsigned long long)vendor << 56ull)
256             | ((unsigned long long)fab << 50ull)
257             | ((unsigned long long)lot << 24ull)
258             | ((unsigned long long)wafer << 18ull)
259             | ((unsigned long long)x << 9ull)
260             | ((unsigned long long)y << 0ull);
261         return uid;
262 }
263
264 static int tsensor_calib_offset[] = {
265         [0] = 0x198,
266         [1] = 0x184,
267         [2] = 0x188,
268         [3] = 0x22c,
269         [4] = 0x254,
270         [5] = 0x258,
271         [6] = 0x25c,
272         [7] = 0x260,
273 };
274
275 int tegra_fuse_get_tsensor_calib(int index, u32 *calib)
276 {
277         if (index < 0 || index >= ARRAY_SIZE(tsensor_calib_offset))
278                 return -EINVAL;
279         *calib = tegra_fuse_readl(tsensor_calib_offset[index]);
280         return 0;
281 }
282
283 int tegra_fuse_calib_base_get_cp(u32 *base_cp, s32 *shifted_cp)
284 {
285         s32 cp;
286         u32 val = tegra_fuse_readl(FUSE_TSENSOR_CALIB_8);
287
288         if (fuse_cp_rev_check() || !val)
289                 return -EINVAL;
290
291         if (base_cp && shifted_cp) {
292                 *base_cp = (((val) & (FUSE_BASE_CP_MASK
293                                 << FUSE_BASE_CP_SHIFT))
294                                 >> FUSE_BASE_CP_SHIFT);
295
296                 val = tegra_fuse_readl(FUSE_SPARE_REALIGNMENT_REG_0);
297                 cp = (((val) & (FUSE_SHIFT_CP_MASK
298                                 << FUSE_SHIFT_CP_SHIFT))
299                                 >> FUSE_SHIFT_CP_SHIFT);
300
301                 *shifted_cp = ((s32)(cp)
302                                 << (32 - FUSE_SHIFT_CP_BITS)
303                                 >> (32 - FUSE_SHIFT_CP_BITS));
304         }
305         return 0;
306 }
307
308 int tegra_fuse_calib_base_get_ft(u32 *base_ft, s32 *shifted_ft)
309 {
310         s32 ft;
311         u32 val = tegra_fuse_readl(FUSE_TSENSOR_CALIB_8);
312
313         if (fuse_ft_rev_check() || !val)
314                 return -EINVAL;
315
316         if (base_ft && shifted_ft) {
317                 *base_ft = (((val) & (FUSE_BASE_FT_MASK
318                                 << FUSE_BASE_FT_SHIFT))
319                                 >> FUSE_BASE_FT_SHIFT);
320
321                 ft = (((val) & (FUSE_SHIFT_FT_MASK
322                                 << FUSE_SHIFT_FT_SHIFT))
323                                 >> FUSE_SHIFT_FT_SHIFT);
324
325                 *shifted_ft = ((s32)(ft)
326                                 << (32 - FUSE_SHIFT_FT_BITS)
327                                 >> (32 - FUSE_SHIFT_FT_BITS));
328         }
329         return 0;
330 }
331
332 int tegra_fuse_add_sysfs_variables(struct platform_device *pdev,
333                                         bool odm_security_mode)
334 {
335         dev_attr_odm_lock.attr.mode = 0640;
336         if (odm_security_mode) {
337                 dev_attr_public_key.attr.mode =  0440;
338                 dev_attr_pkc_disable.attr.mode = 0440;
339                 dev_attr_vp8_enable.attr.mode = 0440;
340         } else {
341                 dev_attr_public_key.attr.mode =  0640;
342                 dev_attr_pkc_disable.attr.mode = 0640;
343                 dev_attr_vp8_enable.attr.mode = 0640;
344         }
345         CHK_ERR(sysfs_create_file(&pdev->dev.kobj, &dev_attr_public_key.attr));
346         CHK_ERR(sysfs_create_file(&pdev->dev.kobj, &dev_attr_pkc_disable.attr));
347         CHK_ERR(sysfs_create_file(&pdev->dev.kobj, &dev_attr_vp8_enable.attr));
348         CHK_ERR(sysfs_create_file(&pdev->dev.kobj, &dev_attr_odm_lock.attr));
349
350         return 0;
351 }
352
353 int tegra_fuse_rm_sysfs_variables(struct platform_device *pdev)
354 {
355         sysfs_remove_file(&pdev->dev.kobj, &dev_attr_public_key.attr);
356         sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pkc_disable.attr);
357         sysfs_remove_file(&pdev->dev.kobj, &dev_attr_vp8_enable.attr);
358         sysfs_remove_file(&pdev->dev.kobj, &dev_attr_odm_lock.attr);
359
360         return 0;
361 }
362
363 int tegra_fuse_ch_sysfs_perm(struct kobject *kobj)
364 {
365         CHK_ERR(sysfs_chmod_file(kobj, &dev_attr_public_key.attr, 0440));
366         CHK_ERR(sysfs_chmod_file(kobj, &dev_attr_pkc_disable.attr, 0440));
367         CHK_ERR(sysfs_chmod_file(kobj, &dev_attr_vp8_enable.attr, 0440));
368
369         return 0;
370 }
371 #endif /* __TEGRA12x_FUSE_OFFSETS_H */