* [U-Boot] [PATCH v3 2/7] imx: Add useful fuse definitions
2013-03-26 21:24 [U-Boot] [PATCH v3 1/7] imx: Homogenize and fix fuse register definitions Benoît Thébaudeau
@ 2013-03-26 21:24 ` Benoît Thébaudeau
2013-03-26 21:24 ` [U-Boot] [PATCH v3 3/7] Add fuse API and commands Benoît Thébaudeau
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Benoît Thébaudeau @ 2013-03-26 21:24 UTC (permalink / raw)
To: u-boot
Define the UID (SoC unique ID) fuses, and the fuses available for the user.
Signed-off-by: Beno?t Th?baudeau <benoit.thebaudeau@advansee.com>
---
Changes in v3:
- Add i.MX6 GP2.
Changes in v2:
- Rebase against latest master.
arch/arm/include/asm/arch-mx25/imx-regs.h | 11 ++++++++++-
arch/arm/include/asm/arch-mx31/imx-regs.h | 12 ++++++++++++
arch/arm/include/asm/arch-mx35/imx-regs.h | 12 ++++++++++++
arch/arm/include/asm/arch-mx5/imx-regs.h | 16 +++++++++++++++-
arch/arm/include/asm/arch-mx6/imx-regs.h | 4 +++-
5 files changed, 52 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/arch-mx25/imx-regs.h b/arch/arm/include/asm/arch-mx25/imx-regs.h
index 99c32d4..cf7bb5a 100644
--- a/arch/arm/include/asm/arch-mx25/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx25/imx-regs.h
@@ -126,10 +126,19 @@ struct iim_regs {
};
struct fuse_bank0_regs {
- u32 fuse0_25[0x1a];
+ u32 fuse0_7[8];
+ u32 uid[8];
+ u32 fuse16_25[0xa];
u32 mac_addr[6];
};
+struct fuse_bank1_regs {
+ u32 fuse0_21[0x16];
+ u32 usr5;
+ u32 fuse23_29[7];
+ u32 usr6[2];
+};
+
/* Multi-Layer AHB Crossbar Switch (MAX) registers */
struct max_regs {
u32 mpr0;
diff --git a/arch/arm/include/asm/arch-mx31/imx-regs.h b/arch/arm/include/asm/arch-mx31/imx-regs.h
index f67f49c..5d8d8f4 100644
--- a/arch/arm/include/asm/arch-mx31/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx31/imx-regs.h
@@ -92,6 +92,18 @@ struct iim_regs {
} bank[3];
};
+struct fuse_bank0_regs {
+ u32 fuse0_5[6];
+ u32 usr;
+ u32 fuse7_15[9];
+};
+
+struct fuse_bank2_regs {
+ u32 fuse0;
+ u32 uid[8];
+ u32 fuse9_15[7];
+};
+
struct iomuxc_regs {
u32 unused1;
u32 unused2;
diff --git a/arch/arm/include/asm/arch-mx35/imx-regs.h b/arch/arm/include/asm/arch-mx35/imx-regs.h
index 64546d2..63c6e24 100644
--- a/arch/arm/include/asm/arch-mx35/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx35/imx-regs.h
@@ -274,6 +274,18 @@ struct iim_regs {
} bank[3];
};
+struct fuse_bank0_regs {
+ u32 fuse0_7[8];
+ u32 uid[8];
+ u32 fuse16_31[0x10];
+};
+
+struct fuse_bank1_regs {
+ u32 fuse0_21[0x16];
+ u32 usr;
+ u32 fuse23_31[9];
+};
+
/* General Purpose Timer (GPT) registers */
struct gpt_regs {
u32 ctrl; /* control */
diff --git a/arch/arm/include/asm/arch-mx5/imx-regs.h b/arch/arm/include/asm/arch-mx5/imx-regs.h
index f457b4e..8fce11b 100644
--- a/arch/arm/include/asm/arch-mx5/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx5/imx-regs.h
@@ -515,8 +515,14 @@ struct iim_regs {
};
struct fuse_bank0_regs {
- u32 fuse0_23[24];
+ u32 fuse0_7[8];
+ u32 uid[8];
+ u32 fuse16_23[8];
+#if defined(CONFIG_MX51)
+ u32 imei[8];
+#elif defined(CONFIG_MX53)
u32 gp[8];
+#endif
};
struct fuse_bank1_regs {
@@ -525,6 +531,14 @@ struct fuse_bank1_regs {
u32 fuse15_31[0x11];
};
+#if defined(CONFIG_MX53)
+struct fuse_bank4_regs {
+ u32 fuse0_4[5];
+ u32 gp[3];
+ u32 fuse8_31[0x18];
+};
+#endif
+
#endif /* __ASSEMBLER__*/
#endif /* __ASM_ARCH_MX5_IMX_REGS_H__ */
diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h
index cdaf5f8..efab943 100644
--- a/arch/arm/include/asm/arch-mx6/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx6/imx-regs.h
@@ -405,7 +405,9 @@ struct fuse_bank4_regs {
u32 mac_addr_high;
u32 rsvd3[0xb];
u32 gp1;
- u32 rsvd4[7];
+ u32 rsvd4[3];
+ u32 gp2;
+ u32 rsvd5[3];
};
struct aipstz_regs {
--
1.7.10.4
^ permalink raw reply related [flat|nested] 8+ messages in thread* [U-Boot] [PATCH v3 3/7] Add fuse API and commands
2013-03-26 21:24 [U-Boot] [PATCH v3 1/7] imx: Homogenize and fix fuse register definitions Benoît Thébaudeau
2013-03-26 21:24 ` [U-Boot] [PATCH v3 2/7] imx: Add useful fuse definitions Benoît Thébaudeau
@ 2013-03-26 21:24 ` Benoît Thébaudeau
[not found] ` <591915556.930388.1364333319357.JavaMail.root@advansee.com>
2013-03-26 21:24 ` [U-Boot] [PATCH v3 4/7] Add fsl_iim driver Benoît Thébaudeau
` (3 subsequent siblings)
5 siblings, 1 reply; 8+ messages in thread
From: Benoît Thébaudeau @ 2013-03-26 21:24 UTC (permalink / raw)
To: u-boot
This can be useful for fuse-like hardware, OTP SoC options, etc.
Signed-off-by: Beno?t Th?baudeau <benoit.thebaudeau@advansee.com>
---
Changes in v3:
- Rebase against latest u-boot-imx/master.
- Update copyright years.
- Rename the "ovride" command to "override" as it is nicer to read.
- For obvious safety reasons, ask the user to confirm each fuse programming
operation, unless the '-y' command line option was given, which can be used
in scripts.
- Rename "row" to "word" since it is less confusing and it is vocabulary common
to iim and ocotp in the reference manuals.
- Add doc/README.fuse.
Changes in v2:
- Rebase against latest master.
README | 1 +
common/Makefile | 1 +
common/cmd_fuse.c | 214 ++++++++++++++++++++++++++++++++++++++++++++++
doc/README.fuse | 73 ++++++++++++++++
include/config_cmd_all.h | 1 +
include/fuse.h | 49 +++++++++++
6 files changed, 339 insertions(+)
create mode 100644 common/cmd_fuse.c
create mode 100644 doc/README.fuse
create mode 100644 include/fuse.h
diff --git a/README b/README
index e45ae4a..14ab9df 100644
--- a/README
+++ b/README
@@ -844,6 +844,7 @@ The following options need to be configured:
CONFIG_CMD_FDOS * Dos diskette Support
CONFIG_CMD_FLASH flinfo, erase, protect
CONFIG_CMD_FPGA FPGA device initialization support
+ CONFIG_CMD_FUSE Device fuse support
CONFIG_CMD_GETTIME * Get time since boot
CONFIG_CMD_GO * the 'go' command (exec code)
CONFIG_CMD_GREPENV * search environment
diff --git a/common/Makefile b/common/Makefile
index 719fc23..7207ad7 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -105,6 +105,7 @@ ifdef CONFIG_FPGA
COBJS-$(CONFIG_CMD_FPGA) += cmd_fpga.o
endif
COBJS-$(CONFIG_CMD_FS_GENERIC) += cmd_fs.o
+COBJS-$(CONFIG_CMD_FUSE) += cmd_fuse.o
COBJS-$(CONFIG_CMD_GETTIME) += cmd_gettime.o
COBJS-$(CONFIG_CMD_GPIO) += cmd_gpio.o
COBJS-$(CONFIG_CMD_I2C) += cmd_i2c.o
diff --git a/common/cmd_fuse.c b/common/cmd_fuse.c
new file mode 100644
index 0000000..862efda
--- /dev/null
+++ b/common/cmd_fuse.c
@@ -0,0 +1,214 @@
+/*
+ * (C) Copyright 2009-2013 ADVANSEE
+ * Beno?t Th?baudeau <benoit.thebaudeau@advansee.com>
+ *
+ * Based on the mpc512x iim code:
+ * Copyright 2008 Silicon Turnkey Express, Inc.
+ * Martha Marx <mmarx@silicontkx.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <fuse.h>
+#include <asm/errno.h>
+
+static int strtou32(const char *str, unsigned int base, u32 *result)
+{
+ char *ep;
+
+ *result = simple_strtoul(str, &ep, base);
+ if (ep == str || *ep != '\0')
+ return -EINVAL;
+
+ return 0;
+}
+
+static int confirm_prog(void)
+{
+ puts("Warning: Programming fuses is an irreversible operation!\n"
+ " This may brick your system.\n"
+ " Use this command only if you are sure of "
+ "what you are doing!\n"
+ "\nReally perform this fuse programming? <y/N>\n");
+
+ if (getc() == 'y') {
+ int c;
+
+ putc('y');
+ c = getc();
+ putc('\n');
+ if (c == '\r')
+ return 1;
+ }
+
+ puts("Fuse programming aborted\n");
+ return 0;
+}
+
+static int do_fuse(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ const char *op = argc >= 2 ? argv[1] : NULL;
+ int confirmed = argc >= 3 && !strcmp(argv[2], "-y");
+ u32 bank, word, bit, cnt, val;
+ int ret, i;
+
+ argc -= 2 + confirmed;
+ argv += 2 + confirmed;
+
+ if (argc < 2 || strtou32(argv[0], 0, &bank) ||
+ strtou32(argv[1], 0, &word))
+ return CMD_RET_USAGE;
+
+ if (!strcmp(op, "read.bit")) {
+ if (argc != 3 || strtou32(argv[2], 0, &bit))
+ return CMD_RET_USAGE;
+
+ printf("Reading bank %u word 0x%.8x bit %u: ", bank, word, bit);
+ ret = fuse_read_bit(bank, word, bit, &val);
+ if (ret)
+ goto err;
+
+ printf("%u\n", val);
+ } else if (!strcmp(op, "read.word")) {
+ if (argc == 2)
+ cnt = 1;
+ else if (argc != 3 || strtou32(argv[2], 0, &cnt))
+ return CMD_RET_USAGE;
+
+ printf("Reading bank %u:\n", bank);
+ for (i = 0; i < cnt; i++, word++) {
+ if (!(i % 4))
+ printf("\nWord 0x%.8x:", word);
+
+ ret = fuse_read_word(bank, word, &val);
+ if (ret)
+ goto err;
+
+ printf(" %.8x", val);
+ }
+ putc('\n');
+ } else if (!strcmp(op, "sense.bit")) {
+ if (argc != 3 || strtou32(argv[2], 0, &bit))
+ return CMD_RET_USAGE;
+
+ printf("Sensing bank %u word 0x%.8x bit %u: ", bank, word, bit);
+ ret = fuse_sense_bit(bank, word, bit, &val);
+ if (ret)
+ goto err;
+
+ printf("%u\n", val);
+ } else if (!strcmp(op, "sense.word")) {
+ if (argc == 2)
+ cnt = 1;
+ else if (argc != 3 || strtou32(argv[2], 0, &cnt))
+ return CMD_RET_USAGE;
+
+ printf("Sensing bank %u:\n", bank);
+ for (i = 0; i < cnt; i++, word++) {
+ if (!(i % 4))
+ printf("\nWord 0x%.8x:", word);
+
+ ret = fuse_sense_word(bank, word, &val);
+ if (ret)
+ goto err;
+
+ printf(" %.8x", val);
+ }
+ putc('\n');
+ } else if (!strcmp(op, "prog.bit")) {
+ if (argc != 3 || strtou32(argv[2], 0, &bit))
+ return CMD_RET_USAGE;
+
+ printf("Programming bank %u word 0x%.8x bit %u...\n",
+ bank, word, bit);
+ if (!confirmed && !confirm_prog())
+ return CMD_RET_FAILURE;
+ ret = fuse_prog_bit(bank, word, bit);
+ if (ret)
+ goto err;
+ } else if (!strcmp(op, "prog.word")) {
+ if (argc < 3)
+ return CMD_RET_USAGE;
+
+ for (i = 2; i < argc; i++, word++) {
+ if (strtou32(argv[i], 16, &val))
+ return CMD_RET_USAGE;
+
+ printf("Programming bank %u word 0x%.8x to 0x%.8x...\n",
+ bank, word, val);
+ if (!confirmed && !confirm_prog())
+ return CMD_RET_FAILURE;
+ ret = fuse_prog_word(bank, word, val);
+ if (ret)
+ goto err;
+ }
+ } else if (!strcmp(op, "override.bit")) {
+ if (argc != 4 || strtou32(argv[2], 0, &bit) ||
+ strtou32(argv[3], 0, &val) || val > 1)
+ return CMD_RET_USAGE;
+
+ printf("Overriding bank %u word 0x%.8x bit %u with %u...\n",
+ bank, word, bit, val);
+ ret = fuse_override_bit(bank, word, bit, val);
+ if (ret)
+ goto err;
+ } else if (!strcmp(op, "override.word")) {
+ if (argc < 3)
+ return CMD_RET_USAGE;
+
+ for (i = 2; i < argc; i++, word++) {
+ if (strtou32(argv[i], 16, &val))
+ return CMD_RET_USAGE;
+
+ printf("Overriding bank %u word 0x%.8x with "
+ "0x%.8x...\n", bank, word, val);
+ ret = fuse_override_word(bank, word, val);
+ if (ret)
+ goto err;
+ }
+ } else {
+ return CMD_RET_USAGE;
+ }
+
+ return 0;
+
+err:
+ puts("ERROR\n");
+ return ret;
+}
+
+U_BOOT_CMD(
+ fuse, CONFIG_SYS_MAXARGS, 0, do_fuse,
+ "Fuse sub-system",
+ "read.bit <bank> <word> <bit> - read a fuse bit\n"
+ "fuse read.word <bank> <word> [<cnt>] - read 1 or 'cnt' fuse words,\n"
+ " starting at 'word'\n"
+ "fuse sense.bit <bank> <word> <bit> - sense a fuse bit\n"
+ "fuse sense.word <bank> <word> [<cnt>] - sense 1 or 'cnt' fuse words,\n"
+ " starting at 'word'\n"
+ "fuse prog.bit [-y] <bank> <word> <bit> - program a fuse bit\n"
+ " (PERMANENT)\n"
+ "fuse prog.word [-y] <bank> <word> <hexval> [<hexval>...] - program 1\n"
+ " or several fuse words, starting at 'word' (PERMANENT)\n"
+ "fuse override.bit <bank> <word> <bit> <val> - override a fuse bit\n"
+ "fuse override.word <bank> <word> <hexval> [<hexval>...] - override 1\n"
+ " or several fuse words, starting at 'word'"
+);
diff --git a/doc/README.fuse b/doc/README.fuse
new file mode 100644
index 0000000..ee365ff
--- /dev/null
+++ b/doc/README.fuse
@@ -0,0 +1,73 @@
+Fuse API functions and commands
+
+The fuse API allows to control a fusebox and how it is used by the upper
+hardware layers.
+
+A fuse corresponds to a single non-volatile memory bit that can be programmed
+(i.e. blown, set to 1) only once. The programming operation is irreversible. A
+fuse that has not been programmed reads 0.
+
+Fuses can be used by SoCs to store various permanent configuration and data,
+e.g. boot configuration, security configuration, MAC addresses, etc.
+
+A fuse word is the smallest group of fuses that can be read at once from the
+fusebox control IP registers. This is limited to 32 bits with the current API.
+
+A fuse bank is the smallest group of fuse words having a common ID, as defined
+by each SoC.
+
+Upon startup, the fusebox control IP reads the fuse values and stores them to a
+volatile shadow cache.
+
+See the README files of the drivers implementing this API in order to know the
+SoC- and implementation-specific details.
+
+The API provides both bit and word accesses because the access type may change
+depending on the IP, and it is safer to manipulate only bits (when no more is
+needed) in order to avoid programming a wrong value.
+
+Functions / commands:
+
+ int fuse_read_bit(u32 bank, u32 word, u32 bit, u32 *val);
+ fuse read.bit <bank> <word> <bit>
+ int fuse_read_word(u32 bank, u32 word, u32 *val);
+ fuse read.word <bank> <word> [<cnt>]
+ Read a fuse bit or fuse words from the shadow cache.
+
+ int fuse_sense_bit(u32 bank, u32 word, u32 bit, u32 *val);
+ fuse sense.bit <bank> <word> <bit>
+ int fuse_sense_word(u32 bank, u32 word, u32 *val);
+ fuse sense.word <bank> <word> [<cnt>]
+ Sense - i.e. read directly from the fusebox, skipping the shadow cache - a
+ fuse bit or fuse words. This operation does not update the shadow cache.
+
+ This is useful to know the true value of a fuse if an override has been
+ performed (see below).
+
+ int fuse_prog_bit(u32 bank, u32 word, u32 bit);
+ fuse prog.bit [-y] <bank> <word> <bit>
+ int fuse_prog_word(u32 bank, u32 word, u32 val);
+ fuse prog.word [-y] <bank> <word> <hexval> [<hexval>...]
+ Program a fuse bit or fuse words. This operation directly affects the
+ fusebox and is irreversible. The shadow cache is updated accordingly or
+ not, depending on each IP.
+
+ int fuse_override_bit(u32 bank, u32 word, u32 bit, u32 val);
+ fuse override.bit <bank> <word> <bit> <val>
+ int fuse_override_word(u32 bank, u32 word, u32 val);
+ fuse override.word <bank> <word> <hexval> [<hexval>...]
+ Override a fuse bit or fuse words in the shadow cache.
+
+ The fusebox is unaffected, so following this operation, the shadow cache
+ may differ from the fusebox values. Read or sense operations can then be
+ used to get the values from the shadow cache or from the fusebox.
+
+ This is useful to change the behaviors linked to some cached fuse values,
+ either because this is needed only temporarily, or because some of the
+ fuses have already been programmed or are locked (if the SoC allows to
+ override a locked fuse).
+
+Configuration:
+
+ CONFIG_CMD_FUSE
+ Define this to enable the fuse commands.
diff --git a/include/config_cmd_all.h b/include/config_cmd_all.h
index 0930781..041b18e 100644
--- a/include/config_cmd_all.h
+++ b/include/config_cmd_all.h
@@ -40,6 +40,7 @@
#define CONFIG_CMD_FDOS /* Floppy DOS support */
#define CONFIG_CMD_FLASH /* flinfo, erase, protect */
#define CONFIG_CMD_FPGA /* FPGA configuration Support */
+#define CONFIG_CMD_FUSE /* Device fuse support */
#define CONFIG_CMD_GETTIME /* Get time since boot */
#define CONFIG_CMD_HASH /* calculate hash / digest */
#define CONFIG_CMD_HWFLOW /* RTS/CTS hw flow control */
diff --git a/include/fuse.h b/include/fuse.h
new file mode 100644
index 0000000..97dc569
--- /dev/null
+++ b/include/fuse.h
@@ -0,0 +1,49 @@
+/*
+ * (C) Copyright 2009-2013 ADVANSEE
+ * Beno?t Th?baudeau <benoit.thebaudeau@advansee.com>
+ *
+ * Based on the mpc512x iim code:
+ * Copyright 2008 Silicon Turnkey Express, Inc.
+ * Martha Marx <mmarx@silicontkx.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _FUSE_H_
+#define _FUSE_H_
+
+/*
+ * Read/Sense/Program/Override interface:
+ * bank: Fuse bank
+ * word: Fuse word within the bank
+ * bit: Fuse bit within the word
+ * val: Value to read/write
+ *
+ * Returns: 0 on success, not 0 on failure
+ */
+int fuse_read_bit(u32 bank, u32 word, u32 bit, u32 *val);
+int fuse_read_word(u32 bank, u32 word, u32 *val);
+int fuse_sense_bit(u32 bank, u32 word, u32 bit, u32 *val);
+int fuse_sense_word(u32 bank, u32 word, u32 *val);
+int fuse_prog_bit(u32 bank, u32 word, u32 bit);
+int fuse_prog_word(u32 bank, u32 word, u32 val);
+int fuse_override_bit(u32 bank, u32 word, u32 bit, u32 val);
+int fuse_override_word(u32 bank, u32 word, u32 val);
+
+#endif /* _FUSE_H_ */
--
1.7.10.4
^ permalink raw reply related [flat|nested] 8+ messages in thread* [U-Boot] [PATCH v3 4/7] Add fsl_iim driver
2013-03-26 21:24 [U-Boot] [PATCH v3 1/7] imx: Homogenize and fix fuse register definitions Benoît Thébaudeau
2013-03-26 21:24 ` [U-Boot] [PATCH v3 2/7] imx: Add useful fuse definitions Benoît Thébaudeau
2013-03-26 21:24 ` [U-Boot] [PATCH v3 3/7] Add fuse API and commands Benoît Thébaudeau
@ 2013-03-26 21:24 ` Benoît Thébaudeau
2013-03-26 21:24 ` [U-Boot] [PATCH v3 5/7] mpc: iim: Switch to common fsl_iim Benoît Thébaudeau
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Benoît Thébaudeau @ 2013-03-26 21:24 UTC (permalink / raw)
To: u-boot
Add a fsl_iim driver common to i.MX and MPC.
Signed-off-by: Beno?t Th?baudeau <benoit.thebaudeau@advansee.com>
---
Changes in v3:
- Update copyright years.
- Rename "row" to "word" since it is less confusing and it is vocabulary common
to iim and ocotp in the reference manuals.
- Add doc/README.fsl_iim.
Changes in v2:
- Rebase against latest master.
doc/README.fsl_iim | 51 ++++++++
drivers/misc/Makefile | 1 +
drivers/misc/fsl_iim.c | 318 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 370 insertions(+)
create mode 100644 doc/README.fsl_iim
create mode 100644 drivers/misc/fsl_iim.c
diff --git a/doc/README.fsl_iim b/doc/README.fsl_iim
new file mode 100644
index 0000000..2472521
--- /dev/null
+++ b/doc/README.fsl_iim
@@ -0,0 +1,51 @@
+Driver implementing the fuse API for Freescale's IC Identification Module (IIM)
+
+This IP can be found on the following SoCs:
+ - MPC512x,
+ - i.MX25,
+ - i.MX27,
+ - i.MX31,
+ - i.MX35,
+ - i.MX51,
+ - i.MX53.
+
+The section numbers in this file refer to the i.MX25 Reference Manual.
+
+A fuse word contains 8 fuse bit slots, as explained in 30.4.2.2.1.
+
+A bank contains 256 fuse word slots, as shown by the memory map in 30.3.1.
+
+Some fuse bit or word slots may not have the corresponding fuses actually
+implemented in the fusebox.
+
+See the README files of the SoCs using this driver in order to know the
+conventions used by U-Boot to store some specific data in the fuses, e.g. MAC
+addresses.
+
+Fuse operations:
+
+ Read
+ Read operations are implemented as read accesses to the shadow registers,
+ using "Word y of Bank x" from the register summary in 30.3.2. This is
+ explained in detail in 30.4.5.1.
+
+ Sense
+ Sense operations are implemented as explained in 30.4.5.2.
+
+ Program
+ Program operations are implemented as explained in 30.4.5.3. Following
+ this operation, the shadow registers are reloaded by the hardware (not
+ immediately, but this does not make any difference for a user reading
+ these registers).
+
+ Override
+ Override operations are implemented as write accesses to the shadow
+ registers, as explained in 30.4.5.4.
+
+Configuration:
+
+ CONFIG_FSL_IIM
+ Define this to enable the fsl_iim driver.
+
+ CONFIG_SYS_FSL_IIM_ADDR
+ This should be defined to the base address of the IIM IP.
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 8cdc3b6..c6dadd4 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -28,6 +28,7 @@ LIB := $(obj)libmisc.o
COBJS-$(CONFIG_ALI152X) += ali512x.o
COBJS-$(CONFIG_DS4510) += ds4510.o
COBJS-$(CONFIG_CBMEM_CONSOLE) += cbmem_console.o
+COBJS-$(CONFIG_FSL_IIM) += fsl_iim.o
COBJS-$(CONFIG_GPIO_LED) += gpio_led.o
COBJS-$(CONFIG_FSL_MC9SDZ60) += mc9sdz60.o
COBJS-$(CONFIG_NS87308) += ns87308.o
diff --git a/drivers/misc/fsl_iim.c b/drivers/misc/fsl_iim.c
new file mode 100644
index 0000000..33b9c9a
--- /dev/null
+++ b/drivers/misc/fsl_iim.c
@@ -0,0 +1,318 @@
+/*
+ * (C) Copyright 2009-2013 ADVANSEE
+ * Beno?t Th?baudeau <benoit.thebaudeau@advansee.com>
+ *
+ * Based on the mpc512x iim code:
+ * Copyright 2008 Silicon Turnkey Express, Inc.
+ * Martha Marx <mmarx@silicontkx.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <common.h>
+#include <hwconfig.h>
+#include <fuse.h>
+#include <asm/errno.h>
+#include <asm/byteorder.h>
+#include <asm/io.h>
+
+/* FSL IIM-specific constants */
+#define STAT_BUSY 0x80
+#define STAT_PRGD 0x02
+#define STAT_SNSD 0x01
+
+#define STATM_PRGD_M 0x02
+#define STATM_SNSD_M 0x01
+
+#define ERR_PRGE 0x80
+#define ERR_WPE 0x40
+#define ERR_OPE 0x20
+#define ERR_RPE 0x10
+#define ERR_WLRE 0x08
+#define ERR_SNSE 0x04
+#define ERR_PARITYE 0x02
+
+#define EMASK_PRGE_M 0x80
+#define EMASK_WPE_M 0x40
+#define EMASK_OPE_M 0x20
+#define EMASK_RPE_M 0x10
+#define EMASK_WLRE_M 0x08
+#define EMASK_SNSE_M 0x04
+#define EMASK_PARITYE_M 0x02
+
+#define FCTL_DPC 0x80
+#define FCTL_PRG_LENGTH_MASK 0x70
+#define FCTL_ESNS_N 0x08
+#define FCTL_ESNS_0 0x04
+#define FCTL_ESNS_1 0x02
+#define FCTL_PRG 0x01
+
+#define UA_A_BANK_MASK 0x38
+#define UA_A_ROWH_MASK 0x07
+
+#define LA_A_ROWL_MASK 0xf8
+#define LA_A_BIT_MASK 0x07
+
+#define PREV_PROD_REV_MASK 0xf8
+#define PREV_PROD_VT_MASK 0x07
+
+/* Select the correct accessors depending on endianness */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define iim_read32 in_le32
+#define iim_write32 out_le32
+#define iim_clrsetbits32 clrsetbits_le32
+#define iim_clrbits32 clrbits_le32
+#define iim_setbits32 setbits_le32
+#elif __BYTE_ORDER == __BIG_ENDIAN
+#define iim_read32 in_be32
+#define iim_write32 out_be32
+#define iim_clrsetbits32 clrsetbits_be32
+#define iim_clrbits32 clrbits_be32
+#define iim_setbits32 setbits_be32
+#else
+#error "Endianess is not defined: please fix to continue"
+#endif
+
+/* IIM control registers */
+struct fsl_iim {
+ u32 stat;
+ u32 statm;
+ u32 err;
+ u32 emask;
+ u32 fctl;
+ u32 ua;
+ u32 la;
+ u32 sdat;
+ u32 prev;
+ u32 srev;
+ u32 prg_p;
+ u32 scs[0x1f5];
+ struct {
+ u32 word[0x100];
+ } bank[8];
+};
+
+int fuse_read_bit(u32 bank, u32 word, u32 bit, u32 *val)
+{
+ int ret;
+
+ if (bit >= 8) {
+ puts("fsl_iim fuse read: Invalid argument\n");
+ return -EINVAL;
+ }
+
+ ret = fuse_read_word(bank, word, val);
+ if (ret)
+ return ret;
+
+ *val = !!(*val & 1 << bit);
+ return 0;
+}
+
+int fuse_read_word(u32 bank, u32 word, u32 *val)
+{
+ volatile struct fsl_iim *regs =
+ (struct fsl_iim *)CONFIG_SYS_FSL_IIM_ADDR;
+ u32 err;
+
+ if (bank >= ARRAY_SIZE(regs->bank) ||
+ word >= ARRAY_SIZE(regs->bank[0].word) ||
+ val == NULL) {
+ puts("fsl_iim fuse read: Invalid argument\n");
+ return -EINVAL;
+ }
+
+ iim_write32(®s->err, iim_read32(®s->err));
+ *val = iim_read32(®s->bank[bank].word[word]);
+ err = iim_read32(®s->err);
+ iim_write32(®s->err, iim_read32(®s->err));
+
+ if (err & ERR_RPE) {
+ puts("fsl_iim fuse read: Read protect error\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int fuse_sense_bit(u32 bank, u32 word, u32 bit, u32 *val)
+{
+ int ret;
+
+ if (bit >= 8) {
+ puts("fsl_iim fuse sense: Invalid argument\n");
+ return -EINVAL;
+ }
+
+ ret = fuse_sense_word(bank, word, val);
+ if (ret)
+ return ret;
+
+ *val = !!(*val & 1 << bit);
+ return 0;
+}
+
+int fuse_sense_word(u32 bank, u32 word, u32 *val)
+{
+ volatile struct fsl_iim *regs =
+ (struct fsl_iim *)CONFIG_SYS_FSL_IIM_ADDR;
+ u32 stat, err;
+
+ if (bank >= ARRAY_SIZE(regs->bank) ||
+ word >= ARRAY_SIZE(regs->bank[0].word) ||
+ val == NULL) {
+ puts("fsl_iim fuse sense: Invalid argument\n");
+ return -EINVAL;
+ }
+
+ iim_write32(®s->stat, iim_read32(®s->stat));
+ iim_write32(®s->err, iim_read32(®s->err));
+ iim_write32(®s->ua, bank << 3 | word >> 5);
+ iim_write32(®s->la, word << 3 & 0xff);
+ iim_write32(®s->fctl, iim_read32(®s->fctl) | FCTL_ESNS_N);
+ while (iim_read32(®s->stat) & STAT_BUSY)
+ udelay(20);
+ stat = iim_read32(®s->stat);
+ err = iim_read32(®s->err);
+ iim_write32(®s->stat, iim_read32(®s->stat));
+ iim_write32(®s->err, iim_read32(®s->err));
+
+ if (err & ERR_SNSE) {
+ puts("fsl_iim fuse sense: Explicit sense cycle error\n");
+ return -EIO;
+ }
+
+ if (!(stat & STAT_SNSD)) {
+ puts("fsl_iim fuse sense: Explicit sense cycle "
+ "did not complete\n");
+ return -EIO;
+ }
+
+ *val = iim_read32(®s->sdat);
+ return 0;
+}
+
+int fuse_prog_bit(u32 bank, u32 word, u32 bit)
+{
+ volatile struct fsl_iim *regs =
+ (struct fsl_iim *)CONFIG_SYS_FSL_IIM_ADDR;
+ u32 stat, err;
+
+ if (bank >= ARRAY_SIZE(regs->bank) ||
+ word >= ARRAY_SIZE(regs->bank[0].word) ||
+ bit >= 8) {
+ puts("fsl_iim fuse program: Invalid argument\n");
+ return -EINVAL;
+ }
+
+ iim_write32(®s->stat, iim_read32(®s->stat));
+ iim_write32(®s->err, iim_read32(®s->err));
+ iim_write32(®s->ua, bank << 3 | word >> 5);
+ iim_write32(®s->la, (word << 3 | bit) & 0xff);
+ iim_write32(®s->prg_p, 0xaa);
+ iim_write32(®s->fctl, iim_read32(®s->fctl) | FCTL_PRG);
+ while (iim_read32(®s->stat) & STAT_BUSY)
+ udelay(20);
+ stat = iim_read32(®s->stat);
+ err = iim_read32(®s->err);
+ iim_write32(®s->stat, iim_read32(®s->stat));
+ iim_write32(®s->err, iim_read32(®s->err));
+ iim_write32(®s->prg_p, 0x00);
+
+ if (err & ERR_PRGE) {
+ puts("fsl_iim fuse program: Program error\n");
+ return -EIO;
+ }
+
+ if (err & ERR_WPE) {
+ puts("fsl_iim fuse program: Write protect error\n");
+ return -EIO;
+ }
+
+ if (!(stat & STAT_PRGD)) {
+ puts("fsl_iim fuse program: Program did not complete\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int fuse_prog_word(u32 bank, u32 word, u32 val)
+{
+ int bit, ret;
+
+ if (val & ~0xff) {
+ puts("fsl_iim fuse program: Invalid argument\n");
+ return -EINVAL;
+ }
+
+ for (bit = 0; val; bit++, val >>= 1)
+ if (val & 0x01) {
+ ret = fuse_prog_bit(bank, word, bit);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+int fuse_override_bit(u32 bank, u32 word, u32 bit, u32 val)
+{
+ u32 word_val;
+ int ret;
+
+ if (bit >= 8 || val > 1) {
+ puts("fsl_iim fuse override: Invalid argument\n");
+ return -EINVAL;
+ }
+
+ ret = fuse_read_word(bank, word, &word_val);
+ if (ret)
+ return ret;
+
+ return fuse_override_word(bank, word,
+ (word_val & ~(1 << bit)) | val << bit);
+}
+
+int fuse_override_word(u32 bank, u32 word, u32 val)
+{
+ volatile struct fsl_iim *regs =
+ (struct fsl_iim *)CONFIG_SYS_FSL_IIM_ADDR;
+ u32 err;
+
+ if (bank >= ARRAY_SIZE(regs->bank) ||
+ word >= ARRAY_SIZE(regs->bank[0].word) ||
+ val & ~0xff) {
+ puts("fsl_iim fuse override: Invalid argument\n");
+ return -EINVAL;
+ }
+
+ iim_write32(®s->err, iim_read32(®s->err));
+ iim_write32(®s->bank[bank].word[word], val);
+ err = iim_read32(®s->err);
+ iim_write32(®s->err, iim_read32(®s->err));
+
+ if (err & ERR_OPE) {
+ puts("fsl_iim fuse override: Override protect error\n");
+ return -EIO;
+ }
+
+ return 0;
+}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 8+ messages in thread* [U-Boot] [PATCH v3 5/7] mpc: iim: Switch to common fsl_iim
2013-03-26 21:24 [U-Boot] [PATCH v3 1/7] imx: Homogenize and fix fuse register definitions Benoît Thébaudeau
` (2 preceding siblings ...)
2013-03-26 21:24 ` [U-Boot] [PATCH v3 4/7] Add fsl_iim driver Benoît Thébaudeau
@ 2013-03-26 21:24 ` Benoît Thébaudeau
2013-03-26 21:24 ` [U-Boot] [PATCH v3 6/7] mx51evk: Enable support for iim Benoît Thébaudeau
2013-03-26 21:24 ` [U-Boot] [PATCH v3 7/7] imx: Document fuse assignments for MAC addresses Benoît Thébaudeau
5 siblings, 0 replies; 8+ messages in thread
From: Benoît Thébaudeau @ 2013-03-26 21:24 UTC (permalink / raw)
To: u-boot
Signed-off-by: Beno?t Th?baudeau <benoit.thebaudeau@advansee.com>
---
Changes in v3: None
Changes in v2:
- Rebase against latest master.
arch/powerpc/cpu/mpc512x/Makefile | 1 -
arch/powerpc/cpu/mpc512x/iim.c | 394 -------------------------------
board/davedenx/aria/aria.c | 2 +-
board/esd/mecp5123/mecp5123.c | 2 +-
board/freescale/mpc5121ads/mpc5121ads.c | 2 +-
board/pdm360ng/pdm360ng.c | 2 +-
include/configs/aria.h | 2 +-
include/configs/mecp5123.h | 2 +-
include/configs/mpc5121ads.h | 2 +-
9 files changed, 7 insertions(+), 402 deletions(-)
delete mode 100644 arch/powerpc/cpu/mpc512x/iim.c
diff --git a/arch/powerpc/cpu/mpc512x/Makefile b/arch/powerpc/cpu/mpc512x/Makefile
index b53232f..4f4c9ec 100644
--- a/arch/powerpc/cpu/mpc512x/Makefile
+++ b/arch/powerpc/cpu/mpc512x/Makefile
@@ -38,7 +38,6 @@ COBJS-y += serial.o
COBJS-y += speed.o
COBJS-$(CONFIG_FSL_DIU_FB) += diu.o
COBJS-$(CONFIG_CMD_IDE) += ide.o
-COBJS-$(CONFIG_IIM) += iim.o
COBJS-$(CONFIG_PCI) += pci.o
# Stub implementations of cache management functions for USB
diff --git a/arch/powerpc/cpu/mpc512x/iim.c b/arch/powerpc/cpu/mpc512x/iim.c
deleted file mode 100644
index abec8f6..0000000
--- a/arch/powerpc/cpu/mpc512x/iim.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Copyright 2008 Silicon Turnkey Express, Inc.
- * Martha Marx <mmarx@silicontkx.com>
- *
- * ADS5121 IIM (Fusebox) Interface
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <command.h>
-#include <asm/io.h>
-
-#ifdef CONFIG_CMD_FUSE
-
-DECLARE_GLOBAL_DATA_PTR;
-
-static char cur_bank = '1';
-
-char *iim_err_msg(u32 err)
-{
- static char *IIM_errs[] = {
- "Parity Error in cache",
- "Explicit Sense Cycle Error",
- "Write to Locked Register Error",
- "Read Protect Error",
- "Override Protect Error",
- "Write Protect Error"};
-
- int i;
-
- if (!err)
- return "";
- for (i = 1; i < 8; i++)
- if (err & (1 << i))
- printf("IIM - %s\n", IIM_errs[i-1]);
- return "";
-}
-
-int in_range(int n, int min, int max, char *err, char *usg)
-{
- if (n > max || n < min) {
- printf(err);
- printf("Usage:\n%s\n", usg);
- return 0;
- }
- return 1;
-}
-
-int ads5121_fuse_read(int bank, int fstart, int num)
-{
- iim512x_t *iim = &((immap_t *) CONFIG_SYS_IMMR)->iim;
- u32 *iim_fb, dummy;
- int f, ctr;
-
- out_be32(&iim->err, in_be32(&iim->err));
- if (bank == 0)
- iim_fb = (u32 *)&(iim->fbac0);
- else
- iim_fb = (u32 *)&(iim->fbac1);
-/* try a read to see if Read Protect is set */
- dummy = in_be32(&iim_fb[0]);
- if (in_be32(&iim->err) & IIM_ERR_RPE) {
- printf("\tRead protect fuse is set\n");
- out_be32(&iim->err, IIM_ERR_RPE);
- return 0;
- }
- printf("Reading Bank %d cache\n", bank);
- for (f = fstart, ctr = 0; num > 0; ctr++, num--, f++) {
- if (ctr % 4 == 0)
- printf("F%2d:", f);
- printf("\t%#04x", (u8)(iim_fb[f]));
- if (ctr % 4 == 3)
- printf("\n");
- }
- if (ctr % 4 != 0)
- printf("\n");
-}
-
-int ads5121_fuse_override(int bank, int f, u8 val)
-{
- iim512x_t *iim = &((immap_t *) CONFIG_SYS_IMMR)->iim;
- u32 *iim_fb;
- u32 iim_stat;
- int i;
-
- out_be32(&iim->err, in_be32(&iim->err));
- if (bank == 0)
- iim_fb = (u32 *)&(iim->fbac0);
- else
- iim_fb = (u32 *)&(iim->fbac1);
-/* try a read to see if Read Protect is set */
- iim_stat = in_be32(&iim_fb[0]);
- if (in_be32(&iim->err) & IIM_ERR_RPE) {
- printf("Read protect fuse is set on bank %d;"
- "Override protect may also be set\n", bank);
- printf("An attempt will be made to override\n");
- out_be32(&iim->err, IIM_ERR_RPE);
- }
- if (iim_stat & IIM_FBAC_FBOP) {
- printf("Override protect fuse is set on bank %d\n", bank);
- return 1;
- }
- if (f > IIM_FMAX) /* reset the entire bank */
- for (i = 0; i < IIM_FMAX + 1; i++)
- out_be32(&iim_fb[i], 0);
- else
- out_be32(&iim_fb[f], val);
- return 0;
-}
-
-int ads5121_fuse_prog(cmd_tbl_t *cmdtp, int bank, char *fuseno_bitno)
-{
- iim512x_t *iim = &((immap_t *) CONFIG_SYS_IMMR)->iim;
- int f, i, bitno;
- u32 stat, err;
-
- f = simple_strtol(fuseno_bitno, NULL, 10);
- if (f == 0 && fuseno_bitno[0] != '0')
- f = -1;
- if (!in_range(f, 0, IIM_FMAX,
- "<frow> must be between 0-31\n\n", cmdtp->usage))
- return 1;
- bitno = -1;
- for (i = 0; i < 6; i++) {
- if (fuseno_bitno[i] == '_') {
- bitno = simple_strtol(&(fuseno_bitno[i+1]), NULL, 10);
- if (bitno == 0 && fuseno_bitno[i+1] != '0')
- bitno = -1;
- break;
- }
- }
- if (!in_range(bitno, 0, 7, "Bit number ranges from 0-7\n"
- "Example of <frow_bitno>: \"18_4\" sets bit 4 of row 18\n",
- cmdtp->usage))
- return 1;
- out_be32(&iim->err, in_be32(&iim->err));
- out_be32(&iim->prg_p, IIM_PRG_P_SET);
- out_be32(&iim->ua, IIM_SET_UA(bank, f));
- out_be32(&iim->la, IIM_SET_LA(f, bitno));
-#ifdef DEBUG
- printf("Programming disabled with DEBUG defined \n");
- printf(""Set up to pro
- printf("iim.ua = %x; iim.la = %x\n", iim->ua, iim->la);
-#else
- out_be32(&iim->fctl, IIM_FCTL_PROG_PULSE | IIM_FCTL_PROG);
- do
- udelay(20);
- while ((stat = in_be32(&iim->stat)) & IIM_STAT_BUSY);
- out_be32(&iim->prg_p, 0);
- err = in_be32(&iim->err);
- if (stat & IIM_STAT_PRGD) {
- if (!(err & (IIM_ERR_WPE | IIM_ERR_WPE))) {
- printf("Fuse is successfully set");
- if (err)
- printf(" - however there are other errors");
- printf("\n");
- }
- iim->stat = 0;
- }
- if (err) {
- iim_err_msg(err);
- out_be32(&iim->err, in_be32(&iim->err));
- }
-#endif
-}
-
-int ads5121_fuse_sense(int bank, int fstart, int num)
-{
- iim512x_t *iim = &((immap_t *) CONFIG_SYS_IMMR)->iim;
- u32 iim_fbac;
- u32 stat, err, err_hold = 0;
- int f, ctr;
-
- out_be32(&iim->err, in_be32(&iim->err));
- if (bank == 0)
- iim_fbac = in_be32(&iim->fbac0);
- else
- iim_fbac = in_be32(&iim->fbac1);
- if (iim_fbac & IIM_FBAC_FBESP) {
- printf("\tSense Protect disallows this operation\n");
- out_be32(&iim->err, IIM_FBAC_FBESP);
- return 1;
- }
- err = in_be32(&iim->err);
- if (err) {
- iim_err_msg(err);
- err_hold |= err;
- }
- if (err & IIM_ERR_RPE)
- printf("\tRead protect fuse is set; "
- "Sense Protect may be set but will be attempted\n");
- if (err)
- out_be32(&iim->err, err);
- printf("Sensing fuse(s) on Bank %d\n", bank);
- for (f = fstart, ctr = 0; num > 0; ctr++, f++, num--) {
- out_be32(&iim->ua, IIM_SET_UA(bank, f));
- out_be32(&iim->la, IIM_SET_LA(f, 0));
- out_be32(&iim->fctl, IIM_FCTL_ESNS_N);
- do
- udelay(20);
- while ((stat = in_be32(&iim->stat)) & IIM_STAT_BUSY);
- err = in_be32(&iim->err);
- if (err & IIM_ERR_SNSE) {
- iim_err_msg(err);
- out_be32(&iim->err, IIM_ERR_SNSE);
- return 1;
- }
- if (stat & IIM_STAT_SNSD) {
- out_be32(&iim->stat, 0);
- if (ctr % 4 == 0)
- printf("F%2d:", f);
- printf("\t%#04x", (u8)iim->sdat);
- if (ctr % 4 == 3)
- printf("\n");
- }
- if (err) {
- err_hold |= err;
- out_be32(&iim->err, err);
- }
- }
- if (ctr % 4 != 0)
- printf("\n");
- if (err_hold)
- iim_err_msg(err_hold);
-
- return 0;
-}
-
-int ads5121_fuse_stat(int bank)
-{
- iim512x_t *iim = &((immap_t *) CONFIG_SYS_IMMR)->iim;
- u32 iim_fbac;
- u32 err;
-
- out_be32(&iim->err, in_be32(&iim->err));
- if (bank == 0)
- iim_fbac = in_be32(&iim->fbac0);
- else
- iim_fbac = in_be32(&iim->fbac1);
- err = in_be32(&iim->err);
- if (err)
- iim_err_msg(err);
- if (err & IIM_ERR_RPE || iim_fbac & IIM_FBAC_FBRP) {
- if (iim_fbac == 0)
- printf("Since protection settings can't be read - "
- "try sensing fuse row 0;\n");
- return 0;
- }
- if (iim_fbac & IIM_PROTECTION)
- printf("Protection Fuses Bank %d = %#04x:\n", bank, iim_fbac);
- else if (!(err & IIM_ERR_RPE))
- printf("No Protection fuses are set\n");
- if (iim_fbac & IIM_FBAC_FBWP)
- printf("\tWrite Protect fuse is set\n");
- if (iim_fbac & IIM_FBAC_FBOP)
- printf("\tOverride Protect fuse is set\n");
- if (iim_fbac & IIM_FBAC_FBESP)
- printf("\tSense Protect Fuse is set\n");
- out_be32(&iim->err, in_be32(&iim->err));
-
- return 0;
-}
-
-int do_ads5121_fuse(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
- int frow, n, v, bank;
-
- if (cur_bank == '0')
- bank = 0;
- else
- bank = 1;
-
- switch (argc) {
- case 0:
- case 1:
- printf("Usage:\n%s\n", cmdtp->usage);
- return 1;
- case 2:
- if (strncmp(argv[1], "stat", 4) == 0)
- return ads5121_fuse_stat(bank);
- if (strncmp(argv[1], "read", 4) == 0)
- return ads5121_fuse_read(bank, 0, IIM_FMAX + 1);
- if (strncmp(argv[1], "sense", 5) == 0)
- return ads5121_fuse_sense(bank, 0, IIM_FMAX + 1);
- if (strncmp(argv[1], "ovride", 6) == 0)
- return ads5121_fuse_override(bank, IIM_FMAX + 1, 0);
- if (strncmp(argv[1], "bank", 4) == 0) {
- printf("Active Fuse Bank is %c\n", cur_bank);
- return 0;
- }
- printf("Usage:\n%s\n", cmdtp->usage);
- return 1;
- case 3:
- if (strncmp(argv[1], "bank", 4) == 0) {
- if (argv[2][0] == '0')
- cur_bank = '0';
- else if (argv[2][0] == '1')
- cur_bank = '1';
- else {
- printf("Usage:\n%s\n", cmdtp->usage);
- return 1;
- }
-
- printf("Setting Active Fuse Bank to %c\n", cur_bank);
- return 0;
- }
- if (strncmp(argv[1], "prog", 4) == 0)
- return ads5121_fuse_prog(cmdtp, bank, argv[2]);
-
- frow = (int)simple_strtol(argv[2], NULL, 10);
- if (frow == 0 && argv[2][0] != '0')
- frow = -1;
- if (!in_range(frow, 0, IIM_FMAX,
- "<frow> must be between 0-31\n\n", cmdtp->usage))
- return 1;
- if (strncmp(argv[1], "read", 4) == 0)
- return ads5121_fuse_read(bank, frow, 1);
- if (strncmp(argv[1], "ovride", 6) == 0)
- return ads5121_fuse_override(bank, frow, 0);
- if (strncmp(argv[1], "sense", 5) == 0)
- return ads5121_fuse_sense(bank, frow, 1);
- printf("Usage:\n%s\n", cmdtp->usage);
- return 1;
- case 4:
- frow = (int)simple_strtol(argv[2], NULL, 10);
- if (frow == 0 && argv[2][0] != '0')
- frow = -1;
- if (!in_range(frow, 0, IIM_FMAX,
- "<frow> must be between 0-31\n\n", cmdtp->usage))
- return 1;
- if (strncmp(argv[1], "read", 4) == 0) {
- n = (int)simple_strtol(argv[3], NULL, 10);
- if (!in_range(frow + n, frow + 1, IIM_FMAX + 1,
- "<frow>+<n> must be between 1-32\n\n",
- cmdtp->usage))
- return 1;
- return ads5121_fuse_read(bank, frow, n);
- }
- if (strncmp(argv[1], "ovride", 6) == 0) {
- v = (int)simple_strtol(argv[3], NULL, 10);
- return ads5121_fuse_override(bank, frow, v);
- }
- if (strncmp(argv[1], "sense", 5) == 0) {
- n = (int)simple_strtol(argv[3], NULL, 10);
- if (!in_range(frow + n, frow + 1, IIM_FMAX + 1,
- "<frow>+<n> must be between 1-32\n\n",
- cmdtp->usage))
- return 1;
- return ads5121_fuse_sense(bank, frow, n);
- }
- printf("Usage:\n%s\n", cmdtp->usage);
- return 1;
- default: /* at least 5 args */
- printf("Usage:\n%s\n", cmdtp->usage);
- return 1;
- }
-}
-
-U_BOOT_CMD(
- fuse, CONFIG_SYS_MAXARGS, 0, do_ads5121_fuse,
- " - Read, Sense, Override or Program Fuses\n",
- "bank <n> - sets active Fuse Bank to 0 or 1\n"
- " no args shows current active bank\n"
- "fuse stat - print active fuse bank's protection status\n"
- "fuse read [<frow> [<n>]] - print <n> fuse rows starting at <frow>\n"
- " no args to print entire bank's fuses\n"
- "fuse ovride [<frow> [<v>]]- override fuses at <frow> with <v>\n"
- " no <v> defaults to 0 for the row\n"
- " no args resets entire bank to 0\n"
- " NOTE - settings persist until hard reset\n"
- "fuse sense [<frow>] - senses current fuse at <frow>\n"
- " no args for entire bank\n"
- "fuse prog <frow_bit> - program fuse at row <frow>, bit <_bit>\n"
- " <frow> is 0-31, <bit> is 0-7; eg. 13_2 \n"
- " WARNING - this is permanent"
-);
-#endif /* CONFIG_CMD_FUSE */
diff --git a/board/davedenx/aria/aria.c b/board/davedenx/aria/aria.c
index 31b079b..d2ffba4 100644
--- a/board/davedenx/aria/aria.c
+++ b/board/davedenx/aria/aria.c
@@ -92,7 +92,7 @@ int board_early_init_f(void)
*/
out_be32(&im->clk.sccr[0], SCCR1_CLOCKS_EN);
out_be32(&im->clk.sccr[1], SCCR2_CLOCKS_EN);
-#if defined(CONFIG_IIM) || defined(CONFIG_CMD_FUSE)
+#if defined(CONFIG_FSL_IIM) || defined(CONFIG_CMD_FUSE)
setbits_be32(&im->clk.sccr[1], CLOCK_SCCR2_IIM_EN);
#endif
diff --git a/board/esd/mecp5123/mecp5123.c b/board/esd/mecp5123/mecp5123.c
index 748ad7c..804a022 100644
--- a/board/esd/mecp5123/mecp5123.c
+++ b/board/esd/mecp5123/mecp5123.c
@@ -110,7 +110,7 @@ int board_early_init_f(void)
*/
out_be32(&im->clk.sccr[0], SCCR1_CLOCKS_EN);
out_be32(&im->clk.sccr[1], SCCR2_CLOCKS_EN);
-#if defined(CONFIG_IIM) || defined(CONFIG_CMD_FUSE)
+#if defined(CONFIG_FSL_IIM) || defined(CONFIG_CMD_FUSE)
setbits_be32(&im->clk.sccr[1], CLOCK_SCCR2_IIM_EN);
#endif
diff --git a/board/freescale/mpc5121ads/mpc5121ads.c b/board/freescale/mpc5121ads/mpc5121ads.c
index 97eeab3..0d33680 100644
--- a/board/freescale/mpc5121ads/mpc5121ads.c
+++ b/board/freescale/mpc5121ads/mpc5121ads.c
@@ -129,7 +129,7 @@ int board_early_init_f(void)
*/
out_be32 (&im->clk.sccr[0], SCCR1_CLOCKS_EN);
out_be32 (&im->clk.sccr[1], SCCR2_CLOCKS_EN);
-#if defined(CONFIG_IIM) || defined(CONFIG_CMD_FUSE)
+#if defined(CONFIG_FSL_IIM) || defined(CONFIG_CMD_FUSE)
setbits_be32 (&im->clk.sccr[1], CLOCK_SCCR2_IIM_EN);
#endif
diff --git a/board/pdm360ng/pdm360ng.c b/board/pdm360ng/pdm360ng.c
index a2a1323..da81590 100644
--- a/board/pdm360ng/pdm360ng.c
+++ b/board/pdm360ng/pdm360ng.c
@@ -94,7 +94,7 @@ int board_early_init_f(void)
*/
out_be32(&im->clk.sccr[0], SCCR1_CLOCKS_EN);
out_be32(&im->clk.sccr[1], SCCR2_CLOCKS_EN);
-#if defined(CONFIG_IIM) || defined(CONFIG_CMD_FUSE)
+#if defined(CONFIG_FSL_IIM) || defined(CONFIG_CMD_FUSE)
setbits_be32(&im->clk.sccr[1], CLOCK_SCCR2_IIM_EN);
#endif
diff --git a/include/configs/aria.h b/include/configs/aria.h
index 0b31c50..7905e45 100644
--- a/include/configs/aria.h
+++ b/include/configs/aria.h
@@ -379,7 +379,7 @@
/*
* IIM - IC Identification Module
*/
-#undef CONFIG_IIM
+#undef CONFIG_FSL_IIM
/*
* EEPROM configuration for Atmel AT24C32A-10TQ-2.7:
diff --git a/include/configs/mecp5123.h b/include/configs/mecp5123.h
index cafc273..8db47ed 100644
--- a/include/configs/mecp5123.h
+++ b/include/configs/mecp5123.h
@@ -251,7 +251,7 @@
/*
* IIM - IC Identification Module
*/
-#undef CONFIG_IIM
+#undef CONFIG_FSL_IIM
/*
* EEPROM configuration
diff --git a/include/configs/mpc5121ads.h b/include/configs/mpc5121ads.h
index 3f55d35..5b34124 100644
--- a/include/configs/mpc5121ads.h
+++ b/include/configs/mpc5121ads.h
@@ -347,7 +347,7 @@
/*
* IIM - IC Identification Module
*/
-#undef CONFIG_IIM
+#undef CONFIG_FSL_IIM
/*
* EEPROM configuration
--
1.7.10.4
^ permalink raw reply related [flat|nested] 8+ messages in thread* [U-Boot] [PATCH v3 6/7] mx51evk: Enable support for iim
2013-03-26 21:24 [U-Boot] [PATCH v3 1/7] imx: Homogenize and fix fuse register definitions Benoît Thébaudeau
` (3 preceding siblings ...)
2013-03-26 21:24 ` [U-Boot] [PATCH v3 5/7] mpc: iim: Switch to common fsl_iim Benoît Thébaudeau
@ 2013-03-26 21:24 ` Benoît Thébaudeau
2013-03-26 21:24 ` [U-Boot] [PATCH v3 7/7] imx: Document fuse assignments for MAC addresses Benoît Thébaudeau
5 siblings, 0 replies; 8+ messages in thread
From: Benoît Thébaudeau @ 2013-03-26 21:24 UTC (permalink / raw)
To: u-boot
This allows to test the iim driver in the mainline tree.
Signed-off-by: Beno?t Th?baudeau <benoit.thebaudeau@advansee.com>
---
Changes in v3:
- New patch.
Changes in v2: None
include/configs/mx51evk.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/configs/mx51evk.h b/include/configs/mx51evk.h
index cb3d938..cdd72cc 100644
--- a/include/configs/mx51evk.h
+++ b/include/configs/mx51evk.h
@@ -53,6 +53,10 @@
/*
* Hardware drivers
*/
+#define CONFIG_FSL_IIM
+#define CONFIG_SYS_FSL_IIM_ADDR IIM_BASE_ADDR
+#define CONFIG_CMD_FUSE
+
#define CONFIG_MXC_UART
#define CONFIG_MXC_UART_BASE UART1_BASE
#define CONFIG_MXC_GPIO
--
1.7.10.4
^ permalink raw reply related [flat|nested] 8+ messages in thread* [U-Boot] [PATCH v3 7/7] imx: Document fuse assignments for MAC addresses
2013-03-26 21:24 [U-Boot] [PATCH v3 1/7] imx: Homogenize and fix fuse register definitions Benoît Thébaudeau
` (4 preceding siblings ...)
2013-03-26 21:24 ` [U-Boot] [PATCH v3 6/7] mx51evk: Enable support for iim Benoît Thébaudeau
@ 2013-03-26 21:24 ` Benoît Thébaudeau
5 siblings, 0 replies; 8+ messages in thread
From: Benoît Thébaudeau @ 2013-03-26 21:24 UTC (permalink / raw)
To: u-boot
Signed-off-by: Beno?t Th?baudeau <benoit.thebaudeau@advansee.com>
---
Changes in v3:
- New patch.
Changes in v2: None
doc/README.imx25 | 10 ++++++++++
doc/README.imx27 | 10 ++++++++++
doc/README.imx5 | 6 ++++++
doc/README.imx6 | 10 ++++++++++
4 files changed, 36 insertions(+)
create mode 100644 doc/README.imx25
create mode 100644 doc/README.imx27
create mode 100644 doc/README.imx6
diff --git a/doc/README.imx25 b/doc/README.imx25
new file mode 100644
index 0000000..0ca21b6
--- /dev/null
+++ b/doc/README.imx25
@@ -0,0 +1,10 @@
+U-Boot for Freescale i.MX25
+
+This file contains information for the port of U-Boot to the Freescale i.MX25
+SoC.
+
+1. CONVENTIONS FOR FUSE ASSIGNMENTS
+-----------------------------------
+
+1.1 MAC Address: It is stored in the words 26 to 31 of fuse bank 0, using the
+ natural MAC byte order (i.e. MSB first).
diff --git a/doc/README.imx27 b/doc/README.imx27
new file mode 100644
index 0000000..6f92cb4
--- /dev/null
+++ b/doc/README.imx27
@@ -0,0 +1,10 @@
+U-Boot for Freescale i.MX27
+
+This file contains information for the port of U-Boot to the Freescale i.MX27
+SoC.
+
+1. CONVENTIONS FOR FUSE ASSIGNMENTS
+-----------------------------------
+
+1.1 MAC Address: It is stored in the words 4 to 9 of fuse bank 0, using the
+ reversed MAC byte order (i.e. LSB first).
diff --git a/doc/README.imx5 b/doc/README.imx5
index e08941e..c5312b6 100644
--- a/doc/README.imx5
+++ b/doc/README.imx5
@@ -20,3 +20,9 @@ i.MX5x SoCs.
This option should be enabled for boards having a SYS_ON_OFF_CTL signal
connected to GPIO1[23] and triggering the MAIN_PWR_ON signal like in the
reference designs.
+
+2. CONVENTIONS FOR FUSE ASSIGNMENTS
+-----------------------------------
+
+2.1 MAC Address: It is stored in the words 9 to 14 of fuse bank 1, using the
+ natural MAC byte order (i.e. MSB first).
diff --git a/doc/README.imx6 b/doc/README.imx6
new file mode 100644
index 0000000..d20c3e1
--- /dev/null
+++ b/doc/README.imx6
@@ -0,0 +1,10 @@
+U-Boot for Freescale i.MX6x
+
+This file contains information for the port of U-Boot to the Freescale i.MX6x
+SoCs.
+
+1. CONVENTIONS FOR FUSE ASSIGNMENTS
+-----------------------------------
+
+1.1 MAC Address: It is stored in fuse bank 4, with the 32 lsbs in word 2 and the
+ 16 msbs in word 3.
--
1.7.10.4
^ permalink raw reply related [flat|nested] 8+ messages in thread