xref: /openbmc/u-boot/drivers/misc/stm32mp_fuse.c (revision f3275aa4)
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 		if (ret < 0)
33 			return ret;
34 		ret = 0;
35 		break;
36 
37 	default:
38 		printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
39 		ret = -EINVAL;
40 		break;
41 	}
42 
43 	return ret;
44 }
45 
46 int fuse_prog(u32 bank, u32 word, u32 val)
47 {
48 	struct udevice *dev;
49 	int ret;
50 
51 	switch (bank) {
52 	case STM32MP_OTP_BANK:
53 		ret = uclass_get_device_by_driver(UCLASS_MISC,
54 						  DM_GET_DRIVER(stm32mp_bsec),
55 						  &dev);
56 		if (ret)
57 			return ret;
58 		ret = misc_write(dev, word * 4 + STM32_BSEC_OTP_OFFSET,
59 				 &val, 4);
60 		if (ret < 0)
61 			return ret;
62 		ret = 0;
63 		break;
64 
65 	default:
66 		printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
67 		ret = -EINVAL;
68 		break;
69 	}
70 
71 	return ret;
72 }
73 
74 int fuse_sense(u32 bank, u32 word, u32 *val)
75 {
76 	struct udevice *dev;
77 	int ret;
78 
79 	switch (bank) {
80 	case STM32MP_OTP_BANK:
81 		ret = uclass_get_device_by_driver(UCLASS_MISC,
82 						  DM_GET_DRIVER(stm32mp_bsec),
83 						  &dev);
84 		if (ret)
85 			return ret;
86 		ret = misc_read(dev, word * 4 + STM32_BSEC_OTP_OFFSET, val, 4);
87 		if (ret < 0)
88 			return ret;
89 		ret = 0;
90 		break;
91 
92 	default:
93 		printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
94 		ret = -EINVAL;
95 		break;
96 	}
97 
98 	return ret;
99 }
100 
101 int fuse_override(u32 bank, u32 word, u32 val)
102 {
103 	struct udevice *dev;
104 	int ret;
105 
106 	switch (bank) {
107 	case STM32MP_OTP_BANK:
108 		ret = uclass_get_device_by_driver(UCLASS_MISC,
109 						  DM_GET_DRIVER(stm32mp_bsec),
110 						  &dev);
111 		if (ret)
112 			return ret;
113 		ret = misc_write(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,
114 				 &val, 4);
115 		if (ret < 0)
116 			return ret;
117 		ret = 0;
118 		break;
119 
120 	default:
121 		printf("stm32mp %s: wrong value for bank %i\n",
122 		       __func__, bank);
123 		ret = -EINVAL;
124 		break;
125 	}
126 
127 	return ret;
128 }
129