Add K3_FUSE config option to add and enable fuse sub-system implementation function calls.
Signed-off-by: Harsha Vardhan V M <h...@ti.com> Reviewed-by: Tom Rini <tr...@konsulko.com> --- drivers/misc/Kconfig | 7 ++++ drivers/misc/Makefile | 1 + drivers/misc/k3_fuse.c | 78 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 drivers/misc/k3_fuse.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index da84b35e804..834e0285097 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -468,6 +468,13 @@ config STM32MP_FUSE for STM32MP architecture. This API is needed for CMD_FUSE. +config K3_FUSE + bool "Enable TI K3 fuse wrapper providing the fuse API" + depends on MISC && CMD_FUSE && CMD_FUSE_WRITEBUFF + help + If you say Y here, you will get support for the fuse API (OTP) + for TI K3 architecture. + config STM32_RCC bool "Enable RCC driver for the STM32 SoC's family" depends on (ARCH_STM32 || ARCH_STM32MP) && MISC diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index dac805e4cdd..0b81ba2604f 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_$(XPL_)I2C_EEPROM) += i2c_eeprom.o obj-$(CONFIG_IHS_FPGA) += ihs_fpga.o obj-$(CONFIG_IMX8) += imx8/ obj-$(CONFIG_IMX_ELE) += imx_ele/ +obj-$(CONFIG_K3_FUSE) += k3_fuse.o obj-$(CONFIG_LED_STATUS) += status_led.o obj-$(CONFIG_LED_STATUS_GPIO) += gpio_led.o obj-$(CONFIG_MPC83XX_SERDES) += mpc83xx_serdes.o diff --git a/drivers/misc/k3_fuse.c b/drivers/misc/k3_fuse.c new file mode 100644 index 00000000000..4a8ff1f2523 --- /dev/null +++ b/drivers/misc/k3_fuse.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2025 Texas Instruments Incorporated, <www.ti.com> + */ + +#include <errno.h> +#include <stdio.h> +#include <fuse.h> +#include <linux/arm-smccc.h> +#include <string.h> + +#define K3_SIP_OTP_WRITEBUFF 0xC2000000 +#define K3_SIP_OTP_WRITE 0xC2000001 +#define K3_SIP_OTP_READ 0xC2000002 + +int fuse_read(u32 bank, u32 word, u32 *val) +{ + struct arm_smccc_res res; + + if (bank != 0U) { + printf("Invalid bank argument, ONLY bank 0 is supported\n"); + return -EINVAL; + } + + /* Make SiP SMC call and send the word in the parameter register */ + arm_smccc_smc(K3_SIP_OTP_READ, word, + 0, 0, 0, 0, 0, 0, &res); + + *val = res.a1; + if (res.a0 != 0) + printf("SMC call failed: Error code %lu\n", res.a0); + + return res.a0; +} + +int fuse_sense(u32 bank, u32 word, u32 *val) +{ + return -EPERM; +} + +int fuse_prog(u32 bank, u32 word, u32 val) +{ + struct arm_smccc_res res; + u32 mask = val; + + if (bank != 0U) { + printf("Invalid bank argument, ONLY bank 0 is supported\n"); + return -EINVAL; + } + + /* Make SiP SMC call and send the word, val and mask in the parameter register */ + arm_smccc_smc(K3_SIP_OTP_WRITE, word, + val, mask, 0, 0, 0, 0, &res); + + if (res.a0 != 0) + printf("SMC call failed: Error code %lu\n", res.a0); + + return res.a0; +} + +int fuse_override(u32 bank, u32 word, u32 val) +{ + return -EPERM; +} + +int fuse_writebuff(ulong addr) +{ + struct arm_smccc_res res; + + /* Make SiP SMC call and send the addr in the parameter register */ + arm_smccc_smc(K3_SIP_OTP_WRITEBUFF, (unsigned long)addr, + 0, 0, 0, 0, 0, 0, &res); + + if (res.a0 != 0) + printf("SMC call failed: Error code %lu\n", res.a0); + + return res.a0; +} -- 2.34.1