cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fuse-tegra30.c (10325B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (c) 2013-2022, 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		.nvmem_name = "fuse",
    349		.cell_name = "gpu-gcplex-config-fuse",
    350		.dev_id = "17000000.gpu",
    351		.con_id = "gcplex-config-fuse",
    352	}, {
    353		.nvmem_name = "fuse",
    354		.cell_name = "gpu-pdi0",
    355		.dev_id = "17000000.gpu",
    356		.con_id = "pdi0",
    357	}, {
    358		.nvmem_name = "fuse",
    359		.cell_name = "gpu-pdi1",
    360		.dev_id = "17000000.gpu",
    361		.con_id = "pdi1",
    362	},
    363};
    364
    365static const struct tegra_fuse_info tegra194_fuse_info = {
    366	.read = tegra30_fuse_read,
    367	.size = 0x300,
    368	.spare = 0x280,
    369};
    370
    371const struct tegra_fuse_soc tegra194_fuse_soc = {
    372	.init = tegra30_fuse_init,
    373	.info = &tegra194_fuse_info,
    374	.lookups = tegra194_fuse_lookups,
    375	.num_lookups = ARRAY_SIZE(tegra194_fuse_lookups),
    376	.soc_attr_group = &tegra194_soc_attr_group,
    377	.clk_suspend_on = false,
    378};
    379#endif
    380
    381#if defined(CONFIG_ARCH_TEGRA_234_SOC)
    382static const struct nvmem_cell_lookup tegra234_fuse_lookups[] = {
    383	{
    384		.nvmem_name = "fuse",
    385		.cell_name = "xusb-pad-calibration",
    386		.dev_id = "3520000.padctl",
    387		.con_id = "calibration",
    388	}, {
    389		.nvmem_name = "fuse",
    390		.cell_name = "xusb-pad-calibration-ext",
    391		.dev_id = "3520000.padctl",
    392		.con_id = "calibration-ext",
    393	},
    394};
    395
    396static const struct tegra_fuse_info tegra234_fuse_info = {
    397	.read = tegra30_fuse_read,
    398	.size = 0x300,
    399	.spare = 0x280,
    400};
    401
    402const struct tegra_fuse_soc tegra234_fuse_soc = {
    403	.init = tegra30_fuse_init,
    404	.info = &tegra234_fuse_info,
    405	.lookups = tegra234_fuse_lookups,
    406	.num_lookups = ARRAY_SIZE(tegra234_fuse_lookups),
    407	.soc_attr_group = &tegra194_soc_attr_group,
    408	.clk_suspend_on = false,
    409};
    410#endif