OSDN Git Service

smb3: Add defines for new information level, FileIdInformation
[tomoyo/tomoyo-test1.git] / drivers / soc / tegra / fuse / fuse-tegra.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/clk.h>
7 #include <linux/device.h>
8 #include <linux/kobject.h>
9 #include <linux/init.h>
10 #include <linux/io.h>
11 #include <linux/nvmem-consumer.h>
12 #include <linux/nvmem-provider.h>
13 #include <linux/of.h>
14 #include <linux/of_address.h>
15 #include <linux/platform_device.h>
16 #include <linux/slab.h>
17 #include <linux/sys_soc.h>
18
19 #include <soc/tegra/common.h>
20 #include <soc/tegra/fuse.h>
21
22 #include "fuse.h"
23
24 struct tegra_sku_info tegra_sku_info;
25 EXPORT_SYMBOL(tegra_sku_info);
26
27 static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
28         [TEGRA_REVISION_UNKNOWN] = "unknown",
29         [TEGRA_REVISION_A01]     = "A01",
30         [TEGRA_REVISION_A02]     = "A02",
31         [TEGRA_REVISION_A03]     = "A03",
32         [TEGRA_REVISION_A03p]    = "A03 prime",
33         [TEGRA_REVISION_A04]     = "A04",
34 };
35
36 static const struct of_device_id car_match[] __initconst = {
37         { .compatible = "nvidia,tegra20-car", },
38         { .compatible = "nvidia,tegra30-car", },
39         { .compatible = "nvidia,tegra114-car", },
40         { .compatible = "nvidia,tegra124-car", },
41         { .compatible = "nvidia,tegra132-car", },
42         { .compatible = "nvidia,tegra210-car", },
43         {},
44 };
45
46 static struct tegra_fuse *fuse = &(struct tegra_fuse) {
47         .base = NULL,
48         .soc = NULL,
49 };
50
51 static const struct of_device_id tegra_fuse_match[] = {
52 #ifdef CONFIG_ARCH_TEGRA_186_SOC
53         { .compatible = "nvidia,tegra186-efuse", .data = &tegra186_fuse_soc },
54 #endif
55 #ifdef CONFIG_ARCH_TEGRA_210_SOC
56         { .compatible = "nvidia,tegra210-efuse", .data = &tegra210_fuse_soc },
57 #endif
58 #ifdef CONFIG_ARCH_TEGRA_132_SOC
59         { .compatible = "nvidia,tegra132-efuse", .data = &tegra124_fuse_soc },
60 #endif
61 #ifdef CONFIG_ARCH_TEGRA_124_SOC
62         { .compatible = "nvidia,tegra124-efuse", .data = &tegra124_fuse_soc },
63 #endif
64 #ifdef CONFIG_ARCH_TEGRA_114_SOC
65         { .compatible = "nvidia,tegra114-efuse", .data = &tegra114_fuse_soc },
66 #endif
67 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
68         { .compatible = "nvidia,tegra30-efuse", .data = &tegra30_fuse_soc },
69 #endif
70 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
71         { .compatible = "nvidia,tegra20-efuse", .data = &tegra20_fuse_soc },
72 #endif
73         { /* sentinel */ }
74 };
75
76 static int tegra_fuse_read(void *priv, unsigned int offset, void *value,
77                            size_t bytes)
78 {
79         unsigned int count = bytes / 4, i;
80         struct tegra_fuse *fuse = priv;
81         u32 *buffer = value;
82
83         for (i = 0; i < count; i++)
84                 buffer[i] = fuse->read(fuse, offset + i * 4);
85
86         return 0;
87 }
88
89 static const struct nvmem_cell_info tegra_fuse_cells[] = {
90         {
91                 .name = "tsensor-cpu1",
92                 .offset = 0x084,
93                 .bytes = 4,
94                 .bit_offset = 0,
95                 .nbits = 32,
96         }, {
97                 .name = "tsensor-cpu2",
98                 .offset = 0x088,
99                 .bytes = 4,
100                 .bit_offset = 0,
101                 .nbits = 32,
102         }, {
103                 .name = "tsensor-cpu0",
104                 .offset = 0x098,
105                 .bytes = 4,
106                 .bit_offset = 0,
107                 .nbits = 32,
108         }, {
109                 .name = "xusb-pad-calibration",
110                 .offset = 0x0f0,
111                 .bytes = 4,
112                 .bit_offset = 0,
113                 .nbits = 32,
114         }, {
115                 .name = "tsensor-cpu3",
116                 .offset = 0x12c,
117                 .bytes = 4,
118                 .bit_offset = 0,
119                 .nbits = 32,
120         }, {
121                 .name = "sata-calibration",
122                 .offset = 0x124,
123                 .bytes = 1,
124                 .bit_offset = 0,
125                 .nbits = 2,
126         }, {
127                 .name = "tsensor-gpu",
128                 .offset = 0x154,
129                 .bytes = 4,
130                 .bit_offset = 0,
131                 .nbits = 32,
132         }, {
133                 .name = "tsensor-mem0",
134                 .offset = 0x158,
135                 .bytes = 4,
136                 .bit_offset = 0,
137                 .nbits = 32,
138         }, {
139                 .name = "tsensor-mem1",
140                 .offset = 0x15c,
141                 .bytes = 4,
142                 .bit_offset = 0,
143                 .nbits = 32,
144         }, {
145                 .name = "tsensor-pllx",
146                 .offset = 0x160,
147                 .bytes = 4,
148                 .bit_offset = 0,
149                 .nbits = 32,
150         }, {
151                 .name = "tsensor-common",
152                 .offset = 0x180,
153                 .bytes = 4,
154                 .bit_offset = 0,
155                 .nbits = 32,
156         }, {
157                 .name = "tsensor-realignment",
158                 .offset = 0x1fc,
159                 .bytes = 4,
160                 .bit_offset = 0,
161                 .nbits = 32,
162         }, {
163                 .name = "gpu-calibration",
164                 .offset = 0x204,
165                 .bytes = 4,
166                 .bit_offset = 0,
167                 .nbits = 32,
168         }, {
169                 .name = "xusb-pad-calibration-ext",
170                 .offset = 0x250,
171                 .bytes = 4,
172                 .bit_offset = 0,
173                 .nbits = 32,
174         },
175 };
176
177 static int tegra_fuse_probe(struct platform_device *pdev)
178 {
179         void __iomem *base = fuse->base;
180         struct nvmem_config nvmem;
181         struct resource *res;
182         int err;
183
184         /* take over the memory region from the early initialization */
185         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
186         fuse->phys = res->start;
187         fuse->base = devm_ioremap_resource(&pdev->dev, res);
188         if (IS_ERR(fuse->base)) {
189                 err = PTR_ERR(fuse->base);
190                 fuse->base = base;
191                 return err;
192         }
193
194         fuse->clk = devm_clk_get(&pdev->dev, "fuse");
195         if (IS_ERR(fuse->clk)) {
196                 if (PTR_ERR(fuse->clk) != -EPROBE_DEFER)
197                         dev_err(&pdev->dev, "failed to get FUSE clock: %ld",
198                                 PTR_ERR(fuse->clk));
199
200                 fuse->base = base;
201                 return PTR_ERR(fuse->clk);
202         }
203
204         platform_set_drvdata(pdev, fuse);
205         fuse->dev = &pdev->dev;
206
207         if (fuse->soc->probe) {
208                 err = fuse->soc->probe(fuse);
209                 if (err < 0)
210                         goto restore;
211         }
212
213         memset(&nvmem, 0, sizeof(nvmem));
214         nvmem.dev = &pdev->dev;
215         nvmem.name = "fuse";
216         nvmem.id = -1;
217         nvmem.owner = THIS_MODULE;
218         nvmem.cells = tegra_fuse_cells;
219         nvmem.ncells = ARRAY_SIZE(tegra_fuse_cells);
220         nvmem.type = NVMEM_TYPE_OTP;
221         nvmem.read_only = true;
222         nvmem.root_only = true;
223         nvmem.reg_read = tegra_fuse_read;
224         nvmem.size = fuse->soc->info->size;
225         nvmem.word_size = 4;
226         nvmem.stride = 4;
227         nvmem.priv = fuse;
228
229         fuse->nvmem = devm_nvmem_register(&pdev->dev, &nvmem);
230         if (IS_ERR(fuse->nvmem)) {
231                 err = PTR_ERR(fuse->nvmem);
232                 dev_err(&pdev->dev, "failed to register NVMEM device: %d\n",
233                         err);
234                 goto restore;
235         }
236
237         /* release the early I/O memory mapping */
238         iounmap(base);
239
240         return 0;
241
242 restore:
243         fuse->base = base;
244         return err;
245 }
246
247 static struct platform_driver tegra_fuse_driver = {
248         .driver = {
249                 .name = "tegra-fuse",
250                 .of_match_table = tegra_fuse_match,
251                 .suppress_bind_attrs = true,
252         },
253         .probe = tegra_fuse_probe,
254 };
255 builtin_platform_driver(tegra_fuse_driver);
256
257 bool __init tegra_fuse_read_spare(unsigned int spare)
258 {
259         unsigned int offset = fuse->soc->info->spare + spare * 4;
260
261         return fuse->read_early(fuse, offset) & 1;
262 }
263
264 u32 __init tegra_fuse_read_early(unsigned int offset)
265 {
266         return fuse->read_early(fuse, offset);
267 }
268
269 int tegra_fuse_readl(unsigned long offset, u32 *value)
270 {
271         if (!fuse->read || !fuse->clk)
272                 return -EPROBE_DEFER;
273
274         if (IS_ERR(fuse->clk))
275                 return PTR_ERR(fuse->clk);
276
277         *value = fuse->read(fuse, offset);
278
279         return 0;
280 }
281 EXPORT_SYMBOL(tegra_fuse_readl);
282
283 static void tegra_enable_fuse_clk(void __iomem *base)
284 {
285         u32 reg;
286
287         reg = readl_relaxed(base + 0x48);
288         reg |= 1 << 28;
289         writel(reg, base + 0x48);
290
291         /*
292          * Enable FUSE clock. This needs to be hardcoded because the clock
293          * subsystem is not active during early boot.
294          */
295         reg = readl(base + 0x14);
296         reg |= 1 << 7;
297         writel(reg, base + 0x14);
298 }
299
300 struct device * __init tegra_soc_device_register(void)
301 {
302         struct soc_device_attribute *attr;
303         struct soc_device *dev;
304
305         attr = kzalloc(sizeof(*attr), GFP_KERNEL);
306         if (!attr)
307                 return NULL;
308
309         attr->family = kasprintf(GFP_KERNEL, "Tegra");
310         attr->revision = kasprintf(GFP_KERNEL, "%d", tegra_sku_info.revision);
311         attr->soc_id = kasprintf(GFP_KERNEL, "%u", tegra_get_chip_id());
312
313         dev = soc_device_register(attr);
314         if (IS_ERR(dev)) {
315                 kfree(attr->soc_id);
316                 kfree(attr->revision);
317                 kfree(attr->family);
318                 kfree(attr);
319                 return ERR_CAST(dev);
320         }
321
322         return soc_device_to_device(dev);
323 }
324
325 static int __init tegra_init_fuse(void)
326 {
327         const struct of_device_id *match;
328         struct device_node *np;
329         struct resource regs;
330
331         tegra_init_apbmisc();
332
333         np = of_find_matching_node_and_match(NULL, tegra_fuse_match, &match);
334         if (!np) {
335                 /*
336                  * Fall back to legacy initialization for 32-bit ARM only. All
337                  * 64-bit ARM device tree files for Tegra are required to have
338                  * a FUSE node.
339                  *
340                  * This is for backwards-compatibility with old device trees
341                  * that didn't contain a FUSE node.
342                  */
343                 if (IS_ENABLED(CONFIG_ARM) && soc_is_tegra()) {
344                         u8 chip = tegra_get_chip_id();
345
346                         regs.start = 0x7000f800;
347                         regs.end = 0x7000fbff;
348                         regs.flags = IORESOURCE_MEM;
349
350                         switch (chip) {
351 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
352                         case TEGRA20:
353                                 fuse->soc = &tegra20_fuse_soc;
354                                 break;
355 #endif
356
357 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
358                         case TEGRA30:
359                                 fuse->soc = &tegra30_fuse_soc;
360                                 break;
361 #endif
362
363 #ifdef CONFIG_ARCH_TEGRA_114_SOC
364                         case TEGRA114:
365                                 fuse->soc = &tegra114_fuse_soc;
366                                 break;
367 #endif
368
369 #ifdef CONFIG_ARCH_TEGRA_124_SOC
370                         case TEGRA124:
371                                 fuse->soc = &tegra124_fuse_soc;
372                                 break;
373 #endif
374
375                         default:
376                                 pr_warn("Unsupported SoC: %02x\n", chip);
377                                 break;
378                         }
379                 } else {
380                         /*
381                          * At this point we're not running on Tegra, so play
382                          * nice with multi-platform kernels.
383                          */
384                         return 0;
385                 }
386         } else {
387                 /*
388                  * Extract information from the device tree if we've found a
389                  * matching node.
390                  */
391                 if (of_address_to_resource(np, 0, &regs) < 0) {
392                         pr_err("failed to get FUSE register\n");
393                         return -ENXIO;
394                 }
395
396                 fuse->soc = match->data;
397         }
398
399         np = of_find_matching_node(NULL, car_match);
400         if (np) {
401                 void __iomem *base = of_iomap(np, 0);
402                 if (base) {
403                         tegra_enable_fuse_clk(base);
404                         iounmap(base);
405                 } else {
406                         pr_err("failed to map clock registers\n");
407                         return -ENXIO;
408                 }
409         }
410
411         fuse->base = ioremap(regs.start, resource_size(&regs));
412         if (!fuse->base) {
413                 pr_err("failed to map FUSE registers\n");
414                 return -ENXIO;
415         }
416
417         fuse->soc->init(fuse);
418
419         pr_info("Tegra Revision: %s SKU: %d CPU Process: %d SoC Process: %d\n",
420                 tegra_revision_name[tegra_sku_info.revision],
421                 tegra_sku_info.sku_id, tegra_sku_info.cpu_process_id,
422                 tegra_sku_info.soc_process_id);
423         pr_debug("Tegra CPU Speedo ID %d, SoC Speedo ID %d\n",
424                  tegra_sku_info.cpu_speedo_id, tegra_sku_info.soc_speedo_id);
425
426         if (fuse->soc->lookups) {
427                 size_t size = sizeof(*fuse->lookups) * fuse->soc->num_lookups;
428
429                 fuse->lookups = kmemdup(fuse->soc->lookups, size, GFP_KERNEL);
430                 if (!fuse->lookups)
431                         return -ENOMEM;
432
433                 nvmem_add_cell_lookups(fuse->lookups, fuse->soc->num_lookups);
434         }
435
436         return 0;
437 }
438 early_initcall(tegra_init_fuse);
439
440 #ifdef CONFIG_ARM64
441 static int __init tegra_init_soc(void)
442 {
443         struct device_node *np;
444         struct device *soc;
445
446         /* make sure we're running on Tegra */
447         np = of_find_matching_node(NULL, tegra_fuse_match);
448         if (!np)
449                 return 0;
450
451         of_node_put(np);
452
453         soc = tegra_soc_device_register();
454         if (IS_ERR(soc)) {
455                 pr_err("failed to register SoC device: %ld\n", PTR_ERR(soc));
456                 return PTR_ERR(soc);
457         }
458
459         return 0;
460 }
461 device_initcall(tegra_init_soc);
462 #endif