Skip to content
Snippets Groups Projects
fuse.c 3.33 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*
     * (C) Copyright 2009-2013 ADVANSEE
     * Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
     *
     * Based on the mpc512x iim code:
     * Copyright 2008 Silicon Turnkey Express, Inc.
     * Martha Marx <mmarx@silicontkx.com>
     *
    
     * SPDX-License-Identifier:	GPL-2.0+
    
     */
    
    #include <common.h>
    #include <command.h>
    
    #include <console.h>
    
    #include <fuse.h>
    #include <asm/errno.h>
    
    static int strtou32(const char *str, unsigned int base, u32 *result)
    {
    	char *ep;
    
    	*result = simple_strtoul(str, &ep, base);
    	if (ep == str || *ep != '\0')
    		return -EINVAL;
    
    	return 0;
    }
    
    static int confirm_prog(void)
    {
    	puts("Warning: Programming fuses is an irreversible operation!\n"
    			"         This may brick your system.\n"
    			"         Use this command only if you are sure of "
    					"what you are doing!\n"
    			"\nReally perform this fuse programming? <y/N>\n");
    
    
    	if (confirm_yesno())
    		return 1;
    
    
    	puts("Fuse programming aborted\n");
    	return 0;
    }
    
    static int do_fuse(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
    {
    	const char *op = argc >= 2 ? argv[1] : NULL;
    	int confirmed = argc >= 3 && !strcmp(argv[2], "-y");
    	u32 bank, word, cnt, val;
    	int ret, i;
    
    	argc -= 2 + confirmed;
    	argv += 2 + confirmed;
    
    	if (argc < 2 || strtou32(argv[0], 0, &bank) ||
    			strtou32(argv[1], 0, &word))
    		return CMD_RET_USAGE;
    
    	if (!strcmp(op, "read")) {
    		if (argc == 2)
    			cnt = 1;
    		else if (argc != 3 || strtou32(argv[2], 0, &cnt))
    			return CMD_RET_USAGE;
    
    		printf("Reading bank %u:\n", bank);
    		for (i = 0; i < cnt; i++, word++) {
    			if (!(i % 4))
    				printf("\nWord 0x%.8x:", word);
    
    			ret = fuse_read(bank, word, &val);
    			if (ret)
    				goto err;
    
    			printf(" %.8x", val);
    		}
    		putc('\n');
    	} else if (!strcmp(op, "sense")) {
    		if (argc == 2)
    			cnt = 1;
    		else if (argc != 3 || strtou32(argv[2], 0, &cnt))
    			return CMD_RET_USAGE;
    
    		printf("Sensing bank %u:\n", bank);
    		for (i = 0; i < cnt; i++, word++) {
    			if (!(i % 4))
    				printf("\nWord 0x%.8x:", word);
    
    			ret = fuse_sense(bank, word, &val);
    			if (ret)
    				goto err;
    
    			printf(" %.8x", val);
    		}
    		putc('\n');
    	} else if (!strcmp(op, "prog")) {
    		if (argc < 3)
    			return CMD_RET_USAGE;
    
    		for (i = 2; i < argc; i++, word++) {
    			if (strtou32(argv[i], 16, &val))
    				return CMD_RET_USAGE;
    
    			printf("Programming bank %u word 0x%.8x to 0x%.8x...\n",
    					bank, word, val);
    			if (!confirmed && !confirm_prog())
    				return CMD_RET_FAILURE;
    			ret = fuse_prog(bank, word, val);
    			if (ret)
    				goto err;
    		}
    	} else if (!strcmp(op, "override")) {
    		if (argc < 3)
    			return CMD_RET_USAGE;
    
    		for (i = 2; i < argc; i++, word++) {
    			if (strtou32(argv[i], 16, &val))
    				return CMD_RET_USAGE;
    
    			printf("Overriding bank %u word 0x%.8x with "
    					"0x%.8x...\n", bank, word, val);
    			ret = fuse_override(bank, word, val);
    			if (ret)
    				goto err;
    		}
    	} else {
    		return CMD_RET_USAGE;
    	}
    
    	return 0;
    
    err:
    	puts("ERROR\n");
    
    	return CMD_RET_FAILURE;
    
    }
    
    U_BOOT_CMD(
    	fuse, CONFIG_SYS_MAXARGS, 0, do_fuse,
    	"Fuse sub-system",
    	     "read <bank> <word> [<cnt>] - read 1 or 'cnt' fuse words,\n"
    	"    starting at 'word'\n"
    	"fuse sense <bank> <word> [<cnt>] - sense 1 or 'cnt' fuse words,\n"
    	"    starting at 'word'\n"
    	"fuse prog [-y] <bank> <word> <hexval> [<hexval>...] - program 1 or\n"
    	"    several fuse words, starting at 'word' (PERMANENT)\n"
    	"fuse override <bank> <word> <hexval> [<hexval>...] - override 1 or\n"
    	"    several fuse words, starting at 'word'"
    );