brintos

brintos / linux-shallow public Read only

0
0
Text · 15.9 KiB · eb14e5f Raw
702 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*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/nvmem-provider.h>13#include <linux/platform_device.h>14#include <linux/pm_runtime.h>15#include <linux/random.h>16 17#include <soc/tegra/fuse.h>18 19#include "fuse.h"20 21#define FUSE_BEGIN	0x10022 23/* Tegra30 and later */24#define FUSE_VENDOR_CODE	0x10025#define FUSE_FAB_CODE		0x10426#define FUSE_LOT_CODE_0		0x10827#define FUSE_LOT_CODE_1		0x10c28#define FUSE_WAFER_ID		0x11029#define FUSE_X_COORDINATE	0x11430#define FUSE_Y_COORDINATE	0x11831 32#define FUSE_HAS_REVISION_INFO	BIT(0)33 34#if defined(CONFIG_ARCH_TEGRA_3x_SOC) || \35    defined(CONFIG_ARCH_TEGRA_114_SOC) || \36    defined(CONFIG_ARCH_TEGRA_124_SOC) || \37    defined(CONFIG_ARCH_TEGRA_132_SOC) || \38    defined(CONFIG_ARCH_TEGRA_210_SOC) || \39    defined(CONFIG_ARCH_TEGRA_186_SOC) || \40    defined(CONFIG_ARCH_TEGRA_194_SOC) || \41    defined(CONFIG_ARCH_TEGRA_234_SOC) || \42    defined(CONFIG_ARCH_TEGRA_241_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#endif102 103#ifdef CONFIG_ARCH_TEGRA_3x_SOC104static 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#endif118 119#ifdef CONFIG_ARCH_TEGRA_114_SOC120static 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#endif134 135#if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC)136static const struct nvmem_cell_info tegra124_fuse_cells[] = {137	{138		.name = "tsensor-cpu1",139		.offset = 0x084,140		.bytes = 4,141		.bit_offset = 0,142		.nbits = 32,143	}, {144		.name = "tsensor-cpu2",145		.offset = 0x088,146		.bytes = 4,147		.bit_offset = 0,148		.nbits = 32,149	}, {150		.name = "tsensor-cpu0",151		.offset = 0x098,152		.bytes = 4,153		.bit_offset = 0,154		.nbits = 32,155	}, {156		.name = "xusb-pad-calibration",157		.offset = 0x0f0,158		.bytes = 4,159		.bit_offset = 0,160		.nbits = 32,161	}, {162		.name = "tsensor-cpu3",163		.offset = 0x12c,164		.bytes = 4,165		.bit_offset = 0,166		.nbits = 32,167	}, {168		.name = "sata-calibration",169		.offset = 0x124,170		.bytes = 4,171		.bit_offset = 0,172		.nbits = 32,173	}, {174		.name = "tsensor-gpu",175		.offset = 0x154,176		.bytes = 4,177		.bit_offset = 0,178		.nbits = 32,179	}, {180		.name = "tsensor-mem0",181		.offset = 0x158,182		.bytes = 4,183		.bit_offset = 0,184		.nbits = 32,185	}, {186		.name = "tsensor-mem1",187		.offset = 0x15c,188		.bytes = 4,189		.bit_offset = 0,190		.nbits = 32,191	}, {192		.name = "tsensor-pllx",193		.offset = 0x160,194		.bytes = 4,195		.bit_offset = 0,196		.nbits = 32,197	}, {198		.name = "tsensor-common",199		.offset = 0x180,200		.bytes = 4,201		.bit_offset = 0,202		.nbits = 32,203	}, {204		.name = "tsensor-realignment",205		.offset = 0x1fc,206		.bytes = 4,207		.bit_offset = 0,208		.nbits = 32,209	},210};211 212static const struct nvmem_cell_lookup tegra124_fuse_lookups[] = {213	{214		.nvmem_name = "fuse",215		.cell_name = "xusb-pad-calibration",216		.dev_id = "7009f000.padctl",217		.con_id = "calibration",218	}, {219		.nvmem_name = "fuse",220		.cell_name = "sata-calibration",221		.dev_id = "70020000.sata",222		.con_id = "calibration",223	}, {224		.nvmem_name = "fuse",225		.cell_name = "tsensor-common",226		.dev_id = "700e2000.thermal-sensor",227		.con_id = "common",228	}, {229		.nvmem_name = "fuse",230		.cell_name = "tsensor-realignment",231		.dev_id = "700e2000.thermal-sensor",232		.con_id = "realignment",233	}, {234		.nvmem_name = "fuse",235		.cell_name = "tsensor-cpu0",236		.dev_id = "700e2000.thermal-sensor",237		.con_id = "cpu0",238	}, {239		.nvmem_name = "fuse",240		.cell_name = "tsensor-cpu1",241		.dev_id = "700e2000.thermal-sensor",242		.con_id = "cpu1",243	}, {244		.nvmem_name = "fuse",245		.cell_name = "tsensor-cpu2",246		.dev_id = "700e2000.thermal-sensor",247		.con_id = "cpu2",248	}, {249		.nvmem_name = "fuse",250		.cell_name = "tsensor-cpu3",251		.dev_id = "700e2000.thermal-sensor",252		.con_id = "cpu3",253	}, {254		.nvmem_name = "fuse",255		.cell_name = "tsensor-mem0",256		.dev_id = "700e2000.thermal-sensor",257		.con_id = "mem0",258	}, {259		.nvmem_name = "fuse",260		.cell_name = "tsensor-mem1",261		.dev_id = "700e2000.thermal-sensor",262		.con_id = "mem1",263	}, {264		.nvmem_name = "fuse",265		.cell_name = "tsensor-gpu",266		.dev_id = "700e2000.thermal-sensor",267		.con_id = "gpu",268	}, {269		.nvmem_name = "fuse",270		.cell_name = "tsensor-pllx",271		.dev_id = "700e2000.thermal-sensor",272		.con_id = "pllx",273	},274};275 276static const struct tegra_fuse_info tegra124_fuse_info = {277	.read = tegra30_fuse_read,278	.size = 0x300,279	.spare = 0x200,280};281 282const struct tegra_fuse_soc tegra124_fuse_soc = {283	.init = tegra30_fuse_init,284	.speedo_init = tegra124_init_speedo_data,285	.info = &tegra124_fuse_info,286	.lookups = tegra124_fuse_lookups,287	.num_lookups = ARRAY_SIZE(tegra124_fuse_lookups),288	.cells = tegra124_fuse_cells,289	.num_cells = ARRAY_SIZE(tegra124_fuse_cells),290	.soc_attr_group = &tegra_soc_attr_group,291	.clk_suspend_on = true,292};293#endif294 295#if defined(CONFIG_ARCH_TEGRA_210_SOC)296static const struct nvmem_cell_info tegra210_fuse_cells[] = {297	{298		.name = "tsensor-cpu1",299		.offset = 0x084,300		.bytes = 4,301		.bit_offset = 0,302		.nbits = 32,303	}, {304		.name = "tsensor-cpu2",305		.offset = 0x088,306		.bytes = 4,307		.bit_offset = 0,308		.nbits = 32,309	}, {310		.name = "tsensor-cpu0",311		.offset = 0x098,312		.bytes = 4,313		.bit_offset = 0,314		.nbits = 32,315	}, {316		.name = "xusb-pad-calibration",317		.offset = 0x0f0,318		.bytes = 4,319		.bit_offset = 0,320		.nbits = 32,321	}, {322		.name = "tsensor-cpu3",323		.offset = 0x12c,324		.bytes = 4,325		.bit_offset = 0,326		.nbits = 32,327	}, {328		.name = "sata-calibration",329		.offset = 0x124,330		.bytes = 4,331		.bit_offset = 0,332		.nbits = 32,333	}, {334		.name = "tsensor-gpu",335		.offset = 0x154,336		.bytes = 4,337		.bit_offset = 0,338		.nbits = 32,339	}, {340		.name = "tsensor-mem0",341		.offset = 0x158,342		.bytes = 4,343		.bit_offset = 0,344		.nbits = 32,345	}, {346		.name = "tsensor-mem1",347		.offset = 0x15c,348		.bytes = 4,349		.bit_offset = 0,350		.nbits = 32,351	}, {352		.name = "tsensor-pllx",353		.offset = 0x160,354		.bytes = 4,355		.bit_offset = 0,356		.nbits = 32,357	}, {358		.name = "tsensor-common",359		.offset = 0x180,360		.bytes = 4,361		.bit_offset = 0,362		.nbits = 32,363	}, {364		.name = "gpu-calibration",365		.offset = 0x204,366		.bytes = 4,367		.bit_offset = 0,368		.nbits = 32,369	}, {370		.name = "xusb-pad-calibration-ext",371		.offset = 0x250,372		.bytes = 4,373		.bit_offset = 0,374		.nbits = 32,375	},376};377 378static const struct nvmem_cell_lookup tegra210_fuse_lookups[] = {379	{380		.nvmem_name = "fuse",381		.cell_name = "tsensor-cpu1",382		.dev_id = "700e2000.thermal-sensor",383		.con_id = "cpu1",384	}, {385		.nvmem_name = "fuse",386		.cell_name = "tsensor-cpu2",387		.dev_id = "700e2000.thermal-sensor",388		.con_id = "cpu2",389	}, {390		.nvmem_name = "fuse",391		.cell_name = "tsensor-cpu0",392		.dev_id = "700e2000.thermal-sensor",393		.con_id = "cpu0",394	}, {395		.nvmem_name = "fuse",396		.cell_name = "xusb-pad-calibration",397		.dev_id = "7009f000.padctl",398		.con_id = "calibration",399	}, {400		.nvmem_name = "fuse",401		.cell_name = "tsensor-cpu3",402		.dev_id = "700e2000.thermal-sensor",403		.con_id = "cpu3",404	}, {405		.nvmem_name = "fuse",406		.cell_name = "sata-calibration",407		.dev_id = "70020000.sata",408		.con_id = "calibration",409	}, {410		.nvmem_name = "fuse",411		.cell_name = "tsensor-gpu",412		.dev_id = "700e2000.thermal-sensor",413		.con_id = "gpu",414	}, {415		.nvmem_name = "fuse",416		.cell_name = "tsensor-mem0",417		.dev_id = "700e2000.thermal-sensor",418		.con_id = "mem0",419	}, {420		.nvmem_name = "fuse",421		.cell_name = "tsensor-mem1",422		.dev_id = "700e2000.thermal-sensor",423		.con_id = "mem1",424	}, {425		.nvmem_name = "fuse",426		.cell_name = "tsensor-pllx",427		.dev_id = "700e2000.thermal-sensor",428		.con_id = "pllx",429	}, {430		.nvmem_name = "fuse",431		.cell_name = "tsensor-common",432		.dev_id = "700e2000.thermal-sensor",433		.con_id = "common",434	}, {435		.nvmem_name = "fuse",436		.cell_name = "gpu-calibration",437		.dev_id = "57000000.gpu",438		.con_id = "calibration",439	}, {440		.nvmem_name = "fuse",441		.cell_name = "xusb-pad-calibration-ext",442		.dev_id = "7009f000.padctl",443		.con_id = "calibration-ext",444	},445};446 447static const struct tegra_fuse_info tegra210_fuse_info = {448	.read = tegra30_fuse_read,449	.size = 0x300,450	.spare = 0x280,451};452 453const struct tegra_fuse_soc tegra210_fuse_soc = {454	.init = tegra30_fuse_init,455	.speedo_init = tegra210_init_speedo_data,456	.info = &tegra210_fuse_info,457	.lookups = tegra210_fuse_lookups,458	.cells = tegra210_fuse_cells,459	.num_cells = ARRAY_SIZE(tegra210_fuse_cells),460	.num_lookups = ARRAY_SIZE(tegra210_fuse_lookups),461	.soc_attr_group = &tegra_soc_attr_group,462	.clk_suspend_on = false,463};464#endif465 466#if defined(CONFIG_ARCH_TEGRA_186_SOC)467static const struct nvmem_cell_info tegra186_fuse_cells[] = {468	{469		.name = "xusb-pad-calibration",470		.offset = 0x0f0,471		.bytes = 4,472		.bit_offset = 0,473		.nbits = 32,474	}, {475		.name = "xusb-pad-calibration-ext",476		.offset = 0x250,477		.bytes = 4,478		.bit_offset = 0,479		.nbits = 32,480	},481};482 483static const struct nvmem_cell_lookup tegra186_fuse_lookups[] = {484	{485		.nvmem_name = "fuse",486		.cell_name = "xusb-pad-calibration",487		.dev_id = "3520000.padctl",488		.con_id = "calibration",489	}, {490		.nvmem_name = "fuse",491		.cell_name = "xusb-pad-calibration-ext",492		.dev_id = "3520000.padctl",493		.con_id = "calibration-ext",494	},495};496 497static const struct nvmem_keepout tegra186_fuse_keepouts[] = {498	{ .start = 0x01c, .end = 0x0f0 },499	{ .start = 0x138, .end = 0x198 },500	{ .start = 0x1d8, .end = 0x250 },501	{ .start = 0x280, .end = 0x290 },502	{ .start = 0x340, .end = 0x344 }503};504 505static const struct tegra_fuse_info tegra186_fuse_info = {506	.read = tegra30_fuse_read,507	.size = 0x478,508	.spare = 0x280,509};510 511const struct tegra_fuse_soc tegra186_fuse_soc = {512	.init = tegra30_fuse_init,513	.info = &tegra186_fuse_info,514	.lookups = tegra186_fuse_lookups,515	.num_lookups = ARRAY_SIZE(tegra186_fuse_lookups),516	.cells = tegra186_fuse_cells,517	.num_cells = ARRAY_SIZE(tegra186_fuse_cells),518	.keepouts = tegra186_fuse_keepouts,519	.num_keepouts = ARRAY_SIZE(tegra186_fuse_keepouts),520	.soc_attr_group = &tegra_soc_attr_group,521	.clk_suspend_on = false,522};523#endif524 525#if defined(CONFIG_ARCH_TEGRA_194_SOC)526static const struct nvmem_cell_info tegra194_fuse_cells[] = {527	{528		.name = "xusb-pad-calibration",529		.offset = 0x0f0,530		.bytes = 4,531		.bit_offset = 0,532		.nbits = 32,533	}, {534		.name = "gpu-gcplex-config-fuse",535		.offset = 0x1c8,536		.bytes = 4,537		.bit_offset = 0,538		.nbits = 32,539	}, {540		.name = "xusb-pad-calibration-ext",541		.offset = 0x250,542		.bytes = 4,543		.bit_offset = 0,544		.nbits = 32,545	}, {546		.name = "gpu-pdi0",547		.offset = 0x300,548		.bytes = 4,549		.bit_offset = 0,550		.nbits = 32,551	}, {552		.name = "gpu-pdi1",553		.offset = 0x304,554		.bytes = 4,555		.bit_offset = 0,556		.nbits = 32,557	},558};559 560static const struct nvmem_cell_lookup tegra194_fuse_lookups[] = {561	{562		.nvmem_name = "fuse",563		.cell_name = "xusb-pad-calibration",564		.dev_id = "3520000.padctl",565		.con_id = "calibration",566	}, {567		.nvmem_name = "fuse",568		.cell_name = "xusb-pad-calibration-ext",569		.dev_id = "3520000.padctl",570		.con_id = "calibration-ext",571	}, {572		.nvmem_name = "fuse",573		.cell_name = "gpu-gcplex-config-fuse",574		.dev_id = "17000000.gpu",575		.con_id = "gcplex-config-fuse",576	}, {577		.nvmem_name = "fuse",578		.cell_name = "gpu-pdi0",579		.dev_id = "17000000.gpu",580		.con_id = "pdi0",581	}, {582		.nvmem_name = "fuse",583		.cell_name = "gpu-pdi1",584		.dev_id = "17000000.gpu",585		.con_id = "pdi1",586	},587};588 589static const struct nvmem_keepout tegra194_fuse_keepouts[] = {590	{ .start = 0x01c, .end = 0x0b8 },591	{ .start = 0x12c, .end = 0x198 },592	{ .start = 0x1a0, .end = 0x1bc },593	{ .start = 0x1d8, .end = 0x250 },594	{ .start = 0x270, .end = 0x290 },595	{ .start = 0x310, .end = 0x45c }596};597 598static const struct tegra_fuse_info tegra194_fuse_info = {599	.read = tegra30_fuse_read,600	.size = 0x650,601	.spare = 0x280,602};603 604const struct tegra_fuse_soc tegra194_fuse_soc = {605	.init = tegra30_fuse_init,606	.info = &tegra194_fuse_info,607	.lookups = tegra194_fuse_lookups,608	.num_lookups = ARRAY_SIZE(tegra194_fuse_lookups),609	.cells = tegra194_fuse_cells,610	.num_cells = ARRAY_SIZE(tegra194_fuse_cells),611	.keepouts = tegra194_fuse_keepouts,612	.num_keepouts = ARRAY_SIZE(tegra194_fuse_keepouts),613	.soc_attr_group = &tegra194_soc_attr_group,614	.clk_suspend_on = false,615};616#endif617 618#if defined(CONFIG_ARCH_TEGRA_234_SOC)619static const struct nvmem_cell_info tegra234_fuse_cells[] = {620	{621		.name = "xusb-pad-calibration",622		.offset = 0x0f0,623		.bytes = 4,624		.bit_offset = 0,625		.nbits = 32,626	}, {627		.name = "xusb-pad-calibration-ext",628		.offset = 0x250,629		.bytes = 4,630		.bit_offset = 0,631		.nbits = 32,632	},633};634 635static const struct nvmem_cell_lookup tegra234_fuse_lookups[] = {636	{637		.nvmem_name = "fuse",638		.cell_name = "xusb-pad-calibration",639		.dev_id = "3520000.padctl",640		.con_id = "calibration",641	}, {642		.nvmem_name = "fuse",643		.cell_name = "xusb-pad-calibration-ext",644		.dev_id = "3520000.padctl",645		.con_id = "calibration-ext",646	},647};648 649static const struct nvmem_keepout tegra234_fuse_keepouts[] = {650	{ .start = 0x01c, .end = 0x0c8 },651	{ .start = 0x12c, .end = 0x184 },652	{ .start = 0x190, .end = 0x198 },653	{ .start = 0x1a0, .end = 0x204 },654	{ .start = 0x21c, .end = 0x250 },655	{ .start = 0x25c, .end = 0x2f0 },656	{ .start = 0x310, .end = 0x3d8 },657	{ .start = 0x400, .end = 0x4f0 },658	{ .start = 0x4f8, .end = 0x7e8 },659	{ .start = 0x8d0, .end = 0x8d8 },660	{ .start = 0xacc, .end = 0xf00 }661};662 663static const struct tegra_fuse_info tegra234_fuse_info = {664	.read = tegra30_fuse_read,665	.size = 0xf90,666	.spare = 0x280,667};668 669const struct tegra_fuse_soc tegra234_fuse_soc = {670	.init = tegra30_fuse_init,671	.info = &tegra234_fuse_info,672	.lookups = tegra234_fuse_lookups,673	.num_lookups = ARRAY_SIZE(tegra234_fuse_lookups),674	.cells = tegra234_fuse_cells,675	.num_cells = ARRAY_SIZE(tegra234_fuse_cells),676	.keepouts = tegra234_fuse_keepouts,677	.num_keepouts = ARRAY_SIZE(tegra234_fuse_keepouts),678	.soc_attr_group = &tegra194_soc_attr_group,679	.clk_suspend_on = false,680};681#endif682 683#if defined(CONFIG_ARCH_TEGRA_241_SOC)684static const struct tegra_fuse_info tegra241_fuse_info = {685	.read = tegra30_fuse_read,686	.size = 0x16008,687	.spare = 0xcf0,688};689 690static const struct nvmem_keepout tegra241_fuse_keepouts[] = {691	{ .start = 0xc, .end = 0x1600c }692};693 694const struct tegra_fuse_soc tegra241_fuse_soc = {695	.init = tegra30_fuse_init,696	.info = &tegra241_fuse_info,697	.keepouts = tegra241_fuse_keepouts,698	.num_keepouts = ARRAY_SIZE(tegra241_fuse_keepouts),699	.soc_attr_group = &tegra194_soc_attr_group,700};701#endif702