stpmic1: add NVM update support in fuse command
[oweals/u-boot.git] / drivers / misc / stm32mp_fuse.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
4  */
5
6 #include <common.h>
7 #include <command.h>
8 #include <misc.h>
9 #include <errno.h>
10 #include <dm/device.h>
11 #include <dm/uclass.h>
12 #include <power/stpmic1.h>
13
14 #define STM32MP_OTP_BANK        0
15 #define STM32MP_NVM_BANK        1
16
17 /*
18  * The 'fuse' command API
19  */
20 int fuse_read(u32 bank, u32 word, u32 *val)
21 {
22         int ret = 0;
23         struct udevice *dev;
24
25         switch (bank) {
26         case STM32MP_OTP_BANK:
27                 ret = uclass_get_device_by_driver(UCLASS_MISC,
28                                                   DM_GET_DRIVER(stm32mp_bsec),
29                                                   &dev);
30                 if (ret)
31                         return ret;
32                 ret = misc_read(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,
33                                 val, 4);
34                 if (ret < 0)
35                         return ret;
36                 ret = 0;
37                 break;
38
39 #ifdef CONFIG_PMIC_STPMIC1
40         case STM32MP_NVM_BANK:
41                 *val = 0;
42                 ret = stpmic1_shadow_read_byte(word, (u8 *)val);
43                 break;
44 #endif /* CONFIG_PMIC_STPMIC1 */
45
46         default:
47                 printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
48                 ret = -EINVAL;
49                 break;
50         }
51
52         return ret;
53 }
54
55 int fuse_prog(u32 bank, u32 word, u32 val)
56 {
57         struct udevice *dev;
58         int ret;
59
60         switch (bank) {
61         case STM32MP_OTP_BANK:
62                 ret = uclass_get_device_by_driver(UCLASS_MISC,
63                                                   DM_GET_DRIVER(stm32mp_bsec),
64                                                   &dev);
65                 if (ret)
66                         return ret;
67                 ret = misc_write(dev, word * 4 + STM32_BSEC_OTP_OFFSET,
68                                  &val, 4);
69                 if (ret < 0)
70                         return ret;
71                 ret = 0;
72                 break;
73
74 #ifdef CONFIG_PMIC_STPMIC1
75         case STM32MP_NVM_BANK:
76                 ret = stpmic1_nvm_write_byte(word, (u8 *)&val);
77                 break;
78 #endif /* CONFIG_PMIC_STPMIC1 */
79
80         default:
81                 printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
82                 ret = -EINVAL;
83                 break;
84         }
85
86         return ret;
87 }
88
89 int fuse_sense(u32 bank, u32 word, u32 *val)
90 {
91         struct udevice *dev;
92         int ret;
93
94         switch (bank) {
95         case STM32MP_OTP_BANK:
96                 ret = uclass_get_device_by_driver(UCLASS_MISC,
97                                                   DM_GET_DRIVER(stm32mp_bsec),
98                                                   &dev);
99                 if (ret)
100                         return ret;
101                 ret = misc_read(dev, word * 4 + STM32_BSEC_OTP_OFFSET, val, 4);
102                 if (ret < 0)
103                         return ret;
104                 ret = 0;
105                 break;
106
107 #ifdef CONFIG_PMIC_STPMIC1
108         case STM32MP_NVM_BANK:
109                 *val = 0;
110                 ret = stpmic1_nvm_read_byte(word, (u8 *)val);
111                 break;
112 #endif /* CONFIG_PMIC_STPMIC1 */
113
114         default:
115                 printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
116                 ret = -EINVAL;
117                 break;
118         }
119
120         return ret;
121 }
122
123 int fuse_override(u32 bank, u32 word, u32 val)
124 {
125         struct udevice *dev;
126         int ret;
127
128         switch (bank) {
129         case STM32MP_OTP_BANK:
130                 ret = uclass_get_device_by_driver(UCLASS_MISC,
131                                                   DM_GET_DRIVER(stm32mp_bsec),
132                                                   &dev);
133                 if (ret)
134                         return ret;
135                 ret = misc_write(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,
136                                  &val, 4);
137                 if (ret < 0)
138                         return ret;
139                 ret = 0;
140                 break;
141
142 #ifdef CONFIG_PMIC_STPMIC1
143         case STM32MP_NVM_BANK:
144                 ret = stpmic1_shadow_write_byte(word, (u8 *)&val);
145                 break;
146 #endif /* CONFIG_PMIC_STPMIC1 */
147
148         default:
149                 printf("stm32mp %s: wrong value for bank %i\n",
150                        __func__, bank);
151                 ret = -EINVAL;
152                 break;
153         }
154
155         return ret;
156 }