[PATCH 1/2] cmd: add fuse_blow/fuse_sense for the i.MX IIM fusebox
Baruch Siach
baruch at tkos.co.il
Thu Aug 12 04:34:10 EDT 2010
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 at 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 at 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 at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -
More information about the barebox
mailing list