linux/drivers/soc/tegra/fuse/fuse-tegra30.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/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/pm_runtime.h>
  16#include <linux/random.h>
  17
  18#include <soc/tegra/fuse.h>
  19
  20#include "fuse.h"
  21
  22#define FUSE_BEGIN      0x100
  23
  24/* Tegra30 and later */
  25#define FUSE_VENDOR_CODE        0x100
  26#define FUSE_FAB_CODE           0x104
  27#define FUSE_LOT_CODE_0         0x108
  28#define FUSE_LOT_CODE_1         0x10c
  29#define FUSE_WAFER_ID           0x110
  30#define FUSE_X_COORDINATE       0x114
  31#define FUSE_Y_COORDINATE       0x118
  32
  33#define FUSE_HAS_REVISION_INFO  BIT(0)
  34
  35#if defined(CONFIG_ARCH_TEGRA_3x_SOC) || \
  36    defined(CONFIG_ARCH_TEGRA_114_SOC) || \
  37    defined(CONFIG_ARCH_TEGRA_124_SOC) || \
  38    defined(CONFIG_ARCH_TEGRA_132_SOC) || \
  39    defined(CONFIG_ARCH_TEGRA_210_SOC) || \
  40    defined(CONFIG_ARCH_TEGRA_186_SOC) || \
  41    defined(CONFIG_ARCH_TEGRA_194_SOC) || \
  42    defined(CONFIG_ARCH_TEGRA_234_SOC)
  43static u32 tegra30_fuse_read_early(struct tegra_fuse *fuse, unsigned int offset)
  44{
  45        if (WARN_ON(!fuse->base))
  46                return 0;
  47
  48        return readl_relaxed(fuse->base + FUSE_BEGIN + offset);
  49}
  50
  51static u32 tegra30_fuse_read(struct tegra_fuse *fuse, unsigned int offset)
  52{
  53        u32 value;
  54        int err;
  55
  56        err = pm_runtime_resume_and_get(fuse->dev);
  57        if (err)
  58                return 0;
  59
  60        value = readl_relaxed(fuse->base + FUSE_BEGIN + offset);
  61
  62        pm_runtime_put(fuse->dev);
  63
  64        return value;
  65}
  66
  67static 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
  89static 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
 104static const struct tegra_fuse_info tegra30_fuse_info = {
 105        .read = tegra30_fuse_read,
 106        .size = 0x2a4,
 107        .spare = 0x144,
 108};
 109
 110const 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        .soc_attr_group = &tegra_soc_attr_group,
 115        .clk_suspend_on = false,
 116};
 117#endif
 118
 119#ifdef CONFIG_ARCH_TEGRA_114_SOC
 120static const struct tegra_fuse_info tegra114_fuse_info = {
 121        .read = tegra30_fuse_read,
 122        .size = 0x2a0,
 123        .spare = 0x180,
 124};
 125
 126const struct tegra_fuse_soc tegra114_fuse_soc = {
 127        .init = tegra30_fuse_init,
 128        .speedo_init = tegra114_init_speedo_data,
 129        .info = &tegra114_fuse_info,
 130        .soc_attr_group = &tegra_soc_attr_group,
 131        .clk_suspend_on = false,
 132};
 133#endif
 134
 135#if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC)
 136static const struct nvmem_cell_lookup tegra124_fuse_lookups[] = {
 137        {
 138                .nvmem_name = "fuse",
 139                .cell_name = "xusb-pad-calibration",
 140                .dev_id = "7009f000.padctl",
 141                .con_id = "calibration",
 142        }, {
 143                .nvmem_name = "fuse",
 144                .cell_name = "sata-calibration",
 145                .dev_id = "70020000.sata",
 146                .con_id = "calibration",
 147        }, {
 148                .nvmem_name = "fuse",
 149                .cell_name = "tsensor-common",
 150                .dev_id = "700e2000.thermal-sensor",
 151                .con_id = "common",
 152        }, {
 153                .nvmem_name = "fuse",
 154                .cell_name = "tsensor-realignment",
 155                .dev_id = "700e2000.thermal-sensor",
 156                .con_id = "realignment",
 157        }, {
 158                .nvmem_name = "fuse",
 159                .cell_name = "tsensor-cpu0",
 160                .dev_id = "700e2000.thermal-sensor",
 161                .con_id = "cpu0",
 162        }, {
 163                .nvmem_name = "fuse",
 164                .cell_name = "tsensor-cpu1",
 165                .dev_id = "700e2000.thermal-sensor",
 166                .con_id = "cpu1",
 167        }, {
 168                .nvmem_name = "fuse",
 169                .cell_name = "tsensor-cpu2",
 170                .dev_id = "700e2000.thermal-sensor",
 171                .con_id = "cpu2",
 172        }, {
 173                .nvmem_name = "fuse",
 174                .cell_name = "tsensor-cpu3",
 175                .dev_id = "700e2000.thermal-sensor",
 176                .con_id = "cpu3",
 177        }, {
 178                .nvmem_name = "fuse",
 179                .cell_name = "tsensor-mem0",
 180                .dev_id = "700e2000.thermal-sensor",
 181                .con_id = "mem0",
 182        }, {
 183                .nvmem_name = "fuse",
 184                .cell_name = "tsensor-mem1",
 185                .dev_id = "700e2000.thermal-sensor",
 186                .con_id = "mem1",
 187        }, {
 188                .nvmem_name = "fuse",
 189                .cell_name = "tsensor-gpu",
 190                .dev_id = "700e2000.thermal-sensor",
 191                .con_id = "gpu",
 192        }, {
 193                .nvmem_name = "fuse",
 194                .cell_name = "tsensor-pllx",
 195                .dev_id = "700e2000.thermal-sensor",
 196                .con_id = "pllx",
 197        },
 198};
 199
 200static const struct tegra_fuse_info tegra124_fuse_info = {
 201        .read = tegra30_fuse_read,
 202        .size = 0x300,
 203        .spare = 0x200,
 204};
 205
 206const struct tegra_fuse_soc tegra124_fuse_soc = {
 207        .init = tegra30_fuse_init,
 208        .speedo_init = tegra124_init_speedo_data,
 209        .info = &tegra124_fuse_info,
 210        .lookups = tegra124_fuse_lookups,
 211        .num_lookups = ARRAY_SIZE(tegra124_fuse_lookups),
 212        .soc_attr_group = &tegra_soc_attr_group,
 213        .clk_suspend_on = true,
 214};
 215#endif
 216
 217#if defined(CONFIG_ARCH_TEGRA_210_SOC)
 218static const struct nvmem_cell_lookup tegra210_fuse_lookups[] = {
 219        {
 220                .nvmem_name = "fuse",
 221                .cell_name = "tsensor-cpu1",
 222                .dev_id = "700e2000.thermal-sensor",
 223                .con_id = "cpu1",
 224        }, {
 225                .nvmem_name = "fuse",
 226                .cell_name = "tsensor-cpu2",
 227                .dev_id = "700e2000.thermal-sensor",
 228                .con_id = "cpu2",
 229        }, {
 230                .nvmem_name = "fuse",
 231                .cell_name = "tsensor-cpu0",
 232                .dev_id = "700e2000.thermal-sensor",
 233                .con_id = "cpu0",
 234        }, {
 235                .nvmem_name = "fuse",
 236                .cell_name = "xusb-pad-calibration",
 237                .dev_id = "7009f000.padctl",
 238                .con_id = "calibration",
 239        }, {
 240                .nvmem_name = "fuse",
 241                .cell_name = "tsensor-cpu3",
 242                .dev_id = "700e2000.thermal-sensor",
 243                .con_id = "cpu3",
 244        }, {
 245                .nvmem_name = "fuse",
 246                .cell_name = "sata-calibration",
 247                .dev_id = "70020000.sata",
 248                .con_id = "calibration",
 249        }, {
 250                .nvmem_name = "fuse",
 251                .cell_name = "tsensor-gpu",
 252                .dev_id = "700e2000.thermal-sensor",
 253                .con_id = "gpu",
 254        }, {
 255                .nvmem_name = "fuse",
 256                .cell_name = "tsensor-mem0",
 257                .dev_id = "700e2000.thermal-sensor",
 258                .con_id = "mem0",
 259        }, {
 260                .nvmem_name = "fuse",
 261                .cell_name = "tsensor-mem1",
 262                .dev_id = "700e2000.thermal-sensor",
 263                .con_id = "mem1",
 264        }, {
 265                .nvmem_name = "fuse",
 266                .cell_name = "tsensor-pllx",
 267                .dev_id = "700e2000.thermal-sensor",
 268                .con_id = "pllx",
 269        }, {
 270                .nvmem_name = "fuse",
 271                .cell_name = "tsensor-common",
 272                .dev_id = "700e2000.thermal-sensor",
 273                .con_id = "common",
 274        }, {
 275                .nvmem_name = "fuse",
 276                .cell_name = "gpu-calibration",
 277                .dev_id = "57000000.gpu",
 278                .con_id = "calibration",
 279        }, {
 280                .nvmem_name = "fuse",
 281                .cell_name = "xusb-pad-calibration-ext",
 282                .dev_id = "7009f000.padctl",
 283                .con_id = "calibration-ext",
 284        },
 285};
 286
 287static const struct tegra_fuse_info tegra210_fuse_info = {
 288        .read = tegra30_fuse_read,
 289        .size = 0x300,
 290        .spare = 0x280,
 291};
 292
 293const struct tegra_fuse_soc tegra210_fuse_soc = {
 294        .init = tegra30_fuse_init,
 295        .speedo_init = tegra210_init_speedo_data,
 296        .info = &tegra210_fuse_info,
 297        .lookups = tegra210_fuse_lookups,
 298        .num_lookups = ARRAY_SIZE(tegra210_fuse_lookups),
 299        .soc_attr_group = &tegra_soc_attr_group,
 300        .clk_suspend_on = false,
 301};
 302#endif
 303
 304#if defined(CONFIG_ARCH_TEGRA_186_SOC)
 305static const struct nvmem_cell_lookup tegra186_fuse_lookups[] = {
 306        {
 307                .nvmem_name = "fuse",
 308                .cell_name = "xusb-pad-calibration",
 309                .dev_id = "3520000.padctl",
 310                .con_id = "calibration",
 311        }, {
 312                .nvmem_name = "fuse",
 313                .cell_name = "xusb-pad-calibration-ext",
 314                .dev_id = "3520000.padctl",
 315                .con_id = "calibration-ext",
 316        },
 317};
 318
 319static const struct tegra_fuse_info tegra186_fuse_info = {
 320        .read = tegra30_fuse_read,
 321        .size = 0x300,
 322        .spare = 0x280,
 323};
 324
 325const struct tegra_fuse_soc tegra186_fuse_soc = {
 326        .init = tegra30_fuse_init,
 327        .info = &tegra186_fuse_info,
 328        .lookups = tegra186_fuse_lookups,
 329        .num_lookups = ARRAY_SIZE(tegra186_fuse_lookups),
 330        .soc_attr_group = &tegra_soc_attr_group,
 331        .clk_suspend_on = false,
 332};
 333#endif
 334
 335#if defined(CONFIG_ARCH_TEGRA_194_SOC)
 336static const struct nvmem_cell_lookup tegra194_fuse_lookups[] = {
 337        {
 338                .nvmem_name = "fuse",
 339                .cell_name = "xusb-pad-calibration",
 340                .dev_id = "3520000.padctl",
 341                .con_id = "calibration",
 342        }, {
 343                .nvmem_name = "fuse",
 344                .cell_name = "xusb-pad-calibration-ext",
 345                .dev_id = "3520000.padctl",
 346                .con_id = "calibration-ext",
 347        },
 348};
 349
 350static const struct tegra_fuse_info tegra194_fuse_info = {
 351        .read = tegra30_fuse_read,
 352        .size = 0x300,
 353        .spare = 0x280,
 354};
 355
 356const struct tegra_fuse_soc tegra194_fuse_soc = {
 357        .init = tegra30_fuse_init,
 358        .info = &tegra194_fuse_info,
 359        .lookups = tegra194_fuse_lookups,
 360        .num_lookups = ARRAY_SIZE(tegra194_fuse_lookups),
 361        .soc_attr_group = &tegra194_soc_attr_group,
 362        .clk_suspend_on = false,
 363};
 364#endif
 365
 366#if defined(CONFIG_ARCH_TEGRA_234_SOC)
 367static const struct nvmem_cell_lookup tegra234_fuse_lookups[] = {
 368        {
 369                .nvmem_name = "fuse",
 370                .cell_name = "xusb-pad-calibration",
 371                .dev_id = "3520000.padctl",
 372                .con_id = "calibration",
 373        }, {
 374                .nvmem_name = "fuse",
 375                .cell_name = "xusb-pad-calibration-ext",
 376                .dev_id = "3520000.padctl",
 377                .con_id = "calibration-ext",
 378        },
 379};
 380
 381static const struct tegra_fuse_info tegra234_fuse_info = {
 382        .read = tegra30_fuse_read,
 383        .size = 0x300,
 384        .spare = 0x280,
 385};
 386
 387const struct tegra_fuse_soc tegra234_fuse_soc = {
 388        .init = tegra30_fuse_init,
 389        .info = &tegra234_fuse_info,
 390        .lookups = tegra234_fuse_lookups,
 391        .num_lookups = ARRAY_SIZE(tegra234_fuse_lookups),
 392        .soc_attr_group = &tegra194_soc_attr_group,
 393        .clk_suspend_on = false,
 394};
 395#endif
 396