mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Baruch Siach <baruch@tkos.co.il>
To: Sascha Hauer <s.hauer@pengutronix.de>
Cc: barebox@lists.infradead.org
Subject: Re: [PATCH v2 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox
Date: Thu, 12 Aug 2010 12:27:01 +0300	[thread overview]
Message-ID: <20100812092701.GE13166@jasper.tkos.co.il> (raw)
In-Reply-To: <20100812090600.GY27749@pengutronix.de>

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

  reply	other threads:[~2010-08-12  9:27 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-10  6:25 [PATCH " 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 [this message]
2010-08-12 12:04         ` Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100812092701.GE13166@jasper.tkos.co.il \
    --to=baruch@tkos.co.il \
    --cc=barebox@lists.infradead.org \
    --cc=s.hauer@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox