Merge branch 'master' of git://git.denx.de/u-boot-sunxi
[platform/kernel/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
13 #define STM32MP_OTP_BANK        0
14
15 /*
16  * The 'fuse' command API
17  */
18 int fuse_read(u32 bank, u32 word, u32 *val)
19 {
20         int ret = 0;
21         struct udevice *dev;
22
23         switch (bank) {
24         case STM32MP_OTP_BANK:
25                 ret = uclass_get_device_by_driver(UCLASS_MISC,
26                                                   DM_GET_DRIVER(stm32mp_bsec),
27                                                   &dev);
28                 if (ret)
29                         return ret;
30                 ret = misc_read(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,
31                                 val, 4);
32                 break;
33
34         default:
35                 printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
36                 ret = -EINVAL;
37                 break;
38         }
39
40         return ret;
41 }
42
43 int fuse_prog(u32 bank, u32 word, u32 val)
44 {
45         struct udevice *dev;
46         int ret;
47
48         switch (bank) {
49         case STM32MP_OTP_BANK:
50                 ret = uclass_get_device_by_driver(UCLASS_MISC,
51                                                   DM_GET_DRIVER(stm32mp_bsec),
52                                                   &dev);
53                 if (ret)
54                         return ret;
55                 ret = misc_write(dev, word * 4 + STM32_BSEC_OTP_OFFSET,
56                                  &val, 4);
57                 break;
58
59         default:
60                 printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
61                 ret = -EINVAL;
62                 break;
63         }
64
65         return ret;
66 }
67
68 int fuse_sense(u32 bank, u32 word, u32 *val)
69 {
70         struct udevice *dev;
71         int ret;
72
73         switch (bank) {
74         case STM32MP_OTP_BANK:
75                 ret = uclass_get_device_by_driver(UCLASS_MISC,
76                                                   DM_GET_DRIVER(stm32mp_bsec),
77                                                   &dev);
78                 if (ret)
79                         return ret;
80                 ret = misc_read(dev, word * 4 + STM32_BSEC_OTP_OFFSET, val, 4);
81                 break;
82
83         default:
84                 printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
85                 ret = -EINVAL;
86                 break;
87         }
88
89         return ret;
90 }
91
92 int fuse_override(u32 bank, u32 word, u32 val)
93 {
94         struct udevice *dev;
95         int ret;
96
97         switch (bank) {
98         case STM32MP_OTP_BANK:
99                 ret = uclass_get_device_by_driver(UCLASS_MISC,
100                                                   DM_GET_DRIVER(stm32mp_bsec),
101                                                   &dev);
102                 if (ret)
103                         return ret;
104                 ret = misc_write(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,
105                                  &val, 4);
106                 break;
107
108         default:
109                 printf("stm32mp %s: wrong value for bank %i\n",
110                        __func__, bank);
111                 ret = -EINVAL;
112                 break;
113         }
114
115         return ret;
116 }