1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // Copyright (C) 2019 Spreadtrum Communications Inc. |
3 | |
4 | #include <linux/clk.h> |
5 | #include <linux/delay.h> |
6 | #include <linux/hwspinlock.h> |
7 | #include <linux/io.h> |
8 | #include <linux/module.h> |
9 | #include <linux/nvmem-provider.h> |
10 | #include <linux/of.h> |
11 | #include <linux/platform_device.h> |
12 | |
13 | #define SPRD_EFUSE_ENABLE 0x20 |
14 | #define SPRD_EFUSE_ERR_FLAG 0x24 |
15 | #define SPRD_EFUSE_ERR_CLR 0x28 |
16 | #define SPRD_EFUSE_MAGIC_NUM 0x2c |
17 | #define SPRD_EFUSE_FW_CFG 0x50 |
18 | #define SPRD_EFUSE_PW_SWT 0x54 |
19 | #define SPRD_EFUSE_MEM(val) (0x1000 + ((val) << 2)) |
20 | |
21 | #define SPRD_EFUSE_VDD_EN BIT(0) |
22 | #define SPRD_EFUSE_AUTO_CHECK_EN BIT(1) |
23 | #define SPRD_EFUSE_DOUBLE_EN BIT(2) |
24 | #define SPRD_EFUSE_MARGIN_RD_EN BIT(3) |
25 | #define SPRD_EFUSE_LOCK_WR_EN BIT(4) |
26 | |
27 | #define SPRD_EFUSE_ERR_CLR_MASK GENMASK(13, 0) |
28 | |
29 | #define SPRD_EFUSE_ENK1_ON BIT(0) |
30 | #define SPRD_EFUSE_ENK2_ON BIT(1) |
31 | #define SPRD_EFUSE_PROG_EN BIT(2) |
32 | |
33 | #define SPRD_EFUSE_MAGIC_NUMBER 0x8810 |
34 | |
35 | /* Block width (bytes) definitions */ |
36 | #define SPRD_EFUSE_BLOCK_WIDTH 4 |
37 | |
38 | /* |
39 | * The Spreadtrum AP efuse contains 2 parts: normal efuse and secure efuse, |
40 | * and we can only access the normal efuse in kernel. So define the normal |
41 | * block offset index and normal block numbers. |
42 | */ |
43 | #define SPRD_EFUSE_NORMAL_BLOCK_NUMS 24 |
44 | #define SPRD_EFUSE_NORMAL_BLOCK_OFFSET 72 |
45 | |
46 | /* Timeout (ms) for the trylock of hardware spinlocks */ |
47 | #define SPRD_EFUSE_HWLOCK_TIMEOUT 5000 |
48 | |
49 | /* |
50 | * Since different Spreadtrum SoC chip can have different normal block numbers |
51 | * and offset. And some SoC can support block double feature, which means |
52 | * when reading or writing data to efuse memory, the controller can save double |
53 | * data in case one data become incorrect after a long period. |
54 | * |
55 | * Thus we should save them in the device data structure. |
56 | */ |
57 | struct sprd_efuse_variant_data { |
58 | u32 blk_nums; |
59 | u32 blk_offset; |
60 | bool blk_double; |
61 | }; |
62 | |
63 | struct sprd_efuse { |
64 | struct device *dev; |
65 | struct clk *clk; |
66 | struct hwspinlock *hwlock; |
67 | struct mutex mutex; |
68 | void __iomem *base; |
69 | const struct sprd_efuse_variant_data *data; |
70 | }; |
71 | |
72 | static const struct sprd_efuse_variant_data ums312_data = { |
73 | .blk_nums = SPRD_EFUSE_NORMAL_BLOCK_NUMS, |
74 | .blk_offset = SPRD_EFUSE_NORMAL_BLOCK_OFFSET, |
75 | .blk_double = false, |
76 | }; |
77 | |
78 | /* |
79 | * On Spreadtrum platform, we have multi-subsystems will access the unique |
80 | * efuse controller, so we need one hardware spinlock to synchronize between |
81 | * the multiple subsystems. |
82 | */ |
83 | static int sprd_efuse_lock(struct sprd_efuse *efuse) |
84 | { |
85 | int ret; |
86 | |
87 | mutex_lock(&efuse->mutex); |
88 | |
89 | ret = hwspin_lock_timeout_raw(hwlock: efuse->hwlock, |
90 | SPRD_EFUSE_HWLOCK_TIMEOUT); |
91 | if (ret) { |
92 | dev_err(efuse->dev, "timeout get the hwspinlock\n" ); |
93 | mutex_unlock(lock: &efuse->mutex); |
94 | return ret; |
95 | } |
96 | |
97 | return 0; |
98 | } |
99 | |
100 | static void sprd_efuse_unlock(struct sprd_efuse *efuse) |
101 | { |
102 | hwspin_unlock_raw(hwlock: efuse->hwlock); |
103 | mutex_unlock(lock: &efuse->mutex); |
104 | } |
105 | |
106 | static void sprd_efuse_set_prog_power(struct sprd_efuse *efuse, bool en) |
107 | { |
108 | u32 val = readl(addr: efuse->base + SPRD_EFUSE_PW_SWT); |
109 | |
110 | if (en) |
111 | val &= ~SPRD_EFUSE_ENK2_ON; |
112 | else |
113 | val &= ~SPRD_EFUSE_ENK1_ON; |
114 | |
115 | writel(val, addr: efuse->base + SPRD_EFUSE_PW_SWT); |
116 | |
117 | /* Open or close efuse power need wait 1000us to make power stable. */ |
118 | usleep_range(min: 1000, max: 1200); |
119 | |
120 | if (en) |
121 | val |= SPRD_EFUSE_ENK1_ON; |
122 | else |
123 | val |= SPRD_EFUSE_ENK2_ON; |
124 | |
125 | writel(val, addr: efuse->base + SPRD_EFUSE_PW_SWT); |
126 | |
127 | /* Open or close efuse power need wait 1000us to make power stable. */ |
128 | usleep_range(min: 1000, max: 1200); |
129 | } |
130 | |
131 | static void sprd_efuse_set_read_power(struct sprd_efuse *efuse, bool en) |
132 | { |
133 | u32 val = readl(addr: efuse->base + SPRD_EFUSE_ENABLE); |
134 | |
135 | if (en) |
136 | val |= SPRD_EFUSE_VDD_EN; |
137 | else |
138 | val &= ~SPRD_EFUSE_VDD_EN; |
139 | |
140 | writel(val, addr: efuse->base + SPRD_EFUSE_ENABLE); |
141 | |
142 | /* Open or close efuse power need wait 1000us to make power stable. */ |
143 | usleep_range(min: 1000, max: 1200); |
144 | } |
145 | |
146 | static void sprd_efuse_set_prog_lock(struct sprd_efuse *efuse, bool en) |
147 | { |
148 | u32 val = readl(addr: efuse->base + SPRD_EFUSE_ENABLE); |
149 | |
150 | if (en) |
151 | val |= SPRD_EFUSE_LOCK_WR_EN; |
152 | else |
153 | val &= ~SPRD_EFUSE_LOCK_WR_EN; |
154 | |
155 | writel(val, addr: efuse->base + SPRD_EFUSE_ENABLE); |
156 | } |
157 | |
158 | static void sprd_efuse_set_auto_check(struct sprd_efuse *efuse, bool en) |
159 | { |
160 | u32 val = readl(addr: efuse->base + SPRD_EFUSE_ENABLE); |
161 | |
162 | if (en) |
163 | val |= SPRD_EFUSE_AUTO_CHECK_EN; |
164 | else |
165 | val &= ~SPRD_EFUSE_AUTO_CHECK_EN; |
166 | |
167 | writel(val, addr: efuse->base + SPRD_EFUSE_ENABLE); |
168 | } |
169 | |
170 | static void sprd_efuse_set_data_double(struct sprd_efuse *efuse, bool en) |
171 | { |
172 | u32 val = readl(addr: efuse->base + SPRD_EFUSE_ENABLE); |
173 | |
174 | if (en) |
175 | val |= SPRD_EFUSE_DOUBLE_EN; |
176 | else |
177 | val &= ~SPRD_EFUSE_DOUBLE_EN; |
178 | |
179 | writel(val, addr: efuse->base + SPRD_EFUSE_ENABLE); |
180 | } |
181 | |
182 | static void sprd_efuse_set_prog_en(struct sprd_efuse *efuse, bool en) |
183 | { |
184 | u32 val = readl(addr: efuse->base + SPRD_EFUSE_PW_SWT); |
185 | |
186 | if (en) |
187 | val |= SPRD_EFUSE_PROG_EN; |
188 | else |
189 | val &= ~SPRD_EFUSE_PROG_EN; |
190 | |
191 | writel(val, addr: efuse->base + SPRD_EFUSE_PW_SWT); |
192 | } |
193 | |
194 | static int sprd_efuse_raw_prog(struct sprd_efuse *efuse, u32 blk, bool doub, |
195 | bool lock, u32 *data) |
196 | { |
197 | u32 status; |
198 | int ret = 0; |
199 | |
200 | /* |
201 | * We need set the correct magic number before writing the efuse to |
202 | * allow programming, and block other programming until we clear the |
203 | * magic number. |
204 | */ |
205 | writel(SPRD_EFUSE_MAGIC_NUMBER, |
206 | addr: efuse->base + SPRD_EFUSE_MAGIC_NUM); |
207 | |
208 | /* |
209 | * Power on the efuse, enable programme and enable double data |
210 | * if asked. |
211 | */ |
212 | sprd_efuse_set_prog_power(efuse, en: true); |
213 | sprd_efuse_set_prog_en(efuse, en: true); |
214 | sprd_efuse_set_data_double(efuse, en: doub); |
215 | |
216 | /* |
217 | * Enable the auto-check function to validate if the programming is |
218 | * successful. |
219 | */ |
220 | if (lock) |
221 | sprd_efuse_set_auto_check(efuse, en: true); |
222 | |
223 | writel(val: *data, addr: efuse->base + SPRD_EFUSE_MEM(blk)); |
224 | |
225 | /* Disable auto-check and data double after programming */ |
226 | if (lock) |
227 | sprd_efuse_set_auto_check(efuse, en: false); |
228 | sprd_efuse_set_data_double(efuse, en: false); |
229 | |
230 | /* |
231 | * Check the efuse error status, if the programming is successful, |
232 | * we should lock this efuse block to avoid programming again. |
233 | */ |
234 | status = readl(addr: efuse->base + SPRD_EFUSE_ERR_FLAG); |
235 | if (status) { |
236 | dev_err(efuse->dev, |
237 | "write error status %u of block %d\n" , status, blk); |
238 | |
239 | writel(SPRD_EFUSE_ERR_CLR_MASK, |
240 | addr: efuse->base + SPRD_EFUSE_ERR_CLR); |
241 | ret = -EBUSY; |
242 | } else if (lock) { |
243 | sprd_efuse_set_prog_lock(efuse, en: lock); |
244 | writel(val: 0, addr: efuse->base + SPRD_EFUSE_MEM(blk)); |
245 | sprd_efuse_set_prog_lock(efuse, en: false); |
246 | } |
247 | |
248 | sprd_efuse_set_prog_power(efuse, en: false); |
249 | writel(val: 0, addr: efuse->base + SPRD_EFUSE_MAGIC_NUM); |
250 | |
251 | return ret; |
252 | } |
253 | |
254 | static int sprd_efuse_raw_read(struct sprd_efuse *efuse, int blk, u32 *val, |
255 | bool doub) |
256 | { |
257 | u32 status; |
258 | |
259 | /* |
260 | * Need power on the efuse before reading data from efuse, and will |
261 | * power off the efuse after reading process. |
262 | */ |
263 | sprd_efuse_set_read_power(efuse, en: true); |
264 | |
265 | /* Enable double data if asked */ |
266 | sprd_efuse_set_data_double(efuse, en: doub); |
267 | |
268 | /* Start to read data from efuse block */ |
269 | *val = readl(addr: efuse->base + SPRD_EFUSE_MEM(blk)); |
270 | |
271 | /* Disable double data */ |
272 | sprd_efuse_set_data_double(efuse, en: false); |
273 | |
274 | /* Power off the efuse */ |
275 | sprd_efuse_set_read_power(efuse, en: false); |
276 | |
277 | /* |
278 | * Check the efuse error status and clear them if there are some |
279 | * errors occurred. |
280 | */ |
281 | status = readl(addr: efuse->base + SPRD_EFUSE_ERR_FLAG); |
282 | if (status) { |
283 | dev_err(efuse->dev, |
284 | "read error status %d of block %d\n" , status, blk); |
285 | |
286 | writel(SPRD_EFUSE_ERR_CLR_MASK, |
287 | addr: efuse->base + SPRD_EFUSE_ERR_CLR); |
288 | return -EBUSY; |
289 | } |
290 | |
291 | return 0; |
292 | } |
293 | |
294 | static int sprd_efuse_read(void *context, u32 offset, void *val, size_t bytes) |
295 | { |
296 | struct sprd_efuse *efuse = context; |
297 | bool blk_double = efuse->data->blk_double; |
298 | u32 index = offset / SPRD_EFUSE_BLOCK_WIDTH + efuse->data->blk_offset; |
299 | u32 blk_offset = (offset % SPRD_EFUSE_BLOCK_WIDTH) * BITS_PER_BYTE; |
300 | u32 data; |
301 | int ret; |
302 | |
303 | ret = sprd_efuse_lock(efuse); |
304 | if (ret) |
305 | return ret; |
306 | |
307 | ret = clk_prepare_enable(clk: efuse->clk); |
308 | if (ret) |
309 | goto unlock; |
310 | |
311 | ret = sprd_efuse_raw_read(efuse, blk: index, val: &data, doub: blk_double); |
312 | if (!ret) { |
313 | data >>= blk_offset; |
314 | memcpy(val, &data, bytes); |
315 | } |
316 | |
317 | clk_disable_unprepare(clk: efuse->clk); |
318 | |
319 | unlock: |
320 | sprd_efuse_unlock(efuse); |
321 | return ret; |
322 | } |
323 | |
324 | static int sprd_efuse_write(void *context, u32 offset, void *val, size_t bytes) |
325 | { |
326 | struct sprd_efuse *efuse = context; |
327 | bool blk_double = efuse->data->blk_double; |
328 | bool lock; |
329 | int ret; |
330 | |
331 | ret = sprd_efuse_lock(efuse); |
332 | if (ret) |
333 | return ret; |
334 | |
335 | ret = clk_prepare_enable(clk: efuse->clk); |
336 | if (ret) |
337 | goto unlock; |
338 | |
339 | /* |
340 | * If the writing bytes are equal with the block width, which means the |
341 | * whole block will be programmed. For this case, we should not allow |
342 | * this block to be programmed again by locking this block. |
343 | * |
344 | * If the block was programmed partially, we should allow this block to |
345 | * be programmed again. |
346 | */ |
347 | if (bytes < SPRD_EFUSE_BLOCK_WIDTH) |
348 | lock = false; |
349 | else |
350 | lock = true; |
351 | |
352 | ret = sprd_efuse_raw_prog(efuse, blk: offset, doub: blk_double, lock, data: val); |
353 | |
354 | clk_disable_unprepare(clk: efuse->clk); |
355 | |
356 | unlock: |
357 | sprd_efuse_unlock(efuse); |
358 | return ret; |
359 | } |
360 | |
361 | static int sprd_efuse_probe(struct platform_device *pdev) |
362 | { |
363 | struct device_node *np = pdev->dev.of_node; |
364 | struct nvmem_device *nvmem; |
365 | struct nvmem_config econfig = { }; |
366 | struct sprd_efuse *efuse; |
367 | const struct sprd_efuse_variant_data *pdata; |
368 | int ret; |
369 | |
370 | pdata = of_device_get_match_data(dev: &pdev->dev); |
371 | if (!pdata) { |
372 | dev_err(&pdev->dev, "No matching driver data found\n" ); |
373 | return -EINVAL; |
374 | } |
375 | |
376 | efuse = devm_kzalloc(dev: &pdev->dev, size: sizeof(*efuse), GFP_KERNEL); |
377 | if (!efuse) |
378 | return -ENOMEM; |
379 | |
380 | efuse->base = devm_platform_ioremap_resource(pdev, index: 0); |
381 | if (IS_ERR(ptr: efuse->base)) |
382 | return PTR_ERR(ptr: efuse->base); |
383 | |
384 | ret = of_hwspin_lock_get_id(np, index: 0); |
385 | if (ret < 0) { |
386 | dev_err(&pdev->dev, "failed to get hwlock id\n" ); |
387 | return ret; |
388 | } |
389 | |
390 | efuse->hwlock = devm_hwspin_lock_request_specific(dev: &pdev->dev, id: ret); |
391 | if (!efuse->hwlock) { |
392 | dev_err(&pdev->dev, "failed to request hwlock\n" ); |
393 | return -ENXIO; |
394 | } |
395 | |
396 | efuse->clk = devm_clk_get(dev: &pdev->dev, id: "enable" ); |
397 | if (IS_ERR(ptr: efuse->clk)) { |
398 | dev_err(&pdev->dev, "failed to get enable clock\n" ); |
399 | return PTR_ERR(ptr: efuse->clk); |
400 | } |
401 | |
402 | mutex_init(&efuse->mutex); |
403 | efuse->dev = &pdev->dev; |
404 | efuse->data = pdata; |
405 | |
406 | econfig.stride = 1; |
407 | econfig.word_size = 1; |
408 | econfig.read_only = false; |
409 | econfig.name = "sprd-efuse" ; |
410 | econfig.size = efuse->data->blk_nums * SPRD_EFUSE_BLOCK_WIDTH; |
411 | econfig.add_legacy_fixed_of_cells = true; |
412 | econfig.reg_read = sprd_efuse_read; |
413 | econfig.reg_write = sprd_efuse_write; |
414 | econfig.priv = efuse; |
415 | econfig.dev = &pdev->dev; |
416 | nvmem = devm_nvmem_register(dev: &pdev->dev, cfg: &econfig); |
417 | if (IS_ERR(ptr: nvmem)) { |
418 | dev_err(&pdev->dev, "failed to register nvmem\n" ); |
419 | return PTR_ERR(ptr: nvmem); |
420 | } |
421 | |
422 | return 0; |
423 | } |
424 | |
425 | static const struct of_device_id sprd_efuse_of_match[] = { |
426 | { .compatible = "sprd,ums312-efuse" , .data = &ums312_data }, |
427 | { } |
428 | }; |
429 | |
430 | static struct platform_driver sprd_efuse_driver = { |
431 | .probe = sprd_efuse_probe, |
432 | .driver = { |
433 | .name = "sprd-efuse" , |
434 | .of_match_table = sprd_efuse_of_match, |
435 | }, |
436 | }; |
437 | |
438 | module_platform_driver(sprd_efuse_driver); |
439 | |
440 | MODULE_AUTHOR("Freeman Liu <freeman.liu@spreadtrum.com>" ); |
441 | MODULE_DESCRIPTION("Spreadtrum AP efuse driver" ); |
442 | MODULE_LICENSE("GPL v2" ); |
443 | |