mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-03 21:48:15 +00:00 
			
		
		
		
	Move imx8 sci header file to include/firmware/imx, then we could use build macro to reuse some i.MX8 drivers for i.MX9, such as drivers/cpu/imx8_cpu.c. Signed-off-by: Peng Fan <peng.fan@nxp.com> Signed-off-by: Stefano Babic <sbabic@denx.de>
		
			
				
	
	
		
			96 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			96 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
// SPDX-License-Identifier: GPL-2.0
 | 
						|
/*
 | 
						|
 * Copyright 2019 NXP
 | 
						|
 */
 | 
						|
 | 
						|
#include <common.h>
 | 
						|
#include <console.h>
 | 
						|
#include <errno.h>
 | 
						|
#include <fuse.h>
 | 
						|
#include <firmware/imx/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;
 | 
						|
}
 |