]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - patches/0084-ENGR00120476-Add-fuse-support-for-mx51.patch
imported Ka-Ro specific additions to U-Boot 2009.08 for TX28
[karo-tx-uboot.git] / patches / 0084-ENGR00120476-Add-fuse-support-for-mx51.patch
1 From 3de15e03d89eeda18e665d270c6e3abf65c94d1d Mon Sep 17 00:00:00 2001
2 From: Terry Lv <r65388@freescale.com>
3 Date: Tue, 26 Jan 2010 20:18:22 +0800
4 Subject: [PATCH] ENGR00120476: Add fuse support for mx51
5
6 Add fuse support for mx51.
7
8 Signed-off-by: Terry Lv <r65388@freescale.com>
9 ---
10  cpu/arm_cortexa8/mx51/Makefile       |    3 +
11  cpu/arm_cortexa8/mx51/cmd_fuse.c     |   92 ++++++++++
12  cpu/arm_cortexa8/mx51/imx_fuse.c     |  333 ++++++++++++++++++++++++++++++++++
13  drivers/net/mxc_fec.c                |    4 +
14  include/asm-arm/arch-mx51/imx_fuse.h |   33 ++++
15  include/asm-arm/arch-mx51/mx51.h     |   35 ++++-
16  include/configs/mx51_3stack.h        |    6 +
17  include/configs/mx51_bbg.h           |    6 +
18  8 files changed, 511 insertions(+), 1 deletions(-)
19
20 diff --git a/cpu/arm_cortexa8/mx51/Makefile b/cpu/arm_cortexa8/mx51/Makefile
21 index 435f26f..79f697d 100644
22 --- a/cpu/arm_cortexa8/mx51/Makefile
23 +++ b/cpu/arm_cortexa8/mx51/Makefile
24 @@ -28,6 +28,9 @@ include $(TOPDIR)/config.mk
25  LIB    = $(obj)lib$(SOC).a
26  
27  COBJS  = interrupts.o serial.o generic.o iomux.o timer.o cache.o
28 +COBJS-$(CONFIG_CMD_FUSE) += cmd_fuse.o
29 +COBJS-$(CONFIG_IMX_FUSE) += imx_fuse.o
30 +COBJS += $(COBJS-y)
31  SOBJS = mxc_nand_load.o
32  
33  SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
34 diff --git a/cpu/arm_cortexa8/mx51/cmd_fuse.c b/cpu/arm_cortexa8/mx51/cmd_fuse.c
35 new file mode 100644
36 index 0000000..1d32e3a
37 --- /dev/null
38 +++ b/cpu/arm_cortexa8/mx51/cmd_fuse.c
39 @@ -0,0 +1,92 @@
40 +/*
41 + * (C) Copyright 2008-2010 Freescale Semiconductor, Inc.
42 + * Terry Lv
43 + *
44 + * Copyright 2007, Freescale Semiconductor, Inc
45 + * Andy Fleming
46 + *
47 + * Based vaguely on the pxa mmc code:
48 + * (C) Copyright 2003
49 + * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
50 + *
51 + * See file CREDITS for list of people who contributed to this
52 + * project.
53 + *
54 + * This program is free software; you can redistribute it and/or
55 + * modify it under the terms of the GNU General Public License as
56 + * published by the Free Software Foundation; either version 2 of
57 + * the License, or (at your option) any later version.
58 + *
59 + * This program is distributed in the hope that it will be useful,
60 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
61 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
62 + * GNU General Public License for more details.
63 + *
64 + * You should have received a copy of the GNU General Public License
65 + * along with this program; if not, write to the Free Software
66 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
67 + * MA 02111-1307 USA
68 + */
69 +
70 +#include <linux/types.h>
71 +#include <asm/io.h>
72 +#include <asm/arch/mx51.h>
73 +#include <command.h>
74 +#include <common.h>
75 +#include <asm/arch/imx_fuse.h>
76 +
77 +int do_fuseops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
78 +{
79 +       int rc = 0;
80 +       int bank = 0,
81 +               row = 0,
82 +               val = 0;
83 +
84 +       switch (argc) {
85 +       case 4:
86 +               if (strcmp(argv[1], "read") == 0) {
87 +                       bank = simple_strtoul(argv[2], NULL, 16);
88 +                       row = simple_strtoul(argv[3], NULL, 16);
89 +
90 +                       fuse_read(bank, row);
91 +               } else if (strcmp(argv[1], "blow") == 0) {
92 +                       fuse_blow_func(argv[2], argv[3]);
93 +               } else {
94 +                       printf("It is too dangeous for you to use fuse command.\n");
95 +                       printf("Usage:\n%s\n", cmdtp->usage);
96 +                       rc = 1;
97 +               }
98 +               break;
99 +       case 5:
100 +               if (strcmp(argv[1], "blow") == 0) {
101 +                       bank = simple_strtoul(argv[2], NULL, 16);
102 +                       row = simple_strtoul(argv[3], NULL, 16);
103 +                       val = simple_strtoul(argv[4], NULL, 16);
104 +
105 +                       fuse_blow(bank, row, val);
106 +               } else {
107 +                       printf("It is too dangeous for you to use fuse command.\n");
108 +                       printf("Usage:\n%s\n", cmdtp->usage);
109 +                       rc = 1;
110 +               }
111 +               break;
112 +       default:
113 +               rc = 1;
114 +               printf("It is too dangeous for you to use fuse command.\n");
115 +               printf("Usage:\n%s\n", cmdtp->usage);
116 +               break;
117 +       }
118 +
119 +       return rc;
120 +}
121 +
122 +U_BOOT_CMD(
123 +       fuse, 5, 1, do_fuseops,
124 +       "Fuse sub system",
125 +       "read <bank> <row>      - Read some fuses\n"
126 +       "blow <bank> <row> <value>      - Blow some fuses\n"
127 +       "blow scc <value>       - Blow scc value\n"
128 +       "blow srk <value>       - Blow srk value\n"
129 +       "blow fecmac <0x##:0x##:0x##:0x##:0x##:0x##>"
130 +       "- Blow FEC Mac address\n");
131 +
132 diff --git a/cpu/arm_cortexa8/mx51/imx_fuse.c b/cpu/arm_cortexa8/mx51/imx_fuse.c
133 new file mode 100644
134 index 0000000..3901a25
135 --- /dev/null
136 +++ b/cpu/arm_cortexa8/mx51/imx_fuse.c
137 @@ -0,0 +1,333 @@
138 +/*
139 + * (C) Copyright 2008-2010 Freescale Semiconductor, Inc.
140 + * Terry Lv
141 + *
142 + * Copyright 2007, Freescale Semiconductor, Inc
143 + * Andy Fleming
144 + *
145 + * Based vaguely on the pxa mmc code:
146 + * (C) Copyright 2003
147 + * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
148 + *
149 + * See file CREDITS for list of people who contributed to this
150 + * project.
151 + *
152 + * This program is free software; you can redistribute it and/or
153 + * modify it under the terms of the GNU General Public License as
154 + * published by the Free Software Foundation; either version 2 of
155 + * the License, or (at your option) any later version.
156 + *
157 + * This program is distributed in the hope that it will be useful,
158 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
159 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
160 + * GNU General Public License for more details.
161 + *
162 + * You should have received a copy of the GNU General Public License
163 + * along with this program; if not, write to the Free Software
164 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
165 + * MA 02111-1307 USA
166 + */
167 +
168 +#include <linux/types.h>
169 +#include <asm/io.h>
170 +#include <asm/arch/mx51.h>
171 +#include <asm/arch/imx_fuse.h>
172 +#include <common.h>
173 +#include <net.h>
174 +
175 +static void quick_itoa(u32 num, char *a)
176 +{
177 +       int i, j, k;
178 +       for (i = 0; i <= 7; i++) {
179 +               j = (num >> (4 * i)) & 0xF;
180 +               k = (j < 10) ? '0' : ('a' - 0xa);
181 +               a[i] = j + k;
182 +       }
183 +}
184 +
185 +/* slen - streng length, e.g.: 23 -> slen=2; abcd -> slen=4 */
186 +/* only convert hex value as string input. so "12" is 0x12. */
187 +static u32 quick_atoi(char *a, u32 slen)
188 +{
189 +       u32 i, num = 0, digit;
190 +
191 +       for (i = 0; i < slen; i++) {
192 +               if (a[i] >= '0' && a[i] <= '9') {
193 +                       digit = a[i] - '0';
194 +               } else if (a[i] >= 'a' && a[i] <= 'f') {
195 +                       digit = a[i] - 'a' + 10;
196 +               } else if (a[i] >= 'A' && a[i] <= 'F') {
197 +                       digit = a[i] - 'A' + 10;
198 +               } else {
199 +                       printf("ERROR: %c\n", a[i]);
200 +                       return -1;
201 +               }
202 +               num = (num * 16) + digit;
203 +       }
204 +
205 +    return num;
206 +}
207 +
208 +static void fuse_op_start(void)
209 +{
210 +    /* Do not generate interrupt */
211 +    writel(0, IIM_BASE_ADDR + IIM_STATM_OFF);
212 +    /* clear the status bits and error bits */
213 +    writel(0x3, IIM_BASE_ADDR + IIM_STAT_OFF);
214 +    writel(0xFE, IIM_BASE_ADDR + IIM_ERR_OFF);
215 +}
216 +
217 +/*
218 + * The action should be either:
219 + *          POLL_FUSE_PRGD
220 + * or:
221 + *          POLL_FUSE_SNSD
222 + */
223 +static s32 poll_fuse_op_done(s32 action)
224 +{
225 +       u32 status, error;
226 +
227 +       if (action != POLL_FUSE_PRGD && action != POLL_FUSE_SNSD) {
228 +               printf("%s(%d) invalid operation\n", __func__, action);
229 +               return -1;
230 +    }
231 +
232 +    /* Poll busy bit till it is NOT set */
233 +       while ((readl(IIM_BASE_ADDR + IIM_STAT_OFF) & IIM_STAT_BUSY) != 0)
234 +               ;
235 +
236 +    /* Test for successful write */
237 +       status = readl(IIM_BASE_ADDR + IIM_STAT_OFF);
238 +       error = readl(IIM_BASE_ADDR + IIM_ERR_OFF);
239 +
240 +       if ((status & action) != 0 && \
241 +                       (error & (action >> IIM_ERR_SHIFT)) == 0) {
242 +               if (error) {
243 +                       printf("Even though the operation seems successful...\n");
244 +                       printf("There are some error(s) at addr=0x%x: 0x%x\n",
245 +                                       (IIM_BASE_ADDR + IIM_ERR_OFF), error);
246 +               }
247 +               return 0;
248 +       }
249 +       printf("%s(%d) failed\n", __func__, action);
250 +       printf("status address=0x%x, value=0x%x\n",
251 +                       (IIM_BASE_ADDR + IIM_STAT_OFF), status);
252 +       printf("There are some error(s) at addr=0x%x: 0x%x\n",
253 +                       (IIM_BASE_ADDR + IIM_ERR_OFF), error);
254 +       return -1;
255 +}
256 +
257 +static u32 sense_fuse(s32 bank, s32 row, s32 bit)
258 +{
259 +       s32 addr, addr_l, addr_h, reg_addr;
260 +
261 +       fuse_op_start();
262 +
263 +       addr = ((bank << 11) | (row << 3) | (bit & 0x7));
264 +       /* Set IIM Program Upper Address */
265 +       addr_h = (addr >> 8) & 0x000000FF;
266 +       /* Set IIM Program Lower Address */
267 +       addr_l = (addr & 0x000000FF);
268 +
269 +#ifdef IIM_FUSE_DEBUG
270 +       printf("%s: addr_h=0x%x, addr_l=0x%x\n",
271 +                       __func__, addr_h, addr_l);
272 +#endif
273 +       writel(addr_h, IIM_BASE_ADDR + IIM_UA_OFF);
274 +       writel(addr_l, IIM_BASE_ADDR + IIM_LA_OFF);
275 +
276 +    /* Start sensing */
277 +       writel(0x8, IIM_BASE_ADDR + IIM_FCTL_OFF);
278 +       if (poll_fuse_op_done(POLL_FUSE_SNSD) != 0) {
279 +               printf("%s(bank: %d, row: %d, bit: %d failed\n",
280 +                               __func__, bank, row, bit);
281 +       }
282 +       reg_addr = IIM_BASE_ADDR + IIM_SDAT_OFF;
283 +
284 +       return readl(reg_addr);
285 +}
286 +
287 +int fuse_read(int bank, char row)
288 +{
289 +    u32 fuse_val;
290 +       s32 err = 0;
291 +
292 +       printf("Read fuse at bank:%d row:%d\n", bank, row);
293 +       fuse_val = sense_fuse(bank, row, 0);
294 +       printf("fuses at (bank:%d, row:%d) = 0x%x\n", bank, row, fuse_val);
295 +
296 +       return err;
297 +}
298 +
299 +/* Blow fuses based on the bank, row and bit positions (all 0-based)
300 +*/
301 +static s32 fuse_blow_bit(s32 bank, s32 row, s32 bit)
302 +{
303 +       int addr, addr_l, addr_h, ret = -1;
304 +
305 +       fuse_op_start();
306 +
307 +       /* Disable IIM Program Protect */
308 +       writel(0xAA, IIM_BASE_ADDR + IIM_PREG_P_OFF);
309 +
310 +       addr = ((bank << 11) | (row << 3) | (bit & 0x7));
311 +       /* Set IIM Program Upper Address */
312 +       addr_h = (addr >> 8) & 0x000000FF;
313 +       /* Set IIM Program Lower Address */
314 +       addr_l = (addr & 0x000000FF);
315 +
316 +#ifdef IIM_FUSE_DEBUG
317 +       printf("blowing addr_h=0x%x, addr_l=0x%x\n", addr_h, addr_l);
318 +#endif
319 +
320 +       writel(addr_h, IIM_BASE_ADDR + IIM_UA_OFF);
321 +       writel(addr_l, IIM_BASE_ADDR + IIM_LA_OFF);
322 +
323 +       /* Start Programming */
324 +       writel(0x31, IIM_BASE_ADDR + IIM_FCTL_OFF);
325 +       if (poll_fuse_op_done(POLL_FUSE_PRGD) == 0)
326 +               ret = 0;
327 +
328 +       /* Enable IIM Program Protect */
329 +       writel(0x0, IIM_BASE_ADDR + IIM_PREG_P_OFF);
330 +
331 +       return ret;
332 +}
333 +
334 +static void fuse_blow_row(s32 bank, s32 row, s32 value)
335 +{
336 +       u32 reg, i;
337 +
338 +       /* enable fuse blown */
339 +       reg = readl(CCM_BASE_ADDR + 0x64);
340 +       reg |= 0x10;
341 +       writel(reg, CCM_BASE_ADDR + 0x64);
342 +
343 +       for (i = 0; i < 8; i++) {
344 +               if (((value >> i) & 0x1) == 0)
345 +                       continue;
346 +       if (fuse_blow_bit(bank, row, i) != 0) {
347 +                       printf("fuse_blow_bit(bank: %d, row: %d, bit: %d failed\n",
348 +                                       bank, row, i);
349 +               }
350 +    }
351 +    reg &= ~0x10;
352 +    writel(reg, CCM_BASE_ADDR + 0x64);
353 +}
354 +
355 +int fuse_blow(int bank, int row, int val)
356 +{
357 +    u32 fuse_val, err = 0;
358 +
359 +       printf("Blowing fuse at bank:%d row:%d value:%d\n",
360 +                       bank, row, val);
361 +       fuse_blow_row(bank, row, val);
362 +       fuse_val = sense_fuse(bank, row, 0);
363 +       printf("fuses at (bank:%d, row:%d) = 0x%x\n", bank, row, fuse_val);
364 +
365 +       return err;
366 +}
367 +
368 +static int fuse_read_mac_addr(u8 *data)
369 +{
370 +    data[0] = sense_fuse(1, 9, 0) ;
371 +    data[1] = sense_fuse(1, 10, 0) ;
372 +    data[2] = sense_fuse(1, 11, 0) ;
373 +    data[3] = sense_fuse(1, 12, 0) ;
374 +    data[4] = sense_fuse(1, 13, 0) ;
375 +    data[5] = sense_fuse(1, 14, 0) ;
376 +
377 +    if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
378 +               (data[3] == 0) && (data[4] == 0) && (data[5] == 0)) {
379 +               return 0;
380 +    }
381 +
382 +    return 1;
383 +}
384 +
385 +int fuse_blow_func(char *func_name, char *func_val)
386 +{
387 +       u32 value, i;
388 +       char *s;
389 +       char val[3];
390 +       s32 err = 0;
391 +
392 +       if (0 == strcmp(func_name, "scc")) {
393 +               /* fuse_blow scc C3D153EDFD2EA9982226EF5047D3B9A0B9C7138EA87C028401D28C2C2C0B9AA2 */
394 +               printf("Ready to burn SCC fuses\n");
395 +               s = func_val;
396 +               for (i = 0; ; ++i) {
397 +                       memcpy(val, s, 2);
398 +                       val[2] = '\0';
399 +                       value = quick_atoi(val, 2);
400 +                       /* printf("fuse_blow_row(2, %d, value=0x%x)\n", i, value); */
401 +                       fuse_blow_row(2, i, value);
402 +
403 +                       if ((++s)[0] == '\0') {
404 +                               printf("ERROR: Odd string input\n");
405 +                               err = -1;
406 +                               break;
407 +                       }
408 +                       if ((++s)[0] == '\0') {
409 +                               printf("Successful\n");
410 +                               break;
411 +                       }
412 +               }
413 +       } else if (0 == strcmp(func_name, "srk")) {
414 +               /* fuse_blow srk 418bccd09b53bee1ab59e2662b3c7877bc0094caee201052add49be8780dff95 */
415 +               printf("Ready to burn SRK key fuses\n");
416 +               s = func_val;
417 +               for (i = 0; ; ++i) {
418 +                       memcpy(val, s, 2);
419 +                       val[2] = '\0';
420 +                       value = quick_atoi(val, 2);
421 +                       if (i == 0) {
422 +                               /* 0x41 goes to SRK_HASH[255:248], bank 1, row 1 */
423 +                               fuse_blow_row(1, 1, value);
424 +                       } else {
425 +                               /* 0x8b in SRK_HASH[247:240] bank 3, row 1 */
426 +                               /* 0xcc in SRK_HASH[239:232] bank 3, row 2 */
427 +                               /* ... */
428 +                               fuse_blow_row(3, i, value);
429 +
430 +                               if ((++s)[0] == '\0') {
431 +                                       printf("ERROR: Odd string input\n");
432 +                                       err = -1;
433 +                                       break;
434 +                               }
435 +                               if ((++s)[0] == '\0') {
436 +                                       printf("Successful\n");
437 +                                       break;
438 +                               }
439 +                       }
440 +               }
441 +       } else if (0 == strcmp(func_name, "fecmac")) {
442 +               u8 ea[6] = { 0 };
443 +
444 +               if (NULL == func_val) {
445 +                       /* Read the Mac address and print it */
446 +                       fuse_read_mac_addr(ea);
447 +
448 +                       printf("FEC MAC address: ");
449 +                       printf("0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n\n",
450 +                                       ea[0], ea[1], ea[2], ea[3], ea[4], ea[5]);
451 +
452 +                       return 0;
453 +               }
454 +
455 +               eth_parse_enetaddr(func_val, ea);
456 +               if (!is_valid_ether_addr(ea)) {
457 +                       printf("Error: invalid mac address parameter!\n");
458 +                       err = -1;
459 +               } else {
460 +                       for (i = 0; i < 6; ++i)
461 +                               fuse_blow_row(1, i + 9, ea[i]);
462 +               }
463 +       } else {
464 +               printf("This command is not supported\n");
465 +       }
466 +
467 +       return err;
468 +}
469 +
470 +
471 diff --git a/drivers/net/mxc_fec.c b/drivers/net/mxc_fec.c
472 index 8aa32c7..c3e813d 100644
473 --- a/drivers/net/mxc_fec.c
474 +++ b/drivers/net/mxc_fec.c
475 @@ -729,6 +729,10 @@ void mxc_fec_set_mac_from_env(char *mac_addr)
476         int i;
477  
478         eth_parse_enetaddr(mac_addr, ea);
479 +       if (!is_valid_ether_addr(ea)) {
480 +               printf("Error: invalid FEC MAC address!\n");
481 +               return;
482 +       }
483  
484         for (i = 0; i < sizeof(fec_info) / sizeof(fec_info[0]); i++) {
485                 fecp = (fec_t *)(fec_info[i].iobase);
486 diff --git a/include/asm-arm/arch-mx51/imx_fuse.h b/include/asm-arm/arch-mx51/imx_fuse.h
487 new file mode 100644
488 index 0000000..8a65613
489 --- /dev/null
490 +++ b/include/asm-arm/arch-mx51/imx_fuse.h
491 @@ -0,0 +1,33 @@
492 +/*
493 + * (C) Copyright 2009-2010 Freescale Semiconductor, Inc.
494 + *
495 + * Configuration settings for the MX51-3Stack Freescale board.
496 + *
497 + * This program is free software; you can redistribute it and/or
498 + * modify it under the terms of the GNU General Public License as
499 + * published by the Free Software Foundation; either version 2 of
500 + * the License, or (at your option) any later version.
501 + *
502 + * This program is distributed in the hope that it will be useful,
503 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
504 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
505 + * GNU General Public License for more details.
506 + *
507 + * You should have received a copy of the GNU General Public License
508 + * along with this program; if not, write to the Free Software
509 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
510 + * MA 02111-1307 USA
511 + */
512 +
513 +#ifndef _IMX_FUSE_H_
514 +#define _IMX_FUSE_H_
515 +
516 +#define IIM_ERR_SHIFT       8
517 +#define POLL_FUSE_PRGD      (IIM_STAT_PRGD | (IIM_ERR_PRGE << IIM_ERR_SHIFT))
518 +#define POLL_FUSE_SNSD      (IIM_STAT_SNSD | (IIM_ERR_SNSE << IIM_ERR_SHIFT))
519 +
520 +int fuse_read(int bank, char row);
521 +int fuse_blow(int bank, int row, int val);
522 +int fuse_blow_func(char *func_name, char *func_val);
523 +
524 +#endif
525 diff --git a/include/asm-arm/arch-mx51/mx51.h b/include/asm-arm/arch-mx51/mx51.h
526 index 00e50cf..5fc57bb 100644
527 --- a/include/asm-arm/arch-mx51/mx51.h
528 +++ b/include/asm-arm/arch-mx51/mx51.h
529 @@ -1,5 +1,5 @@
530  /*
531 - * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
532 + * Copyright 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
533   */
534  
535  /*
536 @@ -390,6 +390,39 @@
537  #define DP_MFD_216     (4 - 1)
538  #define DP_MFN_216     3
539  
540 +/* IIM */
541 +#define IIM_STAT_OFF            0x00
542 +#define IIM_STAT_BUSY           (1 << 7)
543 +#define IIM_STAT_PRGD           (1 << 1)
544 +#define IIM_STAT_SNSD           (1 << 0)
545 +#define IIM_STATM_OFF           0x04
546 +#define IIM_ERR_OFF             0x08
547 +#define IIM_ERR_PRGE            (1 << 7)
548 +#define IIM_ERR_WPE         (1 << 6)
549 +#define IIM_ERR_OPE         (1 << 5)
550 +#define IIM_ERR_RPE         (1 << 4)
551 +#define IIM_ERR_WLRE        (1 << 3)
552 +#define IIM_ERR_SNSE        (1 << 2)
553 +#define IIM_ERR_PARITYE     (1 << 1)
554 +#define IIM_EMASK_OFF           0x0C
555 +#define IIM_FCTL_OFF            0x10
556 +#define IIM_UA_OFF              0x14
557 +#define IIM_LA_OFF              0x18
558 +#define IIM_SDAT_OFF            0x1C
559 +#define IIM_PREV_OFF            0x20
560 +#define IIM_SREV_OFF            0x24
561 +#define IIM_PREG_P_OFF          0x28
562 +#define IIM_SCS0_OFF            0x2C
563 +#define IIM_SCS1_P_OFF          0x30
564 +#define IIM_SCS2_OFF            0x34
565 +#define IIM_SCS3_P_OFF          0x38
566 +
567 +#define IIM_PROD_REV_SH         3
568 +#define IIM_PROD_REV_LEN        5
569 +#define IIM_SREV_REV_SH         4
570 +#define IIM_SREV_REV_LEN        4
571 +#define PROD_SIGNATURE_MX51     0x1
572 +
573  #define CHIP_REV_1_0            0x10
574  #define CHIP_REV_1_1            0x11
575  #define CHIP_REV_2_0            0x20
576 diff --git a/include/configs/mx51_3stack.h b/include/configs/mx51_3stack.h
577 index 292e2cc..f6083c5 100644
578 --- a/include/configs/mx51_3stack.h
579 +++ b/include/configs/mx51_3stack.h
580 @@ -93,6 +93,12 @@
581  #define CONFIG_CMD_MII
582  #define CONFIG_CMD_NET
583  #define CONFIG_CMD_MMC
584 +#define CONFIG_CMD_FUSE
585 +
586 +/*
587 + * FUSE Configs
588 + * */
589 +#define CONFIG_IMX_FUSE
590  
591  /*
592   * MMC Configs
593 diff --git a/include/configs/mx51_bbg.h b/include/configs/mx51_bbg.h
594 index aee33ba..f773563 100644
595 --- a/include/configs/mx51_bbg.h
596 +++ b/include/configs/mx51_bbg.h
597 @@ -119,6 +119,12 @@
598  #define CONFIG_CMD_SPI
599  #define CONFIG_CMD_SF
600  #define CONFIG_CMD_MMC
601 +#define CONFIG_CMD_FUSE
602 +
603 +/*
604 + * FUSE Configs
605 + * */
606 +#define CONFIG_IMX_FUSE
607  
608  /*
609   * SPI Configs
610 -- 
611 1.5.4.4
612