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