blob: 84e0bddcd44c57b45ec7856d8d25464b02869a5f [file] [log] [blame]
Patrick Delaunay19f58992018-05-17 15:24:05 +02001// 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>
Simon Glassf7ae49f2020-05-10 11:40:05 -06008#include <log.h>
Patrick Delaunay19f58992018-05-17 15:24:05 +02009#include <misc.h>
10#include <asm/io.h>
Patrick Delaunaybd3f60d2020-06-16 18:27:44 +020011#include <asm/arch/bsec.h>
Patrick Delaunayd859c612019-02-12 11:44:40 +010012#include <asm/arch/stm32mp1_smc.h>
13#include <linux/arm-smccc.h>
Patrick Delaunayee7d7722019-04-18 17:32:39 +020014#include <linux/iopoll.h>
Patrick Delaunay19f58992018-05-17 15:24:05 +020015
16#define BSEC_OTP_MAX_VALUE 95
Patrick Delaunay19f58992018-05-17 15:24:05 +020017#define BSEC_TIMEOUT_US 10000
18
19/* BSEC REGISTER OFFSET (base relative) */
20#define BSEC_OTP_CONF_OFF 0x000
21#define BSEC_OTP_CTRL_OFF 0x004
22#define BSEC_OTP_WRDATA_OFF 0x008
23#define BSEC_OTP_STATUS_OFF 0x00C
24#define BSEC_OTP_LOCK_OFF 0x010
Patrick Delaunaybd3f60d2020-06-16 18:27:44 +020025#define BSEC_DENABLE_OFF 0x014
Patrick Delaunay19f58992018-05-17 15:24:05 +020026#define BSEC_DISTURBED_OFF 0x01C
27#define BSEC_ERROR_OFF 0x034
Patrick Delaunay7ae22d72020-02-12 19:37:38 +010028#define BSEC_WRLOCK_OFF 0x04C /* OTP write permananet lock */
29#define BSEC_SPLOCK_OFF 0x064 /* OTP write sticky lock */
30#define BSEC_SWLOCK_OFF 0x07C /* shadow write sticky lock */
31#define BSEC_SRLOCK_OFF 0x094 /* shadow read sticky lock */
Patrick Delaunay19f58992018-05-17 15:24:05 +020032#define BSEC_OTP_DATA_OFF 0x200
33
34/* BSEC_CONFIGURATION Register MASK */
35#define BSEC_CONF_POWER_UP 0x001
36
37/* BSEC_CONTROL Register */
38#define BSEC_READ 0x000
39#define BSEC_WRITE 0x100
40
41/* LOCK Register */
42#define OTP_LOCK_MASK 0x1F
43#define OTP_LOCK_BANK_SHIFT 0x05
44#define OTP_LOCK_BIT_MASK 0x01
45
46/* STATUS Register */
47#define BSEC_MODE_BUSY_MASK 0x08
48#define BSEC_MODE_PROGFAIL_MASK 0x10
49#define BSEC_MODE_PWR_MASK 0x20
50
Patrick Delaunaybd3f60d2020-06-16 18:27:44 +020051/* DENABLE Register */
52#define BSEC_DENABLE_DBGSWENABLE BIT(10)
53
Patrick Delaunay19f58992018-05-17 15:24:05 +020054/*
55 * OTP Lock services definition
56 * Value must corresponding to the bit number in the register
57 */
58#define BSEC_LOCK_PROGRAM 0x04
59
60/**
Patrick Delaunay7ae22d72020-02-12 19:37:38 +010061 * bsec_lock() - manage lock for each type SR/SP/SW
62 * @address: address of bsec IP register
63 * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
64 * Return: true if locked else false
65 */
66static bool bsec_read_lock(u32 address, u32 otp)
67{
68 u32 bit;
69 u32 bank;
70
71 bit = 1 << (otp & OTP_LOCK_MASK);
72 bank = ((otp >> OTP_LOCK_BANK_SHIFT) & OTP_LOCK_MASK) * sizeof(u32);
73
74 return !!(readl(address + bank) & bit);
75}
76
Patrick Delaunay7ae22d72020-02-12 19:37:38 +010077/**
Patrick Delaunay19f58992018-05-17 15:24:05 +020078 * bsec_check_error() - Check status of one otp
79 * @base: base address of bsec IP
80 * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
81 * Return: 0 if no error, -EAGAIN or -ENOTSUPP
82 */
83static u32 bsec_check_error(u32 base, u32 otp)
84{
85 u32 bit;
86 u32 bank;
87
88 bit = 1 << (otp & OTP_LOCK_MASK);
89 bank = ((otp >> OTP_LOCK_BANK_SHIFT) & OTP_LOCK_MASK) * sizeof(u32);
90
91 if (readl(base + BSEC_DISTURBED_OFF + bank) & bit)
92 return -EAGAIN;
93 else if (readl(base + BSEC_ERROR_OFF + bank) & bit)
94 return -ENOTSUPP;
95
96 return 0;
97}
98
99/**
Patrick Delaunay19f58992018-05-17 15:24:05 +0200100 * bsec_read_SR_lock() - read SR lock (Shadowing)
101 * @base: base address of bsec IP
102 * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
103 * Return: true if locked else false
104 */
105static bool bsec_read_SR_lock(u32 base, u32 otp)
106{
107 return bsec_read_lock(base + BSEC_SRLOCK_OFF, otp);
108}
109
110/**
111 * bsec_read_SP_lock() - read SP lock (program Lock)
112 * @base: base address of bsec IP
113 * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
114 * Return: true if locked else false
115 */
116static bool bsec_read_SP_lock(u32 base, u32 otp)
117{
118 return bsec_read_lock(base + BSEC_SPLOCK_OFF, otp);
119}
120
121/**
122 * bsec_SW_lock() - manage SW lock (Write in Shadow)
123 * @base: base address of bsec IP
124 * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
125 * Return: true if locked else false
126 */
127static bool bsec_read_SW_lock(u32 base, u32 otp)
128{
129 return bsec_read_lock(base + BSEC_SWLOCK_OFF, otp);
130}
131
132/**
133 * bsec_power_safmem() - Activate or deactivate safmem power
134 * @base: base address of bsec IP
135 * @power: true to power up , false to power down
136 * Return: 0 if succeed
137 */
138static int bsec_power_safmem(u32 base, bool power)
139{
140 u32 val;
141 u32 mask;
142
143 if (power) {
144 setbits_le32(base + BSEC_OTP_CONF_OFF, BSEC_CONF_POWER_UP);
145 mask = BSEC_MODE_PWR_MASK;
146 } else {
147 clrbits_le32(base + BSEC_OTP_CONF_OFF, BSEC_CONF_POWER_UP);
148 mask = 0;
149 }
150
151 /* waiting loop */
152 return readl_poll_timeout(base + BSEC_OTP_STATUS_OFF,
153 val, (val & BSEC_MODE_PWR_MASK) == mask,
154 BSEC_TIMEOUT_US);
155}
156
157/**
158 * bsec_shadow_register() - copy safmen otp to bsec data
159 * @base: base address of bsec IP
160 * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
161 * Return: 0 if no error
162 */
163static int bsec_shadow_register(u32 base, u32 otp)
164{
165 u32 val;
166 int ret;
167 bool power_up = false;
168
169 /* check if shadowing of otp is locked */
170 if (bsec_read_SR_lock(base, otp))
171 pr_debug("bsec : OTP %d is locked and refreshed with 0\n", otp);
172
173 /* check if safemem is power up */
174 val = readl(base + BSEC_OTP_STATUS_OFF);
175 if (!(val & BSEC_MODE_PWR_MASK)) {
176 ret = bsec_power_safmem(base, true);
177 if (ret)
178 return ret;
Patrick Delaunay815bc8b2019-02-27 17:01:28 +0100179 power_up = true;
Patrick Delaunay19f58992018-05-17 15:24:05 +0200180 }
181 /* set BSEC_OTP_CTRL_OFF with the otp value*/
182 writel(otp | BSEC_READ, base + BSEC_OTP_CTRL_OFF);
183
184 /* check otp status*/
185 ret = readl_poll_timeout(base + BSEC_OTP_STATUS_OFF,
186 val, (val & BSEC_MODE_BUSY_MASK) == 0,
187 BSEC_TIMEOUT_US);
188 if (ret)
189 return ret;
190
191 ret = bsec_check_error(base, otp);
192
193 if (power_up)
194 bsec_power_safmem(base, false);
195
196 return ret;
197}
198
199/**
200 * bsec_read_shadow() - read an otp data value from shadow
201 * @base: base address of bsec IP
202 * @val: read value
203 * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
204 * Return: 0 if no error
205 */
206static int bsec_read_shadow(u32 base, u32 *val, u32 otp)
207{
208 *val = readl(base + BSEC_OTP_DATA_OFF + otp * sizeof(u32));
209
210 return bsec_check_error(base, otp);
211}
212
213/**
214 * bsec_write_shadow() - write value in BSEC data register in shadow
215 * @base: base address of bsec IP
216 * @val: value to write
217 * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
218 * Return: 0 if no error
219 */
220static int bsec_write_shadow(u32 base, u32 val, u32 otp)
221{
222 /* check if programming of otp is locked */
223 if (bsec_read_SW_lock(base, otp))
224 pr_debug("bsec : OTP %d is lock, write will be ignore\n", otp);
225
226 writel(val, base + BSEC_OTP_DATA_OFF + otp * sizeof(u32));
227
228 return bsec_check_error(base, otp);
229}
230
231/**
232 * bsec_program_otp() - program a bit in SAFMEM
233 * @base: base address of bsec IP
234 * @val: value to program
235 * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
236 * after the function the otp data is not refreshed in shadow
237 * Return: 0 if no error
238 */
239static int bsec_program_otp(long base, u32 val, u32 otp)
240{
241 u32 ret;
242 bool power_up = false;
243
244 if (bsec_read_SP_lock(base, otp))
245 pr_debug("bsec : OTP %d locked, prog will be ignore\n", otp);
246
247 if (readl(base + BSEC_OTP_LOCK_OFF) & (1 << BSEC_LOCK_PROGRAM))
248 pr_debug("bsec : Global lock, prog will be ignore\n");
249
250 /* check if safemem is power up */
251 if (!(readl(base + BSEC_OTP_STATUS_OFF) & BSEC_MODE_PWR_MASK)) {
252 ret = bsec_power_safmem(base, true);
253 if (ret)
254 return ret;
255
256 power_up = true;
257 }
258 /* set value in write register*/
259 writel(val, base + BSEC_OTP_WRDATA_OFF);
260
261 /* set BSEC_OTP_CTRL_OFF with the otp value */
262 writel(otp | BSEC_WRITE, base + BSEC_OTP_CTRL_OFF);
263
264 /* check otp status*/
265 ret = readl_poll_timeout(base + BSEC_OTP_STATUS_OFF,
266 val, (val & BSEC_MODE_BUSY_MASK) == 0,
267 BSEC_TIMEOUT_US);
268 if (ret)
269 return ret;
270
271 if (val & BSEC_MODE_PROGFAIL_MASK)
272 ret = -EACCES;
273 else
274 ret = bsec_check_error(base, otp);
275
276 if (power_up)
277 bsec_power_safmem(base, false);
278
279 return ret;
280}
281
282/* BSEC MISC driver *******************************************************/
Simon Glass8a8d24b2020-12-03 16:55:23 -0700283struct stm32mp_bsec_plat {
Patrick Delaunay19f58992018-05-17 15:24:05 +0200284 u32 base;
285};
286
287static int stm32mp_bsec_read_otp(struct udevice *dev, u32 *val, u32 otp)
288{
Simon Glass8a8d24b2020-12-03 16:55:23 -0700289 struct stm32mp_bsec_plat *plat;
Patrick Delaunay19f58992018-05-17 15:24:05 +0200290 u32 tmp_data = 0;
291 int ret;
292
Patrick Delaunay4e9e3582020-07-31 16:31:51 +0200293 if (IS_ENABLED(CONFIG_TFABOOT))
294 return stm32_smc(STM32_SMC_BSEC,
295 STM32_SMC_READ_OTP,
296 otp, 0, val);
297
Simon Glassc69cda22020-12-03 16:55:20 -0700298 plat = dev_get_plat(dev);
Patrick Delaunay4e9e3582020-07-31 16:31:51 +0200299
Patrick Delaunay19f58992018-05-17 15:24:05 +0200300 /* read current shadow value */
301 ret = bsec_read_shadow(plat->base, &tmp_data, otp);
302 if (ret)
303 return ret;
304
305 /* copy otp in shadow */
306 ret = bsec_shadow_register(plat->base, otp);
307 if (ret)
308 return ret;
309
310 ret = bsec_read_shadow(plat->base, val, otp);
311 if (ret)
312 return ret;
313
314 /* restore shadow value */
315 ret = bsec_write_shadow(plat->base, tmp_data, otp);
Patrick Delaunay4e9e3582020-07-31 16:31:51 +0200316
Patrick Delaunay19f58992018-05-17 15:24:05 +0200317 return ret;
318}
319
320static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp)
321{
Simon Glass8a8d24b2020-12-03 16:55:23 -0700322 struct stm32mp_bsec_plat *plat;
Patrick Delaunay4e9e3582020-07-31 16:31:51 +0200323
324 if (IS_ENABLED(CONFIG_TFABOOT))
325 return stm32_smc(STM32_SMC_BSEC,
326 STM32_SMC_READ_SHADOW,
327 otp, 0, val);
328
Simon Glassc69cda22020-12-03 16:55:20 -0700329 plat = dev_get_plat(dev);
Patrick Delaunay19f58992018-05-17 15:24:05 +0200330
331 return bsec_read_shadow(plat->base, val, otp);
332}
333
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100334static int stm32mp_bsec_read_lock(struct udevice *dev, u32 *val, u32 otp)
335{
Simon Glass8a8d24b2020-12-03 16:55:23 -0700336 struct stm32mp_bsec_plat *plat = dev_get_plat(dev);
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100337
338 /* return OTP permanent write lock status */
339 *val = bsec_read_lock(plat->base + BSEC_WRLOCK_OFF, otp);
340
341 return 0;
342}
343
Patrick Delaunay19f58992018-05-17 15:24:05 +0200344static int stm32mp_bsec_write_otp(struct udevice *dev, u32 val, u32 otp)
345{
Simon Glass8a8d24b2020-12-03 16:55:23 -0700346 struct stm32mp_bsec_plat *plat;
Patrick Delaunay4e9e3582020-07-31 16:31:51 +0200347
348 if (IS_ENABLED(CONFIG_TFABOOT))
349 return stm32_smc_exec(STM32_SMC_BSEC,
350 STM32_SMC_PROG_OTP,
351 otp, val);
352
Simon Glassc69cda22020-12-03 16:55:20 -0700353 plat = dev_get_plat(dev);
Patrick Delaunay19f58992018-05-17 15:24:05 +0200354
355 return bsec_program_otp(plat->base, val, otp);
Patrick Delaunay4e9e3582020-07-31 16:31:51 +0200356
Patrick Delaunay19f58992018-05-17 15:24:05 +0200357}
358
359static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp)
360{
Simon Glass8a8d24b2020-12-03 16:55:23 -0700361 struct stm32mp_bsec_plat *plat;
Patrick Delaunay4e9e3582020-07-31 16:31:51 +0200362
363 if (IS_ENABLED(CONFIG_TFABOOT))
364 return stm32_smc_exec(STM32_SMC_BSEC,
365 STM32_SMC_WRITE_SHADOW,
366 otp, val);
367
Simon Glassc69cda22020-12-03 16:55:20 -0700368 plat = dev_get_plat(dev);
Patrick Delaunay19f58992018-05-17 15:24:05 +0200369
370 return bsec_write_shadow(plat->base, val, otp);
371}
372
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100373static int stm32mp_bsec_write_lock(struct udevice *dev, u32 val, u32 otp)
374{
Patrick Delaunay4e9e3582020-07-31 16:31:51 +0200375 if (!IS_ENABLED(CONFIG_TFABOOT))
376 return -ENOTSUPP;
377
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100378 if (val == 1)
379 return stm32_smc_exec(STM32_SMC_BSEC,
380 STM32_SMC_WRLOCK_OTP,
381 otp, 0);
382 if (val == 0)
383 return 0; /* nothing to do */
384
385 return -EINVAL;
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100386}
387
Patrick Delaunay19f58992018-05-17 15:24:05 +0200388static int stm32mp_bsec_read(struct udevice *dev, int offset,
389 void *buf, int size)
390{
391 int ret;
392 int i;
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100393 bool shadow = true, lock = false;
Patrick Delaunay19f58992018-05-17 15:24:05 +0200394 int nb_otp = size / sizeof(u32);
395 int otp;
Patrick Delaunay745b6762019-06-21 15:26:43 +0200396 unsigned int offs = offset;
Patrick Delaunay19f58992018-05-17 15:24:05 +0200397
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100398 if (offs >= STM32_BSEC_LOCK_OFFSET) {
399 offs -= STM32_BSEC_LOCK_OFFSET;
400 lock = true;
401 } else if (offs >= STM32_BSEC_OTP_OFFSET) {
Patrick Delaunay745b6762019-06-21 15:26:43 +0200402 offs -= STM32_BSEC_OTP_OFFSET;
Patrick Delaunay19f58992018-05-17 15:24:05 +0200403 shadow = false;
404 }
Patrick Delaunay0c8620d2019-08-02 13:08:02 +0200405
Patrick Delaunaydf2d1b82020-02-12 19:37:37 +0100406 if ((offs % 4) || (size % 4))
Patrick Delaunay0c8620d2019-08-02 13:08:02 +0200407 return -EINVAL;
408
Patrick Delaunay745b6762019-06-21 15:26:43 +0200409 otp = offs / sizeof(u32);
Patrick Delaunay19f58992018-05-17 15:24:05 +0200410
Patrick Delaunay0c8620d2019-08-02 13:08:02 +0200411 for (i = otp; i < (otp + nb_otp) && i <= BSEC_OTP_MAX_VALUE; i++) {
Patrick Delaunay19f58992018-05-17 15:24:05 +0200412 u32 *addr = &((u32 *)buf)[i - otp];
413
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100414 if (lock)
415 ret = stm32mp_bsec_read_lock(dev, addr, i);
416 else if (shadow)
Patrick Delaunay19f58992018-05-17 15:24:05 +0200417 ret = stm32mp_bsec_read_shadow(dev, addr, i);
418 else
419 ret = stm32mp_bsec_read_otp(dev, addr, i);
420
421 if (ret)
422 break;
423 }
Patrick Delaunay0c8620d2019-08-02 13:08:02 +0200424 if (ret)
425 return ret;
426 else
427 return (i - otp) * 4;
Patrick Delaunay19f58992018-05-17 15:24:05 +0200428}
429
430static int stm32mp_bsec_write(struct udevice *dev, int offset,
431 const void *buf, int size)
432{
433 int ret = 0;
434 int i;
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100435 bool shadow = true, lock = false;
Patrick Delaunay19f58992018-05-17 15:24:05 +0200436 int nb_otp = size / sizeof(u32);
437 int otp;
Patrick Delaunay745b6762019-06-21 15:26:43 +0200438 unsigned int offs = offset;
Patrick Delaunay19f58992018-05-17 15:24:05 +0200439
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100440 if (offs >= STM32_BSEC_LOCK_OFFSET) {
441 offs -= STM32_BSEC_LOCK_OFFSET;
442 lock = true;
443 } else if (offs >= STM32_BSEC_OTP_OFFSET) {
Patrick Delaunay745b6762019-06-21 15:26:43 +0200444 offs -= STM32_BSEC_OTP_OFFSET;
Patrick Delaunay19f58992018-05-17 15:24:05 +0200445 shadow = false;
446 }
Patrick Delaunay0c8620d2019-08-02 13:08:02 +0200447
Patrick Delaunaydf2d1b82020-02-12 19:37:37 +0100448 if ((offs % 4) || (size % 4))
Patrick Delaunay0c8620d2019-08-02 13:08:02 +0200449 return -EINVAL;
450
Patrick Delaunay745b6762019-06-21 15:26:43 +0200451 otp = offs / sizeof(u32);
Patrick Delaunay19f58992018-05-17 15:24:05 +0200452
Patrick Delaunay0c8620d2019-08-02 13:08:02 +0200453 for (i = otp; i < otp + nb_otp && i <= BSEC_OTP_MAX_VALUE; i++) {
Patrick Delaunay19f58992018-05-17 15:24:05 +0200454 u32 *val = &((u32 *)buf)[i - otp];
455
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100456 if (lock)
457 ret = stm32mp_bsec_write_lock(dev, *val, i);
458 else if (shadow)
Patrick Delaunay19f58992018-05-17 15:24:05 +0200459 ret = stm32mp_bsec_write_shadow(dev, *val, i);
460 else
461 ret = stm32mp_bsec_write_otp(dev, *val, i);
462 if (ret)
463 break;
464 }
Patrick Delaunay0c8620d2019-08-02 13:08:02 +0200465 if (ret)
466 return ret;
467 else
468 return (i - otp) * 4;
Patrick Delaunay19f58992018-05-17 15:24:05 +0200469}
470
471static const struct misc_ops stm32mp_bsec_ops = {
472 .read = stm32mp_bsec_read,
473 .write = stm32mp_bsec_write,
474};
475
Simon Glassd1998a92020-12-03 16:55:21 -0700476static int stm32mp_bsec_of_to_plat(struct udevice *dev)
Patrick Delaunay19f58992018-05-17 15:24:05 +0200477{
Simon Glass8a8d24b2020-12-03 16:55:23 -0700478 struct stm32mp_bsec_plat *plat = dev_get_plat(dev);
Patrick Delaunay19f58992018-05-17 15:24:05 +0200479
480 plat->base = (u32)dev_read_addr_ptr(dev);
481
482 return 0;
483}
484
Patrick Delaunay815bc8b2019-02-27 17:01:28 +0100485static int stm32mp_bsec_probe(struct udevice *dev)
486{
487 int otp;
Simon Glass8a8d24b2020-12-03 16:55:23 -0700488 struct stm32mp_bsec_plat *plat;
Patrick Delaunay815bc8b2019-02-27 17:01:28 +0100489
Patrick Delaunay95bd49a2020-05-25 12:19:41 +0200490 /*
491 * update unlocked shadow for OTP cleared by the rom code
492 * only executed in U-Boot proper when TF-A is not used
493 */
Patrick Delaunay4e9e3582020-07-31 16:31:51 +0200494
495 if (!IS_ENABLED(CONFIG_TFABOOT) && !IS_ENABLED(CONFIG_SPL_BUILD)) {
Simon Glassc69cda22020-12-03 16:55:20 -0700496 plat = dev_get_plat(dev);
Patrick Delaunay4e9e3582020-07-31 16:31:51 +0200497
498 for (otp = 57; otp <= BSEC_OTP_MAX_VALUE; otp++)
499 if (!bsec_read_SR_lock(plat->base, otp))
500 bsec_shadow_register(plat->base, otp);
501 }
Patrick Delaunay815bc8b2019-02-27 17:01:28 +0100502
503 return 0;
504}
Patrick Delaunay815bc8b2019-02-27 17:01:28 +0100505
Patrick Delaunay19f58992018-05-17 15:24:05 +0200506static const struct udevice_id stm32mp_bsec_ids[] = {
Patrick Delaunaybfe1f082019-02-27 17:01:27 +0100507 { .compatible = "st,stm32mp15-bsec" },
Patrick Delaunay19f58992018-05-17 15:24:05 +0200508 {}
509};
510
511U_BOOT_DRIVER(stm32mp_bsec) = {
512 .name = "stm32mp_bsec",
513 .id = UCLASS_MISC,
514 .of_match = stm32mp_bsec_ids,
Simon Glassd1998a92020-12-03 16:55:21 -0700515 .of_to_plat = stm32mp_bsec_of_to_plat,
Simon Glass8a8d24b2020-12-03 16:55:23 -0700516 .plat_auto = sizeof(struct stm32mp_bsec_plat),
Patrick Delaunay19f58992018-05-17 15:24:05 +0200517 .ops = &stm32mp_bsec_ops,
Patrick Delaunay815bc8b2019-02-27 17:01:28 +0100518 .probe = stm32mp_bsec_probe,
Patrick Delaunay19f58992018-05-17 15:24:05 +0200519};
Patrick Delaunaybd3f60d2020-06-16 18:27:44 +0200520
521bool bsec_dbgswenable(void)
522{
523 struct udevice *dev;
Simon Glass8a8d24b2020-12-03 16:55:23 -0700524 struct stm32mp_bsec_plat *plat;
Patrick Delaunaybd3f60d2020-06-16 18:27:44 +0200525 int ret;
526
527 ret = uclass_get_device_by_driver(UCLASS_MISC,
Simon Glass65e25be2020-12-28 20:34:56 -0700528 DM_DRIVER_GET(stm32mp_bsec), &dev);
Patrick Delaunaybd3f60d2020-06-16 18:27:44 +0200529 if (ret || !dev) {
530 pr_debug("bsec driver not available\n");
531 return false;
532 }
533
Simon Glassc69cda22020-12-03 16:55:20 -0700534 plat = dev_get_plat(dev);
Patrick Delaunaybd3f60d2020-06-16 18:27:44 +0200535 if (readl(plat->base + BSEC_DENABLE_OFF) & BSEC_DENABLE_DBGSWENABLE)
536 return true;
537
538 return false;
539}