]> git.sur5r.net Git - u-boot/blob - arch/arm/mach-stm32mp/bsec.c
stm32mp1: add bsec driver
[u-boot] / arch / arm / mach-stm32mp / bsec.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 <dm.h>
8 #include <misc.h>
9 #include <asm/io.h>
10 #include <linux/iopoll.h>
11
12 #define BSEC_OTP_MAX_VALUE              95
13
14 #define BSEC_TIMEOUT_US                 10000
15
16 /* BSEC REGISTER OFFSET (base relative) */
17 #define BSEC_OTP_CONF_OFF               0x000
18 #define BSEC_OTP_CTRL_OFF               0x004
19 #define BSEC_OTP_WRDATA_OFF             0x008
20 #define BSEC_OTP_STATUS_OFF             0x00C
21 #define BSEC_OTP_LOCK_OFF               0x010
22 #define BSEC_DISTURBED_OFF              0x01C
23 #define BSEC_ERROR_OFF                  0x034
24 #define BSEC_SPLOCK_OFF                 0x064 /* Program safmem sticky lock */
25 #define BSEC_SWLOCK_OFF                 0x07C /* write in OTP sticky lock */
26 #define BSEC_SRLOCK_OFF                 0x094 /* shadowing sticky lock */
27 #define BSEC_OTP_DATA_OFF               0x200
28
29 /* BSEC_CONFIGURATION Register MASK */
30 #define BSEC_CONF_POWER_UP              0x001
31
32 /* BSEC_CONTROL Register */
33 #define BSEC_READ                       0x000
34 #define BSEC_WRITE                      0x100
35
36 /* LOCK Register */
37 #define OTP_LOCK_MASK                   0x1F
38 #define OTP_LOCK_BANK_SHIFT             0x05
39 #define OTP_LOCK_BIT_MASK               0x01
40
41 /* STATUS Register */
42 #define BSEC_MODE_BUSY_MASK             0x08
43 #define BSEC_MODE_PROGFAIL_MASK         0x10
44 #define BSEC_MODE_PWR_MASK              0x20
45
46 /*
47  * OTP Lock services definition
48  * Value must corresponding to the bit number in the register
49  */
50 #define BSEC_LOCK_PROGRAM               0x04
51
52 /**
53  * bsec_check_error() - Check status of one otp
54  * @base: base address of bsec IP
55  * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
56  * Return: 0 if no error, -EAGAIN or -ENOTSUPP
57  */
58 static u32 bsec_check_error(u32 base, u32 otp)
59 {
60         u32 bit;
61         u32 bank;
62
63         bit = 1 << (otp & OTP_LOCK_MASK);
64         bank = ((otp >> OTP_LOCK_BANK_SHIFT) & OTP_LOCK_MASK) * sizeof(u32);
65
66         if (readl(base + BSEC_DISTURBED_OFF + bank) & bit)
67                 return -EAGAIN;
68         else if (readl(base + BSEC_ERROR_OFF + bank) & bit)
69                 return -ENOTSUPP;
70
71         return 0;
72 }
73
74 /**
75  * bsec_lock() - manage lock for each type SR/SP/SW
76  * @address: address of bsec IP register
77  * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
78  * Return: true if locked else false
79  */
80 static bool bsec_read_lock(u32 address, u32 otp)
81 {
82         u32 bit;
83         u32 bank;
84
85         bit = 1 << (otp & OTP_LOCK_MASK);
86         bank = ((otp >> OTP_LOCK_BANK_SHIFT) & OTP_LOCK_MASK) * sizeof(u32);
87
88         return !!(readl(address + bank) & bit);
89 }
90
91 /**
92  * bsec_read_SR_lock() - read SR lock (Shadowing)
93  * @base: base address of bsec IP
94  * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
95  * Return: true if locked else false
96  */
97 static bool bsec_read_SR_lock(u32 base, u32 otp)
98 {
99         return bsec_read_lock(base + BSEC_SRLOCK_OFF, otp);
100 }
101
102 /**
103  * bsec_read_SP_lock() - read SP lock (program Lock)
104  * @base: base address of bsec IP
105  * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
106  * Return: true if locked else false
107  */
108 static bool bsec_read_SP_lock(u32 base, u32 otp)
109 {
110         return bsec_read_lock(base + BSEC_SPLOCK_OFF, otp);
111 }
112
113 /**
114  * bsec_SW_lock() - manage SW lock (Write in Shadow)
115  * @base: base address of bsec IP
116  * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
117  * Return: true if locked else false
118  */
119 static bool bsec_read_SW_lock(u32 base, u32 otp)
120 {
121         return bsec_read_lock(base + BSEC_SWLOCK_OFF, otp);
122 }
123
124 /**
125  * bsec_power_safmem() - Activate or deactivate safmem power
126  * @base: base address of bsec IP
127  * @power: true to power up , false to power down
128  * Return: 0 if succeed
129  */
130 static int bsec_power_safmem(u32 base, bool power)
131 {
132         u32 val;
133         u32 mask;
134
135         if (power) {
136                 setbits_le32(base + BSEC_OTP_CONF_OFF, BSEC_CONF_POWER_UP);
137                 mask = BSEC_MODE_PWR_MASK;
138         } else {
139                 clrbits_le32(base + BSEC_OTP_CONF_OFF, BSEC_CONF_POWER_UP);
140                 mask = 0;
141         }
142
143         /* waiting loop */
144         return readl_poll_timeout(base + BSEC_OTP_STATUS_OFF,
145                                   val, (val & BSEC_MODE_PWR_MASK) == mask,
146                                   BSEC_TIMEOUT_US);
147 }
148
149 /**
150  * bsec_shadow_register() - copy safmen otp to bsec data
151  * @base: base address of bsec IP
152  * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
153  * Return: 0 if no error
154  */
155 static int bsec_shadow_register(u32 base, u32 otp)
156 {
157         u32 val;
158         int ret;
159         bool power_up = false;
160
161         /* check if shadowing of otp is locked */
162         if (bsec_read_SR_lock(base, otp))
163                 pr_debug("bsec : OTP %d is locked and refreshed with 0\n", otp);
164
165         /* check if safemem is power up */
166         val = readl(base + BSEC_OTP_STATUS_OFF);
167         if (!(val & BSEC_MODE_PWR_MASK)) {
168                 ret = bsec_power_safmem(base, true);
169                 if (ret)
170                         return ret;
171                 power_up = 1;
172         }
173         /* set BSEC_OTP_CTRL_OFF with the otp value*/
174         writel(otp | BSEC_READ, base + BSEC_OTP_CTRL_OFF);
175
176         /* check otp status*/
177         ret = readl_poll_timeout(base + BSEC_OTP_STATUS_OFF,
178                                  val, (val & BSEC_MODE_BUSY_MASK) == 0,
179                                  BSEC_TIMEOUT_US);
180         if (ret)
181                 return ret;
182
183         ret = bsec_check_error(base, otp);
184
185         if (power_up)
186                 bsec_power_safmem(base, false);
187
188         return ret;
189 }
190
191 /**
192  * bsec_read_shadow() - read an otp data value from shadow
193  * @base: base address of bsec IP
194  * @val: read value
195  * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
196  * Return: 0 if no error
197  */
198 static int bsec_read_shadow(u32 base, u32 *val, u32 otp)
199 {
200         *val = readl(base + BSEC_OTP_DATA_OFF + otp * sizeof(u32));
201
202         return bsec_check_error(base, otp);
203 }
204
205 /**
206  * bsec_write_shadow() - write value in BSEC data register in shadow
207  * @base: base address of bsec IP
208  * @val: value to write
209  * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
210  * Return: 0 if no error
211  */
212 static int bsec_write_shadow(u32 base, u32 val, u32 otp)
213 {
214         /* check if programming of otp is locked */
215         if (bsec_read_SW_lock(base, otp))
216                 pr_debug("bsec : OTP %d is lock, write will be ignore\n", otp);
217
218         writel(val, base + BSEC_OTP_DATA_OFF + otp * sizeof(u32));
219
220         return bsec_check_error(base, otp);
221 }
222
223 /**
224  * bsec_program_otp() - program a bit in SAFMEM
225  * @base: base address of bsec IP
226  * @val: value to program
227  * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
228  * after the function the otp data is not refreshed in shadow
229  * Return: 0 if no error
230  */
231 static int bsec_program_otp(long base, u32 val, u32 otp)
232 {
233         u32 ret;
234         bool power_up = false;
235
236         if (bsec_read_SP_lock(base, otp))
237                 pr_debug("bsec : OTP %d locked, prog will be ignore\n", otp);
238
239         if (readl(base + BSEC_OTP_LOCK_OFF) & (1 << BSEC_LOCK_PROGRAM))
240                 pr_debug("bsec : Global lock, prog will be ignore\n");
241
242         /* check if safemem is power up */
243         if (!(readl(base + BSEC_OTP_STATUS_OFF) & BSEC_MODE_PWR_MASK)) {
244                 ret = bsec_power_safmem(base, true);
245                 if (ret)
246                         return ret;
247
248                 power_up = true;
249         }
250         /* set value in write register*/
251         writel(val, base + BSEC_OTP_WRDATA_OFF);
252
253         /* set BSEC_OTP_CTRL_OFF with the otp value */
254         writel(otp | BSEC_WRITE, base + BSEC_OTP_CTRL_OFF);
255
256         /* check otp status*/
257         ret = readl_poll_timeout(base + BSEC_OTP_STATUS_OFF,
258                                  val, (val & BSEC_MODE_BUSY_MASK) == 0,
259                                  BSEC_TIMEOUT_US);
260         if (ret)
261                 return ret;
262
263         if (val & BSEC_MODE_PROGFAIL_MASK)
264                 ret = -EACCES;
265         else
266                 ret = bsec_check_error(base, otp);
267
268         if (power_up)
269                 bsec_power_safmem(base, false);
270
271         return ret;
272 }
273
274 /* BSEC MISC driver *******************************************************/
275 struct stm32mp_bsec_platdata {
276         u32 base;
277 };
278
279 static int stm32mp_bsec_read_otp(struct udevice *dev, u32 *val, u32 otp)
280 {
281         struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
282         u32 tmp_data = 0;
283         int ret;
284
285         /* read current shadow value */
286         ret = bsec_read_shadow(plat->base, &tmp_data, otp);
287         if (ret)
288                 return ret;
289
290         /* copy otp in shadow */
291         ret = bsec_shadow_register(plat->base, otp);
292         if (ret)
293                 return ret;
294
295         ret = bsec_read_shadow(plat->base, val, otp);
296         if (ret)
297                 return ret;
298
299         /* restore shadow value */
300         ret = bsec_write_shadow(plat->base, tmp_data, otp);
301         return ret;
302 }
303
304 static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp)
305 {
306         struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
307
308         return bsec_read_shadow(plat->base, val, otp);
309 }
310
311 static int stm32mp_bsec_write_otp(struct udevice *dev, u32 val, u32 otp)
312 {
313         struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
314
315         return bsec_program_otp(plat->base, val, otp);
316 }
317
318 static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp)
319 {
320         struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
321
322         return bsec_write_shadow(plat->base, val, otp);
323 }
324
325 static int stm32mp_bsec_read(struct udevice *dev, int offset,
326                              void *buf, int size)
327 {
328         int ret;
329         int i;
330         bool shadow = true;
331         int nb_otp = size / sizeof(u32);
332         int otp;
333
334         if (offset >= STM32_BSEC_OTP_OFFSET) {
335                 offset -= STM32_BSEC_OTP_OFFSET;
336                 shadow = false;
337         }
338         otp = offset / sizeof(u32);
339
340         if (otp < 0 || (otp + nb_otp - 1) > BSEC_OTP_MAX_VALUE) {
341                 dev_err(dev, "wrong value for otp, max value : %i\n",
342                         BSEC_OTP_MAX_VALUE);
343                 return -EINVAL;
344         }
345
346         for (i = otp; i < (otp + nb_otp); i++) {
347                 u32 *addr = &((u32 *)buf)[i - otp];
348
349                 if (shadow)
350                         ret = stm32mp_bsec_read_shadow(dev, addr, i);
351                 else
352                         ret = stm32mp_bsec_read_otp(dev, addr, i);
353
354                 if (ret)
355                         break;
356         }
357         return ret;
358 }
359
360 static int stm32mp_bsec_write(struct udevice *dev, int offset,
361                               const void *buf, int size)
362 {
363         int ret = 0;
364         int i;
365         bool shadow = true;
366         int nb_otp = size / sizeof(u32);
367         int otp;
368
369         if (offset >= STM32_BSEC_OTP_OFFSET) {
370                 offset -= STM32_BSEC_OTP_OFFSET;
371                 shadow = false;
372         }
373         otp = offset / sizeof(u32);
374
375         if (otp < 0 || (otp + nb_otp - 1) > BSEC_OTP_MAX_VALUE) {
376                 dev_err(dev, "wrong value for otp, max value : %d\n",
377                         BSEC_OTP_MAX_VALUE);
378                 return -EINVAL;
379         }
380
381         for (i = otp; i < otp + nb_otp; i++) {
382                 u32 *val = &((u32 *)buf)[i - otp];
383
384                 if (shadow)
385                         ret = stm32mp_bsec_write_shadow(dev, *val, i);
386                 else
387                         ret = stm32mp_bsec_write_otp(dev, *val, i);
388                 if (ret)
389                         break;
390         }
391         return ret;
392 }
393
394 static const struct misc_ops stm32mp_bsec_ops = {
395         .read = stm32mp_bsec_read,
396         .write = stm32mp_bsec_write,
397 };
398
399 static int stm32mp_bsec_ofdata_to_platdata(struct udevice *dev)
400 {
401         struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
402
403         plat->base = (u32)dev_read_addr_ptr(dev);
404
405         return 0;
406 }
407
408 static const struct udevice_id stm32mp_bsec_ids[] = {
409         { .compatible = "st,stm32mp-bsec" },
410         {}
411 };
412
413 U_BOOT_DRIVER(stm32mp_bsec) = {
414         .name = "stm32mp_bsec",
415         .id = UCLASS_MISC,
416         .of_match = stm32mp_bsec_ids,
417         .ofdata_to_platdata = stm32mp_bsec_ofdata_to_platdata,
418         .platdata_auto_alloc_size = sizeof(struct stm32mp_bsec_platdata),
419         .ops = &stm32mp_bsec_ops,
420         .flags  = DM_FLAG_PRE_RELOC,
421 };
422
423 /* bsec IP is not present in device tee, manage IP address by platdata */
424 static struct stm32mp_bsec_platdata stm32_bsec_platdata = {
425         .base = STM32_BSEC_BASE,
426 };
427
428 U_BOOT_DEVICE(stm32mp_bsec) = {
429         .name = "stm32mp_bsec",
430         .platdata = &stm32_bsec_platdata,
431 };