blob: 8dc246b0dbe8292fc2991634f61d1a1203407252 [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>
8#include <misc.h>
9#include <errno.h>
10#include <dm/device.h>
11#include <dm/uclass.h>
Patrick Delaunay31e45a12019-02-04 11:26:22 +010012#include <power/stpmic1.h>
Patrick Delaunayc3600e12018-05-17 15:24:06 +020013
14#define STM32MP_OTP_BANK 0
Patrick Delaunay31e45a12019-02-04 11:26:22 +010015#define STM32MP_NVM_BANK 1
Patrick Delaunayc3600e12018-05-17 15:24:06 +020016
17/*
18 * The 'fuse' command API
19 */
20int 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);
Simon Glass8729b1a2018-11-06 15:21:39 -070034 if (ret < 0)
35 return ret;
36 ret = 0;
Patrick Delaunayc3600e12018-05-17 15:24:06 +020037 break;
38
Patrick Delaunay31e45a12019-02-04 11:26:22 +010039#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
Patrick Delaunayc3600e12018-05-17 15:24:06 +020046 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
55int 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);
Simon Glass8729b1a2018-11-06 15:21:39 -070069 if (ret < 0)
70 return ret;
71 ret = 0;
Patrick Delaunayc3600e12018-05-17 15:24:06 +020072 break;
73
Patrick Delaunay31e45a12019-02-04 11:26:22 +010074#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
Patrick Delaunayc3600e12018-05-17 15:24:06 +020080 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
89int 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);
Simon Glass8729b1a2018-11-06 15:21:39 -0700102 if (ret < 0)
103 return ret;
104 ret = 0;
Patrick Delaunayc3600e12018-05-17 15:24:06 +0200105 break;
106
Patrick Delaunay31e45a12019-02-04 11:26:22 +0100107#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
Patrick Delaunayc3600e12018-05-17 15:24:06 +0200114 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
123int 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);
Simon Glass8729b1a2018-11-06 15:21:39 -0700137 if (ret < 0)
138 return ret;
139 ret = 0;
Patrick Delaunayc3600e12018-05-17 15:24:06 +0200140 break;
141
Patrick Delaunay31e45a12019-02-04 11:26:22 +0100142#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
Patrick Delaunayc3600e12018-05-17 15:24:06 +0200148 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}