mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [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