blob: 801d946b773bbbc6216b9bfa344d6cdc62688179 [file] [log] [blame]
Patrick Delaunayc3600e12018-05-17 15:24:06 +02001// 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>
Patrick Delaunaybe56ab12019-06-21 15:26:50 +02008#include <fuse.h>
Patrick Delaunayc3600e12018-05-17 15:24:06 +02009#include <misc.h>
10#include <errno.h>
11#include <dm/device.h>
12#include <dm/uclass.h>
Patrick Delaunay31e45a12019-02-04 11:26:22 +010013#include <power/stpmic1.h>
Patrick Delaunayc3600e12018-05-17 15:24:06 +020014
15#define STM32MP_OTP_BANK 0
Patrick Delaunay31e45a12019-02-04 11:26:22 +010016#define STM32MP_NVM_BANK 1
Patrick Delaunayc3600e12018-05-17 15:24:06 +020017
18/*
19 * The 'fuse' command API
20 */
21int fuse_read(u32 bank, u32 word, u32 *val)
22{
23 int ret = 0;
24 struct udevice *dev;
25
26 switch (bank) {
27 case STM32MP_OTP_BANK:
28 ret = uclass_get_device_by_driver(UCLASS_MISC,
29 DM_GET_DRIVER(stm32mp_bsec),
30 &dev);
31 if (ret)
32 return ret;
33 ret = misc_read(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,
34 val, 4);
Simon Glass8729b1a2018-11-06 15:21:39 -070035 if (ret < 0)
36 return ret;
37 ret = 0;
Patrick Delaunayc3600e12018-05-17 15:24:06 +020038 break;
39
Patrick Delaunay31e45a12019-02-04 11:26:22 +010040#ifdef CONFIG_PMIC_STPMIC1
41 case STM32MP_NVM_BANK:
42 *val = 0;
43 ret = stpmic1_shadow_read_byte(word, (u8 *)val);
44 break;
45#endif /* CONFIG_PMIC_STPMIC1 */
46
Patrick Delaunayc3600e12018-05-17 15:24:06 +020047 default:
48 printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
49 ret = -EINVAL;
50 break;
51 }
52
53 return ret;
54}
55
56int fuse_prog(u32 bank, u32 word, u32 val)
57{
58 struct udevice *dev;
59 int ret;
60
61 switch (bank) {
62 case STM32MP_OTP_BANK:
63 ret = uclass_get_device_by_driver(UCLASS_MISC,
64 DM_GET_DRIVER(stm32mp_bsec),
65 &dev);
66 if (ret)
67 return ret;
68 ret = misc_write(dev, word * 4 + STM32_BSEC_OTP_OFFSET,
69 &val, 4);
Simon Glass8729b1a2018-11-06 15:21:39 -070070 if (ret < 0)
71 return ret;
72 ret = 0;
Patrick Delaunayc3600e12018-05-17 15:24:06 +020073 break;
74
Patrick Delaunay31e45a12019-02-04 11:26:22 +010075#ifdef CONFIG_PMIC_STPMIC1
76 case STM32MP_NVM_BANK:
77 ret = stpmic1_nvm_write_byte(word, (u8 *)&val);
78 break;
79#endif /* CONFIG_PMIC_STPMIC1 */
80
Patrick Delaunayc3600e12018-05-17 15:24:06 +020081 default:
82 printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
83 ret = -EINVAL;
84 break;
85 }
86
87 return ret;
88}
89
90int fuse_sense(u32 bank, u32 word, u32 *val)
91{
92 struct udevice *dev;
93 int ret;
94
95 switch (bank) {
96 case STM32MP_OTP_BANK:
97 ret = uclass_get_device_by_driver(UCLASS_MISC,
98 DM_GET_DRIVER(stm32mp_bsec),
99 &dev);
100 if (ret)
101 return ret;
102 ret = misc_read(dev, word * 4 + STM32_BSEC_OTP_OFFSET, val, 4);
Simon Glass8729b1a2018-11-06 15:21:39 -0700103 if (ret < 0)
104 return ret;
105 ret = 0;
Patrick Delaunayc3600e12018-05-17 15:24:06 +0200106 break;
107
Patrick Delaunay31e45a12019-02-04 11:26:22 +0100108#ifdef CONFIG_PMIC_STPMIC1
109 case STM32MP_NVM_BANK:
110 *val = 0;
111 ret = stpmic1_nvm_read_byte(word, (u8 *)val);
112 break;
113#endif /* CONFIG_PMIC_STPMIC1 */
114
Patrick Delaunayc3600e12018-05-17 15:24:06 +0200115 default:
116 printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
117 ret = -EINVAL;
118 break;
119 }
120
121 return ret;
122}
123
124int fuse_override(u32 bank, u32 word, u32 val)
125{
126 struct udevice *dev;
127 int ret;
128
129 switch (bank) {
130 case STM32MP_OTP_BANK:
131 ret = uclass_get_device_by_driver(UCLASS_MISC,
132 DM_GET_DRIVER(stm32mp_bsec),
133 &dev);
134 if (ret)
135 return ret;
136 ret = misc_write(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,
137 &val, 4);
Simon Glass8729b1a2018-11-06 15:21:39 -0700138 if (ret < 0)
139 return ret;
140 ret = 0;
Patrick Delaunayc3600e12018-05-17 15:24:06 +0200141 break;
142
Patrick Delaunay31e45a12019-02-04 11:26:22 +0100143#ifdef CONFIG_PMIC_STPMIC1
144 case STM32MP_NVM_BANK:
145 ret = stpmic1_shadow_write_byte(word, (u8 *)&val);
146 break;
147#endif /* CONFIG_PMIC_STPMIC1 */
148
Patrick Delaunayc3600e12018-05-17 15:24:06 +0200149 default:
150 printf("stm32mp %s: wrong value for bank %i\n",
151 __func__, bank);
152 ret = -EINVAL;
153 break;
154 }
155
156 return ret;
157}