
This can be useful for fuse-like hardware, OTP SoC options, etc.
Signed-off-by: Benoît Thébaudeau benoit.thebaudeau@advansee.com Cc: Wolfgang Denk wd@denx.de Cc: Stefano Babic sbabic@denx.de --- {u-boot-4d3c95f.orig => u-boot-4d3c95f}/README | 1 + .../common/Makefile | 1 + /dev/null => u-boot-4d3c95f/common/cmd_fuse.c | 182 ++++++++++++++++++++ .../include/config_cmd_all.h | 1 + /dev/null => u-boot-4d3c95f/include/fuse.h | 49 ++++++ 5 files changed, 234 insertions(+) create mode 100644 u-boot-4d3c95f/common/cmd_fuse.c create mode 100644 u-boot-4d3c95f/include/fuse.h
diff --git u-boot-4d3c95f.orig/README u-boot-4d3c95f/README index fb9d904..c40fd34 100644 --- u-boot-4d3c95f.orig/README +++ u-boot-4d3c95f/README @@ -780,6 +780,7 @@ The following options need to be configured: CONFIG_CMD_FDOS * Dos diskette Support CONFIG_CMD_FLASH flinfo, erase, protect CONFIG_CMD_FPGA FPGA device initialization support + CONFIG_CMD_FUSE Device fuse support CONFIG_CMD_GO * the 'go' command (exec code) CONFIG_CMD_GREPENV * search environment CONFIG_CMD_HWFLOW * RTS/CTS hw flow control diff --git u-boot-4d3c95f.orig/common/Makefile u-boot-4d3c95f/common/Makefile index 3d62775..44ef757 100644 --- u-boot-4d3c95f.orig/common/Makefile +++ u-boot-4d3c95f/common/Makefile @@ -96,6 +96,7 @@ COBJS-$(CONFIG_CMD_FLASH) += cmd_flash.o ifdef CONFIG_FPGA COBJS-$(CONFIG_CMD_FPGA) += cmd_fpga.o endif +COBJS-$(CONFIG_CMD_FUSE) += cmd_fuse.o COBJS-$(CONFIG_CMD_GPIO) += cmd_gpio.o COBJS-$(CONFIG_CMD_I2C) += cmd_i2c.o COBJS-$(CONFIG_CMD_IDE) += cmd_ide.o diff --git u-boot-4d3c95f/common/cmd_fuse.c u-boot-4d3c95f/common/cmd_fuse.c new file mode 100644 index 0000000..fd54d40 --- /dev/null +++ u-boot-4d3c95f/common/cmd_fuse.c @@ -0,0 +1,182 @@ +/* + * (C) Copyright 2009-2012 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 + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.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 do_fuse(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + u32 bank, row, bit, cnt, val; + int ret, i; + + if (argc < 4 || strtou32(argv[2], 0, &bank) || + strtou32(argv[3], 0, &row)) + return CMD_RET_USAGE; + + if (!strcmp(argv[1], "read.bit")) { + if (argc != 5 || strtou32(argv[4], 0, &bit)) + return CMD_RET_USAGE; + + printf("Reading bank %u row 0x%.8x bit %u: ", bank, row, bit); + ret = fuse_read_bit(bank, row, bit, &val); + if (ret) + goto err; + + printf("%u\n", val); + } else if (!strcmp(argv[1], "read.row")) { + if (argc == 4) + cnt = 1; + else if (argc != 5 || strtou32(argv[4], 0, &cnt)) + return CMD_RET_USAGE; + + printf("Reading bank %u:\n", bank); + for (i = 0; i < cnt; i++, row++) { + if (!(i % 4)) + printf("\nRow 0x%.8x:", row); + + ret = fuse_read_row(bank, row, &val); + if (ret) + goto err; + + printf(" %.8x", val); + } + putc('\n'); + } else if (!strcmp(argv[1], "sense.bit")) { + if (argc != 5 || strtou32(argv[4], 0, &bit)) + return CMD_RET_USAGE; + + printf("Sensing bank %u row 0x%.8x bit %u: ", bank, row, bit); + ret = fuse_sense_bit(bank, row, bit, &val); + if (ret) + goto err; + + printf("%u\n", val); + } else if (!strcmp(argv[1], "sense.row")) { + if (argc == 4) + cnt = 1; + else if (argc != 5 || strtou32(argv[4], 0, &cnt)) + return CMD_RET_USAGE; + + printf("Sensing bank %u:\n", bank); + for (i = 0; i < cnt; i++, row++) { + if (!(i % 4)) + printf("\nRow 0x%.8x:", row); + + ret = fuse_sense_row(bank, row, &val); + if (ret) + goto err; + + printf(" %.8x", val); + } + putc('\n'); + } else if (!strcmp(argv[1], "prog.bit")) { + if (argc != 5 || strtou32(argv[4], 0, &bit)) + return CMD_RET_USAGE; + + printf("Programming bank %u row 0x%.8x bit %u...\n", + bank, row, bit); + ret = fuse_prog_bit(bank, row, bit); + if (ret) + goto err; + } else if (!strcmp(argv[1], "prog.row")) { + if (argc < 5) + return CMD_RET_USAGE; + + for (i = 4; i < argc; i++, row++) { + if (strtou32(argv[i], 16, &val)) + return CMD_RET_USAGE; + + printf("Programming bank %u row 0x%.8x to 0x%.8x...\n", + bank, row, val); + ret = fuse_prog_row(bank, row, val); + if (ret) + goto err; + } + } else if (!strcmp(argv[1], "ovride.bit")) { + if (argc != 6 || strtou32(argv[4], 0, &bit) || + strtou32(argv[5], 0, &val) || val > 1) + return CMD_RET_USAGE; + + printf("Overriding bank %u row 0x%.8x bit %u with %u...\n", + bank, row, bit, val); + ret = fuse_override_bit(bank, row, bit, val); + if (ret) + goto err; + } else if (!strcmp(argv[1], "ovride.row")) { + if (argc < 5) + return CMD_RET_USAGE; + + for (i = 4; i < argc; i++, row++) { + if (strtou32(argv[i], 16, &val)) + return CMD_RET_USAGE; + + printf("Overriding bank %u row 0x%.8x with 0x%.8x...\n", + bank, row, val); + ret = fuse_override_row(bank, row, val); + if (ret) + goto err; + } + } else { + return CMD_RET_USAGE; + } + + return 0; + +err: + puts("ERROR\n"); + return ret; +} + +U_BOOT_CMD( + fuse, CONFIG_SYS_MAXARGS, 0, do_fuse, + "Fuse sub-system", + "read.bit <bank> <row> <bit> - read a fuse bit\n" + "fuse read.row <bank> <row> [<cnt>] - read 1 or 'cnt' fuse rows,\n" + " starting at 'row'\n" + "fuse sense.bit <bank> <row> <bit> - sense a fuse bit\n" + "fuse sense.row <bank> <row> [<cnt>] - sense 1 or 'cnt' fuse rows,\n" + " starting at 'row'\n" + "fuse prog.bit <bank> <row> <bit> - program a fuse bit (PERMANENT)\n" + "fuse prog.row <bank> <row> <hexval> [<hexval>...] - program 1 or\n" + " several fuse rows, starting at 'row' (PERMANENT)\n" + "fuse ovride.bit <bank> <row> <bit> <val> - override a fuse bit\n" + "fuse ovride.row <bank> <row> <hexval> [<hexval>...] - override 1 or\n" + " several fuse rows, starting at 'row'" +); diff --git u-boot-4d3c95f.orig/include/config_cmd_all.h u-boot-4d3c95f/include/config_cmd_all.h index f434cd0..8f7d9ae 100644 --- u-boot-4d3c95f.orig/include/config_cmd_all.h +++ u-boot-4d3c95f/include/config_cmd_all.h @@ -40,6 +40,7 @@ #define CONFIG_CMD_FDOS /* Floppy DOS support */ #define CONFIG_CMD_FLASH /* flinfo, erase, protect */ #define CONFIG_CMD_FPGA /* FPGA configuration Support */ +#define CONFIG_CMD_FUSE /* Device fuse support */ #define CONFIG_CMD_HWFLOW /* RTS/CTS hw flow control */ #define CONFIG_CMD_I2C /* I2C serial bus support */ #define CONFIG_CMD_IDE /* IDE harddisk support */ diff --git u-boot-4d3c95f/include/fuse.h u-boot-4d3c95f/include/fuse.h new file mode 100644 index 0000000..baefefe --- /dev/null +++ u-boot-4d3c95f/include/fuse.h @@ -0,0 +1,49 @@ +/* + * (C) Copyright 2009-2012 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 + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _FUSE_H_ +#define _FUSE_H_ + +/* + * Read/Sense/Program/Override interface: + * bank: Fuse bank + * row: Fuse row within the bank + * bit: Fuse bit within the row + * val: Value to read/write + * + * Returns: 0 on success, not 0 on failure + */ +int fuse_read_bit(u32 bank, u32 row, u32 bit, u32 *val); +int fuse_read_row(u32 bank, u32 row, u32 *val); +int fuse_sense_bit(u32 bank, u32 row, u32 bit, u32 *val); +int fuse_sense_row(u32 bank, u32 row, u32 *val); +int fuse_prog_bit(u32 bank, u32 row, u32 bit); +int fuse_prog_row(u32 bank, u32 row, u32 val); +int fuse_override_bit(u32 bank, u32 row, u32 bit, u32 val); +int fuse_override_row(u32 bank, u32 row, u32 val); + +#endif /* _FUSE_H_ */