Linux-libre 5.7.6-gnu
[librecmc/linux-libre.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 };
115 #endif
116
117 #ifdef CONFIG_ARCH_TEGRA_114_SOC
118 static const struct tegra_fuse_info tegra114_fuse_info = {
119         .read = tegra30_fuse_read,
120         .size = 0x2a0,
121         .spare = 0x180,
122 };
123
124 const struct tegra_fuse_soc tegra114_fuse_soc = {
125         .init = tegra30_fuse_init,
126         .speedo_init = tegra114_init_speedo_data,
127         .info = &tegra114_fuse_info,
128 };
129 #endif
130
131 #if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC)
132 static const struct nvmem_cell_lookup tegra124_fuse_lookups[] = {
133         {
134                 .nvmem_name = "fuse",
135                 .cell_name = "xusb-pad-calibration",
136                 .dev_id = "7009f000.padctl",
137                 .con_id = "calibration",
138         }, {
139                 .nvmem_name = "fuse",
140                 .cell_name = "sata-calibration",
141                 .dev_id = "70020000.sata",
142                 .con_id = "calibration",
143         }, {
144                 .nvmem_name = "fuse",
145                 .cell_name = "tsensor-common",
146                 .dev_id = "700e2000.thermal-sensor",
147                 .con_id = "common",
148         }, {
149                 .nvmem_name = "fuse",
150                 .cell_name = "tsensor-realignment",
151                 .dev_id = "700e2000.thermal-sensor",
152                 .con_id = "realignment",
153         }, {
154                 .nvmem_name = "fuse",
155                 .cell_name = "tsensor-cpu0",
156                 .dev_id = "700e2000.thermal-sensor",
157                 .con_id = "cpu0",
158         }, {
159                 .nvmem_name = "fuse",
160                 .cell_name = "tsensor-cpu1",
161                 .dev_id = "700e2000.thermal-sensor",
162                 .con_id = "cpu1",
163         }, {
164                 .nvmem_name = "fuse",
165                 .cell_name = "tsensor-cpu2",
166                 .dev_id = "700e2000.thermal-sensor",
167                 .con_id = "cpu2",
168         }, {
169                 .nvmem_name = "fuse",
170                 .cell_name = "tsensor-cpu3",
171                 .dev_id = "700e2000.thermal-sensor",
172                 .con_id = "cpu3",
173         }, {
174                 .nvmem_name = "fuse",
175                 .cell_name = "tsensor-mem0",
176                 .dev_id = "700e2000.thermal-sensor",
177                 .con_id = "mem0",
178         }, {
179                 .nvmem_name = "fuse",
180                 .cell_name = "tsensor-mem1",
181                 .dev_id = "700e2000.thermal-sensor",
182                 .con_id = "mem1",
183         }, {
184                 .nvmem_name = "fuse",
185                 .cell_name = "tsensor-gpu",
186                 .dev_id = "700e2000.thermal-sensor",
187                 .con_id = "gpu",
188         }, {
189                 .nvmem_name = "fuse",
190                 .cell_name = "tsensor-pllx",
191                 .dev_id = "700e2000.thermal-sensor",
192                 .con_id = "pllx",
193         },
194 };
195
196 static const struct tegra_fuse_info tegra124_fuse_info = {
197         .read = tegra30_fuse_read,
198         .size = 0x300,
199         .spare = 0x200,
200 };
201
202 const struct tegra_fuse_soc tegra124_fuse_soc = {
203         .init = tegra30_fuse_init,
204         .speedo_init = tegra124_init_speedo_data,
205         .info = &tegra124_fuse_info,
206         .lookups = tegra124_fuse_lookups,
207         .num_lookups = ARRAY_SIZE(tegra124_fuse_lookups),
208 };
209 #endif
210
211 #if defined(CONFIG_ARCH_TEGRA_210_SOC)
212 static const struct nvmem_cell_lookup tegra210_fuse_lookups[] = {
213         {
214                 .nvmem_name = "fuse",
215                 .cell_name = "tsensor-cpu1",
216                 .dev_id = "700e2000.thermal-sensor",
217                 .con_id = "cpu1",
218         }, {
219                 .nvmem_name = "fuse",
220                 .cell_name = "tsensor-cpu2",
221                 .dev_id = "700e2000.thermal-sensor",
222                 .con_id = "cpu2",
223         }, {
224                 .nvmem_name = "fuse",
225                 .cell_name = "tsensor-cpu0",
226                 .dev_id = "700e2000.thermal-sensor",
227                 .con_id = "cpu0",
228         }, {
229                 .nvmem_name = "fuse",
230                 .cell_name = "xusb-pad-calibration",
231                 .dev_id = "7009f000.padctl",
232                 .con_id = "calibration",
233         }, {
234                 .nvmem_name = "fuse",
235                 .cell_name = "tsensor-cpu3",
236                 .dev_id = "700e2000.thermal-sensor",
237                 .con_id = "cpu3",
238         }, {
239                 .nvmem_name = "fuse",
240                 .cell_name = "sata-calibration",
241                 .dev_id = "70020000.sata",
242                 .con_id = "calibration",
243         }, {
244                 .nvmem_name = "fuse",
245                 .cell_name = "tsensor-gpu",
246                 .dev_id = "700e2000.thermal-sensor",
247                 .con_id = "gpu",
248         }, {
249                 .nvmem_name = "fuse",
250                 .cell_name = "tsensor-mem0",
251                 .dev_id = "700e2000.thermal-sensor",
252                 .con_id = "mem0",
253         }, {
254                 .nvmem_name = "fuse",
255                 .cell_name = "tsensor-mem1",
256                 .dev_id = "700e2000.thermal-sensor",
257                 .con_id = "mem1",
258         }, {
259                 .nvmem_name = "fuse",
260                 .cell_name = "tsensor-pllx",
261                 .dev_id = "700e2000.thermal-sensor",
262                 .con_id = "pllx",
263         }, {
264                 .nvmem_name = "fuse",
265                 .cell_name = "tsensor-common",
266                 .dev_id = "700e2000.thermal-sensor",
267                 .con_id = "common",
268         }, {
269                 .nvmem_name = "fuse",
270                 .cell_name = "gpu-calibration",
271                 .dev_id = "57000000.gpu",
272                 .con_id = "calibration",
273         }, {
274                 .nvmem_name = "fuse",
275                 .cell_name = "xusb-pad-calibration-ext",
276                 .dev_id = "7009f000.padctl",
277                 .con_id = "calibration-ext",
278         },
279 };
280
281 static const struct tegra_fuse_info tegra210_fuse_info = {
282         .read = tegra30_fuse_read,
283         .size = 0x300,
284         .spare = 0x280,
285 };
286
287 const struct tegra_fuse_soc tegra210_fuse_soc = {
288         .init = tegra30_fuse_init,
289         .speedo_init = tegra210_init_speedo_data,
290         .info = &tegra210_fuse_info,
291         .lookups = tegra210_fuse_lookups,
292         .num_lookups = ARRAY_SIZE(tegra210_fuse_lookups),
293 };
294 #endif
295
296 #if defined(CONFIG_ARCH_TEGRA_186_SOC)
297 static const struct nvmem_cell_lookup tegra186_fuse_lookups[] = {
298         {
299                 .nvmem_name = "fuse",
300                 .cell_name = "xusb-pad-calibration",
301                 .dev_id = "3520000.padctl",
302                 .con_id = "calibration",
303         }, {
304                 .nvmem_name = "fuse",
305                 .cell_name = "xusb-pad-calibration-ext",
306                 .dev_id = "3520000.padctl",
307                 .con_id = "calibration-ext",
308         },
309 };
310
311 static const struct tegra_fuse_info tegra186_fuse_info = {
312         .read = tegra30_fuse_read,
313         .size = 0x300,
314         .spare = 0x280,
315 };
316
317 const struct tegra_fuse_soc tegra186_fuse_soc = {
318         .init = tegra30_fuse_init,
319         .info = &tegra186_fuse_info,
320         .lookups = tegra186_fuse_lookups,
321         .num_lookups = ARRAY_SIZE(tegra186_fuse_lookups),
322 };
323 #endif
324
325 #if defined(CONFIG_ARCH_TEGRA_194_SOC)
326 static const struct nvmem_cell_lookup tegra194_fuse_lookups[] = {
327         {
328                 .nvmem_name = "fuse",
329                 .cell_name = "xusb-pad-calibration",
330                 .dev_id = "3520000.padctl",
331                 .con_id = "calibration",
332         }, {
333                 .nvmem_name = "fuse",
334                 .cell_name = "xusb-pad-calibration-ext",
335                 .dev_id = "3520000.padctl",
336                 .con_id = "calibration-ext",
337         },
338 };
339
340 static const struct tegra_fuse_info tegra194_fuse_info = {
341         .read = tegra30_fuse_read,
342         .size = 0x300,
343         .spare = 0x280,
344 };
345
346 const struct tegra_fuse_soc tegra194_fuse_soc = {
347         .init = tegra30_fuse_init,
348         .info = &tegra194_fuse_info,
349         .lookups = tegra194_fuse_lookups,
350         .num_lookups = ARRAY_SIZE(tegra194_fuse_lookups),
351 };
352 #endif