]>
git.ipfire.org Git - people/ms/u-boot.git/blob - arch/powerpc/cpu/mpc512x/iim.c
2 * Copyright 2008 Silicon Turnkey Express, Inc.
3 * Martha Marx <mmarx@silicontkx.com>
5 * ADS5121 IIM (Fusebox) Interface
7 * See file CREDITS for list of people who contributed to this
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
30 #ifdef CONFIG_CMD_FUSE
32 DECLARE_GLOBAL_DATA_PTR
;
34 static char cur_bank
= '1';
36 char *iim_err_msg(u32 err
)
38 static char *IIM_errs
[] = {
39 "Parity Error in cache",
40 "Explicit Sense Cycle Error",
41 "Write to Locked Register Error",
43 "Override Protect Error",
44 "Write Protect Error"};
50 for (i
= 1; i
< 8; i
++)
52 printf("IIM - %s\n", IIM_errs
[i
-1]);
56 int in_range(int n
, int min
, int max
, char *err
, char *usg
)
58 if (n
> max
|| n
< min
) {
60 printf("Usage:\n%s\n", usg
);
66 int ads5121_fuse_read(int bank
, int fstart
, int num
)
68 iim512x_t
*iim
= &((immap_t
*) CONFIG_SYS_IMMR
)->iim
;
72 out_be32(&iim
->err
, in_be32(&iim
->err
));
74 iim_fb
= (u32
*)&(iim
->fbac0
);
76 iim_fb
= (u32
*)&(iim
->fbac1
);
77 /* try a read to see if Read Protect is set */
78 dummy
= in_be32(&iim_fb
[0]);
79 if (in_be32(&iim
->err
) & IIM_ERR_RPE
) {
80 printf("\tRead protect fuse is set\n");
81 out_be32(&iim
->err
, IIM_ERR_RPE
);
84 printf("Reading Bank %d cache\n", bank
);
85 for (f
= fstart
, ctr
= 0; num
> 0; ctr
++, num
--, f
++) {
88 printf("\t%#04x", (u8
)(iim_fb
[f
]));
96 int ads5121_fuse_override(int bank
, int f
, u8 val
)
98 iim512x_t
*iim
= &((immap_t
*) CONFIG_SYS_IMMR
)->iim
;
103 out_be32(&iim
->err
, in_be32(&iim
->err
));
105 iim_fb
= (u32
*)&(iim
->fbac0
);
107 iim_fb
= (u32
*)&(iim
->fbac1
);
108 /* try a read to see if Read Protect is set */
109 iim_stat
= in_be32(&iim_fb
[0]);
110 if (in_be32(&iim
->err
) & IIM_ERR_RPE
) {
111 printf("Read protect fuse is set on bank %d;"
112 "Override protect may also be set\n", bank
);
113 printf("An attempt will be made to override\n");
114 out_be32(&iim
->err
, IIM_ERR_RPE
);
116 if (iim_stat
& IIM_FBAC_FBOP
) {
117 printf("Override protect fuse is set on bank %d\n", bank
);
120 if (f
> IIM_FMAX
) /* reset the entire bank */
121 for (i
= 0; i
< IIM_FMAX
+ 1; i
++)
122 out_be32(&iim_fb
[i
], 0);
124 out_be32(&iim_fb
[f
], val
);
128 int ads5121_fuse_prog(cmd_tbl_t
*cmdtp
, int bank
, char *fuseno_bitno
)
130 iim512x_t
*iim
= &((immap_t
*) CONFIG_SYS_IMMR
)->iim
;
134 f
= simple_strtol(fuseno_bitno
, NULL
, 10);
135 if (f
== 0 && fuseno_bitno
[0] != '0')
137 if (!in_range(f
, 0, IIM_FMAX
,
138 "<frow> must be between 0-31\n\n", cmdtp
->usage
))
141 for (i
= 0; i
< 6; i
++) {
142 if (fuseno_bitno
[i
] == '_') {
143 bitno
= simple_strtol(&(fuseno_bitno
[i
+1]), NULL
, 10);
144 if (bitno
== 0 && fuseno_bitno
[i
+1] != '0')
149 if (!in_range(bitno
, 0, 7, "Bit number ranges from 0-7\n"
150 "Example of <frow_bitno>: \"18_4\" sets bit 4 of row 18\n",
153 out_be32(&iim
->err
, in_be32(&iim
->err
));
154 out_be32(&iim
->prg_p
, IIM_PRG_P_SET
);
155 out_be32(&iim
->ua
, IIM_SET_UA(bank
, f
));
156 out_be32(&iim
->la
, IIM_SET_LA(f
, bitno
));
158 printf("Programming disabled with DEBUG defined \n");
159 printf(""Set up to pro
160 printf("iim.ua = %x; iim.la = %x\n", iim
->ua
, iim
->la
);
162 out_be32(&iim
->fctl
, IIM_FCTL_PROG_PULSE
| IIM_FCTL_PROG
);
165 while ((stat
= in_be32(&iim
->stat
)) & IIM_STAT_BUSY
);
166 out_be32(&iim
->prg_p
, 0);
167 err
= in_be32(&iim
->err
);
168 if (stat
& IIM_STAT_PRGD
) {
169 if (!(err
& (IIM_ERR_WPE
| IIM_ERR_WPE
))) {
170 printf("Fuse is successfully set");
172 printf(" - however there are other errors");
179 out_be32(&iim
->err
, in_be32(&iim
->err
));
184 int ads5121_fuse_sense(int bank
, int fstart
, int num
)
186 iim512x_t
*iim
= &((immap_t
*) CONFIG_SYS_IMMR
)->iim
;
188 u32 stat
, err
, err_hold
= 0;
191 out_be32(&iim
->err
, in_be32(&iim
->err
));
193 iim_fbac
= in_be32(&iim
->fbac0
);
195 iim_fbac
= in_be32(&iim
->fbac1
);
196 if (iim_fbac
& IIM_FBAC_FBESP
) {
197 printf("\tSense Protect disallows this operation\n");
198 out_be32(&iim
->err
, IIM_FBAC_FBESP
);
201 err
= in_be32(&iim
->err
);
206 if (err
& IIM_ERR_RPE
)
207 printf("\tRead protect fuse is set; "
208 "Sense Protect may be set but will be attempted\n");
210 out_be32(&iim
->err
, err
);
211 printf("Sensing fuse(s) on Bank %d\n", bank
);
212 for (f
= fstart
, ctr
= 0; num
> 0; ctr
++, f
++, num
--) {
213 out_be32(&iim
->ua
, IIM_SET_UA(bank
, f
));
214 out_be32(&iim
->la
, IIM_SET_LA(f
, 0));
215 out_be32(&iim
->fctl
, IIM_FCTL_ESNS_N
);
218 while ((stat
= in_be32(&iim
->stat
)) & IIM_STAT_BUSY
);
219 err
= in_be32(&iim
->err
);
220 if (err
& IIM_ERR_SNSE
) {
222 out_be32(&iim
->err
, IIM_ERR_SNSE
);
225 if (stat
& IIM_STAT_SNSD
) {
226 out_be32(&iim
->stat
, 0);
229 printf("\t%#04x", (u8
)iim
->sdat
);
235 out_be32(&iim
->err
, err
);
241 iim_err_msg(err_hold
);
246 int ads5121_fuse_stat(int bank
)
248 iim512x_t
*iim
= &((immap_t
*) CONFIG_SYS_IMMR
)->iim
;
252 out_be32(&iim
->err
, in_be32(&iim
->err
));
254 iim_fbac
= in_be32(&iim
->fbac0
);
256 iim_fbac
= in_be32(&iim
->fbac1
);
257 err
= in_be32(&iim
->err
);
260 if (err
& IIM_ERR_RPE
|| iim_fbac
& IIM_FBAC_FBRP
) {
262 printf("Since protection settings can't be read - "
263 "try sensing fuse row 0;\n");
266 if (iim_fbac
& IIM_PROTECTION
)
267 printf("Protection Fuses Bank %d = %#04x:\n", bank
, iim_fbac
);
268 else if (!(err
& IIM_ERR_RPE
))
269 printf("No Protection fuses are set\n");
270 if (iim_fbac
& IIM_FBAC_FBWP
)
271 printf("\tWrite Protect fuse is set\n");
272 if (iim_fbac
& IIM_FBAC_FBOP
)
273 printf("\tOverride Protect fuse is set\n");
274 if (iim_fbac
& IIM_FBAC_FBESP
)
275 printf("\tSense Protect Fuse is set\n");
276 out_be32(&iim
->err
, in_be32(&iim
->err
));
281 int do_ads5121_fuse(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char *argv
[])
283 int frow
, n
, v
, bank
;
293 printf("Usage:\n%s\n", cmdtp
->usage
);
296 if (strncmp(argv
[1], "stat", 4) == 0)
297 return ads5121_fuse_stat(bank
);
298 if (strncmp(argv
[1], "read", 4) == 0)
299 return ads5121_fuse_read(bank
, 0, IIM_FMAX
+ 1);
300 if (strncmp(argv
[1], "sense", 5) == 0)
301 return ads5121_fuse_sense(bank
, 0, IIM_FMAX
+ 1);
302 if (strncmp(argv
[1], "ovride", 6) == 0)
303 return ads5121_fuse_override(bank
, IIM_FMAX
+ 1, 0);
304 if (strncmp(argv
[1], "bank", 4) == 0) {
305 printf("Active Fuse Bank is %c\n", cur_bank
);
308 printf("Usage:\n%s\n", cmdtp
->usage
);
311 if (strncmp(argv
[1], "bank", 4) == 0) {
312 if (argv
[2][0] == '0')
314 else if (argv
[2][0] == '1')
317 printf("Usage:\n%s\n", cmdtp
->usage
);
321 printf("Setting Active Fuse Bank to %c\n", cur_bank
);
324 if (strncmp(argv
[1], "prog", 4) == 0)
325 return ads5121_fuse_prog(cmdtp
, bank
, argv
[2]);
327 frow
= (int)simple_strtol(argv
[2], NULL
, 10);
328 if (frow
== 0 && argv
[2][0] != '0')
330 if (!in_range(frow
, 0, IIM_FMAX
,
331 "<frow> must be between 0-31\n\n", cmdtp
->usage
))
333 if (strncmp(argv
[1], "read", 4) == 0)
334 return ads5121_fuse_read(bank
, frow
, 1);
335 if (strncmp(argv
[1], "ovride", 6) == 0)
336 return ads5121_fuse_override(bank
, frow
, 0);
337 if (strncmp(argv
[1], "sense", 5) == 0)
338 return ads5121_fuse_sense(bank
, frow
, 1);
339 printf("Usage:\n%s\n", cmdtp
->usage
);
342 frow
= (int)simple_strtol(argv
[2], NULL
, 10);
343 if (frow
== 0 && argv
[2][0] != '0')
345 if (!in_range(frow
, 0, IIM_FMAX
,
346 "<frow> must be between 0-31\n\n", cmdtp
->usage
))
348 if (strncmp(argv
[1], "read", 4) == 0) {
349 n
= (int)simple_strtol(argv
[3], NULL
, 10);
350 if (!in_range(frow
+ n
, frow
+ 1, IIM_FMAX
+ 1,
351 "<frow>+<n> must be between 1-32\n\n",
354 return ads5121_fuse_read(bank
, frow
, n
);
356 if (strncmp(argv
[1], "ovride", 6) == 0) {
357 v
= (int)simple_strtol(argv
[3], NULL
, 10);
358 return ads5121_fuse_override(bank
, frow
, v
);
360 if (strncmp(argv
[1], "sense", 5) == 0) {
361 n
= (int)simple_strtol(argv
[3], NULL
, 10);
362 if (!in_range(frow
+ n
, frow
+ 1, IIM_FMAX
+ 1,
363 "<frow>+<n> must be between 1-32\n\n",
366 return ads5121_fuse_sense(bank
, frow
, n
);
368 printf("Usage:\n%s\n", cmdtp
->usage
);
370 default: /* at least 5 args */
371 printf("Usage:\n%s\n", cmdtp
->usage
);
377 fuse
, CONFIG_SYS_MAXARGS
, 0, do_ads5121_fuse
,
378 " - Read, Sense, Override or Program Fuses\n",
379 "bank <n> - sets active Fuse Bank to 0 or 1\n"
380 " no args shows current active bank\n"
381 "fuse stat - print active fuse bank's protection status\n"
382 "fuse read [<frow> [<n>]] - print <n> fuse rows starting at <frow>\n"
383 " no args to print entire bank's fuses\n"
384 "fuse ovride [<frow> [<v>]]- override fuses at <frow> with <v>\n"
385 " no <v> defaults to 0 for the row\n"
386 " no args resets entire bank to 0\n"
387 " NOTE - settings persist until hard reset\n"
388 "fuse sense [<frow>] - senses current fuse at <frow>\n"
389 " no args for entire bank\n"
390 "fuse prog <frow_bit> - program fuse at row <frow>, bit <_bit>\n"
391 " <frow> is 0-31, <bit> is 0-7; eg. 13_2 \n"
392 " WARNING - this is permanent"
394 #endif /* CONFIG_CMD_FUSE */