Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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/pm_runtime.h>
17#include <linux/reset.h>
18#include <linux/slab.h>
19#include <linux/sys_soc.h>
20
21#include <soc/tegra/common.h>
22#include <soc/tegra/fuse.h>
23
24#include "fuse.h"
25
26struct tegra_sku_info tegra_sku_info;
27EXPORT_SYMBOL(tegra_sku_info);
28
29static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
30 [TEGRA_REVISION_UNKNOWN] = "unknown",
31 [TEGRA_REVISION_A01] = "A01",
32 [TEGRA_REVISION_A02] = "A02",
33 [TEGRA_REVISION_A03] = "A03",
34 [TEGRA_REVISION_A03p] = "A03 prime",
35 [TEGRA_REVISION_A04] = "A04",
36};
37
38static const struct of_device_id car_match[] __initconst = {
39 { .compatible = "nvidia,tegra20-car", },
40 { .compatible = "nvidia,tegra30-car", },
41 { .compatible = "nvidia,tegra114-car", },
42 { .compatible = "nvidia,tegra124-car", },
43 { .compatible = "nvidia,tegra132-car", },
44 { .compatible = "nvidia,tegra210-car", },
45 {},
46};
47
48static struct tegra_fuse *fuse = &(struct tegra_fuse) {
49 .base = NULL,
50 .soc = NULL,
51};
52
53static const struct of_device_id tegra_fuse_match[] = {
54#ifdef CONFIG_ARCH_TEGRA_234_SOC
55 { .compatible = "nvidia,tegra234-efuse", .data = &tegra234_fuse_soc },
56#endif
57#ifdef CONFIG_ARCH_TEGRA_194_SOC
58 { .compatible = "nvidia,tegra194-efuse", .data = &tegra194_fuse_soc },
59#endif
60#ifdef CONFIG_ARCH_TEGRA_186_SOC
61 { .compatible = "nvidia,tegra186-efuse", .data = &tegra186_fuse_soc },
62#endif
63#ifdef CONFIG_ARCH_TEGRA_210_SOC
64 { .compatible = "nvidia,tegra210-efuse", .data = &tegra210_fuse_soc },
65#endif
66#ifdef CONFIG_ARCH_TEGRA_132_SOC
67 { .compatible = "nvidia,tegra132-efuse", .data = &tegra124_fuse_soc },
68#endif
69#ifdef CONFIG_ARCH_TEGRA_124_SOC
70 { .compatible = "nvidia,tegra124-efuse", .data = &tegra124_fuse_soc },
71#endif
72#ifdef CONFIG_ARCH_TEGRA_114_SOC
73 { .compatible = "nvidia,tegra114-efuse", .data = &tegra114_fuse_soc },
74#endif
75#ifdef CONFIG_ARCH_TEGRA_3x_SOC
76 { .compatible = "nvidia,tegra30-efuse", .data = &tegra30_fuse_soc },
77#endif
78#ifdef CONFIG_ARCH_TEGRA_2x_SOC
79 { .compatible = "nvidia,tegra20-efuse", .data = &tegra20_fuse_soc },
80#endif
81 { /* sentinel */ }
82};
83
84static int tegra_fuse_read(void *priv, unsigned int offset, void *value,
85 size_t bytes)
86{
87 unsigned int count = bytes / 4, i;
88 struct tegra_fuse *fuse = priv;
89 u32 *buffer = value;
90
91 for (i = 0; i < count; i++)
92 buffer[i] = fuse->read(fuse, offset + i * 4);
93
94 return 0;
95}
96
97static const struct nvmem_cell_info tegra_fuse_cells[] = {
98 {
99 .name = "tsensor-cpu1",
100 .offset = 0x084,
101 .bytes = 4,
102 .bit_offset = 0,
103 .nbits = 32,
104 }, {
105 .name = "tsensor-cpu2",
106 .offset = 0x088,
107 .bytes = 4,
108 .bit_offset = 0,
109 .nbits = 32,
110 }, {
111 .name = "tsensor-cpu0",
112 .offset = 0x098,
113 .bytes = 4,
114 .bit_offset = 0,
115 .nbits = 32,
116 }, {
117 .name = "xusb-pad-calibration",
118 .offset = 0x0f0,
119 .bytes = 4,
120 .bit_offset = 0,
121 .nbits = 32,
122 }, {
123 .name = "tsensor-cpu3",
124 .offset = 0x12c,
125 .bytes = 4,
126 .bit_offset = 0,
127 .nbits = 32,
128 }, {
129 .name = "sata-calibration",
130 .offset = 0x124,
131 .bytes = 1,
132 .bit_offset = 0,
133 .nbits = 2,
134 }, {
135 .name = "tsensor-gpu",
136 .offset = 0x154,
137 .bytes = 4,
138 .bit_offset = 0,
139 .nbits = 32,
140 }, {
141 .name = "tsensor-mem0",
142 .offset = 0x158,
143 .bytes = 4,
144 .bit_offset = 0,
145 .nbits = 32,
146 }, {
147 .name = "tsensor-mem1",
148 .offset = 0x15c,
149 .bytes = 4,
150 .bit_offset = 0,
151 .nbits = 32,
152 }, {
153 .name = "tsensor-pllx",
154 .offset = 0x160,
155 .bytes = 4,
156 .bit_offset = 0,
157 .nbits = 32,
158 }, {
159 .name = "tsensor-common",
160 .offset = 0x180,
161 .bytes = 4,
162 .bit_offset = 0,
163 .nbits = 32,
164 }, {
165 .name = "tsensor-realignment",
166 .offset = 0x1fc,
167 .bytes = 4,
168 .bit_offset = 0,
169 .nbits = 32,
170 }, {
171 .name = "gpu-calibration",
172 .offset = 0x204,
173 .bytes = 4,
174 .bit_offset = 0,
175 .nbits = 32,
176 }, {
177 .name = "xusb-pad-calibration-ext",
178 .offset = 0x250,
179 .bytes = 4,
180 .bit_offset = 0,
181 .nbits = 32,
182 },
183};
184
185static void tegra_fuse_restore(void *base)
186{
187 fuse->clk = NULL;
188 fuse->base = base;
189}
190
191static int tegra_fuse_probe(struct platform_device *pdev)
192{
193 void __iomem *base = fuse->base;
194 struct nvmem_config nvmem;
195 struct resource *res;
196 int err;
197
198 err = devm_add_action(&pdev->dev, tegra_fuse_restore, base);
199 if (err)
200 return err;
201
202 /* take over the memory region from the early initialization */
203 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
204 fuse->phys = res->start;
205 fuse->base = devm_ioremap_resource(&pdev->dev, res);
206 if (IS_ERR(fuse->base)) {
207 err = PTR_ERR(fuse->base);
208 return err;
209 }
210
211 fuse->clk = devm_clk_get(&pdev->dev, "fuse");
212 if (IS_ERR(fuse->clk)) {
213 if (PTR_ERR(fuse->clk) != -EPROBE_DEFER)
214 dev_err(&pdev->dev, "failed to get FUSE clock: %ld",
215 PTR_ERR(fuse->clk));
216
217 return PTR_ERR(fuse->clk);
218 }
219
220 platform_set_drvdata(pdev, fuse);
221 fuse->dev = &pdev->dev;
222
223 err = devm_pm_runtime_enable(&pdev->dev);
224 if (err)
225 return err;
226
227 if (fuse->soc->probe) {
228 err = fuse->soc->probe(fuse);
229 if (err < 0)
230 return err;
231 }
232
233 memset(&nvmem, 0, sizeof(nvmem));
234 nvmem.dev = &pdev->dev;
235 nvmem.name = "fuse";
236 nvmem.id = -1;
237 nvmem.owner = THIS_MODULE;
238 nvmem.cells = tegra_fuse_cells;
239 nvmem.ncells = ARRAY_SIZE(tegra_fuse_cells);
240 nvmem.type = NVMEM_TYPE_OTP;
241 nvmem.read_only = true;
242 nvmem.root_only = true;
243 nvmem.reg_read = tegra_fuse_read;
244 nvmem.size = fuse->soc->info->size;
245 nvmem.word_size = 4;
246 nvmem.stride = 4;
247 nvmem.priv = fuse;
248
249 fuse->nvmem = devm_nvmem_register(&pdev->dev, &nvmem);
250 if (IS_ERR(fuse->nvmem)) {
251 err = PTR_ERR(fuse->nvmem);
252 dev_err(&pdev->dev, "failed to register NVMEM device: %d\n",
253 err);
254 return err;
255 }
256
257 fuse->rst = devm_reset_control_get_optional(&pdev->dev, "fuse");
258 if (IS_ERR(fuse->rst)) {
259 err = PTR_ERR(fuse->rst);
260 dev_err(&pdev->dev, "failed to get FUSE reset: %pe\n",
261 fuse->rst);
262 return err;
263 }
264
265 /*
266 * FUSE clock is enabled at a boot time, hence this resume/suspend
267 * disables the clock besides the h/w resetting.
268 */
269 err = pm_runtime_resume_and_get(&pdev->dev);
270 if (err)
271 return err;
272
273 err = reset_control_reset(fuse->rst);
274 pm_runtime_put(&pdev->dev);
275
276 if (err < 0) {
277 dev_err(&pdev->dev, "failed to reset FUSE: %d\n", err);
278 return err;
279 }
280
281 /* release the early I/O memory mapping */
282 iounmap(base);
283
284 return 0;
285}
286
287static int __maybe_unused tegra_fuse_runtime_resume(struct device *dev)
288{
289 int err;
290
291 err = clk_prepare_enable(fuse->clk);
292 if (err < 0) {
293 dev_err(dev, "failed to enable FUSE clock: %d\n", err);
294 return err;
295 }
296
297 return 0;
298}
299
300static int __maybe_unused tegra_fuse_runtime_suspend(struct device *dev)
301{
302 clk_disable_unprepare(fuse->clk);
303
304 return 0;
305}
306
307static int __maybe_unused tegra_fuse_suspend(struct device *dev)
308{
309 int ret;
310
311 /*
312 * Critical for RAM re-repair operation, which must occur on resume
313 * from LP1 system suspend and as part of CCPLEX cluster switching.
314 */
315 if (fuse->soc->clk_suspend_on)
316 ret = pm_runtime_resume_and_get(dev);
317 else
318 ret = pm_runtime_force_suspend(dev);
319
320 return ret;
321}
322
323static int __maybe_unused tegra_fuse_resume(struct device *dev)
324{
325 int ret = 0;
326
327 if (fuse->soc->clk_suspend_on)
328 pm_runtime_put(dev);
329 else
330 ret = pm_runtime_force_resume(dev);
331
332 return ret;
333}
334
335static const struct dev_pm_ops tegra_fuse_pm = {
336 SET_RUNTIME_PM_OPS(tegra_fuse_runtime_suspend, tegra_fuse_runtime_resume,
337 NULL)
338 SET_SYSTEM_SLEEP_PM_OPS(tegra_fuse_suspend, tegra_fuse_resume)
339};
340
341static struct platform_driver tegra_fuse_driver = {
342 .driver = {
343 .name = "tegra-fuse",
344 .of_match_table = tegra_fuse_match,
345 .pm = &tegra_fuse_pm,
346 .suppress_bind_attrs = true,
347 },
348 .probe = tegra_fuse_probe,
349};
350builtin_platform_driver(tegra_fuse_driver);
351
352u32 __init tegra_fuse_read_spare(unsigned int spare)
353{
354 unsigned int offset = fuse->soc->info->spare + spare * 4;
355
356 return fuse->read_early(fuse, offset) & 1;
357}
358
359u32 __init tegra_fuse_read_early(unsigned int offset)
360{
361 return fuse->read_early(fuse, offset);
362}
363
364int tegra_fuse_readl(unsigned long offset, u32 *value)
365{
366 if (!fuse->read || !fuse->clk)
367 return -EPROBE_DEFER;
368
369 if (IS_ERR(fuse->clk))
370 return PTR_ERR(fuse->clk);
371
372 *value = fuse->read(fuse, offset);
373
374 return 0;
375}
376EXPORT_SYMBOL(tegra_fuse_readl);
377
378static void tegra_enable_fuse_clk(void __iomem *base)
379{
380 u32 reg;
381
382 reg = readl_relaxed(base + 0x48);
383 reg |= 1 << 28;
384 writel(reg, base + 0x48);
385
386 /*
387 * Enable FUSE clock. This needs to be hardcoded because the clock
388 * subsystem is not active during early boot.
389 */
390 reg = readl(base + 0x14);
391 reg |= 1 << 7;
392 writel(reg, base + 0x14);
393}
394
395static ssize_t major_show(struct device *dev, struct device_attribute *attr,
396 char *buf)
397{
398 return sprintf(buf, "%d\n", tegra_get_major_rev());
399}
400
401static DEVICE_ATTR_RO(major);
402
403static ssize_t minor_show(struct device *dev, struct device_attribute *attr,
404 char *buf)
405{
406 return sprintf(buf, "%d\n", tegra_get_minor_rev());
407}
408
409static DEVICE_ATTR_RO(minor);
410
411static struct attribute *tegra_soc_attr[] = {
412 &dev_attr_major.attr,
413 &dev_attr_minor.attr,
414 NULL,
415};
416
417const struct attribute_group tegra_soc_attr_group = {
418 .attrs = tegra_soc_attr,
419};
420
421#if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \
422 IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC)
423static ssize_t platform_show(struct device *dev, struct device_attribute *attr,
424 char *buf)
425{
426 /*
427 * Displays the value in the 'pre_si_platform' field of the HIDREV
428 * register for Tegra194 devices. A value of 0 indicates that the
429 * platform type is silicon and all other non-zero values indicate
430 * the type of simulation platform is being used.
431 */
432 return sprintf(buf, "%d\n", tegra_get_platform());
433}
434
435static DEVICE_ATTR_RO(platform);
436
437static struct attribute *tegra194_soc_attr[] = {
438 &dev_attr_major.attr,
439 &dev_attr_minor.attr,
440 &dev_attr_platform.attr,
441 NULL,
442};
443
444const struct attribute_group tegra194_soc_attr_group = {
445 .attrs = tegra194_soc_attr,
446};
447#endif
448
449struct device * __init tegra_soc_device_register(void)
450{
451 struct soc_device_attribute *attr;
452 struct soc_device *dev;
453
454 attr = kzalloc(sizeof(*attr), GFP_KERNEL);
455 if (!attr)
456 return NULL;
457
458 attr->family = kasprintf(GFP_KERNEL, "Tegra");
459 attr->revision = kasprintf(GFP_KERNEL, "%s",
460 tegra_revision_name[tegra_sku_info.revision]);
461 attr->soc_id = kasprintf(GFP_KERNEL, "%u", tegra_get_chip_id());
462 attr->custom_attr_group = fuse->soc->soc_attr_group;
463
464 dev = soc_device_register(attr);
465 if (IS_ERR(dev)) {
466 kfree(attr->soc_id);
467 kfree(attr->revision);
468 kfree(attr->family);
469 kfree(attr);
470 return ERR_CAST(dev);
471 }
472
473 return soc_device_to_device(dev);
474}
475
476static int __init tegra_init_fuse(void)
477{
478 const struct of_device_id *match;
479 struct device_node *np;
480 struct resource regs;
481
482 tegra_init_apbmisc();
483
484 np = of_find_matching_node_and_match(NULL, tegra_fuse_match, &match);
485 if (!np) {
486 /*
487 * Fall back to legacy initialization for 32-bit ARM only. All
488 * 64-bit ARM device tree files for Tegra are required to have
489 * a FUSE node.
490 *
491 * This is for backwards-compatibility with old device trees
492 * that didn't contain a FUSE node.
493 */
494 if (IS_ENABLED(CONFIG_ARM) && soc_is_tegra()) {
495 u8 chip = tegra_get_chip_id();
496
497 regs.start = 0x7000f800;
498 regs.end = 0x7000fbff;
499 regs.flags = IORESOURCE_MEM;
500
501 switch (chip) {
502#ifdef CONFIG_ARCH_TEGRA_2x_SOC
503 case TEGRA20:
504 fuse->soc = &tegra20_fuse_soc;
505 break;
506#endif
507
508#ifdef CONFIG_ARCH_TEGRA_3x_SOC
509 case TEGRA30:
510 fuse->soc = &tegra30_fuse_soc;
511 break;
512#endif
513
514#ifdef CONFIG_ARCH_TEGRA_114_SOC
515 case TEGRA114:
516 fuse->soc = &tegra114_fuse_soc;
517 break;
518#endif
519
520#ifdef CONFIG_ARCH_TEGRA_124_SOC
521 case TEGRA124:
522 fuse->soc = &tegra124_fuse_soc;
523 break;
524#endif
525
526 default:
527 pr_warn("Unsupported SoC: %02x\n", chip);
528 break;
529 }
530 } else {
531 /*
532 * At this point we're not running on Tegra, so play
533 * nice with multi-platform kernels.
534 */
535 return 0;
536 }
537 } else {
538 /*
539 * Extract information from the device tree if we've found a
540 * matching node.
541 */
542 if (of_address_to_resource(np, 0, ®s) < 0) {
543 pr_err("failed to get FUSE register\n");
544 return -ENXIO;
545 }
546
547 fuse->soc = match->data;
548 }
549
550 np = of_find_matching_node(NULL, car_match);
551 if (np) {
552 void __iomem *base = of_iomap(np, 0);
553 if (base) {
554 tegra_enable_fuse_clk(base);
555 iounmap(base);
556 } else {
557 pr_err("failed to map clock registers\n");
558 return -ENXIO;
559 }
560 }
561
562 fuse->base = ioremap(regs.start, resource_size(®s));
563 if (!fuse->base) {
564 pr_err("failed to map FUSE registers\n");
565 return -ENXIO;
566 }
567
568 fuse->soc->init(fuse);
569
570 pr_info("Tegra Revision: %s SKU: %d CPU Process: %d SoC Process: %d\n",
571 tegra_revision_name[tegra_sku_info.revision],
572 tegra_sku_info.sku_id, tegra_sku_info.cpu_process_id,
573 tegra_sku_info.soc_process_id);
574 pr_debug("Tegra CPU Speedo ID %d, SoC Speedo ID %d\n",
575 tegra_sku_info.cpu_speedo_id, tegra_sku_info.soc_speedo_id);
576
577 if (fuse->soc->lookups) {
578 size_t size = sizeof(*fuse->lookups) * fuse->soc->num_lookups;
579
580 fuse->lookups = kmemdup(fuse->soc->lookups, size, GFP_KERNEL);
581 if (fuse->lookups)
582 nvmem_add_cell_lookups(fuse->lookups, fuse->soc->num_lookups);
583 }
584
585 return 0;
586}
587early_initcall(tegra_init_fuse);
588
589#ifdef CONFIG_ARM64
590static int __init tegra_init_soc(void)
591{
592 struct device_node *np;
593 struct device *soc;
594
595 /* make sure we're running on Tegra */
596 np = of_find_matching_node(NULL, tegra_fuse_match);
597 if (!np)
598 return 0;
599
600 of_node_put(np);
601
602 soc = tegra_soc_device_register();
603 if (IS_ERR(soc)) {
604 pr_err("failed to register SoC device: %ld\n", PTR_ERR(soc));
605 return PTR_ERR(soc);
606 }
607
608 return 0;
609}
610device_initcall(tegra_init_soc);
611#endif