gpio: rcar: Fix runtime PM imbalance on error
[linux/fpc-iii.git] / drivers / soc / tegra / fuse / fuse-tegra30.c
blobe6037f900fb70ab31884be5f0cc48cd2c6e4aed3
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
4 */
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/random.h>
17 #include <soc/tegra/fuse.h>
19 #include "fuse.h"
21 #define FUSE_BEGIN 0x100
23 /* Tegra30 and later */
24 #define FUSE_VENDOR_CODE 0x100
25 #define FUSE_FAB_CODE 0x104
26 #define FUSE_LOT_CODE_0 0x108
27 #define FUSE_LOT_CODE_1 0x10c
28 #define FUSE_WAFER_ID 0x110
29 #define FUSE_X_COORDINATE 0x114
30 #define FUSE_Y_COORDINATE 0x118
32 #define FUSE_HAS_REVISION_INFO BIT(0)
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 static u32 tegra30_fuse_read_early(struct tegra_fuse *fuse, unsigned int offset)
43 if (WARN_ON(!fuse->base))
44 return 0;
46 return readl_relaxed(fuse->base + FUSE_BEGIN + offset);
49 static u32 tegra30_fuse_read(struct tegra_fuse *fuse, unsigned int offset)
51 u32 value;
52 int err;
54 err = clk_prepare_enable(fuse->clk);
55 if (err < 0) {
56 dev_err(fuse->dev, "failed to enable FUSE clock: %d\n", err);
57 return 0;
60 value = readl_relaxed(fuse->base + FUSE_BEGIN + offset);
62 clk_disable_unprepare(fuse->clk);
64 return value;
67 static void __init tegra30_fuse_add_randomness(void)
69 u32 randomness[12];
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);
86 add_device_randomness(randomness, sizeof(randomness));
89 static void __init tegra30_fuse_init(struct tegra_fuse *fuse)
91 fuse->read_early = tegra30_fuse_read_early;
92 fuse->read = tegra30_fuse_read;
94 tegra_init_revision();
96 if (fuse->soc->speedo_init)
97 fuse->soc->speedo_init(&tegra_sku_info);
99 tegra30_fuse_add_randomness();
101 #endif
103 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
104 static const struct tegra_fuse_info tegra30_fuse_info = {
105 .read = tegra30_fuse_read,
106 .size = 0x2a4,
107 .spare = 0x144,
110 const struct tegra_fuse_soc tegra30_fuse_soc = {
111 .init = tegra30_fuse_init,
112 .speedo_init = tegra30_init_speedo_data,
113 .info = &tegra30_fuse_info,
115 #endif
117 #ifdef CONFIG_ARCH_TEGRA_114_SOC
118 static const struct tegra_fuse_info tegra114_fuse_info = {
119 .read = tegra30_fuse_read,
120 .size = 0x2a0,
121 .spare = 0x180,
124 const struct tegra_fuse_soc tegra114_fuse_soc = {
125 .init = tegra30_fuse_init,
126 .speedo_init = tegra114_init_speedo_data,
127 .info = &tegra114_fuse_info,
129 #endif
131 #if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC)
132 static const struct nvmem_cell_lookup tegra124_fuse_lookups[] = {
134 .nvmem_name = "fuse",
135 .cell_name = "xusb-pad-calibration",
136 .dev_id = "7009f000.padctl",
137 .con_id = "calibration",
138 }, {
139 .nvmem_name = "fuse",
140 .cell_name = "sata-calibration",
141 .dev_id = "70020000.sata",
142 .con_id = "calibration",
143 }, {
144 .nvmem_name = "fuse",
145 .cell_name = "tsensor-common",
146 .dev_id = "700e2000.thermal-sensor",
147 .con_id = "common",
148 }, {
149 .nvmem_name = "fuse",
150 .cell_name = "tsensor-realignment",
151 .dev_id = "700e2000.thermal-sensor",
152 .con_id = "realignment",
153 }, {
154 .nvmem_name = "fuse",
155 .cell_name = "tsensor-cpu0",
156 .dev_id = "700e2000.thermal-sensor",
157 .con_id = "cpu0",
158 }, {
159 .nvmem_name = "fuse",
160 .cell_name = "tsensor-cpu1",
161 .dev_id = "700e2000.thermal-sensor",
162 .con_id = "cpu1",
163 }, {
164 .nvmem_name = "fuse",
165 .cell_name = "tsensor-cpu2",
166 .dev_id = "700e2000.thermal-sensor",
167 .con_id = "cpu2",
168 }, {
169 .nvmem_name = "fuse",
170 .cell_name = "tsensor-cpu3",
171 .dev_id = "700e2000.thermal-sensor",
172 .con_id = "cpu3",
173 }, {
174 .nvmem_name = "fuse",
175 .cell_name = "tsensor-mem0",
176 .dev_id = "700e2000.thermal-sensor",
177 .con_id = "mem0",
178 }, {
179 .nvmem_name = "fuse",
180 .cell_name = "tsensor-mem1",
181 .dev_id = "700e2000.thermal-sensor",
182 .con_id = "mem1",
183 }, {
184 .nvmem_name = "fuse",
185 .cell_name = "tsensor-gpu",
186 .dev_id = "700e2000.thermal-sensor",
187 .con_id = "gpu",
188 }, {
189 .nvmem_name = "fuse",
190 .cell_name = "tsensor-pllx",
191 .dev_id = "700e2000.thermal-sensor",
192 .con_id = "pllx",
196 static const struct tegra_fuse_info tegra124_fuse_info = {
197 .read = tegra30_fuse_read,
198 .size = 0x300,
199 .spare = 0x200,
202 const struct tegra_fuse_soc tegra124_fuse_soc = {
203 .init = tegra30_fuse_init,
204 .speedo_init = tegra124_init_speedo_data,
205 .info = &tegra124_fuse_info,
206 .lookups = tegra124_fuse_lookups,
207 .num_lookups = ARRAY_SIZE(tegra124_fuse_lookups),
209 #endif
211 #if defined(CONFIG_ARCH_TEGRA_210_SOC)
212 static const struct nvmem_cell_lookup tegra210_fuse_lookups[] = {
214 .nvmem_name = "fuse",
215 .cell_name = "tsensor-cpu1",
216 .dev_id = "700e2000.thermal-sensor",
217 .con_id = "cpu1",
218 }, {
219 .nvmem_name = "fuse",
220 .cell_name = "tsensor-cpu2",
221 .dev_id = "700e2000.thermal-sensor",
222 .con_id = "cpu2",
223 }, {
224 .nvmem_name = "fuse",
225 .cell_name = "tsensor-cpu0",
226 .dev_id = "700e2000.thermal-sensor",
227 .con_id = "cpu0",
228 }, {
229 .nvmem_name = "fuse",
230 .cell_name = "xusb-pad-calibration",
231 .dev_id = "7009f000.padctl",
232 .con_id = "calibration",
233 }, {
234 .nvmem_name = "fuse",
235 .cell_name = "tsensor-cpu3",
236 .dev_id = "700e2000.thermal-sensor",
237 .con_id = "cpu3",
238 }, {
239 .nvmem_name = "fuse",
240 .cell_name = "sata-calibration",
241 .dev_id = "70020000.sata",
242 .con_id = "calibration",
243 }, {
244 .nvmem_name = "fuse",
245 .cell_name = "tsensor-gpu",
246 .dev_id = "700e2000.thermal-sensor",
247 .con_id = "gpu",
248 }, {
249 .nvmem_name = "fuse",
250 .cell_name = "tsensor-mem0",
251 .dev_id = "700e2000.thermal-sensor",
252 .con_id = "mem0",
253 }, {
254 .nvmem_name = "fuse",
255 .cell_name = "tsensor-mem1",
256 .dev_id = "700e2000.thermal-sensor",
257 .con_id = "mem1",
258 }, {
259 .nvmem_name = "fuse",
260 .cell_name = "tsensor-pllx",
261 .dev_id = "700e2000.thermal-sensor",
262 .con_id = "pllx",
263 }, {
264 .nvmem_name = "fuse",
265 .cell_name = "tsensor-common",
266 .dev_id = "700e2000.thermal-sensor",
267 .con_id = "common",
268 }, {
269 .nvmem_name = "fuse",
270 .cell_name = "gpu-calibration",
271 .dev_id = "57000000.gpu",
272 .con_id = "calibration",
273 }, {
274 .nvmem_name = "fuse",
275 .cell_name = "xusb-pad-calibration-ext",
276 .dev_id = "7009f000.padctl",
277 .con_id = "calibration-ext",
281 static const struct tegra_fuse_info tegra210_fuse_info = {
282 .read = tegra30_fuse_read,
283 .size = 0x300,
284 .spare = 0x280,
287 const struct tegra_fuse_soc tegra210_fuse_soc = {
288 .init = tegra30_fuse_init,
289 .speedo_init = tegra210_init_speedo_data,
290 .info = &tegra210_fuse_info,
291 .lookups = tegra210_fuse_lookups,
292 .num_lookups = ARRAY_SIZE(tegra210_fuse_lookups),
294 #endif
296 #if defined(CONFIG_ARCH_TEGRA_186_SOC)
297 static const struct nvmem_cell_lookup tegra186_fuse_lookups[] = {
299 .nvmem_name = "fuse",
300 .cell_name = "xusb-pad-calibration",
301 .dev_id = "3520000.padctl",
302 .con_id = "calibration",
303 }, {
304 .nvmem_name = "fuse",
305 .cell_name = "xusb-pad-calibration-ext",
306 .dev_id = "3520000.padctl",
307 .con_id = "calibration-ext",
311 static const struct tegra_fuse_info tegra186_fuse_info = {
312 .read = tegra30_fuse_read,
313 .size = 0x300,
314 .spare = 0x280,
317 const struct tegra_fuse_soc tegra186_fuse_soc = {
318 .init = tegra30_fuse_init,
319 .info = &tegra186_fuse_info,
320 .lookups = tegra186_fuse_lookups,
321 .num_lookups = ARRAY_SIZE(tegra186_fuse_lookups),
323 #endif
325 #if defined(CONFIG_ARCH_TEGRA_194_SOC)
326 static const struct nvmem_cell_lookup tegra194_fuse_lookups[] = {
328 .nvmem_name = "fuse",
329 .cell_name = "xusb-pad-calibration",
330 .dev_id = "3520000.padctl",
331 .con_id = "calibration",
332 }, {
333 .nvmem_name = "fuse",
334 .cell_name = "xusb-pad-calibration-ext",
335 .dev_id = "3520000.padctl",
336 .con_id = "calibration-ext",
340 static const struct tegra_fuse_info tegra194_fuse_info = {
341 .read = tegra30_fuse_read,
342 .size = 0x300,
343 .spare = 0x280,
346 const struct tegra_fuse_soc tegra194_fuse_soc = {
347 .init = tegra30_fuse_init,
348 .info = &tegra194_fuse_info,
349 .lookups = tegra194_fuse_lookups,
350 .num_lookups = ARRAY_SIZE(tegra194_fuse_lookups),
352 #endif