Commit c3600e1f92b772f8e50d81c4f1c233839b48f2cf

Authored by Patrick Delaunay
Committed by Tom Rini
1 parent 19f589923a

stm32mp1: add FUSE command support

Add support of fuse command (read/write/program/sense)
on bank 0 to access to BSEC SAFMEM (4096 OTP bits).

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>

Showing 6 changed files with 129 additions and 0 deletions Side-by-side Diff

... ... @@ -204,6 +204,7 @@
204 204 S: Maintained
205 205 F: arch/arm/mach-stm32mp
206 206 F: drivers/clk/clk_stm32mp1.c
  207 +F: drivers/misc/stm32mp_fuse.c
207 208 F: drivers/ram/stm32mp1/
208 209  
209 210 ARM STM STV0991
... ... @@ -1225,6 +1225,7 @@
1225 1225 select DM_SERIAL
1226 1226 select OF_CONTROL
1227 1227 select OF_LIBFDT
  1228 + select MISC
1228 1229 select PINCTRL
1229 1230 select REGMAP
1230 1231 select SUPPORT_SPL
configs/stm32mp15_basic_defconfig
... ... @@ -18,6 +18,7 @@
18 18 # CONFIG_CMD_EXPORTENV is not set
19 19 # CONFIG_CMD_IMPORTENV is not set
20 20 CONFIG_CMD_MEMINFO=y
  21 +CONFIG_CMD_FUSE=y
21 22 CONFIG_CMD_GPIO=y
22 23 CONFIG_CMD_GPT=y
23 24 CONFIG_CMD_I2C=y
drivers/misc/Kconfig
... ... @@ -158,6 +158,15 @@
158 158 help
159 159 The I2C address of the PCA9551 LED controller.
160 160  
  161 +config STM32MP_FUSE
  162 + bool "Enable STM32MP fuse wrapper providing the fuse API"
  163 + depends on ARCH_STM32MP && MISC
  164 + default y if CMD_FUSE
  165 + help
  166 + If you say Y here, you will get support for the fuse API (OTP)
  167 + for STM32MP architecture.
  168 + This API is needed for CMD_FUSE.
  169 +
161 170 config STM32_RCC
162 171 bool "Enable RCC driver for the STM32 SoC's family"
163 172 depends on STM32 && MISC
drivers/misc/Makefile
... ... @@ -51,6 +51,7 @@
51 51 obj-$(CONFIG_QFW) += qfw.o
52 52 obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
53 53 obj-$(CONFIG_STM32_RCC) += stm32_rcc.o
  54 +obj-$(CONFIG_STM32MP_FUSE) += stm32mp_fuse.o
54 55 obj-$(CONFIG_SYS_DPAA_QBMAN) += fsl_portals.o
55 56 obj-$(CONFIG_GDSYS_RXAUI_CTRL) += gdsys_rxaui_ctrl.o
drivers/misc/stm32mp_fuse.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 <command.h>
  8 +#include <misc.h>
  9 +#include <errno.h>
  10 +#include <dm/device.h>
  11 +#include <dm/uclass.h>
  12 +
  13 +#define STM32MP_OTP_BANK 0
  14 +
  15 +/*
  16 + * The 'fuse' command API
  17 + */
  18 +int fuse_read(u32 bank, u32 word, u32 *val)
  19 +{
  20 + int ret = 0;
  21 + struct udevice *dev;
  22 +
  23 + switch (bank) {
  24 + case STM32MP_OTP_BANK:
  25 + ret = uclass_get_device_by_driver(UCLASS_MISC,
  26 + DM_GET_DRIVER(stm32mp_bsec),
  27 + &dev);
  28 + if (ret)
  29 + return ret;
  30 + ret = misc_read(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,
  31 + val, 4);
  32 + break;
  33 +
  34 + default:
  35 + printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
  36 + ret = -EINVAL;
  37 + break;
  38 + }
  39 +
  40 + return ret;
  41 +}
  42 +
  43 +int fuse_prog(u32 bank, u32 word, u32 val)
  44 +{
  45 + struct udevice *dev;
  46 + int ret;
  47 +
  48 + switch (bank) {
  49 + case STM32MP_OTP_BANK:
  50 + ret = uclass_get_device_by_driver(UCLASS_MISC,
  51 + DM_GET_DRIVER(stm32mp_bsec),
  52 + &dev);
  53 + if (ret)
  54 + return ret;
  55 + ret = misc_write(dev, word * 4 + STM32_BSEC_OTP_OFFSET,
  56 + &val, 4);
  57 + break;
  58 +
  59 + default:
  60 + printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
  61 + ret = -EINVAL;
  62 + break;
  63 + }
  64 +
  65 + return ret;
  66 +}
  67 +
  68 +int fuse_sense(u32 bank, u32 word, u32 *val)
  69 +{
  70 + struct udevice *dev;
  71 + int ret;
  72 +
  73 + switch (bank) {
  74 + case STM32MP_OTP_BANK:
  75 + ret = uclass_get_device_by_driver(UCLASS_MISC,
  76 + DM_GET_DRIVER(stm32mp_bsec),
  77 + &dev);
  78 + if (ret)
  79 + return ret;
  80 + ret = misc_read(dev, word * 4 + STM32_BSEC_OTP_OFFSET, val, 4);
  81 + break;
  82 +
  83 + default:
  84 + printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
  85 + ret = -EINVAL;
  86 + break;
  87 + }
  88 +
  89 + return ret;
  90 +}
  91 +
  92 +int fuse_override(u32 bank, u32 word, u32 val)
  93 +{
  94 + struct udevice *dev;
  95 + int ret;
  96 +
  97 + switch (bank) {
  98 + case STM32MP_OTP_BANK:
  99 + ret = uclass_get_device_by_driver(UCLASS_MISC,
  100 + DM_GET_DRIVER(stm32mp_bsec),
  101 + &dev);
  102 + if (ret)
  103 + return ret;
  104 + ret = misc_write(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,
  105 + &val, 4);
  106 + break;
  107 +
  108 + default:
  109 + printf("stm32mp %s: wrong value for bank %i\n",
  110 + __func__, bank);
  111 + ret = -EINVAL;
  112 + break;
  113 + }
  114 +
  115 + return ret;
  116 +}