* [PATCH 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox @ 2010-08-10 6:25 Baruch Siach 2010-08-10 6:25 ` [PATCH 2/2] fec: add support for IIM stored mac address Baruch Siach 2010-08-10 7:09 ` [PATCH 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox Jean-Christophe PLAGNIOL-VILLARD 0 siblings, 2 replies; 9+ messages in thread From: Baruch Siach @ 2010-08-10 6:25 UTC (permalink / raw) To: barebox This has only been tested on i.MX25, but should work on other i.MX chips with IIM. Signed-off-by: Baruch Siach <baruch@tkos.co.il> --- commands/Kconfig | 5 ++ commands/Makefile | 1 + commands/fuse.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+), 0 deletions(-) create mode 100644 commands/fuse.c diff --git a/commands/Kconfig b/commands/Kconfig index 9d11a8b..eb3e48e 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -173,6 +173,11 @@ config CMD_MTEST_ALTERNATIVE depends on CMD_MTEST prompt "alternative mtest implementation" +config CMD_FUSE_BLOW + tristate + depends on ARCH_IMX25 || ARCH_IMX35 + prompt "fuse_blow" + endmenu menu "flash " diff --git a/commands/Makefile b/commands/Makefile index 276af85..aa1c12e 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_CMD_ECHO) += echo.o obj-$(CONFIG_CMD_MEMORY) += mem.o obj-$(CONFIG_CMD_LOADS) += s_record.o obj-$(CONFIG_CMD_MTEST) += memtest.o +obj-$(CONFIG_CMD_FUSE_BLOW) += fuse.o obj-$(CONFIG_CMD_EDIT) += edit.o obj-$(CONFIG_CMD_EXEC) += exec.o obj-$(CONFIG_CMD_SLEEP) += sleep.o diff --git a/commands/fuse.c b/commands/fuse.c new file mode 100644 index 0000000..1c0ccd6 --- /dev/null +++ b/commands/fuse.c @@ -0,0 +1,161 @@ +/* + * fuse.c - i.MX IIM fusebox programing and sensing + * + * Copyright (c) 2010 Baruch Siach <baruch@tkos.co.il>, + * Orex Computed Radiography + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <common.h> +#include <command.h> +#include <asm/io.h> +#include <mach/imx-regs.h> +#include <mach/iim.h> + +static int do_fuse_blow(struct command *cmdtp, int argc, char *argv[]) +{ + unsigned int bank, row, value; + int bit, ret = 0; + u8 err, stat; + + if (argc != 4) + return COMMAND_ERROR_USAGE; + + bank = simple_strtoul(argv[1], NULL, 0); + row = simple_strtoul(argv[2], NULL, 0); + value = simple_strtoul(argv[3], NULL, 0); + + if (bank > 7) { + printf("fuse_blow: invalid bank number\n"); + return 1; + } + + if (row > 0x3ff) { + printf("fuse_blow: invalid row offset\n"); + return 1; + } + + if (value > 0xff) { + printf("fuse_blow: invalid value\n"); + return 1; + } + + /* clear status and error registers */ + writeb(3, IMX_IIM_BASE + IIM_STATM); + writeb(0xfe, IMX_IIM_BASE + IIM_ERR); + + /* unprotect fuse programing */ + writeb(0xaa, IMX_IIM_BASE + IIM_PREG_P); + + /* upper half address register */ + writeb((bank << 3) | (row >> 7), IMX_IIM_BASE + IIM_UA); + + for (bit = 0; bit < 8; bit++) { + if (((value >> bit) & 1) == 0) + continue; + + /* lower half address register */ + writeb(((row << 1) | bit), IMX_IIM_BASE + IIM_LA); + + /* start fuse programing */ + writeb(0x71, IMX_IIM_BASE + IIM_FCTL); + + /* wait for program done */ + while ((readb(IMX_IIM_BASE + IIM_STAT) & 0x80) != 0) + ; + + /* clear program done status */ + stat = readb(IMX_IIM_BASE + IIM_STAT); + writeb(stat, IMX_IIM_BASE + IIM_STAT); + + err = readb(IMX_IIM_BASE + IIM_ERR); + if (err) { + printf("fuse_blow: bit %d program error (0x%02x)\n", + bit, err); + ret = 1; + goto out; + } + } + +out: + /* protect fuse programing */ + writeb(0, IMX_IIM_BASE + IIM_PREG_P); + return ret; +} + +static const __maybe_unused char cmd_fuse_blow_help[] = +"Usage: fuse_blow <bank> <row> <value>\n" +"Blow fuses in <bank> <row> to match <value>\n"; + +BAREBOX_CMD_START(fuse_blow) + .cmd = do_fuse_blow, + .usage = "program fuse row", + BAREBOX_CMD_HELP(cmd_fuse_blow_help) +BAREBOX_CMD_END + +static int do_fuse_sense(struct command *cmdtp, int argc, char *argv[]) +{ + unsigned int bank, row; + u8 err, stat; + + if (argc != 3) + return COMMAND_ERROR_USAGE; + + bank = simple_strtoul(argv[1], NULL, 0); + row = simple_strtoul(argv[2], NULL, 0); + + if (bank > 7) { + printf("fuse_sense: invalid bank number\n"); + return 1; + } + + if (row > 0x3ff) { + printf("fuse_sense: invalid row offset\n"); + return 1; + } + + /* clear status and error registers */ + writeb(3, IMX_IIM_BASE + IIM_STATM); + writeb(0xfe, IMX_IIM_BASE + IIM_ERR); + + /* upper and lower address halves */ + writeb((bank << 3) | (row >> 7), IMX_IIM_BASE + IIM_UA); + writeb((row << 1) & 0xf8, IMX_IIM_BASE + IIM_LA); + + /* start fuse sensing */ + writeb(0x08, IMX_IIM_BASE + IIM_FCTL); + + /* wait for sense done */ + while ((readb(IMX_IIM_BASE + IIM_STAT) & 0x80) != 0) + ; + + stat = readb(IMX_IIM_BASE + IIM_STAT); + writeb(stat, IMX_IIM_BASE + IIM_STAT); + + err = readb(IMX_IIM_BASE + IIM_ERR); + if (err) { + printf("fuse_sense: sense error (0x%02x)\n", err); + return 1; + } + + printf("bank %u row 0x%02x: 0x%02x\n", bank, row, + readb(IMX_IIM_BASE + IIM_SDAT)); + + return 0; +} + +static const __maybe_unused char cmd_fuse_sense_help[] = +"Usage: fuse_sense <bank> <row>\n" +"Sense the fuses row at <bank> <row>\n"; + +BAREBOX_CMD_START(fuse_sense) + .cmd = do_fuse_sense, + .usage = "sense fuse row", + BAREBOX_CMD_HELP(cmd_fuse_sense_help) +BAREBOX_CMD_END -- 1.7.1 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/2] fec: add support for IIM stored mac address 2010-08-10 6:25 [PATCH 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox Baruch Siach @ 2010-08-10 6:25 ` Baruch Siach 2010-08-10 7:09 ` [PATCH 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox Jean-Christophe PLAGNIOL-VILLARD 1 sibling, 0 replies; 9+ messages in thread From: Baruch Siach @ 2010-08-10 6:25 UTC (permalink / raw) To: barebox This patch adds support for i.MX25 only, because that's what I have. Extending this to other i.MX chip should be trivial, given the right IIM_MAC_ADDR define. Signed-off-by: Baruch Siach <baruch@tkos.co.il> --- arch/arm/mach-imx/include/mach/imx25-regs.h | 1 + drivers/net/fec_imx.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-imx/include/mach/imx25-regs.h b/arch/arm/mach-imx/include/mach/imx25-regs.h index 7c2b5f9..f3da7b5 100644 --- a/arch/arm/mach-imx/include/mach/imx25-regs.h +++ b/arch/arm/mach-imx/include/mach/imx25-regs.h @@ -142,6 +142,7 @@ /* IIM fuse definitions */ #define IIM_UID 0x820 +#define IIM_MAC_ADDR 0x868 #endif /* __ASM_ARCH_MX25_REGS_H */ diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c index 40a7543..af93eec 100644 --- a/drivers/net/fec_imx.c +++ b/drivers/net/fec_imx.c @@ -235,6 +235,16 @@ static void fec_rbd_clean(int last, struct buffer_descriptor *pRbd) static int fec_get_hwaddr(struct eth_device *dev, unsigned char *mac) { + int i; + + if (cpu_is_mx25()) { + /* get MAC address from the IMM fusebox */ + for (i = 0; i < 6; i++) + mac[i] = readb(IMX_IIM_BASE + IIM_MAC_ADDR + i*4); + + return 0; + } + /* no eeprom */ return -1; } -- 1.7.1 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox 2010-08-10 6:25 [PATCH 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox Baruch Siach 2010-08-10 6:25 ` [PATCH 2/2] fec: add support for IIM stored mac address Baruch Siach @ 2010-08-10 7:09 ` Jean-Christophe PLAGNIOL-VILLARD 2010-08-12 8:34 ` Baruch Siach 2010-08-12 8:35 ` [PATCH v2 " Baruch Siach 1 sibling, 2 replies; 9+ messages in thread From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-08-10 7:09 UTC (permalink / raw) To: Baruch Siach; +Cc: barebox Hi, sorry I do not really see what the comman do so maybe a small doc or more comment will be nice Best Regards, J. On 09:25 Tue 10 Aug , Baruch Siach wrote: > This has only been tested on i.MX25, but should work on other i.MX chips with > IIM. > > Signed-off-by: Baruch Siach <baruch@tkos.co.il> > --- > commands/Kconfig | 5 ++ > commands/Makefile | 1 + > commands/fuse.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 167 insertions(+), 0 deletions(-) > create mode 100644 commands/fuse.c > > diff --git a/commands/Kconfig b/commands/Kconfig > index 9d11a8b..eb3e48e 100644 > --- a/commands/Kconfig > +++ b/commands/Kconfig > @@ -173,6 +173,11 @@ config CMD_MTEST_ALTERNATIVE > depends on CMD_MTEST > prompt "alternative mtest implementation" > > +config CMD_FUSE_BLOW > + tristate > + depends on ARCH_IMX25 || ARCH_IMX35 > + prompt "fuse_blow" > + > endmenu > > menu "flash " > diff --git a/commands/Makefile b/commands/Makefile > index 276af85..aa1c12e 100644 > --- a/commands/Makefile > +++ b/commands/Makefile > @@ -8,6 +8,7 @@ obj-$(CONFIG_CMD_ECHO) += echo.o > obj-$(CONFIG_CMD_MEMORY) += mem.o > obj-$(CONFIG_CMD_LOADS) += s_record.o > obj-$(CONFIG_CMD_MTEST) += memtest.o > +obj-$(CONFIG_CMD_FUSE_BLOW) += fuse.o > obj-$(CONFIG_CMD_EDIT) += edit.o > obj-$(CONFIG_CMD_EXEC) += exec.o > obj-$(CONFIG_CMD_SLEEP) += sleep.o > diff --git a/commands/fuse.c b/commands/fuse.c > new file mode 100644 > index 0000000..1c0ccd6 > --- /dev/null > +++ b/commands/fuse.c > @@ -0,0 +1,161 @@ > +/* > + * fuse.c - i.MX IIM fusebox programing and sensing > + * > + * Copyright (c) 2010 Baruch Siach <baruch@tkos.co.il>, > + * Orex Computed Radiography > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 > + * as published by the Free Software Foundation. > + * > + * http://www.opensource.org/licenses/gpl-license.html > + * http://www.gnu.org/copyleft/gpl.html > + */ > + > +#include <common.h> > +#include <command.h> > +#include <asm/io.h> > +#include <mach/imx-regs.h> > +#include <mach/iim.h> > + > +static int do_fuse_blow(struct command *cmdtp, int argc, char *argv[]) > +{ > + unsigned int bank, row, value; > + int bit, ret = 0; > + u8 err, stat; > + > + if (argc != 4) > + return COMMAND_ERROR_USAGE; > + > + bank = simple_strtoul(argv[1], NULL, 0); > + row = simple_strtoul(argv[2], NULL, 0); > + value = simple_strtoul(argv[3], NULL, 0); > + > + if (bank > 7) { > + printf("fuse_blow: invalid bank number\n"); > + return 1; > + } > + > + if (row > 0x3ff) { > + printf("fuse_blow: invalid row offset\n"); > + return 1; > + } > + > + if (value > 0xff) { > + printf("fuse_blow: invalid value\n"); > + return 1; > + } > + > + /* clear status and error registers */ > + writeb(3, IMX_IIM_BASE + IIM_STATM); > + writeb(0xfe, IMX_IIM_BASE + IIM_ERR); > + > + /* unprotect fuse programing */ > + writeb(0xaa, IMX_IIM_BASE + IIM_PREG_P); > + > + /* upper half address register */ > + writeb((bank << 3) | (row >> 7), IMX_IIM_BASE + IIM_UA); > + > + for (bit = 0; bit < 8; bit++) { > + if (((value >> bit) & 1) == 0) > + continue; > + > + /* lower half address register */ > + writeb(((row << 1) | bit), IMX_IIM_BASE + IIM_LA); > + > + /* start fuse programing */ > + writeb(0x71, IMX_IIM_BASE + IIM_FCTL); > + > + /* wait for program done */ > + while ((readb(IMX_IIM_BASE + IIM_STAT) & 0x80) != 0) > + ; > + > + /* clear program done status */ > + stat = readb(IMX_IIM_BASE + IIM_STAT); > + writeb(stat, IMX_IIM_BASE + IIM_STAT); > + > + err = readb(IMX_IIM_BASE + IIM_ERR); > + if (err) { > + printf("fuse_blow: bit %d program error (0x%02x)\n", > + bit, err); > + ret = 1; > + goto out; > + } > + } > + > +out: > + /* protect fuse programing */ > + writeb(0, IMX_IIM_BASE + IIM_PREG_P); > + return ret; > +} > + > +static const __maybe_unused char cmd_fuse_blow_help[] = > +"Usage: fuse_blow <bank> <row> <value>\n" > +"Blow fuses in <bank> <row> to match <value>\n"; > + > +BAREBOX_CMD_START(fuse_blow) > + .cmd = do_fuse_blow, > + .usage = "program fuse row", > + BAREBOX_CMD_HELP(cmd_fuse_blow_help) > +BAREBOX_CMD_END > + > +static int do_fuse_sense(struct command *cmdtp, int argc, char *argv[]) > +{ > + unsigned int bank, row; > + u8 err, stat; > + > + if (argc != 3) > + return COMMAND_ERROR_USAGE; > + > + bank = simple_strtoul(argv[1], NULL, 0); > + row = simple_strtoul(argv[2], NULL, 0); > + > + if (bank > 7) { > + printf("fuse_sense: invalid bank number\n"); > + return 1; > + } > + > + if (row > 0x3ff) { > + printf("fuse_sense: invalid row offset\n"); > + return 1; > + } > + > + /* clear status and error registers */ > + writeb(3, IMX_IIM_BASE + IIM_STATM); > + writeb(0xfe, IMX_IIM_BASE + IIM_ERR); > + > + /* upper and lower address halves */ > + writeb((bank << 3) | (row >> 7), IMX_IIM_BASE + IIM_UA); > + writeb((row << 1) & 0xf8, IMX_IIM_BASE + IIM_LA); > + > + /* start fuse sensing */ > + writeb(0x08, IMX_IIM_BASE + IIM_FCTL); > + > + /* wait for sense done */ > + while ((readb(IMX_IIM_BASE + IIM_STAT) & 0x80) != 0) > + ; > + > + stat = readb(IMX_IIM_BASE + IIM_STAT); > + writeb(stat, IMX_IIM_BASE + IIM_STAT); > + > + err = readb(IMX_IIM_BASE + IIM_ERR); > + if (err) { > + printf("fuse_sense: sense error (0x%02x)\n", err); > + return 1; > + } > + > + printf("bank %u row 0x%02x: 0x%02x\n", bank, row, > + readb(IMX_IIM_BASE + IIM_SDAT)); > + > + return 0; > +} > + > +static const __maybe_unused char cmd_fuse_sense_help[] = > +"Usage: fuse_sense <bank> <row>\n" > +"Sense the fuses row at <bank> <row>\n"; > + > +BAREBOX_CMD_START(fuse_sense) > + .cmd = do_fuse_sense, > + .usage = "sense fuse row", > + BAREBOX_CMD_HELP(cmd_fuse_sense_help) > +BAREBOX_CMD_END > -- > 1.7.1 > > > _______________________________________________ > barebox mailing list > barebox@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/barebox _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox 2010-08-10 7:09 ` [PATCH 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox Jean-Christophe PLAGNIOL-VILLARD @ 2010-08-12 8:34 ` Baruch Siach 2010-08-12 8:35 ` [PATCH v2 " Baruch Siach 1 sibling, 0 replies; 9+ messages in thread From: Baruch Siach @ 2010-08-12 8:34 UTC (permalink / raw) To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox Hi Jean-Christophe On Tue, Aug 10, 2010 at 09:09:09AM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote: > sorry I do not really see what the comman do so maybe a small doc or > more comment will be nice OK. I'll add a documentation comment and resubmit. baruch > On 09:25 Tue 10 Aug , Baruch Siach wrote: > > This has only been tested on i.MX25, but should work on other i.MX chips with > > IIM. > > > > Signed-off-by: Baruch Siach <baruch@tkos.co.il> > > --- > > commands/Kconfig | 5 ++ > > commands/Makefile | 1 + > > commands/fuse.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++ > > 3 files changed, 167 insertions(+), 0 deletions(-) > > create mode 100644 commands/fuse.c > > > > diff --git a/commands/Kconfig b/commands/Kconfig > > index 9d11a8b..eb3e48e 100644 > > --- a/commands/Kconfig > > +++ b/commands/Kconfig > > @@ -173,6 +173,11 @@ config CMD_MTEST_ALTERNATIVE > > depends on CMD_MTEST > > prompt "alternative mtest implementation" > > > > +config CMD_FUSE_BLOW > > + tristate > > + depends on ARCH_IMX25 || ARCH_IMX35 > > + prompt "fuse_blow" > > + > > endmenu > > > > menu "flash " > > diff --git a/commands/Makefile b/commands/Makefile > > index 276af85..aa1c12e 100644 > > --- a/commands/Makefile > > +++ b/commands/Makefile > > @@ -8,6 +8,7 @@ obj-$(CONFIG_CMD_ECHO) += echo.o > > obj-$(CONFIG_CMD_MEMORY) += mem.o > > obj-$(CONFIG_CMD_LOADS) += s_record.o > > obj-$(CONFIG_CMD_MTEST) += memtest.o > > +obj-$(CONFIG_CMD_FUSE_BLOW) += fuse.o > > obj-$(CONFIG_CMD_EDIT) += edit.o > > obj-$(CONFIG_CMD_EXEC) += exec.o > > obj-$(CONFIG_CMD_SLEEP) += sleep.o > > diff --git a/commands/fuse.c b/commands/fuse.c > > new file mode 100644 > > index 0000000..1c0ccd6 > > --- /dev/null > > +++ b/commands/fuse.c > > @@ -0,0 +1,161 @@ > > +/* > > + * fuse.c - i.MX IIM fusebox programing and sensing > > + * > > + * Copyright (c) 2010 Baruch Siach <baruch@tkos.co.il>, > > + * Orex Computed Radiography > > + * > > + * This program is free software; you can redistribute it and/or modify > > + * it under the terms of the GNU General Public License version 2 > > + * as published by the Free Software Foundation. > > + * > > + * http://www.opensource.org/licenses/gpl-license.html > > + * http://www.gnu.org/copyleft/gpl.html > > + */ > > + > > +#include <common.h> > > +#include <command.h> > > +#include <asm/io.h> > > +#include <mach/imx-regs.h> > > +#include <mach/iim.h> > > + > > +static int do_fuse_blow(struct command *cmdtp, int argc, char *argv[]) > > +{ > > + unsigned int bank, row, value; > > + int bit, ret = 0; > > + u8 err, stat; > > + > > + if (argc != 4) > > + return COMMAND_ERROR_USAGE; > > + > > + bank = simple_strtoul(argv[1], NULL, 0); > > + row = simple_strtoul(argv[2], NULL, 0); > > + value = simple_strtoul(argv[3], NULL, 0); > > + > > + if (bank > 7) { > > + printf("fuse_blow: invalid bank number\n"); > > + return 1; > > + } > > + > > + if (row > 0x3ff) { > > + printf("fuse_blow: invalid row offset\n"); > > + return 1; > > + } > > + > > + if (value > 0xff) { > > + printf("fuse_blow: invalid value\n"); > > + return 1; > > + } > > + > > + /* clear status and error registers */ > > + writeb(3, IMX_IIM_BASE + IIM_STATM); > > + writeb(0xfe, IMX_IIM_BASE + IIM_ERR); > > + > > + /* unprotect fuse programing */ > > + writeb(0xaa, IMX_IIM_BASE + IIM_PREG_P); > > + > > + /* upper half address register */ > > + writeb((bank << 3) | (row >> 7), IMX_IIM_BASE + IIM_UA); > > + > > + for (bit = 0; bit < 8; bit++) { > > + if (((value >> bit) & 1) == 0) > > + continue; > > + > > + /* lower half address register */ > > + writeb(((row << 1) | bit), IMX_IIM_BASE + IIM_LA); > > + > > + /* start fuse programing */ > > + writeb(0x71, IMX_IIM_BASE + IIM_FCTL); > > + > > + /* wait for program done */ > > + while ((readb(IMX_IIM_BASE + IIM_STAT) & 0x80) != 0) > > + ; > > + > > + /* clear program done status */ > > + stat = readb(IMX_IIM_BASE + IIM_STAT); > > + writeb(stat, IMX_IIM_BASE + IIM_STAT); > > + > > + err = readb(IMX_IIM_BASE + IIM_ERR); > > + if (err) { > > + printf("fuse_blow: bit %d program error (0x%02x)\n", > > + bit, err); > > + ret = 1; > > + goto out; > > + } > > + } > > + > > +out: > > + /* protect fuse programing */ > > + writeb(0, IMX_IIM_BASE + IIM_PREG_P); > > + return ret; > > +} > > + > > +static const __maybe_unused char cmd_fuse_blow_help[] = > > +"Usage: fuse_blow <bank> <row> <value>\n" > > +"Blow fuses in <bank> <row> to match <value>\n"; > > + > > +BAREBOX_CMD_START(fuse_blow) > > + .cmd = do_fuse_blow, > > + .usage = "program fuse row", > > + BAREBOX_CMD_HELP(cmd_fuse_blow_help) > > +BAREBOX_CMD_END > > + > > +static int do_fuse_sense(struct command *cmdtp, int argc, char *argv[]) > > +{ > > + unsigned int bank, row; > > + u8 err, stat; > > + > > + if (argc != 3) > > + return COMMAND_ERROR_USAGE; > > + > > + bank = simple_strtoul(argv[1], NULL, 0); > > + row = simple_strtoul(argv[2], NULL, 0); > > + > > + if (bank > 7) { > > + printf("fuse_sense: invalid bank number\n"); > > + return 1; > > + } > > + > > + if (row > 0x3ff) { > > + printf("fuse_sense: invalid row offset\n"); > > + return 1; > > + } > > + > > + /* clear status and error registers */ > > + writeb(3, IMX_IIM_BASE + IIM_STATM); > > + writeb(0xfe, IMX_IIM_BASE + IIM_ERR); > > + > > + /* upper and lower address halves */ > > + writeb((bank << 3) | (row >> 7), IMX_IIM_BASE + IIM_UA); > > + writeb((row << 1) & 0xf8, IMX_IIM_BASE + IIM_LA); > > + > > + /* start fuse sensing */ > > + writeb(0x08, IMX_IIM_BASE + IIM_FCTL); > > + > > + /* wait for sense done */ > > + while ((readb(IMX_IIM_BASE + IIM_STAT) & 0x80) != 0) > > + ; > > + > > + stat = readb(IMX_IIM_BASE + IIM_STAT); > > + writeb(stat, IMX_IIM_BASE + IIM_STAT); > > + > > + err = readb(IMX_IIM_BASE + IIM_ERR); > > + if (err) { > > + printf("fuse_sense: sense error (0x%02x)\n", err); > > + return 1; > > + } > > + > > + printf("bank %u row 0x%02x: 0x%02x\n", bank, row, > > + readb(IMX_IIM_BASE + IIM_SDAT)); > > + > > + return 0; > > +} > > + > > +static const __maybe_unused char cmd_fuse_sense_help[] = > > +"Usage: fuse_sense <bank> <row>\n" > > +"Sense the fuses row at <bank> <row>\n"; > > + > > +BAREBOX_CMD_START(fuse_sense) > > + .cmd = do_fuse_sense, > > + .usage = "sense fuse row", > > + BAREBOX_CMD_HELP(cmd_fuse_sense_help) > > +BAREBOX_CMD_END > > -- > > 1.7.1 -- ~. .~ Tk Open Systems =}------------------------------------------------ooO--U--Ooo------------{= - baruch@tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il - _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox 2010-08-10 7:09 ` [PATCH 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox Jean-Christophe PLAGNIOL-VILLARD 2010-08-12 8:34 ` Baruch Siach @ 2010-08-12 8:35 ` Baruch Siach 2010-08-12 8:35 ` [PATCH v2 2/2] fec: add support for IIM stored mac address Baruch Siach 2010-08-12 9:06 ` [PATCH v2 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox Sascha Hauer 1 sibling, 2 replies; 9+ messages in thread From: Baruch Siach @ 2010-08-12 8:35 UTC (permalink / raw) To: barebox This has only been tested on i.MX25, but should work on other i.MX chips with IIM. Signed-off-by: Baruch Siach <baruch@tkos.co.il> --- Changes from v1: Improve commands documentation and add a comment describing the fuse commands. Make fuse_blow and fuse_sense build independent from each other. commands/Kconfig | 10 +++ commands/Makefile | 2 + commands/fuse.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 187 insertions(+), 0 deletions(-) create mode 100644 commands/fuse.c diff --git a/commands/Kconfig b/commands/Kconfig index 9d11a8b..1eae0d7 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -173,6 +173,16 @@ config CMD_MTEST_ALTERNATIVE depends on CMD_MTEST prompt "alternative mtest implementation" +config CMD_FUSE_BLOW + tristate + depends on ARCH_IMX25 || ARCH_IMX35 + prompt "fuse_blow" + +config CMD_FUSE_SENSE + tristate + depends on ARCH_IMX25 || ARCH_IMX35 + prompt "fuse_sense" + endmenu menu "flash " diff --git a/commands/Makefile b/commands/Makefile index 276af85..3c4e1d1 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -8,6 +8,8 @@ obj-$(CONFIG_CMD_ECHO) += echo.o obj-$(CONFIG_CMD_MEMORY) += mem.o obj-$(CONFIG_CMD_LOADS) += s_record.o obj-$(CONFIG_CMD_MTEST) += memtest.o +obj-$(CONFIG_CMD_FUSE_BLOW) += fuse.o +obj-$(CONFIG_CMD_FUSE_SENSE) += fuse.o obj-$(CONFIG_CMD_EDIT) += edit.o obj-$(CONFIG_CMD_EXEC) += exec.o obj-$(CONFIG_CMD_SLEEP) += sleep.o diff --git a/commands/fuse.c b/commands/fuse.c new file mode 100644 index 0000000..c9059b3 --- /dev/null +++ b/commands/fuse.c @@ -0,0 +1,175 @@ +/* + * fuse.c - i.MX IIM fusebox programing and sensing + * + * Provide an interface for programming and sensing the information that are + * stored in on-chip fuse elements. This functionality is part of the IC + * Identification Module (IIM), which is present on some i.MX CPUs. + * + * Copyright (c) 2010 Baruch Siach <baruch@tkos.co.il>, + * Orex Computed Radiography + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <common.h> +#include <command.h> +#include <asm/io.h> +#include <mach/imx-regs.h> +#include <mach/iim.h> + +#ifdef CONFIG_CMD_FUSE_BLOW + +static int do_fuse_blow(struct command *cmdtp, int argc, char *argv[]) +{ + unsigned int bank, row, value; + int bit, ret = 0; + u8 err, stat; + + if (argc != 4) + return COMMAND_ERROR_USAGE; + + bank = simple_strtoul(argv[1], NULL, 0); + row = simple_strtoul(argv[2], NULL, 0); + value = simple_strtoul(argv[3], NULL, 0); + + if (bank > 7) { + printf("fuse_blow: invalid bank number\n"); + return 1; + } + + if (row > 0x3ff) { + printf("fuse_blow: invalid row offset\n"); + return 1; + } + + if (value > 0xff) { + printf("fuse_blow: invalid value\n"); + return 1; + } + + /* clear status and error registers */ + writeb(3, IMX_IIM_BASE + IIM_STATM); + writeb(0xfe, IMX_IIM_BASE + IIM_ERR); + + /* unprotect fuse programing */ + writeb(0xaa, IMX_IIM_BASE + IIM_PREG_P); + + /* upper half address register */ + writeb((bank << 3) | (row >> 7), IMX_IIM_BASE + IIM_UA); + + for (bit = 0; bit < 8; bit++) { + if (((value >> bit) & 1) == 0) + continue; + + /* lower half address register */ + writeb(((row << 1) | bit), IMX_IIM_BASE + IIM_LA); + + /* start fuse programing */ + writeb(0x71, IMX_IIM_BASE + IIM_FCTL); + + /* wait for program done */ + while ((readb(IMX_IIM_BASE + IIM_STAT) & 0x80) != 0) + ; + + /* clear program done status */ + stat = readb(IMX_IIM_BASE + IIM_STAT); + writeb(stat, IMX_IIM_BASE + IIM_STAT); + + err = readb(IMX_IIM_BASE + IIM_ERR); + if (err) { + printf("fuse_blow: bit %d program error (0x%02x)\n", + bit, err); + ret = 1; + goto out; + } + } + +out: + /* protect fuse programing */ + writeb(0, IMX_IIM_BASE + IIM_PREG_P); + return ret; +} + +static const __maybe_unused char cmd_fuse_blow_help[] = +"Usage: fuse_blow <bank> <row> <value>\n" +"Blow unblown fuses in <bank> <row> to match <value>\n" +"Blown fuses are read as 1. Unblown fuses are read as 0.\n" +"WARNING: blown fuses can not be unblown. Use this command carefully.\n"; + +BAREBOX_CMD_START(fuse_blow) + .cmd = do_fuse_blow, + .usage = "program a row of fuses (8 bit)", + BAREBOX_CMD_HELP(cmd_fuse_blow_help) +BAREBOX_CMD_END + +#endif /* CONFIG_CMD_FUSE_BLOW */ + +#ifdef CONFIG_CMD_FUSE_SENSE + +static int do_fuse_sense(struct command *cmdtp, int argc, char *argv[]) +{ + unsigned int bank, row; + u8 err, stat; + + if (argc != 3) + return COMMAND_ERROR_USAGE; + + bank = simple_strtoul(argv[1], NULL, 0); + row = simple_strtoul(argv[2], NULL, 0); + + if (bank > 7) { + printf("fuse_sense: invalid bank number\n"); + return 1; + } + + if (row > 0x3ff) { + printf("fuse_sense: invalid row offset\n"); + return 1; + } + + /* clear status and error registers */ + writeb(3, IMX_IIM_BASE + IIM_STATM); + writeb(0xfe, IMX_IIM_BASE + IIM_ERR); + + /* upper and lower address halves */ + writeb((bank << 3) | (row >> 7), IMX_IIM_BASE + IIM_UA); + writeb((row << 1) & 0xf8, IMX_IIM_BASE + IIM_LA); + + /* start fuse sensing */ + writeb(0x08, IMX_IIM_BASE + IIM_FCTL); + + /* wait for sense done */ + while ((readb(IMX_IIM_BASE + IIM_STAT) & 0x80) != 0) + ; + + stat = readb(IMX_IIM_BASE + IIM_STAT); + writeb(stat, IMX_IIM_BASE + IIM_STAT); + + err = readb(IMX_IIM_BASE + IIM_ERR); + if (err) { + printf("fuse_sense: sense error (0x%02x)\n", err); + return 1; + } + + printf("bank %u row 0x%02x: 0x%02x\n", bank, row, + readb(IMX_IIM_BASE + IIM_SDAT)); + + return 0; +} + +static const __maybe_unused char cmd_fuse_sense_help[] = +"Usage: fuse_sense <bank> <row>\n" +"Sense the fuses row at <bank> <row>\n"; + +BAREBOX_CMD_START(fuse_sense) + .cmd = do_fuse_sense, + .usage = "sense a row of fuses (8 bit)", + BAREBOX_CMD_HELP(cmd_fuse_sense_help) +BAREBOX_CMD_END + +#endif /* CONFIG_CMD_FUSE_SENSE */ -- 1.7.1 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 2/2] fec: add support for IIM stored mac address 2010-08-12 8:35 ` [PATCH v2 " Baruch Siach @ 2010-08-12 8:35 ` Baruch Siach 2010-08-12 9:06 ` [PATCH v2 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox Sascha Hauer 1 sibling, 0 replies; 9+ messages in thread From: Baruch Siach @ 2010-08-12 8:35 UTC (permalink / raw) To: barebox This patch adds support for i.MX25 only, because that's what I have. Extending this to other i.MX chip should be trivial, given the right IIM_MAC_ADDR define. Signed-off-by: Baruch Siach <baruch@tkos.co.il> --- Changes from v1: Add mach/generic.h include for the cpu_is_mx25 macro. arch/arm/mach-imx/include/mach/imx25-regs.h | 1 + drivers/net/fec_imx.c | 11 +++++++++++ 2 files changed, 12 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-imx/include/mach/imx25-regs.h b/arch/arm/mach-imx/include/mach/imx25-regs.h index 7c2b5f9..f3da7b5 100644 --- a/arch/arm/mach-imx/include/mach/imx25-regs.h +++ b/arch/arm/mach-imx/include/mach/imx25-regs.h @@ -142,6 +142,7 @@ /* IIM fuse definitions */ #define IIM_UID 0x820 +#define IIM_MAC_ADDR 0x868 #endif /* __ASM_ARCH_MX25_REGS_H */ diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c index 40a7543..c29119c 100644 --- a/drivers/net/fec_imx.c +++ b/drivers/net/fec_imx.c @@ -32,6 +32,7 @@ #include <mach/imx-regs.h> #include <clock.h> #include <mach/clock.h> +#include <mach/generic.h> #include <xfuncs.h> #include "fec_imx.h" @@ -235,6 +236,16 @@ static void fec_rbd_clean(int last, struct buffer_descriptor *pRbd) static int fec_get_hwaddr(struct eth_device *dev, unsigned char *mac) { + int i; + + if (cpu_is_mx25()) { + /* get MAC address from the IMM fusebox */ + for (i = 0; i < 6; i++) + mac[i] = readb(IMX_IIM_BASE + IIM_MAC_ADDR + i*4); + + return 0; + } + /* no eeprom */ return -1; } -- 1.7.1 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox 2010-08-12 8:35 ` [PATCH v2 " Baruch Siach 2010-08-12 8:35 ` [PATCH v2 2/2] fec: add support for IIM stored mac address Baruch Siach @ 2010-08-12 9:06 ` Sascha Hauer 2010-08-12 9:27 ` Baruch Siach 1 sibling, 1 reply; 9+ messages in thread From: Sascha Hauer @ 2010-08-12 9:06 UTC (permalink / raw) To: Baruch Siach; +Cc: barebox On Thu, Aug 12, 2010 at 11:35:04AM +0300, Baruch Siach wrote: > This has only been tested on i.MX25, but should work on other i.MX chips with > IIM. I would prefer this command to be implemented as a device driver which registers a file under /dev. This way we could use the standard md/mw commands for this and look at a nice hexdump of all fuses and not only one at a time. As blowing fuses is quite dangerous, an additional iim.writeenable variable would be good. Sorry, but a command with three positional arguments is just so U-Boot. Sascha > > Signed-off-by: Baruch Siach <baruch@tkos.co.il> > --- > Changes from v1: > Improve commands documentation and add a comment describing the fuse > commands. > Make fuse_blow and fuse_sense build independent from each other. > > commands/Kconfig | 10 +++ > commands/Makefile | 2 + > commands/fuse.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 187 insertions(+), 0 deletions(-) > create mode 100644 commands/fuse.c > > diff --git a/commands/Kconfig b/commands/Kconfig > index 9d11a8b..1eae0d7 100644 > --- a/commands/Kconfig > +++ b/commands/Kconfig > @@ -173,6 +173,16 @@ config CMD_MTEST_ALTERNATIVE > depends on CMD_MTEST > prompt "alternative mtest implementation" > > +config CMD_FUSE_BLOW > + tristate > + depends on ARCH_IMX25 || ARCH_IMX35 > + prompt "fuse_blow" > + > +config CMD_FUSE_SENSE > + tristate > + depends on ARCH_IMX25 || ARCH_IMX35 > + prompt "fuse_sense" > + > endmenu > > menu "flash " > diff --git a/commands/Makefile b/commands/Makefile > index 276af85..3c4e1d1 100644 > --- a/commands/Makefile > +++ b/commands/Makefile > @@ -8,6 +8,8 @@ obj-$(CONFIG_CMD_ECHO) += echo.o > obj-$(CONFIG_CMD_MEMORY) += mem.o > obj-$(CONFIG_CMD_LOADS) += s_record.o > obj-$(CONFIG_CMD_MTEST) += memtest.o > +obj-$(CONFIG_CMD_FUSE_BLOW) += fuse.o > +obj-$(CONFIG_CMD_FUSE_SENSE) += fuse.o > obj-$(CONFIG_CMD_EDIT) += edit.o > obj-$(CONFIG_CMD_EXEC) += exec.o > obj-$(CONFIG_CMD_SLEEP) += sleep.o > diff --git a/commands/fuse.c b/commands/fuse.c > new file mode 100644 > index 0000000..c9059b3 > --- /dev/null > +++ b/commands/fuse.c > @@ -0,0 +1,175 @@ > +/* > + * fuse.c - i.MX IIM fusebox programing and sensing > + * > + * Provide an interface for programming and sensing the information that are > + * stored in on-chip fuse elements. This functionality is part of the IC > + * Identification Module (IIM), which is present on some i.MX CPUs. > + * > + * Copyright (c) 2010 Baruch Siach <baruch@tkos.co.il>, > + * Orex Computed Radiography > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 > + * as published by the Free Software Foundation. > + * > + * http://www.opensource.org/licenses/gpl-license.html > + * http://www.gnu.org/copyleft/gpl.html > + */ > + > +#include <common.h> > +#include <command.h> > +#include <asm/io.h> > +#include <mach/imx-regs.h> > +#include <mach/iim.h> > + > +#ifdef CONFIG_CMD_FUSE_BLOW > + > +static int do_fuse_blow(struct command *cmdtp, int argc, char *argv[]) > +{ > + unsigned int bank, row, value; > + int bit, ret = 0; > + u8 err, stat; > + > + if (argc != 4) > + return COMMAND_ERROR_USAGE; > + > + bank = simple_strtoul(argv[1], NULL, 0); > + row = simple_strtoul(argv[2], NULL, 0); > + value = simple_strtoul(argv[3], NULL, 0); > + > + if (bank > 7) { > + printf("fuse_blow: invalid bank number\n"); > + return 1; > + } > + > + if (row > 0x3ff) { > + printf("fuse_blow: invalid row offset\n"); > + return 1; > + } > + > + if (value > 0xff) { > + printf("fuse_blow: invalid value\n"); > + return 1; > + } > + > + /* clear status and error registers */ > + writeb(3, IMX_IIM_BASE + IIM_STATM); > + writeb(0xfe, IMX_IIM_BASE + IIM_ERR); > + > + /* unprotect fuse programing */ > + writeb(0xaa, IMX_IIM_BASE + IIM_PREG_P); > + > + /* upper half address register */ > + writeb((bank << 3) | (row >> 7), IMX_IIM_BASE + IIM_UA); > + > + for (bit = 0; bit < 8; bit++) { > + if (((value >> bit) & 1) == 0) > + continue; > + > + /* lower half address register */ > + writeb(((row << 1) | bit), IMX_IIM_BASE + IIM_LA); > + > + /* start fuse programing */ > + writeb(0x71, IMX_IIM_BASE + IIM_FCTL); > + > + /* wait for program done */ > + while ((readb(IMX_IIM_BASE + IIM_STAT) & 0x80) != 0) > + ; > + > + /* clear program done status */ > + stat = readb(IMX_IIM_BASE + IIM_STAT); > + writeb(stat, IMX_IIM_BASE + IIM_STAT); > + > + err = readb(IMX_IIM_BASE + IIM_ERR); > + if (err) { > + printf("fuse_blow: bit %d program error (0x%02x)\n", > + bit, err); > + ret = 1; > + goto out; > + } > + } > + > +out: > + /* protect fuse programing */ > + writeb(0, IMX_IIM_BASE + IIM_PREG_P); > + return ret; > +} > + > +static const __maybe_unused char cmd_fuse_blow_help[] = > +"Usage: fuse_blow <bank> <row> <value>\n" > +"Blow unblown fuses in <bank> <row> to match <value>\n" > +"Blown fuses are read as 1. Unblown fuses are read as 0.\n" > +"WARNING: blown fuses can not be unblown. Use this command carefully.\n"; > + > +BAREBOX_CMD_START(fuse_blow) > + .cmd = do_fuse_blow, > + .usage = "program a row of fuses (8 bit)", > + BAREBOX_CMD_HELP(cmd_fuse_blow_help) > +BAREBOX_CMD_END > + > +#endif /* CONFIG_CMD_FUSE_BLOW */ > + > +#ifdef CONFIG_CMD_FUSE_SENSE > + > +static int do_fuse_sense(struct command *cmdtp, int argc, char *argv[]) > +{ > + unsigned int bank, row; > + u8 err, stat; > + > + if (argc != 3) > + return COMMAND_ERROR_USAGE; > + > + bank = simple_strtoul(argv[1], NULL, 0); > + row = simple_strtoul(argv[2], NULL, 0); > + > + if (bank > 7) { > + printf("fuse_sense: invalid bank number\n"); > + return 1; > + } > + > + if (row > 0x3ff) { > + printf("fuse_sense: invalid row offset\n"); > + return 1; > + } > + > + /* clear status and error registers */ > + writeb(3, IMX_IIM_BASE + IIM_STATM); > + writeb(0xfe, IMX_IIM_BASE + IIM_ERR); > + > + /* upper and lower address halves */ > + writeb((bank << 3) | (row >> 7), IMX_IIM_BASE + IIM_UA); > + writeb((row << 1) & 0xf8, IMX_IIM_BASE + IIM_LA); > + > + /* start fuse sensing */ > + writeb(0x08, IMX_IIM_BASE + IIM_FCTL); > + > + /* wait for sense done */ > + while ((readb(IMX_IIM_BASE + IIM_STAT) & 0x80) != 0) > + ; > + > + stat = readb(IMX_IIM_BASE + IIM_STAT); > + writeb(stat, IMX_IIM_BASE + IIM_STAT); > + > + err = readb(IMX_IIM_BASE + IIM_ERR); > + if (err) { > + printf("fuse_sense: sense error (0x%02x)\n", err); > + return 1; > + } > + > + printf("bank %u row 0x%02x: 0x%02x\n", bank, row, > + readb(IMX_IIM_BASE + IIM_SDAT)); > + > + return 0; > +} > + > +static const __maybe_unused char cmd_fuse_sense_help[] = > +"Usage: fuse_sense <bank> <row>\n" > +"Sense the fuses row at <bank> <row>\n"; > + > +BAREBOX_CMD_START(fuse_sense) > + .cmd = do_fuse_sense, > + .usage = "sense a row of fuses (8 bit)", > + BAREBOX_CMD_HELP(cmd_fuse_sense_help) > +BAREBOX_CMD_END > + > +#endif /* CONFIG_CMD_FUSE_SENSE */ > -- > 1.7.1 > > > _______________________________________________ > barebox mailing list > barebox@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/barebox > -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox 2010-08-12 9:06 ` [PATCH v2 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox Sascha Hauer @ 2010-08-12 9:27 ` Baruch Siach 2010-08-12 12:04 ` Sascha Hauer 0 siblings, 1 reply; 9+ messages in thread From: Baruch Siach @ 2010-08-12 9:27 UTC (permalink / raw) To: Sascha Hauer; +Cc: barebox Hi Sascha, On Thu, Aug 12, 2010 at 11:06:00AM +0200, Sascha Hauer wrote: > On Thu, Aug 12, 2010 at 11:35:04AM +0300, Baruch Siach wrote: > > This has only been tested on i.MX25, but should work on other i.MX chips with > > IIM. > > I would prefer this command to be implemented as a device driver which > registers a file under /dev. This way we could use the standard md/mw > commands for this and look at a nice hexdump of all fuses and not only > one at a time. There are two methods for getting fuses values, direct memory access, and explicit sensing. Each method can independently be disabled with two dedicated protect fuses. How can md choose the right sensing method? The IIM block also has an override functionality. Direct memory write to the fuse row overrides the value in this row. This feature can also be disabled with an override protect fuse. How does mw know whether you want to blow the fuses, or just override them? Currently, you can sense fuses using the direct memory access method, and also override fuses with the regular md/mw command over /dev/mem. baruch > As blowing fuses is quite dangerous, an additional iim.writeenable > variable would be good. > > Sorry, but a command with three positional arguments is just so U-Boot. > > Sascha > > > > > Signed-off-by: Baruch Siach <baruch@tkos.co.il> > > --- > > Changes from v1: > > Improve commands documentation and add a comment describing the fuse > > commands. > > Make fuse_blow and fuse_sense build independent from each other. > > > > commands/Kconfig | 10 +++ > > commands/Makefile | 2 + > > commands/fuse.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++ > > 3 files changed, 187 insertions(+), 0 deletions(-) > > create mode 100644 commands/fuse.c > > > > diff --git a/commands/Kconfig b/commands/Kconfig > > index 9d11a8b..1eae0d7 100644 > > --- a/commands/Kconfig > > +++ b/commands/Kconfig > > @@ -173,6 +173,16 @@ config CMD_MTEST_ALTERNATIVE > > depends on CMD_MTEST > > prompt "alternative mtest implementation" > > > > +config CMD_FUSE_BLOW > > + tristate > > + depends on ARCH_IMX25 || ARCH_IMX35 > > + prompt "fuse_blow" > > + > > +config CMD_FUSE_SENSE > > + tristate > > + depends on ARCH_IMX25 || ARCH_IMX35 > > + prompt "fuse_sense" > > + > > endmenu > > > > menu "flash " > > diff --git a/commands/Makefile b/commands/Makefile > > index 276af85..3c4e1d1 100644 > > --- a/commands/Makefile > > +++ b/commands/Makefile > > @@ -8,6 +8,8 @@ obj-$(CONFIG_CMD_ECHO) += echo.o > > obj-$(CONFIG_CMD_MEMORY) += mem.o > > obj-$(CONFIG_CMD_LOADS) += s_record.o > > obj-$(CONFIG_CMD_MTEST) += memtest.o > > +obj-$(CONFIG_CMD_FUSE_BLOW) += fuse.o > > +obj-$(CONFIG_CMD_FUSE_SENSE) += fuse.o > > obj-$(CONFIG_CMD_EDIT) += edit.o > > obj-$(CONFIG_CMD_EXEC) += exec.o > > obj-$(CONFIG_CMD_SLEEP) += sleep.o > > diff --git a/commands/fuse.c b/commands/fuse.c > > new file mode 100644 > > index 0000000..c9059b3 > > --- /dev/null > > +++ b/commands/fuse.c > > @@ -0,0 +1,175 @@ > > +/* > > + * fuse.c - i.MX IIM fusebox programing and sensing > > + * > > + * Provide an interface for programming and sensing the information that are > > + * stored in on-chip fuse elements. This functionality is part of the IC > > + * Identification Module (IIM), which is present on some i.MX CPUs. > > + * > > + * Copyright (c) 2010 Baruch Siach <baruch@tkos.co.il>, > > + * Orex Computed Radiography > > + * > > + * This program is free software; you can redistribute it and/or modify > > + * it under the terms of the GNU General Public License version 2 > > + * as published by the Free Software Foundation. > > + * > > + * http://www.opensource.org/licenses/gpl-license.html > > + * http://www.gnu.org/copyleft/gpl.html > > + */ > > + > > +#include <common.h> > > +#include <command.h> > > +#include <asm/io.h> > > +#include <mach/imx-regs.h> > > +#include <mach/iim.h> > > + > > +#ifdef CONFIG_CMD_FUSE_BLOW > > + > > +static int do_fuse_blow(struct command *cmdtp, int argc, char *argv[]) > > +{ > > + unsigned int bank, row, value; > > + int bit, ret = 0; > > + u8 err, stat; > > + > > + if (argc != 4) > > + return COMMAND_ERROR_USAGE; > > + > > + bank = simple_strtoul(argv[1], NULL, 0); > > + row = simple_strtoul(argv[2], NULL, 0); > > + value = simple_strtoul(argv[3], NULL, 0); > > + > > + if (bank > 7) { > > + printf("fuse_blow: invalid bank number\n"); > > + return 1; > > + } > > + > > + if (row > 0x3ff) { > > + printf("fuse_blow: invalid row offset\n"); > > + return 1; > > + } > > + > > + if (value > 0xff) { > > + printf("fuse_blow: invalid value\n"); > > + return 1; > > + } > > + > > + /* clear status and error registers */ > > + writeb(3, IMX_IIM_BASE + IIM_STATM); > > + writeb(0xfe, IMX_IIM_BASE + IIM_ERR); > > + > > + /* unprotect fuse programing */ > > + writeb(0xaa, IMX_IIM_BASE + IIM_PREG_P); > > + > > + /* upper half address register */ > > + writeb((bank << 3) | (row >> 7), IMX_IIM_BASE + IIM_UA); > > + > > + for (bit = 0; bit < 8; bit++) { > > + if (((value >> bit) & 1) == 0) > > + continue; > > + > > + /* lower half address register */ > > + writeb(((row << 1) | bit), IMX_IIM_BASE + IIM_LA); > > + > > + /* start fuse programing */ > > + writeb(0x71, IMX_IIM_BASE + IIM_FCTL); > > + > > + /* wait for program done */ > > + while ((readb(IMX_IIM_BASE + IIM_STAT) & 0x80) != 0) > > + ; > > + > > + /* clear program done status */ > > + stat = readb(IMX_IIM_BASE + IIM_STAT); > > + writeb(stat, IMX_IIM_BASE + IIM_STAT); > > + > > + err = readb(IMX_IIM_BASE + IIM_ERR); > > + if (err) { > > + printf("fuse_blow: bit %d program error (0x%02x)\n", > > + bit, err); > > + ret = 1; > > + goto out; > > + } > > + } > > + > > +out: > > + /* protect fuse programing */ > > + writeb(0, IMX_IIM_BASE + IIM_PREG_P); > > + return ret; > > +} > > + > > +static const __maybe_unused char cmd_fuse_blow_help[] = > > +"Usage: fuse_blow <bank> <row> <value>\n" > > +"Blow unblown fuses in <bank> <row> to match <value>\n" > > +"Blown fuses are read as 1. Unblown fuses are read as 0.\n" > > +"WARNING: blown fuses can not be unblown. Use this command carefully.\n"; > > + > > +BAREBOX_CMD_START(fuse_blow) > > + .cmd = do_fuse_blow, > > + .usage = "program a row of fuses (8 bit)", > > + BAREBOX_CMD_HELP(cmd_fuse_blow_help) > > +BAREBOX_CMD_END > > + > > +#endif /* CONFIG_CMD_FUSE_BLOW */ > > + > > +#ifdef CONFIG_CMD_FUSE_SENSE > > + > > +static int do_fuse_sense(struct command *cmdtp, int argc, char *argv[]) > > +{ > > + unsigned int bank, row; > > + u8 err, stat; > > + > > + if (argc != 3) > > + return COMMAND_ERROR_USAGE; > > + > > + bank = simple_strtoul(argv[1], NULL, 0); > > + row = simple_strtoul(argv[2], NULL, 0); > > + > > + if (bank > 7) { > > + printf("fuse_sense: invalid bank number\n"); > > + return 1; > > + } > > + > > + if (row > 0x3ff) { > > + printf("fuse_sense: invalid row offset\n"); > > + return 1; > > + } > > + > > + /* clear status and error registers */ > > + writeb(3, IMX_IIM_BASE + IIM_STATM); > > + writeb(0xfe, IMX_IIM_BASE + IIM_ERR); > > + > > + /* upper and lower address halves */ > > + writeb((bank << 3) | (row >> 7), IMX_IIM_BASE + IIM_UA); > > + writeb((row << 1) & 0xf8, IMX_IIM_BASE + IIM_LA); > > + > > + /* start fuse sensing */ > > + writeb(0x08, IMX_IIM_BASE + IIM_FCTL); > > + > > + /* wait for sense done */ > > + while ((readb(IMX_IIM_BASE + IIM_STAT) & 0x80) != 0) > > + ; > > + > > + stat = readb(IMX_IIM_BASE + IIM_STAT); > > + writeb(stat, IMX_IIM_BASE + IIM_STAT); > > + > > + err = readb(IMX_IIM_BASE + IIM_ERR); > > + if (err) { > > + printf("fuse_sense: sense error (0x%02x)\n", err); > > + return 1; > > + } > > + > > + printf("bank %u row 0x%02x: 0x%02x\n", bank, row, > > + readb(IMX_IIM_BASE + IIM_SDAT)); > > + > > + return 0; > > +} > > + > > +static const __maybe_unused char cmd_fuse_sense_help[] = > > +"Usage: fuse_sense <bank> <row>\n" > > +"Sense the fuses row at <bank> <row>\n"; > > + > > +BAREBOX_CMD_START(fuse_sense) > > + .cmd = do_fuse_sense, > > + .usage = "sense a row of fuses (8 bit)", > > + BAREBOX_CMD_HELP(cmd_fuse_sense_help) > > +BAREBOX_CMD_END > > + > > +#endif /* CONFIG_CMD_FUSE_SENSE */ > > -- > > 1.7.1 > > > > > > _______________________________________________ > > barebox mailing list > > barebox@lists.infradead.org > > http://lists.infradead.org/mailman/listinfo/barebox > > > > -- > Pengutronix e.K. | | > Industrial Linux Solutions | http://www.pengutronix.de/ | > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | -- ~. .~ Tk Open Systems =}------------------------------------------------ooO--U--Ooo------------{= - baruch@tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il - _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox 2010-08-12 9:27 ` Baruch Siach @ 2010-08-12 12:04 ` Sascha Hauer 0 siblings, 0 replies; 9+ messages in thread From: Sascha Hauer @ 2010-08-12 12:04 UTC (permalink / raw) To: Baruch Siach; +Cc: barebox On Thu, Aug 12, 2010 at 12:27:01PM +0300, Baruch Siach wrote: > Hi Sascha, > > On Thu, Aug 12, 2010 at 11:06:00AM +0200, Sascha Hauer wrote: > > On Thu, Aug 12, 2010 at 11:35:04AM +0300, Baruch Siach wrote: > > > This has only been tested on i.MX25, but should work on other i.MX chips with > > > IIM. > > > > I would prefer this command to be implemented as a device driver which > > registers a file under /dev. This way we could use the standard md/mw > > commands for this and look at a nice hexdump of all fuses and not only > > one at a time. > > There are two methods for getting fuses values, direct memory access, and > explicit sensing. Each method can independently be disabled with two dedicated > protect fuses. How can md choose the right sensing method? By trying one method first and fall back to the other method. > > The IIM block also has an override functionality. Direct memory write to the > fuse row overrides the value in this row. This feature can also be disabled > with an override protect fuse. How does mw know whether you want to blow the > fuses, or just override them? You could override them when iim.writeenable=0 and blow them when iim.writeenable=1. Return failure when the override protect fuse is blown. The fuse_blow/fuse_sense commands do not make this decision either, they use the explicit sensing method hardcoded. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2010-08-12 12:04 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2010-08-10 6:25 [PATCH 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox Baruch Siach 2010-08-10 6:25 ` [PATCH 2/2] fec: add support for IIM stored mac address Baruch Siach 2010-08-10 7:09 ` [PATCH 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox Jean-Christophe PLAGNIOL-VILLARD 2010-08-12 8:34 ` Baruch Siach 2010-08-12 8:35 ` [PATCH v2 " Baruch Siach 2010-08-12 8:35 ` [PATCH v2 2/2] fec: add support for IIM stored mac address Baruch Siach 2010-08-12 9:06 ` [PATCH v2 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox Sascha Hauer 2010-08-12 9:27 ` Baruch Siach 2010-08-12 12:04 ` Sascha Hauer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox