1c3600e1fSPatrick Delaunay // SPDX-License-Identifier: GPL-2.0+
2c3600e1fSPatrick Delaunay /*
3c3600e1fSPatrick Delaunay * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
4c3600e1fSPatrick Delaunay */
5c3600e1fSPatrick Delaunay
6c3600e1fSPatrick Delaunay #include <common.h>
7c3600e1fSPatrick Delaunay #include <command.h>
8c3600e1fSPatrick Delaunay #include <misc.h>
9c3600e1fSPatrick Delaunay #include <errno.h>
10c3600e1fSPatrick Delaunay #include <dm/device.h>
11c3600e1fSPatrick Delaunay #include <dm/uclass.h>
12c3600e1fSPatrick Delaunay
13c3600e1fSPatrick Delaunay #define STM32MP_OTP_BANK 0
14c3600e1fSPatrick Delaunay
15c3600e1fSPatrick Delaunay /*
16c3600e1fSPatrick Delaunay * The 'fuse' command API
17c3600e1fSPatrick Delaunay */
fuse_read(u32 bank,u32 word,u32 * val)18c3600e1fSPatrick Delaunay int fuse_read(u32 bank, u32 word, u32 *val)
19c3600e1fSPatrick Delaunay {
20c3600e1fSPatrick Delaunay int ret = 0;
21c3600e1fSPatrick Delaunay struct udevice *dev;
22c3600e1fSPatrick Delaunay
23c3600e1fSPatrick Delaunay switch (bank) {
24c3600e1fSPatrick Delaunay case STM32MP_OTP_BANK:
25c3600e1fSPatrick Delaunay ret = uclass_get_device_by_driver(UCLASS_MISC,
26c3600e1fSPatrick Delaunay DM_GET_DRIVER(stm32mp_bsec),
27c3600e1fSPatrick Delaunay &dev);
28c3600e1fSPatrick Delaunay if (ret)
29c3600e1fSPatrick Delaunay return ret;
30c3600e1fSPatrick Delaunay ret = misc_read(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,
31c3600e1fSPatrick Delaunay val, 4);
32*8729b1aeSSimon Glass if (ret < 0)
33*8729b1aeSSimon Glass return ret;
34*8729b1aeSSimon Glass ret = 0;
35c3600e1fSPatrick Delaunay break;
36c3600e1fSPatrick Delaunay
37c3600e1fSPatrick Delaunay default:
38c3600e1fSPatrick Delaunay printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
39c3600e1fSPatrick Delaunay ret = -EINVAL;
40c3600e1fSPatrick Delaunay break;
41c3600e1fSPatrick Delaunay }
42c3600e1fSPatrick Delaunay
43c3600e1fSPatrick Delaunay return ret;
44c3600e1fSPatrick Delaunay }
45c3600e1fSPatrick Delaunay
fuse_prog(u32 bank,u32 word,u32 val)46c3600e1fSPatrick Delaunay int fuse_prog(u32 bank, u32 word, u32 val)
47c3600e1fSPatrick Delaunay {
48c3600e1fSPatrick Delaunay struct udevice *dev;
49c3600e1fSPatrick Delaunay int ret;
50c3600e1fSPatrick Delaunay
51c3600e1fSPatrick Delaunay switch (bank) {
52c3600e1fSPatrick Delaunay case STM32MP_OTP_BANK:
53c3600e1fSPatrick Delaunay ret = uclass_get_device_by_driver(UCLASS_MISC,
54c3600e1fSPatrick Delaunay DM_GET_DRIVER(stm32mp_bsec),
55c3600e1fSPatrick Delaunay &dev);
56c3600e1fSPatrick Delaunay if (ret)
57c3600e1fSPatrick Delaunay return ret;
58c3600e1fSPatrick Delaunay ret = misc_write(dev, word * 4 + STM32_BSEC_OTP_OFFSET,
59c3600e1fSPatrick Delaunay &val, 4);
60*8729b1aeSSimon Glass if (ret < 0)
61*8729b1aeSSimon Glass return ret;
62*8729b1aeSSimon Glass ret = 0;
63c3600e1fSPatrick Delaunay break;
64c3600e1fSPatrick Delaunay
65c3600e1fSPatrick Delaunay default:
66c3600e1fSPatrick Delaunay printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
67c3600e1fSPatrick Delaunay ret = -EINVAL;
68c3600e1fSPatrick Delaunay break;
69c3600e1fSPatrick Delaunay }
70c3600e1fSPatrick Delaunay
71c3600e1fSPatrick Delaunay return ret;
72c3600e1fSPatrick Delaunay }
73c3600e1fSPatrick Delaunay
fuse_sense(u32 bank,u32 word,u32 * val)74c3600e1fSPatrick Delaunay int fuse_sense(u32 bank, u32 word, u32 *val)
75c3600e1fSPatrick Delaunay {
76c3600e1fSPatrick Delaunay struct udevice *dev;
77c3600e1fSPatrick Delaunay int ret;
78c3600e1fSPatrick Delaunay
79c3600e1fSPatrick Delaunay switch (bank) {
80c3600e1fSPatrick Delaunay case STM32MP_OTP_BANK:
81c3600e1fSPatrick Delaunay ret = uclass_get_device_by_driver(UCLASS_MISC,
82c3600e1fSPatrick Delaunay DM_GET_DRIVER(stm32mp_bsec),
83c3600e1fSPatrick Delaunay &dev);
84c3600e1fSPatrick Delaunay if (ret)
85c3600e1fSPatrick Delaunay return ret;
86c3600e1fSPatrick Delaunay ret = misc_read(dev, word * 4 + STM32_BSEC_OTP_OFFSET, val, 4);
87*8729b1aeSSimon Glass if (ret < 0)
88*8729b1aeSSimon Glass return ret;
89*8729b1aeSSimon Glass ret = 0;
90c3600e1fSPatrick Delaunay break;
91c3600e1fSPatrick Delaunay
92c3600e1fSPatrick Delaunay default:
93c3600e1fSPatrick Delaunay printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
94c3600e1fSPatrick Delaunay ret = -EINVAL;
95c3600e1fSPatrick Delaunay break;
96c3600e1fSPatrick Delaunay }
97c3600e1fSPatrick Delaunay
98c3600e1fSPatrick Delaunay return ret;
99c3600e1fSPatrick Delaunay }
100c3600e1fSPatrick Delaunay
fuse_override(u32 bank,u32 word,u32 val)101c3600e1fSPatrick Delaunay int fuse_override(u32 bank, u32 word, u32 val)
102c3600e1fSPatrick Delaunay {
103c3600e1fSPatrick Delaunay struct udevice *dev;
104c3600e1fSPatrick Delaunay int ret;
105c3600e1fSPatrick Delaunay
106c3600e1fSPatrick Delaunay switch (bank) {
107c3600e1fSPatrick Delaunay case STM32MP_OTP_BANK:
108c3600e1fSPatrick Delaunay ret = uclass_get_device_by_driver(UCLASS_MISC,
109c3600e1fSPatrick Delaunay DM_GET_DRIVER(stm32mp_bsec),
110c3600e1fSPatrick Delaunay &dev);
111c3600e1fSPatrick Delaunay if (ret)
112c3600e1fSPatrick Delaunay return ret;
113c3600e1fSPatrick Delaunay ret = misc_write(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,
114c3600e1fSPatrick Delaunay &val, 4);
115*8729b1aeSSimon Glass if (ret < 0)
116*8729b1aeSSimon Glass return ret;
117*8729b1aeSSimon Glass ret = 0;
118c3600e1fSPatrick Delaunay break;
119c3600e1fSPatrick Delaunay
120c3600e1fSPatrick Delaunay default:
121c3600e1fSPatrick Delaunay printf("stm32mp %s: wrong value for bank %i\n",
122c3600e1fSPatrick Delaunay __func__, bank);
123c3600e1fSPatrick Delaunay ret = -EINVAL;
124c3600e1fSPatrick Delaunay break;
125c3600e1fSPatrick Delaunay }
126c3600e1fSPatrick Delaunay
127c3600e1fSPatrick Delaunay return ret;
128c3600e1fSPatrick Delaunay }
129