Lines Matching +full:tegra20 +full:- +full:efuse
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2013-2023, NVIDIA CORPORATION. All rights reserved.
13 #include <linux/nvmem-consumer.h>
14 #include <linux/nvmem-provider.h>
54 { .compatible = "nvidia,tegra20-car", },
55 { .compatible = "nvidia,tegra30-car", },
56 { .compatible = "nvidia,tegra114-car", },
57 { .compatible = "nvidia,tegra124-car", },
58 { .compatible = "nvidia,tegra132-car", },
59 { .compatible = "nvidia,tegra210-car", },
70 { .compatible = "nvidia,tegra234-efuse", .data = &tegra234_fuse_soc },
73 { .compatible = "nvidia,tegra194-efuse", .data = &tegra194_fuse_soc },
76 { .compatible = "nvidia,tegra186-efuse", .data = &tegra186_fuse_soc },
79 { .compatible = "nvidia,tegra210-efuse", .data = &tegra210_fuse_soc },
82 { .compatible = "nvidia,tegra132-efuse", .data = &tegra124_fuse_soc },
85 { .compatible = "nvidia,tegra124-efuse", .data = &tegra124_fuse_soc },
88 { .compatible = "nvidia,tegra114-efuse", .data = &tegra114_fuse_soc },
91 { .compatible = "nvidia,tegra30-efuse", .data = &tegra30_fuse_soc },
94 { .compatible = "nvidia,tegra20-efuse", .data = &tegra20_fuse_soc },
107 buffer[i] = fuse->read(fuse, offset + i * 4); in tegra_fuse_read()
114 fuse->base = (void __iomem *)base; in tegra_fuse_restore()
115 fuse->clk = NULL; in tegra_fuse_restore()
121 tegra_revision_name[tegra_sku_info->revision], in tegra_fuse_print_sku_info()
122 tegra_sku_info->sku_id, tegra_sku_info->cpu_process_id, in tegra_fuse_print_sku_info()
123 tegra_sku_info->soc_process_id); in tegra_fuse_print_sku_info()
125 tegra_sku_info->cpu_speedo_id, tegra_sku_info->soc_speedo_id); in tegra_fuse_print_sku_info()
130 fuse->lookups = kmemdup_array(fuse->soc->lookups, fuse->soc->num_lookups, in tegra_fuse_add_lookups()
131 sizeof(*fuse->lookups), GFP_KERNEL); in tegra_fuse_add_lookups()
132 if (!fuse->lookups) in tegra_fuse_add_lookups()
133 return -ENOMEM; in tegra_fuse_add_lookups()
135 nvmem_add_cell_lookups(fuse->lookups, fuse->soc->num_lookups); in tegra_fuse_add_lookups()
142 void __iomem *base = fuse->base; in tegra_fuse_probe()
147 err = devm_add_action(&pdev->dev, tegra_fuse_restore, (void __force *)base); in tegra_fuse_probe()
152 fuse->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in tegra_fuse_probe()
153 if (IS_ERR(fuse->base)) in tegra_fuse_probe()
154 return PTR_ERR(fuse->base); in tegra_fuse_probe()
155 fuse->phys = res->start; in tegra_fuse_probe()
158 if (is_acpi_node(dev_fwnode(&pdev->dev)) && !fuse->soc) { in tegra_fuse_probe()
167 fuse->soc = &tegra194_fuse_soc; in tegra_fuse_probe()
172 fuse->soc = &tegra234_fuse_soc; in tegra_fuse_probe()
177 fuse->soc = &tegra241_fuse_soc; in tegra_fuse_probe()
181 return dev_err_probe(&pdev->dev, -EINVAL, "Unsupported SoC: %02x\n", chip); in tegra_fuse_probe()
184 fuse->soc->init(fuse); in tegra_fuse_probe()
190 return dev_err_probe(&pdev->dev, err, "failed to add FUSE lookups\n"); in tegra_fuse_probe()
193 fuse->clk = devm_clk_get_optional(&pdev->dev, "fuse"); in tegra_fuse_probe()
194 if (IS_ERR(fuse->clk)) in tegra_fuse_probe()
195 return dev_err_probe(&pdev->dev, PTR_ERR(fuse->clk), "failed to get FUSE clock\n"); in tegra_fuse_probe()
198 fuse->dev = &pdev->dev; in tegra_fuse_probe()
200 err = devm_pm_runtime_enable(&pdev->dev); in tegra_fuse_probe()
204 if (fuse->soc->probe) { in tegra_fuse_probe()
205 err = fuse->soc->probe(fuse); in tegra_fuse_probe()
211 nvmem.dev = &pdev->dev; in tegra_fuse_probe()
213 nvmem.id = -1; in tegra_fuse_probe()
215 nvmem.cells = fuse->soc->cells; in tegra_fuse_probe()
216 nvmem.ncells = fuse->soc->num_cells; in tegra_fuse_probe()
217 nvmem.keepout = fuse->soc->keepouts; in tegra_fuse_probe()
218 nvmem.nkeepout = fuse->soc->num_keepouts; in tegra_fuse_probe()
223 nvmem.size = fuse->soc->info->size; in tegra_fuse_probe()
228 fuse->nvmem = devm_nvmem_register(&pdev->dev, &nvmem); in tegra_fuse_probe()
229 if (IS_ERR(fuse->nvmem)) { in tegra_fuse_probe()
230 err = PTR_ERR(fuse->nvmem); in tegra_fuse_probe()
231 dev_err(&pdev->dev, "failed to register NVMEM device: %d\n", in tegra_fuse_probe()
236 fuse->rst = devm_reset_control_get_optional(&pdev->dev, "fuse"); in tegra_fuse_probe()
237 if (IS_ERR(fuse->rst)) in tegra_fuse_probe()
238 return dev_err_probe(&pdev->dev, PTR_ERR(fuse->rst), "failed to get FUSE reset\n"); in tegra_fuse_probe()
244 err = pm_runtime_resume_and_get(&pdev->dev); in tegra_fuse_probe()
248 err = reset_control_reset(fuse->rst); in tegra_fuse_probe()
249 pm_runtime_put(&pdev->dev); in tegra_fuse_probe()
252 dev_err(&pdev->dev, "failed to reset FUSE: %d\n", err); in tegra_fuse_probe()
266 err = clk_prepare_enable(fuse->clk); in tegra_fuse_runtime_resume()
277 clk_disable_unprepare(fuse->clk); in tegra_fuse_runtime_suspend()
287 * Critical for RAM re-repair operation, which must occur on resume in tegra_fuse_suspend()
290 if (fuse->soc->clk_suspend_on) in tegra_fuse_suspend()
302 if (fuse->soc->clk_suspend_on) in tegra_fuse_resume()
324 .name = "tegra-fuse",
336 unsigned int offset = fuse->soc->info->spare + spare * 4; in tegra_fuse_read_spare()
338 return fuse->read_early(fuse, offset) & 1; in tegra_fuse_read_spare()
343 return fuse->read_early(fuse, offset); in tegra_fuse_read_early()
348 if (!fuse->dev) in tegra_fuse_readl()
349 return -EPROBE_DEFER; in tegra_fuse_readl()
352 * Wait for fuse->clk to be initialized if device-tree boot is used. in tegra_fuse_readl()
354 if (is_of_node(dev_fwnode(fuse->dev)) && !fuse->clk) in tegra_fuse_readl()
355 return -EPROBE_DEFER; in tegra_fuse_readl()
357 if (!fuse->read) in tegra_fuse_readl()
358 return -EPROBE_DEFER; in tegra_fuse_readl()
360 if (IS_ERR(fuse->clk)) in tegra_fuse_readl()
361 return PTR_ERR(fuse->clk); in tegra_fuse_readl()
363 *value = fuse->read(fuse, offset); in tegra_fuse_readl()
421 * platform type is silicon and all other non-zero values indicate in platform_show()
450 attr->family = kasprintf(GFP_KERNEL, "Tegra"); in tegra_soc_device_register()
452 attr->revision = kasprintf(GFP_KERNEL, "%s %s", in tegra_soc_device_register()
456 attr->revision = kasprintf(GFP_KERNEL, "%s", in tegra_soc_device_register()
458 attr->soc_id = kasprintf(GFP_KERNEL, "%u", tegra_get_chip_id()); in tegra_soc_device_register()
459 attr->custom_attr_group = fuse->soc->soc_attr_group; in tegra_soc_device_register()
463 kfree(attr->soc_id); in tegra_soc_device_register()
464 kfree(attr->revision); in tegra_soc_device_register()
465 kfree(attr->family); in tegra_soc_device_register()
485 * Fall back to legacy initialization for 32-bit ARM only. All in tegra_init_fuse()
486 * 64-bit ARM device tree files for Tegra are required to have in tegra_init_fuse()
489 * This is for backwards-compatibility with old device trees in tegra_init_fuse()
501 case TEGRA20: in tegra_init_fuse()
502 fuse->soc = &tegra20_fuse_soc; in tegra_init_fuse()
508 fuse->soc = &tegra30_fuse_soc; in tegra_init_fuse()
514 fuse->soc = &tegra114_fuse_soc; in tegra_init_fuse()
520 fuse->soc = &tegra124_fuse_soc; in tegra_init_fuse()
531 * nice with multi-platform kernels. in tegra_init_fuse()
542 return -ENXIO; in tegra_init_fuse()
545 fuse->soc = match->data; in tegra_init_fuse()
557 return -ENXIO; in tegra_init_fuse()
561 fuse->base = ioremap(regs.start, resource_size(®s)); in tegra_init_fuse()
562 if (!fuse->base) { in tegra_init_fuse()
564 return -ENXIO; in tegra_init_fuse()
567 fuse->soc->init(fuse); in tegra_init_fuse()