diff options
Diffstat (limited to 'roms/u-boot/drivers/misc/imx8/fuse.c')
-rw-r--r-- | roms/u-boot/drivers/misc/imx8/fuse.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/roms/u-boot/drivers/misc/imx8/fuse.c b/roms/u-boot/drivers/misc/imx8/fuse.c new file mode 100644 index 000000000..38111c525 --- /dev/null +++ b/roms/u-boot/drivers/misc/imx8/fuse.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 NXP + */ + +#include <common.h> +#include <console.h> +#include <errno.h> +#include <fuse.h> +#include <asm/arch/sci/sci.h> +#include <asm/arch/sys_proto.h> +#include <asm/global_data.h> +#include <linux/arm-smccc.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define FSL_ECC_WORD_START_1 0x10 +#define FSL_ECC_WORD_END_1 0x10F + +#ifdef CONFIG_IMX8QM +#define FSL_ECC_WORD_START_2 0x1A0 +#define FSL_ECC_WORD_END_2 0x1FF +#elif defined(CONFIG_IMX8QXP) +#define FSL_ECC_WORD_START_2 0x220 +#define FSL_ECC_WORD_END_2 0x31F +#endif + +#define FSL_QXP_FUSE_GAP_START 0x110 +#define FSL_QXP_FUSE_GAP_END 0x21F + +#define FSL_SIP_OTP_READ 0xc200000A +#define FSL_SIP_OTP_WRITE 0xc200000B + +int fuse_read(u32 bank, u32 word, u32 *val) +{ + return fuse_sense(bank, word, val); +} + +int fuse_sense(u32 bank, u32 word, u32 *val) +{ + struct arm_smccc_res res; + + if (bank != 0) { + printf("Invalid bank argument, ONLY bank 0 is supported\n"); + return -EINVAL; + } + + arm_smccc_smc(FSL_SIP_OTP_READ, (unsigned long)word, 0, 0, + 0, 0, 0, 0, &res); + *val = (u32)res.a1; + + return res.a0; +} + +int fuse_prog(u32 bank, u32 word, u32 val) +{ + struct arm_smccc_res res; + + if (bank != 0) { + printf("Invalid bank argument, ONLY bank 0 is supported\n"); + return -EINVAL; + } + + if (IS_ENABLED(CONFIG_IMX8QXP)) { + if (word >= FSL_QXP_FUSE_GAP_START && + word <= FSL_QXP_FUSE_GAP_END) { + printf("Invalid word argument for this SoC\n"); + return -EINVAL; + } + } + + if ((word >= FSL_ECC_WORD_START_1 && word <= FSL_ECC_WORD_END_1) || + (word >= FSL_ECC_WORD_START_2 && word <= FSL_ECC_WORD_END_2)) { + puts("Warning: Words in this index range have ECC protection\n" + "and can only be programmed once per word. Individual bit\n" + "operations will be rejected after the first one.\n" + "\n\n Really program this word? <y/N>\n"); + + if (!confirm_yesno()) { + puts("Word programming aborted\n"); + return -EPERM; + } + } + + arm_smccc_smc(FSL_SIP_OTP_WRITE, (unsigned long)word, + (unsigned long)val, 0, 0, 0, 0, 0, &res); + + return res.a0; +} + +int fuse_override(u32 bank, u32 word, u32 val) +{ + printf("Override fuse to i.MX8 in u-boot is forbidden\n"); + return -EPERM; +} |