blob: 0c56b440f561af2b543f2316833ad813dd079f97 [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 Delaunay654706b2020-04-01 09:07:33 +020077#ifndef CONFIG_TFABOOT
Patrick Delaunay7ae22d72020-02-12 19:37:38 +010078/**
Patrick Delaunay19f58992018-05-17 15:24:05 +020079 * bsec_check_error() - Check status of one otp
80 * @base: base address of bsec IP
81 * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
82 * Return: 0 if no error, -EAGAIN or -ENOTSUPP
83 */
84static u32 bsec_check_error(u32 base, u32 otp)
85{
86 u32 bit;
87 u32 bank;
88
89 bit = 1 << (otp & OTP_LOCK_MASK);
90 bank = ((otp >> OTP_LOCK_BANK_SHIFT) & OTP_LOCK_MASK) * sizeof(u32);
91
92 if (readl(base + BSEC_DISTURBED_OFF + bank) & bit)
93 return -EAGAIN;
94 else if (readl(base + BSEC_ERROR_OFF + bank) & bit)
95 return -ENOTSUPP;
96
97 return 0;
98}
99
100/**
Patrick Delaunay19f58992018-05-17 15:24:05 +0200101 * bsec_read_SR_lock() - read SR lock (Shadowing)
102 * @base: base address of bsec IP
103 * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
104 * Return: true if locked else false
105 */
106static bool bsec_read_SR_lock(u32 base, u32 otp)
107{
108 return bsec_read_lock(base + BSEC_SRLOCK_OFF, otp);
109}
110
111/**
112 * bsec_read_SP_lock() - read SP lock (program Lock)
113 * @base: base address of bsec IP
114 * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
115 * Return: true if locked else false
116 */
117static bool bsec_read_SP_lock(u32 base, u32 otp)
118{
119 return bsec_read_lock(base + BSEC_SPLOCK_OFF, otp);
120}
121
122/**
123 * bsec_SW_lock() - manage SW lock (Write in Shadow)
124 * @base: base address of bsec IP
125 * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
126 * Return: true if locked else false
127 */
128static bool bsec_read_SW_lock(u32 base, u32 otp)
129{
130 return bsec_read_lock(base + BSEC_SWLOCK_OFF, otp);
131}
132
133/**
134 * bsec_power_safmem() - Activate or deactivate safmem power
135 * @base: base address of bsec IP
136 * @power: true to power up , false to power down
137 * Return: 0 if succeed
138 */
139static int bsec_power_safmem(u32 base, bool power)
140{
141 u32 val;
142 u32 mask;
143
144 if (power) {
145 setbits_le32(base + BSEC_OTP_CONF_OFF, BSEC_CONF_POWER_UP);
146 mask = BSEC_MODE_PWR_MASK;
147 } else {
148 clrbits_le32(base + BSEC_OTP_CONF_OFF, BSEC_CONF_POWER_UP);
149 mask = 0;
150 }
151
152 /* waiting loop */
153 return readl_poll_timeout(base + BSEC_OTP_STATUS_OFF,
154 val, (val & BSEC_MODE_PWR_MASK) == mask,
155 BSEC_TIMEOUT_US);
156}
157
158/**
159 * bsec_shadow_register() - copy safmen otp to bsec data
160 * @base: base address of bsec IP
161 * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
162 * Return: 0 if no error
163 */
164static int bsec_shadow_register(u32 base, u32 otp)
165{
166 u32 val;
167 int ret;
168 bool power_up = false;
169
170 /* check if shadowing of otp is locked */
171 if (bsec_read_SR_lock(base, otp))
172 pr_debug("bsec : OTP %d is locked and refreshed with 0\n", otp);
173
174 /* check if safemem is power up */
175 val = readl(base + BSEC_OTP_STATUS_OFF);
176 if (!(val & BSEC_MODE_PWR_MASK)) {
177 ret = bsec_power_safmem(base, true);
178 if (ret)
179 return ret;
Patrick Delaunay815bc8b2019-02-27 17:01:28 +0100180 power_up = true;
Patrick Delaunay19f58992018-05-17 15:24:05 +0200181 }
182 /* set BSEC_OTP_CTRL_OFF with the otp value*/
183 writel(otp | BSEC_READ, base + BSEC_OTP_CTRL_OFF);
184
185 /* check otp status*/
186 ret = readl_poll_timeout(base + BSEC_OTP_STATUS_OFF,
187 val, (val & BSEC_MODE_BUSY_MASK) == 0,
188 BSEC_TIMEOUT_US);
189 if (ret)
190 return ret;
191
192 ret = bsec_check_error(base, otp);
193
194 if (power_up)
195 bsec_power_safmem(base, false);
196
197 return ret;
198}
199
200/**
201 * bsec_read_shadow() - read an otp data value from shadow
202 * @base: base address of bsec IP
203 * @val: read value
204 * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
205 * Return: 0 if no error
206 */
207static int bsec_read_shadow(u32 base, u32 *val, u32 otp)
208{
209 *val = readl(base + BSEC_OTP_DATA_OFF + otp * sizeof(u32));
210
211 return bsec_check_error(base, otp);
212}
213
214/**
215 * bsec_write_shadow() - write value in BSEC data register in shadow
216 * @base: base address of bsec IP
217 * @val: value to write
218 * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
219 * Return: 0 if no error
220 */
221static int bsec_write_shadow(u32 base, u32 val, u32 otp)
222{
223 /* check if programming of otp is locked */
224 if (bsec_read_SW_lock(base, otp))
225 pr_debug("bsec : OTP %d is lock, write will be ignore\n", otp);
226
227 writel(val, base + BSEC_OTP_DATA_OFF + otp * sizeof(u32));
228
229 return bsec_check_error(base, otp);
230}
231
232/**
233 * bsec_program_otp() - program a bit in SAFMEM
234 * @base: base address of bsec IP
235 * @val: value to program
236 * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
237 * after the function the otp data is not refreshed in shadow
238 * Return: 0 if no error
239 */
240static int bsec_program_otp(long base, u32 val, u32 otp)
241{
242 u32 ret;
243 bool power_up = false;
244
245 if (bsec_read_SP_lock(base, otp))
246 pr_debug("bsec : OTP %d locked, prog will be ignore\n", otp);
247
248 if (readl(base + BSEC_OTP_LOCK_OFF) & (1 << BSEC_LOCK_PROGRAM))
249 pr_debug("bsec : Global lock, prog will be ignore\n");
250
251 /* check if safemem is power up */
252 if (!(readl(base + BSEC_OTP_STATUS_OFF) & BSEC_MODE_PWR_MASK)) {
253 ret = bsec_power_safmem(base, true);
254 if (ret)
255 return ret;
256
257 power_up = true;
258 }
259 /* set value in write register*/
260 writel(val, base + BSEC_OTP_WRDATA_OFF);
261
262 /* set BSEC_OTP_CTRL_OFF with the otp value */
263 writel(otp | BSEC_WRITE, base + BSEC_OTP_CTRL_OFF);
264
265 /* check otp status*/
266 ret = readl_poll_timeout(base + BSEC_OTP_STATUS_OFF,
267 val, (val & BSEC_MODE_BUSY_MASK) == 0,
268 BSEC_TIMEOUT_US);
269 if (ret)
270 return ret;
271
272 if (val & BSEC_MODE_PROGFAIL_MASK)
273 ret = -EACCES;
274 else
275 ret = bsec_check_error(base, otp);
276
277 if (power_up)
278 bsec_power_safmem(base, false);
279
280 return ret;
281}
Patrick Delaunay654706b2020-04-01 09:07:33 +0200282#endif /* CONFIG_TFABOOT */
Patrick Delaunay19f58992018-05-17 15:24:05 +0200283
284/* BSEC MISC driver *******************************************************/
285struct stm32mp_bsec_platdata {
286 u32 base;
287};
288
289static int stm32mp_bsec_read_otp(struct udevice *dev, u32 *val, u32 otp)
290{
Patrick Delaunay654706b2020-04-01 09:07:33 +0200291#ifdef CONFIG_TFABOOT
Patrick Delaunayd859c612019-02-12 11:44:40 +0100292 return stm32_smc(STM32_SMC_BSEC,
293 STM32_SMC_READ_OTP,
294 otp, 0, val);
295#else
Patrick Delaunay19f58992018-05-17 15:24:05 +0200296 struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
297 u32 tmp_data = 0;
298 int ret;
299
300 /* 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);
316 return ret;
Patrick Delaunayd859c612019-02-12 11:44:40 +0100317#endif
Patrick Delaunay19f58992018-05-17 15:24:05 +0200318}
319
320static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp)
321{
Patrick Delaunay654706b2020-04-01 09:07:33 +0200322#ifdef CONFIG_TFABOOT
Patrick Delaunayd859c612019-02-12 11:44:40 +0100323 return stm32_smc(STM32_SMC_BSEC,
324 STM32_SMC_READ_SHADOW,
325 otp, 0, val);
326#else
Patrick Delaunay19f58992018-05-17 15:24:05 +0200327 struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
328
329 return bsec_read_shadow(plat->base, val, otp);
Patrick Delaunayd859c612019-02-12 11:44:40 +0100330#endif
Patrick Delaunay19f58992018-05-17 15:24:05 +0200331}
332
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100333static int stm32mp_bsec_read_lock(struct udevice *dev, u32 *val, u32 otp)
334{
335 struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
336
337 /* return OTP permanent write lock status */
338 *val = bsec_read_lock(plat->base + BSEC_WRLOCK_OFF, otp);
339
340 return 0;
341}
342
Patrick Delaunay19f58992018-05-17 15:24:05 +0200343static int stm32mp_bsec_write_otp(struct udevice *dev, u32 val, u32 otp)
344{
Patrick Delaunay654706b2020-04-01 09:07:33 +0200345#ifdef CONFIG_TFABOOT
Patrick Delaunayd859c612019-02-12 11:44:40 +0100346 return stm32_smc_exec(STM32_SMC_BSEC,
347 STM32_SMC_PROG_OTP,
348 otp, val);
349#else
Patrick Delaunay19f58992018-05-17 15:24:05 +0200350 struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
351
352 return bsec_program_otp(plat->base, val, otp);
Patrick Delaunayd859c612019-02-12 11:44:40 +0100353#endif
Patrick Delaunay19f58992018-05-17 15:24:05 +0200354}
355
356static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp)
357{
Patrick Delaunay654706b2020-04-01 09:07:33 +0200358#ifdef CONFIG_TFABOOT
Patrick Delaunayd859c612019-02-12 11:44:40 +0100359 return stm32_smc_exec(STM32_SMC_BSEC,
360 STM32_SMC_WRITE_SHADOW,
361 otp, val);
362#else
Patrick Delaunay19f58992018-05-17 15:24:05 +0200363 struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
364
365 return bsec_write_shadow(plat->base, val, otp);
Patrick Delaunayd859c612019-02-12 11:44:40 +0100366#endif
Patrick Delaunay19f58992018-05-17 15:24:05 +0200367}
368
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100369static int stm32mp_bsec_write_lock(struct udevice *dev, u32 val, u32 otp)
370{
Patrick Delaunay654706b2020-04-01 09:07:33 +0200371#ifdef CONFIG_TFABOOT
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100372 if (val == 1)
373 return stm32_smc_exec(STM32_SMC_BSEC,
374 STM32_SMC_WRLOCK_OTP,
375 otp, 0);
376 if (val == 0)
377 return 0; /* nothing to do */
378
379 return -EINVAL;
380#else
381 return -ENOTSUPP;
382#endif
383}
384
Patrick Delaunay19f58992018-05-17 15:24:05 +0200385static int stm32mp_bsec_read(struct udevice *dev, int offset,
386 void *buf, int size)
387{
388 int ret;
389 int i;
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100390 bool shadow = true, lock = false;
Patrick Delaunay19f58992018-05-17 15:24:05 +0200391 int nb_otp = size / sizeof(u32);
392 int otp;
Patrick Delaunay745b6762019-06-21 15:26:43 +0200393 unsigned int offs = offset;
Patrick Delaunay19f58992018-05-17 15:24:05 +0200394
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100395 if (offs >= STM32_BSEC_LOCK_OFFSET) {
396 offs -= STM32_BSEC_LOCK_OFFSET;
397 lock = true;
398 } else if (offs >= STM32_BSEC_OTP_OFFSET) {
Patrick Delaunay745b6762019-06-21 15:26:43 +0200399 offs -= STM32_BSEC_OTP_OFFSET;
Patrick Delaunay19f58992018-05-17 15:24:05 +0200400 shadow = false;
401 }
Patrick Delaunay0c8620d2019-08-02 13:08:02 +0200402
Patrick Delaunaydf2d1b82020-02-12 19:37:37 +0100403 if ((offs % 4) || (size % 4))
Patrick Delaunay0c8620d2019-08-02 13:08:02 +0200404 return -EINVAL;
405
Patrick Delaunay745b6762019-06-21 15:26:43 +0200406 otp = offs / sizeof(u32);
Patrick Delaunay19f58992018-05-17 15:24:05 +0200407
Patrick Delaunay0c8620d2019-08-02 13:08:02 +0200408 for (i = otp; i < (otp + nb_otp) && i <= BSEC_OTP_MAX_VALUE; i++) {
Patrick Delaunay19f58992018-05-17 15:24:05 +0200409 u32 *addr = &((u32 *)buf)[i - otp];
410
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100411 if (lock)
412 ret = stm32mp_bsec_read_lock(dev, addr, i);
413 else if (shadow)
Patrick Delaunay19f58992018-05-17 15:24:05 +0200414 ret = stm32mp_bsec_read_shadow(dev, addr, i);
415 else
416 ret = stm32mp_bsec_read_otp(dev, addr, i);
417
418 if (ret)
419 break;
420 }
Patrick Delaunay0c8620d2019-08-02 13:08:02 +0200421 if (ret)
422 return ret;
423 else
424 return (i - otp) * 4;
Patrick Delaunay19f58992018-05-17 15:24:05 +0200425}
426
427static int stm32mp_bsec_write(struct udevice *dev, int offset,
428 const void *buf, int size)
429{
430 int ret = 0;
431 int i;
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100432 bool shadow = true, lock = false;
Patrick Delaunay19f58992018-05-17 15:24:05 +0200433 int nb_otp = size / sizeof(u32);
434 int otp;
Patrick Delaunay745b6762019-06-21 15:26:43 +0200435 unsigned int offs = offset;
Patrick Delaunay19f58992018-05-17 15:24:05 +0200436
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100437 if (offs >= STM32_BSEC_LOCK_OFFSET) {
438 offs -= STM32_BSEC_LOCK_OFFSET;
439 lock = true;
440 } else if (offs >= STM32_BSEC_OTP_OFFSET) {
Patrick Delaunay745b6762019-06-21 15:26:43 +0200441 offs -= STM32_BSEC_OTP_OFFSET;
Patrick Delaunay19f58992018-05-17 15:24:05 +0200442 shadow = false;
443 }
Patrick Delaunay0c8620d2019-08-02 13:08:02 +0200444
Patrick Delaunaydf2d1b82020-02-12 19:37:37 +0100445 if ((offs % 4) || (size % 4))
Patrick Delaunay0c8620d2019-08-02 13:08:02 +0200446 return -EINVAL;
447
Patrick Delaunay745b6762019-06-21 15:26:43 +0200448 otp = offs / sizeof(u32);
Patrick Delaunay19f58992018-05-17 15:24:05 +0200449
Patrick Delaunay0c8620d2019-08-02 13:08:02 +0200450 for (i = otp; i < otp + nb_otp && i <= BSEC_OTP_MAX_VALUE; i++) {
Patrick Delaunay19f58992018-05-17 15:24:05 +0200451 u32 *val = &((u32 *)buf)[i - otp];
452
Patrick Delaunay7ae22d72020-02-12 19:37:38 +0100453 if (lock)
454 ret = stm32mp_bsec_write_lock(dev, *val, i);
455 else if (shadow)
Patrick Delaunay19f58992018-05-17 15:24:05 +0200456 ret = stm32mp_bsec_write_shadow(dev, *val, i);
457 else
458 ret = stm32mp_bsec_write_otp(dev, *val, i);
459 if (ret)
460 break;
461 }
Patrick Delaunay0c8620d2019-08-02 13:08:02 +0200462 if (ret)
463 return ret;
464 else
465 return (i - otp) * 4;
Patrick Delaunay19f58992018-05-17 15:24:05 +0200466}
467
468static const struct misc_ops stm32mp_bsec_ops = {
469 .read = stm32mp_bsec_read,
470 .write = stm32mp_bsec_write,
471};
472
473static int stm32mp_bsec_ofdata_to_platdata(struct udevice *dev)
474{
475 struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
476
477 plat->base = (u32)dev_read_addr_ptr(dev);
478
479 return 0;
480}
481
Patrick Delaunay815bc8b2019-02-27 17:01:28 +0100482static int stm32mp_bsec_probe(struct udevice *dev)
483{
Patrick Delaunay95bd49a2020-05-25 12:19:41 +0200484#if !defined(CONFIG_TFABOOT) && !defined(CONFIG_SPL_BUILD)
Patrick Delaunay815bc8b2019-02-27 17:01:28 +0100485 int otp;
486 struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
487
Patrick Delaunay95bd49a2020-05-25 12:19:41 +0200488 /*
489 * update unlocked shadow for OTP cleared by the rom code
490 * only executed in U-Boot proper when TF-A is not used
491 */
Patrick Delaunay815bc8b2019-02-27 17:01:28 +0100492 for (otp = 57; otp <= BSEC_OTP_MAX_VALUE; otp++)
493 if (!bsec_read_SR_lock(plat->base, otp))
494 bsec_shadow_register(plat->base, otp);
Patrick Delaunay95bd49a2020-05-25 12:19:41 +0200495#endif
Patrick Delaunay815bc8b2019-02-27 17:01:28 +0100496
497 return 0;
498}
Patrick Delaunay815bc8b2019-02-27 17:01:28 +0100499
Patrick Delaunay19f58992018-05-17 15:24:05 +0200500static const struct udevice_id stm32mp_bsec_ids[] = {
Patrick Delaunaybfe1f082019-02-27 17:01:27 +0100501 { .compatible = "st,stm32mp15-bsec" },
Patrick Delaunay19f58992018-05-17 15:24:05 +0200502 {}
503};
504
505U_BOOT_DRIVER(stm32mp_bsec) = {
506 .name = "stm32mp_bsec",
507 .id = UCLASS_MISC,
508 .of_match = stm32mp_bsec_ids,
509 .ofdata_to_platdata = stm32mp_bsec_ofdata_to_platdata,
510 .platdata_auto_alloc_size = sizeof(struct stm32mp_bsec_platdata),
511 .ops = &stm32mp_bsec_ops,
Patrick Delaunay815bc8b2019-02-27 17:01:28 +0100512 .probe = stm32mp_bsec_probe,
Patrick Delaunay19f58992018-05-17 15:24:05 +0200513};
Patrick Delaunaybd3f60d2020-06-16 18:27:44 +0200514
515bool bsec_dbgswenable(void)
516{
517 struct udevice *dev;
518 struct stm32mp_bsec_platdata *plat;
519 int ret;
520
521 ret = uclass_get_device_by_driver(UCLASS_MISC,
522 DM_GET_DRIVER(stm32mp_bsec), &dev);
523 if (ret || !dev) {
524 pr_debug("bsec driver not available\n");
525 return false;
526 }
527
528 plat = dev_get_platdata(dev);
529 if (readl(plat->base + BSEC_DENABLE_OFF) & BSEC_DENABLE_DBGSWENABLE)
530 return true;
531
532 return false;
533}