85accef41fa1bfccf50e45f70c7b06614cd2ac9e
[linux-2.6-microblaze.git] / drivers / soc / tegra / fuse / fuse-tegra30.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2013-2014, NVIDIA CORPORATION.  All rights reserved.
4  */
5
6 #include <linux/device.h>
7 #include <linux/clk.h>
8 #include <linux/err.h>
9 #include <linux/io.h>
10 #include <linux/kernel.h>
11 #include <linux/nvmem-consumer.h>
12 #include <linux/of_device.h>
13 #include <linux/of_address.h>
14 #include <linux/platform_device.h>
15 #include <linux/random.h>
16
17 #include <soc/tegra/fuse.h>
18
19 #include "fuse.h"
20
21 #define FUSE_BEGIN      0x100
22
23 /* Tegra30 and later */
24 #define FUSE_VENDOR_CODE        0x100
25 #define FUSE_FAB_CODE           0x104
26 #define FUSE_LOT_CODE_0         0x108
27 #define FUSE_LOT_CODE_1         0x10c
28 #define FUSE_WAFER_ID           0x110
29 #define FUSE_X_COORDINATE       0x114
30 #define FUSE_Y_COORDINATE       0x118
31
32 #define FUSE_HAS_REVISION_INFO  BIT(0)
33
34 #if defined(CONFIG_ARCH_TEGRA_3x_SOC) || \
35     defined(CONFIG_ARCH_TEGRA_114_SOC) || \
36     defined(CONFIG_ARCH_TEGRA_124_SOC) || \
37     defined(CONFIG_ARCH_TEGRA_132_SOC) || \
38     defined(CONFIG_ARCH_TEGRA_210_SOC) || \
39     defined(CONFIG_ARCH_TEGRA_186_SOC) || \
40     defined(CONFIG_ARCH_TEGRA_194_SOC)
41 static u32 tegra30_fuse_read_early(struct tegra_fuse *fuse, unsigned int offset)
42 {
43         if (WARN_ON(!fuse->base))
44                 return 0;
45
46         return readl_relaxed(fuse->base + FUSE_BEGIN + offset);
47 }
48
49 static u32 tegra30_fuse_read(struct tegra_fuse *fuse, unsigned int offset)
50 {
51         u32 value;
52         int err;
53
54         err = clk_prepare_enable(fuse->clk);
55         if (err < 0) {
56                 dev_err(fuse->dev, "failed to enable FUSE clock: %d\n", err);
57                 return 0;
58         }
59
60         value = readl_relaxed(fuse->base + FUSE_BEGIN + offset);
61
62         clk_disable_unprepare(fuse->clk);
63
64         return value;
65 }
66
67 static void __init tegra30_fuse_add_randomness(void)
68 {
69         u32 randomness[12];
70
71         randomness[0] = tegra_sku_info.sku_id;
72         randomness[1] = tegra_read_straps();
73         randomness[2] = tegra_read_chipid();
74         randomness[3] = tegra_sku_info.cpu_process_id << 16;
75         randomness[3] |= tegra_sku_info.soc_process_id;
76         randomness[4] = tegra_sku_info.cpu_speedo_id << 16;
77         randomness[4] |= tegra_sku_info.soc_speedo_id;
78         randomness[5] = tegra_fuse_read_early(FUSE_VENDOR_CODE);
79         randomness[6] = tegra_fuse_read_early(FUSE_FAB_CODE);
80         randomness[7] = tegra_fuse_read_early(FUSE_LOT_CODE_0);
81         randomness[8] = tegra_fuse_read_early(FUSE_LOT_CODE_1);
82         randomness[9] = tegra_fuse_read_early(FUSE_WAFER_ID);
83         randomness[10] = tegra_fuse_read_early(FUSE_X_COORDINATE);
84         randomness[11] = tegra_fuse_read_early(FUSE_Y_COORDINATE);
85
86         add_device_randomness(randomness, sizeof(randomness));
87 }
88
89 static void __init tegra30_fuse_init(struct tegra_fuse *fuse)
90 {
91         fuse->read_early = tegra30_fuse_read_early;
92         fuse->read = tegra30_fuse_read;
93
94         tegra_init_revision();
95
96         if (fuse->soc->speedo_init)
97                 fuse->soc->speedo_init(&tegra_sku_info);
98
99         tegra30_fuse_add_randomness();
100 }
101 #endif
102
103 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
104 static const struct tegra_fuse_info tegra30_fuse_info = {
105         .read = tegra30_fuse_read,
106         .size = 0x2a4,
107         .spare = 0x144,
108 };
109
110 const struct tegra_fuse_soc tegra30_fuse_soc = {
111         .init = tegra30_fuse_init,
112         .speedo_init = tegra30_init_speedo_data,
113         .info = &tegra30_fuse_info,
114         .soc_attr_group = &tegra_soc_attr_group,
115 };
116 #endif
117
118 #ifdef CONFIG_ARCH_TEGRA_114_SOC
119 static const struct tegra_fuse_info tegra114_fuse_info = {
120         .read = tegra30_fuse_read,
121         .size = 0x2a0,
122         .spare = 0x180,
123 };
124
125 const struct tegra_fuse_soc tegra114_fuse_soc = {
126         .init = tegra30_fuse_init,
127         .speedo_init = tegra114_init_speedo_data,
128         .info = &tegra114_fuse_info,
129         .soc_attr_group = &tegra_soc_attr_group,
130 };
131 #endif
132
133 #if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC)
134 static const struct nvmem_cell_lookup tegra124_fuse_lookups[] = {
135         {
136                 .nvmem_name = "fuse",
137                 .cell_name = "xusb-pad-calibration",
138                 .dev_id = "7009f000.padctl",
139                 .con_id = "calibration",
140         }, {
141                 .nvmem_name = "fuse",
142                 .cell_name = "sata-calibration",
143                 .dev_id = "70020000.sata",
144                 .con_id = "calibration",
145         }, {
146                 .nvmem_name = "fuse",
147                 .cell_name = "tsensor-common",
148                 .dev_id = "700e2000.thermal-sensor",
149                 .con_id = "common",
150         }, {
151                 .nvmem_name = "fuse",
152                 .cell_name = "tsensor-realignment",
153                 .dev_id = "700e2000.thermal-sensor",
154                 .con_id = "realignment",
155         }, {
156                 .nvmem_name = "fuse",
157                 .cell_name = "tsensor-cpu0",
158                 .dev_id = "700e2000.thermal-sensor",
159                 .con_id = "cpu0",
160         }, {
161                 .nvmem_name = "fuse",
162                 .cell_name = "tsensor-cpu1",
163                 .dev_id = "700e2000.thermal-sensor",
164                 .con_id = "cpu1",
165         }, {
166                 .nvmem_name = "fuse",
167                 .cell_name = "tsensor-cpu2",
168                 .dev_id = "700e2000.thermal-sensor",
169                 .con_id = "cpu2",
170         }, {
171                 .nvmem_name = "fuse",
172                 .cell_name = "tsensor-cpu3",
173                 .dev_id = "700e2000.thermal-sensor",
174                 .con_id = "cpu3",
175         }, {
176                 .nvmem_name = "fuse",
177                 .cell_name = "tsensor-mem0",
178                 .dev_id = "700e2000.thermal-sensor",
179                 .con_id = "mem0",
180         }, {
181                 .nvmem_name = "fuse",
182                 .cell_name = "tsensor-mem1",
183                 .dev_id = "700e2000.thermal-sensor",
184                 .con_id = "mem1",
185         }, {
186                 .nvmem_name = "fuse",
187                 .cell_name = "tsensor-gpu",
188                 .dev_id = "700e2000.thermal-sensor",
189                 .con_id = "gpu",
190         }, {
191                 .nvmem_name = "fuse",
192                 .cell_name = "tsensor-pllx",
193                 .dev_id = "700e2000.thermal-sensor",
194                 .con_id = "pllx",
195         },
196 };
197
198 static const struct tegra_fuse_info tegra124_fuse_info = {
199         .read = tegra30_fuse_read,
200         .size = 0x300,
201         .spare = 0x200,
202 };
203
204 const struct tegra_fuse_soc tegra124_fuse_soc = {
205         .init = tegra30_fuse_init,
206         .speedo_init = tegra124_init_speedo_data,
207         .info = &tegra124_fuse_info,
208         .lookups = tegra124_fuse_lookups,
209         .num_lookups = ARRAY_SIZE(tegra124_fuse_lookups),
210         .soc_attr_group = &tegra_soc_attr_group,
211 };
212 #endif
213
214 #if defined(CONFIG_ARCH_TEGRA_210_SOC)
215 static const struct nvmem_cell_lookup tegra210_fuse_lookups[] = {
216         {
217                 .nvmem_name = "fuse",
218                 .cell_name = "tsensor-cpu1",
219                 .dev_id = "700e2000.thermal-sensor",
220                 .con_id = "cpu1",
221         }, {
222                 .nvmem_name = "fuse",
223                 .cell_name = "tsensor-cpu2",
224                 .dev_id = "700e2000.thermal-sensor",
225                 .con_id = "cpu2",
226         }, {
227                 .nvmem_name = "fuse",
228                 .cell_name = "tsensor-cpu0",
229                 .dev_id = "700e2000.thermal-sensor",
230                 .con_id = "cpu0",
231         }, {
232                 .nvmem_name = "fuse",
233                 .cell_name = "xusb-pad-calibration",
234                 .dev_id = "7009f000.padctl",
235                 .con_id = "calibration",
236         }, {
237                 .nvmem_name = "fuse",
238                 .cell_name = "tsensor-cpu3",
239                 .dev_id = "700e2000.thermal-sensor",
240                 .con_id = "cpu3",
241         }, {
242                 .nvmem_name = "fuse",
243                 .cell_name = "sata-calibration",
244                 .dev_id = "70020000.sata",
245                 .con_id = "calibration",
246         }, {
247                 .nvmem_name = "fuse",
248                 .cell_name = "tsensor-gpu",
249                 .dev_id = "700e2000.thermal-sensor",
250                 .con_id = "gpu",
251         }, {
252                 .nvmem_name = "fuse",
253                 .cell_name = "tsensor-mem0",
254                 .dev_id = "700e2000.thermal-sensor",
255                 .con_id = "mem0",
256         }, {
257                 .nvmem_name = "fuse",
258                 .cell_name = "tsensor-mem1",
259                 .dev_id = "700e2000.thermal-sensor",
260                 .con_id = "mem1",
261         }, {
262                 .nvmem_name = "fuse",
263                 .cell_name = "tsensor-pllx",
264                 .dev_id = "700e2000.thermal-sensor",
265                 .con_id = "pllx",
266         }, {
267                 .nvmem_name = "fuse",
268                 .cell_name = "tsensor-common",
269                 .dev_id = "700e2000.thermal-sensor",
270                 .con_id = "common",
271         }, {
272                 .nvmem_name = "fuse",
273                 .cell_name = "gpu-calibration",
274                 .dev_id = "57000000.gpu",
275                 .con_id = "calibration",
276         }, {
277                 .nvmem_name = "fuse",
278                 .cell_name = "xusb-pad-calibration-ext",
279                 .dev_id = "7009f000.padctl",
280                 .con_id = "calibration-ext",
281         },
282 };
283
284 static const struct tegra_fuse_info tegra210_fuse_info = {
285         .read = tegra30_fuse_read,
286         .size = 0x300,
287         .spare = 0x280,
288 };
289
290 const struct tegra_fuse_soc tegra210_fuse_soc = {
291         .init = tegra30_fuse_init,
292         .speedo_init = tegra210_init_speedo_data,
293         .info = &tegra210_fuse_info,
294         .lookups = tegra210_fuse_lookups,
295         .num_lookups = ARRAY_SIZE(tegra210_fuse_lookups),
296         .soc_attr_group = &tegra_soc_attr_group,
297 };
298 #endif
299
300 #if defined(CONFIG_ARCH_TEGRA_186_SOC)
301 static const struct nvmem_cell_lookup tegra186_fuse_lookups[] = {
302         {
303                 .nvmem_name = "fuse",
304                 .cell_name = "xusb-pad-calibration",
305                 .dev_id = "3520000.padctl",
306                 .con_id = "calibration",
307         }, {
308                 .nvmem_name = "fuse",
309                 .cell_name = "xusb-pad-calibration-ext",
310                 .dev_id = "3520000.padctl",
311                 .con_id = "calibration-ext",
312         },
313 };
314
315 static const struct tegra_fuse_info tegra186_fuse_info = {
316         .read = tegra30_fuse_read,
317         .size = 0x300,
318         .spare = 0x280,
319 };
320
321 const struct tegra_fuse_soc tegra186_fuse_soc = {
322         .init = tegra30_fuse_init,
323         .info = &tegra186_fuse_info,
324         .lookups = tegra186_fuse_lookups,
325         .num_lookups = ARRAY_SIZE(tegra186_fuse_lookups),
326         .soc_attr_group = &tegra_soc_attr_group,
327 };
328 #endif
329
330 #if defined(CONFIG_ARCH_TEGRA_194_SOC)
331 static const struct nvmem_cell_lookup tegra194_fuse_lookups[] = {
332         {
333                 .nvmem_name = "fuse",
334                 .cell_name = "xusb-pad-calibration",
335                 .dev_id = "3520000.padctl",
336                 .con_id = "calibration",
337         }, {
338                 .nvmem_name = "fuse",
339                 .cell_name = "xusb-pad-calibration-ext",
340                 .dev_id = "3520000.padctl",
341                 .con_id = "calibration-ext",
342         },
343 };
344
345 static const struct tegra_fuse_info tegra194_fuse_info = {
346         .read = tegra30_fuse_read,
347         .size = 0x300,
348         .spare = 0x280,
349 };
350
351 const struct tegra_fuse_soc tegra194_fuse_soc = {
352         .init = tegra30_fuse_init,
353         .info = &tegra194_fuse_info,
354         .lookups = tegra194_fuse_lookups,
355         .num_lookups = ARRAY_SIZE(tegra194_fuse_lookups),
356         .soc_attr_group = &tegra194_soc_attr_group,
357 };
358 #endif