4 * Copyright (C) 2010, Broadcom Corporation. All Rights Reserved.
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 * $Id: bcmotp.c,v 1.137.2.23 2011-02-01 06:16:34 Exp $
28 #include <bcmendian.h>
34 * There are two different OTP controllers so far:
35 * 1. new IPX OTP controller: chipc 21, >=23
36 * 2. older HND OTP controller: chipc 12, 17, 22
38 * Define BCMHNDOTP to include support for the HND OTP controller.
39 * Define BCMIPXOTP to include support for the IPX OTP controller.
41 * NOTE 1: More than one may be defined
42 * NOTE 2: If none are defined, the default is to include them all.
45 #if !defined(BCMHNDOTP) && !defined(BCMIPXOTP)
50 #define OTPTYPE_HND(ccrev) ((ccrev) < 21 || (ccrev) == 22)
51 #define OTPTYPE_IPX(ccrev) ((ccrev) == 21 || (ccrev) >= 23)
53 #define OTP_ERR_VAL 0x0001
54 #define OTP_MSG_VAL 0x0002
55 #define OTP_DBG_VAL 0x0004
56 uint32 otp_msg_level
= OTP_ERR_VAL
;
58 #if defined(BCMDBG) || defined(BCMDBG_ERR)
59 #define OTP_ERR(args) do {if (otp_msg_level & OTP_ERR_VAL) printf args;} while (0)
65 #define OTP_MSG(args) do {if (otp_msg_level & OTP_MSG_VAL) printf args;} while (0)
66 #define OTP_DBG(args) do {if (otp_msg_level & OTP_DBG_VAL) printf args;} while (0)
72 #define OTPP_TRIES 10000000 /* # of tries for OTPP */
75 #define MAXNUMRDES 9 /* Maximum OTP redundancy entries */
78 /* OTP common function type */
79 typedef int (*otp_status_t
)(void *oh
);
80 typedef int (*otp_size_t
)(void *oh
);
81 typedef void* (*otp_init_t
)(si_t
*sih
);
82 typedef uint16 (*otp_read_bit_t
)(void *oh
, chipcregs_t
*cc
, uint off
);
83 typedef int (*otp_read_region_t
)(si_t
*sih
, int region
, uint16
*data
, uint
*wlen
);
84 typedef int (*otp_nvread_t
)(void *oh
, char *data
, uint
*len
);
85 typedef int (*otp_write_region_t
)(void *oh
, int region
, uint16
*data
, uint wlen
);
86 typedef int (*otp_cis_append_region_t
)(si_t
*sih
, int region
, char *vars
, int count
);
87 typedef int (*otp_lock_t
)(si_t
*sih
);
88 typedef int (*otp_nvwrite_t
)(void *oh
, uint16
*data
, uint wlen
);
89 typedef int (*otp_dump_t
)(void *oh
, int arg
, char *buf
, uint size
);
90 typedef int (*otp_write_word_t
)(void *oh
, uint wn
, uint16 data
);
91 typedef int (*otp_read_word_t
)(void *oh
, uint wn
, uint16
*data
);
93 /* OTP function struct */
94 typedef struct otp_fn_s
{
96 otp_read_bit_t read_bit
;
99 otp_read_region_t read_region
;
102 otp_write_region_t write_region
;
103 otp_cis_append_region_t cis_append_region
;
105 otp_nvwrite_t nvwrite
;
106 #endif /* BCMNVRAMW */
114 otp_write_word_t write_word
;
115 #endif /* BCMNVRAMW */
116 otp_read_word_t read_word
;
120 uint ccrev
; /* chipc revision */
121 otp_fn_t
*fn
; /* OTP functions */
122 si_t
*sih
; /* Saved sb handle */
126 /* IPX OTP section */
127 uint16 wsize
; /* Size of otp in words */
128 uint16 rows
; /* Geometry */
129 uint16 cols
; /* Geometry */
130 uint32 status
; /* Flag bits (lock/prog/rv).
131 * (Reflected only when OTP is power cycled)
133 uint16 hwbase
; /* hardware subregion offset */
134 uint16 hwlim
; /* hardware subregion boundary */
135 uint16 swbase
; /* software subregion offset */
136 uint16 swlim
; /* software subregion boundary */
137 uint16 fbase
; /* fuse subregion offset */
138 uint16 flim
; /* fuse subregion boundary */
139 int otpgu_base
; /* offset to General Use Region */
140 uint16 fusebits
; /* num of fusebits */
143 uint8 width
; /* entry width in bits */
144 uint8 val_shift
; /* value bit offset in the entry */
145 uint8 offsets
; /* # entries */
146 uint8 stat_shift
; /* valid bit in otpstatus */
147 uint16 offset
[MAXNUMRDES
]; /* entry offset in OTP */
148 } rde_cb
; /* OTP redundancy control blocks */
149 #endif /* BCMNVRAMW */
150 #endif /* BCMIPXOTP */
153 /* HND OTP section */
154 uint size
; /* Size of otp in bytes */
155 uint hwprot
; /* Hardware protection bits */
156 uint signvalid
; /* Signature valid bits */
157 int boundary
; /* hw/sw boundary */
158 #endif /* BCMHNDOTP */
161 static otpinfo_t otpinfo
;
166 * Exported functions:
171 * ipxotp_read_region()
174 * ipxotp_write_region()
175 * ipxotp_write_word()
176 * ipxotp_cis_append_region()
181 * IPX internal functions:
187 * ipxotp_fix_word16()
188 * ipxotp_check_word16()
196 #define HWSW_RGN(rgn) (((rgn) == OTP_HW_RGN) ? "h/w" : "s/w")
199 /* CC revs 21, 24 and 27 OTP General Use Region word offset */
200 #define REVA4_OTPGU_BASE 12
202 /* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */
203 #define REVB8_OTPGU_BASE 20
205 /* CC rev 36 OTP General Use Region word offset */
206 #define REV36_OTPGU_BASE 12
208 /* Subregion word offsets in General Use region */
209 #define OTPGU_HSB_OFF 0
210 #define OTPGU_SFB_OFF 1
211 #define OTPGU_CI_OFF 2
212 #define OTPGU_P_OFF 3
213 #define OTPGU_SROM_OFF 4
215 /* Flag bit offsets in General Use region */
216 #define OTPGU_HWP_OFF 60
217 #define OTPGU_SWP_OFF 61
218 #define OTPGU_CIP_OFF 62
219 #define OTPGU_FUSEP_OFF 63
220 #define OTPGU_CIP_MSK 0x4000
221 #define OTPGU_P_MSK 0xf000
222 #define OTPGU_P_SHIFT (OTPGU_HWP_OFF % 16)
224 /* LOCK but offset */
225 #define OTP_LOCK_ROW1_LOC_OFF 63 /* 1st ROW lock bit */
226 #define OTP_LOCK_ROW2_LOC_OFF 127 /* 2nd ROW lock bit */
227 #define OTP_LOCK_RD_LOC_OFF 128 /* Redundnancy Region lock bit */
228 #define OTP_LOCK_GU_LOC_OFF 129 /* General User Region lock bit */
232 #define OTP_SZ_FU_324 ((ROUNDUP(324,8))/8) /* 324 bits */
233 #define OTP_SZ_FU_288 (288/8) /* 288 bits */
234 #define OTP_SZ_FU_216 (216/8) /* 216 bits */
235 #define OTP_SZ_FU_72 (72/8) /* 72 bits */
236 #define OTP_SZ_CHECKSUM (16/8) /* 16 bits */
237 #define OTP4315_SWREG_SZ 178 /* 178 bytes */
238 #define OTP_SZ_FU_144 (144/8) /* 144 bits */
239 #define OTP_SZ_FU_180 ((ROUNDUP(180,8))/8) /* 180 bits */
242 ipxotp_status(void *oh
)
244 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
245 return (int)(oi
->status
);
248 /* Return size in bytes */
250 ipxotp_size(void *oh
)
252 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
253 return (int)oi
->wsize
* 2;
257 ipxotp_otpr(void *oh
, chipcregs_t
*cc
, uint wn
)
261 oi
= (otpinfo_t
*)oh
;
263 ASSERT(wn
< oi
->wsize
);
266 return R_REG(oi
->osh
, &cc
->sromotp
[wn
]);
270 ipxotp_read_bit(void *oh
, chipcregs_t
*cc
, uint off
)
272 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
276 row
= off
/ oi
->cols
;
277 col
= off
% oi
->cols
;
279 otpp
= OTPP_START_BUSY
|
280 ((OTPPOC_READ
<< OTPP_OC_SHIFT
) & OTPP_OC_MASK
) |
281 ((row
<< OTPP_ROW_SHIFT
) & OTPP_ROW_MASK
) |
282 ((col
<< OTPP_COL_SHIFT
) & OTPP_COL_MASK
);
283 OTP_DBG(("%s: off = %d, row = %d, col = %d, otpp = 0x%x",
284 __FUNCTION__
, off
, row
, col
, otpp
));
285 W_REG(oi
->osh
, &cc
->otpprog
, otpp
);
288 ((st
= R_REG(oi
->osh
, &cc
->otpprog
)) & OTPP_START_BUSY
) && (k
< OTPP_TRIES
);
291 if (k
>= OTPP_TRIES
) {
292 OTP_ERR(("\n%s: BUSY stuck: st=0x%x, count=%d\n", __FUNCTION__
, st
, k
));
295 if (st
& OTPP_READERR
) {
296 OTP_ERR(("\n%s: Could not read OTP bit %d\n", __FUNCTION__
, off
));
299 st
= (st
& OTPP_VALUE_MASK
) >> OTPP_VALUE_SHIFT
;
301 OTP_DBG((" => %d\n", st
));
306 /* Calculate max HW/SW region byte size by substracting fuse region and checksum size,
307 * osizew is oi->wsize (OTP size - GU size) in words
310 ipxotp_max_rgnsz(otpinfo_t
*oi
)
312 int osizew
= oi
->wsize
;
318 idx
= si_coreidx(oi
->sih
);
319 cc
= si_setcoreidx(oi
->sih
, SI_CC_IDX
);
322 checksum
= OTP_SZ_CHECKSUM
;
324 /* for new chips, fusebit is available from cc register */
325 if (oi
->sih
->ccrev
>= 35) {
326 oi
->fusebits
= R_REG(oi
->osh
, &cc
->otplayoutextension
) & OTPLAYOUTEXT_FUSE_MASK
;
329 si_setcoreidx(oi
->sih
, idx
);
331 switch (CHIPID(oi
->sih
->chip
)) {
332 case BCM4322_CHIP_ID
: case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
333 oi
->fusebits
= OTP_SZ_FU_288
;
335 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
336 case BCM43224_CHIP_ID
: case BCM43225_CHIP_ID
: case BCM43421_CHIP_ID
:
337 case BCM43226_CHIP_ID
: case BCM43420_CHIP_ID
:
338 oi
->fusebits
= OTP_SZ_FU_72
;
340 case BCM43236_CHIP_ID
: case BCM43235_CHIP_ID
: case BCM43238_CHIP_ID
:
341 case BCM43234_CHIP_ID
: case BCM43237_CHIP_ID
:
342 oi
->fusebits
= OTP_SZ_FU_324
;
344 case BCM4325_CHIP_ID
:
345 case BCM5356_CHIP_ID
:
346 oi
->fusebits
= OTP_SZ_FU_216
;
348 case BCM4336_CHIP_ID
:
349 case BCM43362_CHIP_ID
:
350 oi
->fusebits
= OTP_SZ_FU_144
;
352 case BCM4313_CHIP_ID
:
353 oi
->fusebits
= OTP_SZ_FU_72
;
355 case BCM4330_CHIP_ID
:
356 oi
->fusebits
= OTP_SZ_FU_144
;
358 case BCM4319_CHIP_ID
:
359 oi
->fusebits
= OTP_SZ_FU_180
;
361 case BCM4331_CHIP_ID
:
362 case BCM43431_CHIP_ID
:
363 oi
->fusebits
= OTP_SZ_FU_72
;
365 case BCM43131_CHIP_ID
:
366 case BCM43227_CHIP_ID
:
367 case BCM43228_CHIP_ID
:
368 case BCM43428_CHIP_ID
:
369 oi
->fusebits
= OTP_SZ_FU_72
;
372 ASSERT(0); /* Don't konw about this chip */
375 ret
= osizew
*2 - oi
->fusebits
- checksum
;
377 if (CHIPID(oi
->sih
->chip
) == BCM4315_CHIP_ID
) {
378 ret
= OTP4315_SWREG_SZ
;
381 OTP_MSG(("max region size %d bytes\n", ret
));
386 BCMNMIATTACHFN(_ipxotp_init
)(otpinfo_t
*oi
, chipcregs_t
*cc
)
391 /* record word offset of General Use Region for various chipcommon revs */
392 if (oi
->sih
->ccrev
== 21 || oi
->sih
->ccrev
== 24 || oi
->sih
->ccrev
== 27) {
393 oi
->otpgu_base
= REVA4_OTPGU_BASE
;
394 } else if (oi
->sih
->ccrev
== 36) {
395 /* OTP size greater than equal to 2KB (128 words), otpgu_base is similar to rev23 */
396 if (oi
->wsize
>= 128)
397 oi
->otpgu_base
= REVB8_OTPGU_BASE
;
399 oi
->otpgu_base
= REV36_OTPGU_BASE
;
400 } else if (oi
->sih
->ccrev
== 23 || oi
->sih
->ccrev
>= 25) {
401 oi
->otpgu_base
= REVB8_OTPGU_BASE
;
403 OTP_ERR(("%s: chipc rev %d not supported\n", __FUNCTION__
, oi
->sih
->ccrev
));
406 /* First issue an init command so the status is up to date */
407 otpp
= OTPP_START_BUSY
| ((OTPPOC_INIT
<< OTPP_OC_SHIFT
) & OTPP_OC_MASK
);
409 OTP_DBG(("%s: otpp = 0x%x", __FUNCTION__
, otpp
));
410 W_REG(oi
->osh
, &cc
->otpprog
, otpp
);
412 ((st
= R_REG(oi
->osh
, &cc
->otpprog
)) & OTPP_START_BUSY
) && (k
< OTPP_TRIES
);
415 if (k
>= OTPP_TRIES
) {
416 OTP_ERR(("\n%s: BUSY stuck: st=0x%x, count=%d\n", __FUNCTION__
, st
, k
));
420 /* Read OTP lock bits and subregion programmed indication bits */
421 oi
->status
= R_REG(oi
->osh
, &cc
->otpstatus
);
423 if ((CHIPID(oi
->sih
->chip
) == BCM43222_CHIP_ID
) ||
424 (CHIPID(oi
->sih
->chip
) == BCM43420_CHIP_ID
) ||
425 (CHIPID(oi
->sih
->chip
) == BCM43111_CHIP_ID
) ||
426 (CHIPID(oi
->sih
->chip
) == BCM43112_CHIP_ID
) ||
427 (CHIPID(oi
->sih
->chip
) == BCM43224_CHIP_ID
) ||
428 (CHIPID(oi
->sih
->chip
) == BCM43225_CHIP_ID
) ||
429 (CHIPID(oi
->sih
->chip
) == BCM43421_CHIP_ID
) ||
430 (CHIPID(oi
->sih
->chip
) == BCM43226_CHIP_ID
) ||
431 (CHIPID(oi
->sih
->chip
) == BCM43236_CHIP_ID
) ||
432 (CHIPID(oi
->sih
->chip
) == BCM43235_CHIP_ID
) ||
433 (CHIPID(oi
->sih
->chip
) == BCM43234_CHIP_ID
) ||
434 (CHIPID(oi
->sih
->chip
) == BCM43238_CHIP_ID
) ||
435 (CHIPID(oi
->sih
->chip
) == BCM43237_CHIP_ID
) ||
436 (CHIPID(oi
->sih
->chip
) == BCM4331_CHIP_ID
) ||
437 (CHIPID(oi
->sih
->chip
) == BCM43431_CHIP_ID
) ||
439 if (nvram_match("boardtype", "0xa4cf") && nvram_match("boardrev", "0x1102")) {
441 // skip this code on Belkin f7d4302 - crashes 2nd radio, reason unknown
442 printk(KERN_EMERG
"Belkin f7d4302\n");
446 p_bits
= (ipxotp_otpr(oi
, cc
, oi
->otpgu_base
+ OTPGU_P_OFF
) & OTPGU_P_MSK
)
448 oi
->status
|= (p_bits
<< OTPS_GUP_SHIFT
);
451 OTP_DBG(("%s: status 0x%x\n", __FUNCTION__
, oi
->status
));
454 * h/w region base and fuse region limit are fixed to the top and
455 * the bottom of the general use region. Everything else can be flexible.
457 oi
->hwbase
= oi
->otpgu_base
+ OTPGU_SROM_OFF
;
458 oi
->hwlim
= oi
->wsize
;
459 if (oi
->status
& OTPS_GUP_HW
) {
460 OTP_DBG(("%s: hw region programmed\n", __FUNCTION__
));
461 oi
->hwlim
= ipxotp_otpr(oi
, cc
, oi
->otpgu_base
+ OTPGU_HSB_OFF
) / 16;
462 oi
->swbase
= oi
->hwlim
;
464 oi
->hwlim
= ipxotp_max_rgnsz(oi
) / 2;
465 oi
->swbase
= oi
->hwbase
;
468 /* subtract fuse and checksum from beginning */
469 oi
->swlim
= ipxotp_max_rgnsz(oi
) / 2;
471 if (oi
->status
& OTPS_GUP_SW
) {
472 OTP_DBG(("%s: sw region programmed\n", __FUNCTION__
));
473 oi
->swlim
= ipxotp_otpr(oi
, cc
, oi
->otpgu_base
+ OTPGU_SFB_OFF
) / 16;
474 oi
->fbase
= oi
->swlim
;
477 oi
->fbase
= oi
->swbase
;
479 oi
->flim
= oi
->wsize
;
481 OTP_DBG(("%s: OTP limits---\n"
482 "hwbase %d/%d hwlim %d/%d\n"
483 "swbase %d/%d swlim %d/%d\n"
484 "fbase %d/%d flim %d/%d\n", __FUNCTION__
,
485 oi
->hwbase
, oi
->hwbase
* 16, oi
->hwlim
, oi
->hwlim
* 16,
486 oi
->swbase
, oi
->swbase
* 16, oi
->swlim
, oi
->swlim
* 16,
487 oi
->fbase
, oi
->fbase
* 16, oi
->flim
, oi
->flim
* 16));
491 BCMNMIATTACHFN(ipxotp_init
)(si_t
*sih
)
497 OTP_MSG(("%s: Use IPX OTP controller\n", __FUNCTION__
));
499 /* Make sure we're running IPX OTP */
500 ASSERT(OTPTYPE_IPX(sih
->ccrev
));
501 if (!OTPTYPE_IPX(sih
->ccrev
))
504 /* Make sure OTP is not disabled */
505 if (si_is_otp_disabled(sih
)) {
506 OTP_MSG(("%s: OTP is disabled\n", __FUNCTION__
));
512 /* Make sure OTP is powered up */
513 if (!si_is_otp_powered(sih
)) {
514 OTP_ERR(("%s: OTP is powered down\n", __FUNCTION__
));
520 /* Check for otp size */
521 switch ((sih
->cccaps
& CC_CAP_OTPSIZE
) >> CC_CAP_OTPSIZE_SHIFT
) {
524 OTP_ERR(("%s: no OTP\n", __FUNCTION__
));
541 case 7: /* 16x64 */ /* 1024 bits */
547 /* Don't know the geometry */
548 OTP_ERR(("%s: unknown OTP geometry\n", __FUNCTION__
));
552 OTP_MSG(("%s: rows %u cols %u wsize %u\n", __FUNCTION__
, oi
->rows
, oi
->cols
, oi
->wsize
));
555 /* Initialize OTP redundancy control blocks */
556 if (sih
->ccrev
== 21 || sih
->ccrev
== 24) {
557 uint16 offset
[] = {64, 79, 94, 109, 128, 143, 158, 173};
558 bcopy(offset
, &oi
->rde_cb
.offset
, sizeof(offset
));
559 oi
->rde_cb
.offsets
= ARRAYSIZE(offset
);
560 oi
->rde_cb
.width
= 15;
561 oi
->rde_cb
.val_shift
= 11;
562 oi
->rde_cb
.stat_shift
= 16;
564 else if (sih
->ccrev
== 27) {
565 uint16 offset
[] = {128, 143, 158, 173};
566 bcopy(offset
, &oi
->rde_cb
.offset
, sizeof(offset
));
567 oi
->rde_cb
.offsets
= ARRAYSIZE(offset
);
568 oi
->rde_cb
.width
= 15;
569 oi
->rde_cb
.val_shift
= 11;
570 oi
->rde_cb
.stat_shift
= 20;
573 uint16 offset
[] = {141, 158, 175, 205, 222, 239, 269, 286, 303};
574 bcopy(offset
, &oi
->rde_cb
.offset
, sizeof(offset
));
575 oi
->rde_cb
.offsets
= ARRAYSIZE(offset
);
576 oi
->rde_cb
.width
= 17;
577 oi
->rde_cb
.val_shift
= 13;
578 oi
->rde_cb
.stat_shift
= 16;
580 ASSERT(oi
->rde_cb
.offsets
<= MAXNUMRDES
);
581 #endif /* BCMNVRAMW */
583 /* Retrieve OTP region info */
584 idx
= si_coreidx(sih
);
585 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
588 _ipxotp_init(oi
, cc
);
590 si_setcoreidx(sih
, idx
);
596 ipxotp_read_region(void *oh
, int region
, uint16
*data
, uint
*wlen
)
598 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
603 /* Validate region selection */
606 sz
= (uint
)oi
->hwlim
- oi
->hwbase
;
607 if (!(oi
->status
& OTPS_GUP_HW
)) {
608 OTP_ERR(("%s: h/w region not programmed\n", __FUNCTION__
));
610 return BCME_NOTFOUND
;
613 OTP_ERR(("%s: buffer too small, should be at least %u\n",
614 __FUNCTION__
, oi
->hwlim
- oi
->hwbase
));
616 return BCME_BUFTOOSHORT
;
621 sz
= ((uint
)oi
->swlim
- oi
->swbase
);
622 if (!(oi
->status
& OTPS_GUP_SW
)) {
623 OTP_ERR(("%s: s/w region not programmed\n", __FUNCTION__
));
625 return BCME_NOTFOUND
;
628 OTP_ERR(("%s: buffer too small should be at least %u\n",
629 __FUNCTION__
, oi
->swlim
- oi
->swbase
));
631 return BCME_BUFTOOSHORT
;
637 if (!(oi
->status
& OTPS_GUP_CI
)) {
638 OTP_ERR(("%s: chipid region not programmed\n", __FUNCTION__
));
640 return BCME_NOTFOUND
;
643 OTP_ERR(("%s: buffer too small, should be at least %u\n",
644 __FUNCTION__
, OTPGU_CI_SZ
));
646 return BCME_BUFTOOSHORT
;
648 base
= oi
->otpgu_base
+ OTPGU_CI_OFF
;
651 sz
= (uint
)oi
->flim
- oi
->fbase
;
652 if (!(oi
->status
& OTPS_GUP_FUSE
)) {
653 OTP_ERR(("%s: fuse region not programmed\n", __FUNCTION__
));
655 return BCME_NOTFOUND
;
658 OTP_ERR(("%s: buffer too small, should be at least %u\n",
659 __FUNCTION__
, oi
->flim
- oi
->fbase
));
661 return BCME_BUFTOOSHORT
;
666 sz
= ((uint
)oi
->flim
- oi
->hwbase
);
667 if (!(oi
->status
& (OTPS_GUP_HW
| OTPS_GUP_SW
))) {
668 OTP_ERR(("%s: h/w & s/w region not programmed\n", __FUNCTION__
));
670 return BCME_NOTFOUND
;
673 OTP_ERR(("%s: buffer too small, should be at least %u\n",
674 __FUNCTION__
, oi
->hwlim
- oi
->hwbase
));
676 return BCME_BUFTOOSHORT
;
681 OTP_ERR(("%s: reading region %d is not supported\n", __FUNCTION__
, region
));
685 idx
= si_coreidx(oi
->sih
);
686 cc
= si_setcoreidx(oi
->sih
, SI_CC_IDX
);
690 for (i
= 0; i
< sz
; i
++)
691 data
[i
] = ipxotp_otpr(oh
, cc
, base
+ i
);
693 si_setcoreidx(oi
->sih
, idx
);
699 ipxotp_read_word(void *oh
, uint wn
, uint16
*data
)
701 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
705 idx
= si_coreidx(oi
->sih
);
706 cc
= si_setcoreidx(oi
->sih
, SI_CC_IDX
);
710 *data
= ipxotp_otpr(oh
, cc
, wn
);
712 si_setcoreidx(oi
->sih
, idx
);
717 ipxotp_nvread(void *oh
, char *data
, uint
*len
)
719 return BCME_UNSUPPORTED
;
724 ipxotp_write_bit(otpinfo_t
*oi
, chipcregs_t
*cc
, uint off
)
729 row
= off
/ oi
->cols
;
730 col
= off
% oi
->cols
;
732 otpp
= OTPP_START_BUSY
|
733 ((1 << OTPP_VALUE_SHIFT
) & OTPP_VALUE_MASK
) |
734 ((OTPPOC_BIT_PROG
<< OTPP_OC_SHIFT
) & OTPP_OC_MASK
) |
735 ((row
<< OTPP_ROW_SHIFT
) & OTPP_ROW_MASK
) |
736 ((col
<< OTPP_COL_SHIFT
) & OTPP_COL_MASK
);
737 OTP_DBG(("%s: off = %d, row = %d, col = %d, otpp = 0x%x\n",
738 __FUNCTION__
, off
, row
, col
, otpp
));
740 W_REG(oi
->osh
, &cc
->otpprog
, otpp
);
743 ((st
= R_REG(oi
->osh
, &cc
->otpprog
)) & OTPP_START_BUSY
) && (k
< OTPP_TRIES
);
746 if (k
>= OTPP_TRIES
) {
747 OTP_ERR(("\n%s: BUSY stuck: st=0x%x, count=%d\n", __FUNCTION__
, st
, k
));
756 ipxotp_write_lock_bit(otpinfo_t
*oi
, chipcregs_t
*cc
, uint off
)
761 row
= off
/ oi
->cols
;
762 col
= off
% oi
->cols
;
764 otpp
= OTPP_START_BUSY
|
765 ((OTPPOC_ROW_LOCK
<< OTPP_OC_SHIFT
) & OTPP_OC_MASK
) |
766 ((row
<< OTPP_ROW_SHIFT
) & OTPP_ROW_MASK
) |
767 ((col
<< OTPP_COL_SHIFT
) & OTPP_COL_MASK
);
768 OTP_DBG(("%s: off = %d, row = %d, col = %d, otpp = 0x%x\n",
769 __FUNCTION__
, off
, row
, col
, otpp
));
771 W_REG(oi
->osh
, &cc
->otpprog
, otpp
);
774 ((st
= R_REG(oi
->osh
, &cc
->otpprog
)) & OTPP_START_BUSY
) && (k
< OTPP_TRIES
);
777 if (k
>= OTPP_TRIES
) {
778 OTP_ERR(("\n%s: BUSY stuck: st=0x%x, count=%d\n", __FUNCTION__
, st
, k
));
786 ipxotp_otpwb16(otpinfo_t
*oi
, chipcregs_t
*cc
, int wn
, uint16 data
)
792 for (i
= 0; i
< 16; i
++) {
793 if (data
& (1 << i
)) {
794 if ((rc
= ipxotp_write_bit(oi
, cc
, base
+ i
)))
802 /* Write OTP redundancy entry:
803 * rde - redundancy entry index (-ve for "next")
808 ipxotp_write_rde(void *oh
, int rde
, uint bit
, uint val
)
810 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
816 if ((rde
>= oi
->rde_cb
.offsets
) || (bit
>= oi
->rows
* oi
->cols
) || (val
> 1))
821 for (rde
= 0; rde
< oi
->rde_cb
.offsets
- 1; rde
++) {
822 if ((oi
->status
& (1 << (oi
->rde_cb
.stat_shift
+ rde
))) == 0)
825 OTP_MSG(("%s: Auto rde index %d\n", __FUNCTION__
, rde
));
828 if (oi
->status
& (1 << (oi
->rde_cb
.stat_shift
+ rde
))) {
829 OTP_MSG(("%s: rde %d already in use, status 0x%08x\n", __FUNCTION__
,
834 idx
= si_coreidx(oi
->sih
);
835 cc
= si_setcoreidx(oi
->sih
, SI_CC_IDX
);
838 temp
= ~(~0 << oi
->rde_cb
.width
) &
839 ((~0 << (oi
->rde_cb
.val_shift
+ 1)) | (val
<< oi
->rde_cb
.val_shift
) | bit
);
841 OTP_MSG(("%s: rde %d bit %d val %d bmp 0x%08x\n", __FUNCTION__
, rde
, bit
, val
, temp
));
844 OR_REG(oi
->osh
, &cc
->otpcontrol
, OTPC_PROGEN
);
846 for (i
= 0; i
< oi
->rde_cb
.width
; i
++) {
847 if (!(temp
& (1 << i
)))
849 ipxotp_write_bit(oi
, cc
, oi
->rde_cb
.offset
[rde
] + i
);
853 AND_REG(oi
->osh
, &cc
->otpcontrol
, ~OTPC_PROGEN
);
855 si_otp_power(oi
->sih
, FALSE
);
856 si_otp_power(oi
->sih
, TRUE
);
857 _ipxotp_init(oi
, cc
);
859 si_setcoreidx(oi
->sih
, idx
);
863 /* Set up redundancy entries for the specified bits */
865 ipxotp_fix_word16(void *oh
, uint wn
, uint16 mask
, uint16 val
)
871 oi
= (otpinfo_t
*)oh
;
874 ASSERT(wn
< oi
->wsize
);
876 for (bit
= wn
* 16; mask
; bit
++, mask
>>= 1, val
>>= 1) {
878 if ((rc
= ipxotp_write_rde(oi
, -1, bit
, val
& 1)))
887 ipxotp_check_word16(void *oh
, chipcregs_t
*cc
, uint wn
, uint16 val
)
889 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
890 uint16 word
= ipxotp_otpr(oi
, cc
, wn
);
894 OTP_MSG(("%s: word %d is 0x%04x, wanted 0x%04x, fixing...\n",
895 __FUNCTION__
, wn
, (word
^ val
), val
));
896 if ((rc
= ipxotp_fix_word16(oi
, wn
, word
, val
))) {
897 OTP_ERR(("FAILED, ipxotp_fix_word16 returns %d\n", rc
));
898 /* Fatal error, unfixable. MFGC will have to fail. Board
899 * needs to be discarded!!
901 return BCME_NORESOURCE
;
908 /* expects the caller to disable interrupts before calling this routine */
910 ipxotp_write_region(void *oh
, int region
, uint16
*data
, uint wlen
)
912 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
917 bool rewrite
= FALSE
;
919 uint16
*origdata
= NULL
;
921 otpgu_bit_base
= oi
->otpgu_base
* 16;
923 /* Validate region selection */
926 if (wlen
> (uint
)(oi
->hwlim
- oi
->hwbase
)) {
927 OTP_ERR(("%s: wlen %u exceeds OTP h/w region limit %u\n",
928 __FUNCTION__
, wlen
, oi
->hwlim
- oi
->hwbase
));
929 return BCME_BUFTOOLONG
;
931 rewrite
= !!(oi
->status
& OTPS_GUP_HW
);
935 if (wlen
> (uint
)(oi
->swlim
- oi
->swbase
)) {
936 OTP_ERR(("%s: wlen %u exceeds OTP s/w region limit %u\n",
937 __FUNCTION__
, wlen
, oi
->swlim
- oi
->swbase
));
938 return BCME_BUFTOOLONG
;
940 rewrite
= !!(oi
->status
& OTPS_GUP_SW
);
944 if (oi
->status
& OTPS_GUP_CI
) {
945 OTP_ERR(("%s: chipid region has been programmed\n", __FUNCTION__
));
948 if (wlen
> OTPGU_CI_SZ
) {
949 OTP_ERR(("%s: wlen %u exceeds OTP ci region limit %u\n",
950 __FUNCTION__
, wlen
, OTPGU_CI_SZ
));
951 return BCME_BUFTOOLONG
;
953 if ((wlen
== OTPGU_CI_SZ
) && (data
[OTPGU_CI_SZ
- 1] & OTPGU_P_MSK
) != 0) {
954 OTP_ERR(("%s: subregion programmed bits not zero\n", __FUNCTION__
));
957 base
= oi
->otpgu_base
+ OTPGU_CI_OFF
;
960 if (oi
->status
& OTPS_GUP_FUSE
) {
961 OTP_ERR(("%s: fuse region has been programmed\n", __FUNCTION__
));
964 if (wlen
> (uint
)(oi
->flim
- oi
->fbase
)) {
965 OTP_ERR(("%s: wlen %u exceeds OTP ci region limit %u\n",
966 __FUNCTION__
, wlen
, oi
->flim
- oi
->fbase
));
967 return BCME_BUFTOOLONG
;
969 base
= oi
->flim
- wlen
;
972 OTP_ERR(("%s: writing region %d is not supported\n", __FUNCTION__
, region
));
976 idx
= si_coreidx(oi
->sih
);
977 cc
= si_setcoreidx(oi
->sih
, SI_CC_IDX
);
980 /* Check for conflict; Since some bits might be programmed at ATE time, we need to
981 * avoid redundancy by clearing already written bits, but copy original for verification.
983 if ((origdata
= (uint16
*)MALLOC(oi
->osh
, wlen
* 2)) == NULL
) {
987 for (i
= 0; i
< wlen
; i
++) {
988 origdata
[i
] = data
[i
];
989 data
[i
] = ipxotp_otpr(oi
, cc
, base
+ i
);
990 if (data
[i
] & ~origdata
[i
]) {
991 OTP_ERR(("%s: %s region: word %d incompatible (0x%04x->0x%04x)\n",
992 __FUNCTION__
, HWSW_RGN(region
), i
, data
[i
], origdata
[i
]));
996 data
[i
] ^= origdata
[i
];
998 OTP_MSG(("%s: writing new bits in %s region\n", __FUNCTION__
, HWSW_RGN(region
)));
1001 OR_REG(oi
->osh
, &cc
->otpcontrol
, OTPC_PROGEN
);
1003 /* Write the data */
1004 for (i
= 0; i
< wlen
; i
++) {
1005 ipxotp_otpwb16(oi
, cc
, base
+ i
, data
[i
]);
1008 /* One time set region flag: Update boundary/flag in memory and in OTP */
1012 ipxotp_otpwb16(oi
, cc
, oi
->otpgu_base
+ OTPGU_HSB_OFF
, (base
+ i
) * 16);
1013 ipxotp_write_bit(oi
, cc
, otpgu_bit_base
+ OTPGU_HWP_OFF
);
1016 /* Write HW region limit as well */
1017 ipxotp_otpwb16(oi
, cc
, oi
->otpgu_base
+ OTPGU_HSB_OFF
, base
* 16);
1018 /* write max swlim(covert to bits) to the sw/fuse boundary */
1019 ipxotp_otpwb16(oi
, cc
, oi
->otpgu_base
+ OTPGU_SFB_OFF
, oi
->swlim
* 16);
1020 ipxotp_write_bit(oi
, cc
, otpgu_bit_base
+ OTPGU_SWP_OFF
);
1023 ipxotp_write_bit(oi
, cc
, otpgu_bit_base
+ OTPGU_CIP_OFF
);
1024 /* Also set the OTPGU_CIP_MSK bit in the input so verification
1027 if (wlen
>= OTPGU_CI_SZ
)
1028 data
[OTPGU_CI_SZ
- 1] |= OTPGU_CIP_MSK
;
1031 ipxotp_otpwb16(oi
, cc
, oi
->otpgu_base
+ OTPGU_SFB_OFF
, base
* 16);
1032 ipxotp_write_bit(oi
, cc
, otpgu_bit_base
+ OTPGU_FUSEP_OFF
);
1038 AND_REG(oi
->osh
, &cc
->otpcontrol
, ~OTPC_PROGEN
);
1040 /* Sync region info by retrieving them again (use PMU bit to power cycle OTP) */
1041 si_otp_power(oi
->sih
, FALSE
);
1042 si_otp_power(oi
->sih
, TRUE
);
1044 /* Check and fix for region size and region programmed bits */
1046 uint16 boundary_off
= 0, boundary_val
= 0;
1047 uint16 programmed_off
= 0;
1052 boundary_off
= OTPGU_HSB_OFF
;
1053 boundary_val
= (base
+ i
) * 16;
1054 programmed_off
= OTPGU_HWP_OFF
;
1057 /* Also write 0 to HW region boundary */
1058 if ((rc
= ipxotp_check_word16(oi
, cc
, oi
->otpgu_base
+ OTPGU_HSB_OFF
,
1061 boundary_off
= OTPGU_SFB_OFF
;
1062 boundary_val
= oi
->swlim
* 16;
1063 programmed_off
= OTPGU_SWP_OFF
;
1066 /* No CI region boundary */
1067 programmed_off
= OTPGU_CIP_OFF
;
1070 boundary_off
= OTPGU_SFB_OFF
;
1071 boundary_val
= base
* 16;
1072 programmed_off
= OTPGU_FUSEP_OFF
;
1076 /* Do the actual checking and return BCME_NORESOURCE if we cannot fix */
1077 if ((region
!= OTP_CI_RGN
) &&
1078 (rc
= ipxotp_check_word16(oi
, cc
, oi
->otpgu_base
+ boundary_off
,
1083 if ((bit
= ipxotp_read_bit(oh
, cc
, otpgu_bit_base
+ programmed_off
)) == 0xffff) {
1084 OTP_ERR(("\n%s: FAILED bit %d reads %d\n", __FUNCTION__
, otpgu_bit_base
+
1085 programmed_off
, bit
));
1087 } else if (bit
== 0) { /* error detected, fix it */
1088 OTP_ERR(("\n%s: FAILED bit %d reads %d, fixing\n", __FUNCTION__
,
1089 otpgu_bit_base
+ programmed_off
, bit
));
1090 if ((rc
= ipxotp_write_rde(oi
, -1, otpgu_bit_base
+ programmed_off
, 1))) {
1091 OTP_ERR(("\n%s: cannot fix, ipxotp_write_rde returns %d\n",
1098 /* Update status, apply WAR */
1099 _ipxotp_init(oi
, cc
);
1101 /* Recover original data... */
1103 bcopy(origdata
, data
, wlen
* 2);
1105 /* ...so we can verify and fix where possible */
1106 for (i
= 0; i
< wlen
; i
++) {
1107 if ((rc
= ipxotp_check_word16(oi
, cc
, base
+ i
, data
[i
])))
1113 MFREE(oi
->osh
, origdata
, wlen
* 2);
1115 si_setcoreidx(oi
->sih
, idx
);
1120 ipxotp_write_word(void *oh
, uint wn
, uint16 data
)
1122 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
1128 idx
= si_coreidx(oi
->sih
);
1129 cc
= si_setcoreidx(oi
->sih
, SI_CC_IDX
);
1132 /* Check for conflict */
1134 data
= ipxotp_otpr(oi
, cc
, wn
);
1135 if (data
& ~origdata
) {
1136 OTP_ERR(("%s: word %d incompatible (0x%04x->0x%04x)\n",
1137 __FUNCTION__
, wn
, data
, origdata
));
1144 OR_REG(oi
->osh
, &cc
->otpcontrol
, OTPC_PROGEN
);
1146 rc
= ipxotp_otpwb16(oi
, cc
, wn
, data
);
1149 AND_REG(oi
->osh
, &cc
->otpcontrol
, ~OTPC_PROGEN
);
1152 if ((rc
= ipxotp_check_word16(oi
, cc
, wn
, data
)))
1155 si_setcoreidx(oi
->sih
, idx
);
1160 ipxotp_cis_append_region(si_t
*sih
, int region
, char *vars
, int count
)
1164 uint sz
= OTP_SZ_MAX
/2; /* size in words */
1166 bool newchip
= FALSE
;
1168 ASSERT(region
== OTP_HW_RGN
|| region
== OTP_SW_RGN
);
1171 if ((cis
= MALLOC(osh
, OTP_SZ_MAX
)) == NULL
) {
1175 bzero(cis
, OTP_SZ_MAX
);
1177 rc
= otp_read_region(sih
, region
, (uint16
*)cis
, &sz
);
1178 newchip
= (rc
== BCME_NOTFOUND
) ? TRUE
: FALSE
;
1179 if ((rc
!= 0) && (rc
!= BCME_NOTFOUND
)) {
1184 /* zero count for read, non-zero count for write */
1186 int i
= 0, newlen
= 0;
1189 int termw_len
= 0; /* length of termination word */
1191 /* convert halfwords to bytes offset */
1194 if ((CHIPID(sih
->chip
) == BCM4322_CHIP_ID
) ||
1195 (CHIPID(sih
->chip
) == BCM43231_CHIP_ID
) ||
1196 (CHIPID(sih
->chip
) == BCM4315_CHIP_ID
) ||
1197 (CHIPID(sih
->chip
) == BCM4319_CHIP_ID
)) {
1198 /* bootloader WAR, refer to above twiki link */
1199 cis
[newlen
-1] = 0x00;
1200 cis
[newlen
-2] = 0xff;
1201 cis
[newlen
-3] = 0x00;
1202 cis
[newlen
-4] = 0xff;
1203 cis
[newlen
-5] = 0xff;
1204 cis
[newlen
-6] = 0x1;
1205 cis
[newlen
-7] = 0x2;
1208 cis
[newlen
-1] = 0xff;
1209 cis
[newlen
-2] = 0xff;
1213 if (count
>= newlen
- termw_len
) {
1214 OTP_MSG(("OTP left %x bytes; buffer %x bytes\n", newlen
, count
));
1215 rc
= BCME_BUFTOOLONG
;
1220 /* Walk through the leading zeros (could be 0 or 8 bytes for now) */
1221 for (i
= 0; i
< (int)sz
*2; i
++)
1225 /* Find the place to append */
1226 for (; i
< (int)sz
*2; i
++) {
1229 i
+= ((int)cis
[i
+1] + 1);
1232 for (end
= i
; end
< (int)sz
*2; end
++) {
1238 if (newlen
& 1) /* make it even-sized buffer */
1241 if (newlen
>= (end
- 1)) {
1242 OTP_MSG(("OTP left %x bytes; buffer %x bytes\n", end
-i
, count
));
1243 rc
= BCME_BUFTOOLONG
;
1247 /* copy the buffer */
1248 memcpy(&cis
[i
], vars
, count
);
1250 /* Write the buffer back */
1252 rc
= otp_write_region(sih
, region
, (uint16
*)cis
, newlen
/2);
1254 /* Print the buffer */
1255 OTP_MSG(("Buffer of size %d bytes to write:\n", newlen
));
1256 for (i
= 0; i
< newlen
; i
++) {
1257 OTP_DBG(("%02x ", cis
[i
] & 0xff));
1258 if ((i
% 16) == 15) {
1263 #endif /* BCMNVRAMW */
1267 MFREE(osh
, cis
, OTP_SZ_MAX
);
1272 /* No need to lock for IPXOTP */
1274 ipxotp_lock(void *oh
)
1278 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
1279 int err
= 0, rc
= 0;
1281 idx
= si_coreidx(oi
->sih
);
1282 cc
= si_setcoreidx(oi
->sih
, SI_CC_IDX
);
1286 OR_REG(oi
->osh
, &cc
->otpcontrol
, OTPC_PROGEN
);
1288 err
= ipxotp_write_lock_bit(oi
, cc
, OTP_LOCK_ROW1_LOC_OFF
);
1290 OTP_ERR(("fail to lock ROW1\n"));
1293 err
= ipxotp_write_lock_bit(oi
, cc
, OTP_LOCK_ROW2_LOC_OFF
);
1295 OTP_ERR(("fail to lock ROW2\n"));
1298 err
= ipxotp_write_lock_bit(oi
, cc
, OTP_LOCK_RD_LOC_OFF
);
1300 OTP_ERR(("fail to lock RD\n"));
1303 err
= ipxotp_write_lock_bit(oi
, cc
, OTP_LOCK_GU_LOC_OFF
);
1305 OTP_ERR(("fail to lock GU\n"));
1310 AND_REG(oi
->osh
, &cc
->otpcontrol
, ~OTPC_PROGEN
);
1312 /* Sync region info by retrieving them again (use PMU bit to power cycle OTP) */
1313 si_otp_power(oi
->sih
, FALSE
);
1314 si_otp_power(oi
->sih
, TRUE
);
1316 /* Update status, apply WAR */
1317 _ipxotp_init(oi
, cc
);
1322 ipxotp_nvwrite(void *oh
, uint16
*data
, uint wlen
)
1326 #endif /* BCMNVRAMW */
1330 ipxotp_otprb16(void *oh
, chipcregs_t
*cc
, uint wn
)
1339 for (i
= 0; i
< 16; i
++) {
1340 if ((bit
= ipxotp_read_bit(oh
, cc
, base
+ i
)) == 0xffff)
1342 val
= val
| (bit
<< i
);
1351 ipxotp_dump(void *oh
, int arg
, char *buf
, uint size
)
1353 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
1359 idx
= si_coreidx(oi
->sih
);
1360 cc
= si_setcoreidx(oi
->sih
, SI_CC_IDX
);
1363 count
= ipxotp_size(oh
);
1365 bcm_binit(&b
, buf
, size
);
1366 for (i
= 0; i
< count
/ 2; i
++) {
1368 bcm_bprintf(&b
, "\n0x%04x:", 2 * i
);
1370 val
= ipxotp_otpr(oh
, cc
, i
);
1372 val
= ipxotp_otprb16(oi
, cc
, i
);
1373 bcm_bprintf(&b
, " 0x%04x", val
);
1375 bcm_bprintf(&b
, "\n");
1377 si_setcoreidx(oi
->sih
, idx
);
1379 return ((int)(b
.buf
- b
.origbuf
));
1383 static otp_fn_t ipxotp_fn
= {
1384 (otp_size_t
)ipxotp_size
,
1385 (otp_read_bit_t
)ipxotp_read_bit
,
1387 (otp_init_t
)ipxotp_init
,
1388 (otp_read_region_t
)ipxotp_read_region
,
1389 (otp_nvread_t
)ipxotp_nvread
,
1391 (otp_write_region_t
)ipxotp_write_region
,
1392 (otp_cis_append_region_t
)ipxotp_cis_append_region
,
1393 (otp_lock_t
)ipxotp_lock
,
1394 (otp_nvwrite_t
)ipxotp_nvwrite
,
1395 #endif /* BCMNVRAMW */
1398 (otp_dump_t
)ipxotp_dump
,
1401 (otp_status_t
)ipxotp_status
,
1403 (otp_write_word_t
)ipxotp_write_word
,
1404 #endif /* BCMNVRAMW */
1405 (otp_read_word_t
)ipxotp_read_word
,
1408 #endif /* BCMIPXOTP */
1414 * Exported functions:
1419 * hndotp_read_region()
1420 * hndotp_read_word()
1422 * hndotp_write_region()
1423 * hndotp_cis_append_region()
1428 * HND internal functions:
1431 * hndotp_write_bit()
1432 * hndotp_write_word()
1433 * hndotp_valid_rce()
1434 * hndotp_write_rce()
1435 * hndotp_write_row()
1442 /* Fields in otpstatus */
1443 #define OTPS_PROGFAIL 0x80000000
1444 #define OTPS_PROTECT 0x00000007
1445 #define OTPS_HW_PROTECT 0x00000001
1446 #define OTPS_SW_PROTECT 0x00000002
1447 #define OTPS_CID_PROTECT 0x00000004
1448 #define OTPS_RCEV_MSK 0x00003f00
1449 #define OTPS_RCEV_SHIFT 8
1451 /* Fields in the otpcontrol register */
1452 #define OTPC_RECWAIT 0xff000000
1453 #define OTPC_PROGWAIT 0x00ffff00
1454 #define OTPC_PRW_SHIFT 8
1455 #define OTPC_MAXFAIL 0x00000038
1456 #define OTPC_VSEL 0x00000006
1457 #define OTPC_SELVL 0x00000001
1459 /* OTP regions (Word offsets from otp size) */
1460 #define OTP_SWLIM_OFF (-4)
1461 #define OTP_CIDBASE_OFF 0
1462 #define OTP_CIDLIM_OFF 4
1464 /* Predefined OTP words (Word offset from otp size) */
1465 #define OTP_BOUNDARY_OFF (-4)
1466 #define OTP_HWSIGN_OFF (-3)
1467 #define OTP_SWSIGN_OFF (-2)
1468 #define OTP_CIDSIGN_OFF (-1)
1469 #define OTP_CID_OFF 0
1470 #define OTP_PKG_OFF 1
1471 #define OTP_FID_OFF 2
1472 #define OTP_RSV_OFF 3
1473 #define OTP_LIM_OFF 4
1474 #define OTP_RD_OFF 4 /* Redundancy row starts here */
1475 #define OTP_RC0_OFF 28 /* Redundancy control word 1 */
1476 #define OTP_RC1_OFF 32 /* Redundancy control word 2 */
1477 #define OTP_RC_LIM_OFF 36 /* Redundancy control word end */
1479 #define OTP_HW_REGION OTPS_HW_PROTECT
1480 #define OTP_SW_REGION OTPS_SW_PROTECT
1481 #define OTP_CID_REGION OTPS_CID_PROTECT
1483 #if OTP_HW_REGION != OTP_HW_RGN
1484 #error "incompatible OTP_HW_RGN"
1486 #if OTP_SW_REGION != OTP_SW_RGN
1487 #error "incompatible OTP_SW_RGN"
1489 #if OTP_CID_REGION != OTP_CI_RGN
1490 #error "incompatible OTP_CI_RGN"
1493 /* Redundancy entry definitions */
1494 #define OTP_RCE_ROW_SZ 6
1495 #define OTP_RCE_SIGN_MASK 0x7fff
1496 #define OTP_RCE_ROW_MASK 0x3f
1497 #define OTP_RCE_BITS 21
1498 #define OTP_RCE_SIGN_SZ 15
1499 #define OTP_RCE_BIT0 1
1502 #define OTP_SIGNATURE 0x578a
1503 #define OTP_MAGIC 0x4e56
1506 hndotp_status(void *oh
)
1508 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
1509 return ((int)(oi
->hwprot
| oi
->signvalid
));
1513 hndotp_size(void *oh
)
1515 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
1516 return ((int)(oi
->size
));
1520 hndotp_otpr(void *oh
, chipcregs_t
*cc
, uint wn
)
1522 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
1524 volatile uint16
*ptr
;
1526 ASSERT(wn
< ((oi
->size
/ 2) + OTP_RC_LIM_OFF
));
1529 osh
= si_osh(oi
->sih
);
1531 ptr
= (volatile uint16
*)((volatile char *)cc
+ CC_SROM_OTP
);
1532 return (R_REG(osh
, &ptr
[wn
]));
1536 hndotp_otproff(void *oh
, chipcregs_t
*cc
, int woff
)
1538 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
1540 volatile uint16
*ptr
;
1542 ASSERT(woff
>= (-((int)oi
->size
/ 2)));
1543 ASSERT(woff
< OTP_LIM_OFF
);
1546 osh
= si_osh(oi
->sih
);
1548 ptr
= (volatile uint16
*)((volatile char *)cc
+ CC_SROM_OTP
);
1550 return (R_REG(osh
, &ptr
[(oi
->size
/ 2) + woff
]));
1554 hndotp_read_bit(void *oh
, chipcregs_t
*cc
, uint idx
)
1556 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
1561 osh
= si_osh(oi
->sih
);
1565 otpp
= OTPP_START_BUSY
| OTPP_READ
|
1566 ((row
<< OTPP_ROW_SHIFT
) & OTPP_ROW_MASK
) |
1567 (col
& OTPP_COL_MASK
);
1569 OTP_DBG(("%s: idx = %d, row = %d, col = %d, otpp = 0x%x", __FUNCTION__
,
1570 idx
, row
, col
, otpp
));
1572 W_REG(osh
, &cc
->otpprog
, otpp
);
1573 st
= R_REG(osh
, &cc
->otpprog
);
1574 for (k
= 0; ((st
& OTPP_START_BUSY
) == OTPP_START_BUSY
) && (k
< OTPP_TRIES
); k
++)
1575 st
= R_REG(osh
, &cc
->otpprog
);
1577 if (k
>= OTPP_TRIES
) {
1578 OTP_ERR(("\n%s: BUSY stuck: st=0x%x, count=%d\n", __FUNCTION__
, st
, k
));
1581 if (st
& OTPP_READERR
) {
1582 OTP_ERR(("\n%s: Could not read OTP bit %d\n", __FUNCTION__
, idx
));
1585 st
= (st
& OTPP_VALUE_MASK
) >> OTPP_VALUE_SHIFT
;
1586 OTP_DBG((" => %d\n", st
));
1591 BCMNMIATTACHFN(hndotp_init
)(si_t
*sih
)
1596 uint32 cap
= 0, clkdiv
, otpdiv
= 0;
1600 OTP_MSG(("%s: Use HND OTP controller\n", __FUNCTION__
));
1603 idx
= si_coreidx(sih
);
1604 osh
= si_osh(oi
->sih
);
1607 if ((cc
= si_setcoreidx(sih
, SI_CC_IDX
)) != NULL
) {
1608 cap
= R_REG(osh
, &cc
->capabilities
);
1609 if ((cap
& CC_CAP_OTPSIZE
) == 0) {
1614 /* As of right now, support only 4320a2, 4311a1 and 4312 */
1615 ASSERT((oi
->ccrev
== 12) || (oi
->ccrev
== 17) || (oi
->ccrev
== 22));
1616 if (!((oi
->ccrev
== 12) || (oi
->ccrev
== 17) || (oi
->ccrev
== 22)))
1619 /* Read the OTP byte size. chipcommon rev >= 18 has RCE so the size is
1620 * 8 row (64 bytes) smaller
1622 oi
->size
= 1 << (((cap
& CC_CAP_OTPSIZE
) >> CC_CAP_OTPSIZE_SHIFT
)
1623 + CC_CAP_OTPSIZE_BASE
);
1624 if (oi
->ccrev
>= 18) {
1625 oi
->size
-= ((OTP_RC0_OFF
- OTP_BOUNDARY_OFF
) * 2);
1627 OTP_ERR(("Negative otp size, shouldn't happen for programmed chip."));
1631 oi
->hwprot
= (int)(R_REG(osh
, &cc
->otpstatus
) & OTPS_PROTECT
);
1634 /* Check the region signature */
1635 if (hndotp_otproff(oi
, cc
, OTP_HWSIGN_OFF
) == OTP_SIGNATURE
) {
1636 oi
->signvalid
|= OTP_HW_REGION
;
1637 oi
->boundary
= hndotp_otproff(oi
, cc
, OTP_BOUNDARY_OFF
);
1640 if (hndotp_otproff(oi
, cc
, OTP_SWSIGN_OFF
) == OTP_SIGNATURE
)
1641 oi
->signvalid
|= OTP_SW_REGION
;
1643 if (hndotp_otproff(oi
, cc
, OTP_CIDSIGN_OFF
) == OTP_SIGNATURE
)
1644 oi
->signvalid
|= OTP_CID_REGION
;
1646 /* Set OTP clkdiv for stability */
1647 if (oi
->ccrev
== 22)
1651 clkdiv
= R_REG(osh
, &cc
->clkdiv
);
1652 clkdiv
= (clkdiv
& ~CLKD_OTP
) | (otpdiv
<< CLKD_OTP_SHIFT
);
1653 W_REG(osh
, &cc
->clkdiv
, clkdiv
);
1654 OTP_MSG(("%s: set clkdiv to %x\n", __FUNCTION__
, clkdiv
));
1661 OTP_MSG(("%s: ccrev %d\tsize %d bytes\thwprot %x\tsignvalid %x\tboundary %x\n",
1662 __FUNCTION__
, oi
->ccrev
, oi
->size
, oi
->hwprot
, oi
->signvalid
,
1666 si_setcoreidx(sih
, idx
);
1672 hndotp_read_region(void *oh
, int region
, uint16
*data
, uint
*wlen
)
1674 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
1679 /* Only support HW region (no active chips use HND OTP SW region) */
1680 ASSERT(region
== OTP_HW_REGION
);
1682 OTP_MSG(("%s: region %x wlen %d\n", __FUNCTION__
, region
, *wlen
));
1685 st
= oi
->hwprot
| oi
-> signvalid
;
1686 if ((st
& region
) == 0)
1687 return BCME_NOTFOUND
;
1689 *wlen
= ((int)*wlen
< oi
->boundary
/2) ? *wlen
: (uint
)oi
->boundary
/2;
1691 idx
= si_coreidx(oi
->sih
);
1692 cc
= si_setcoreidx(oi
->sih
, SI_CC_IDX
);
1695 for (i
= 0; i
< (int)*wlen
; i
++)
1696 data
[i
] = hndotp_otpr(oh
, cc
, i
);
1698 si_setcoreidx(oi
->sih
, idx
);
1704 hndotp_read_word(void *oh
, uint wn
, uint16
*data
)
1706 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
1710 idx
= si_coreidx(oi
->sih
);
1711 cc
= si_setcoreidx(oi
->sih
, SI_CC_IDX
);
1714 *data
= hndotp_otpr(oh
, cc
, wn
);
1716 si_setcoreidx(oi
->sih
, idx
);
1721 hndotp_nvread(void *oh
, char *data
, uint
*len
)
1724 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
1725 uint32 base
, bound
, lim
= 0, st
;
1726 int i
, chunk
, gchunks
, tsz
= 0;
1730 uint16
*rawotp
= NULL
;
1732 /* save the orig core */
1733 idx
= si_coreidx(oi
->sih
);
1734 cc
= si_setcoreidx(oi
->sih
, SI_CC_IDX
);
1737 st
= hndotp_status(oh
);
1738 if (!(st
& (OTP_HW_REGION
| OTP_SW_REGION
))) {
1739 OTP_ERR(("OTP not programmed\n"));
1744 /* Read the whole otp so we can easily manipulate it */
1745 lim
= hndotp_size(oh
);
1747 OTP_ERR(("OTP size is 0\n"));
1751 if ((rawotp
= MALLOC(si_osh(oi
->sih
), lim
)) == NULL
) {
1752 OTP_ERR(("Out of memory for rawotp\n"));
1756 for (i
= 0; i
< (int)(lim
/ 2); i
++)
1757 rawotp
[i
] = hndotp_otpr(oh
, cc
, i
);
1759 if ((st
& OTP_HW_REGION
) == 0) {
1760 OTP_ERR(("otp: hw region not written (0x%x)\n", st
));
1762 /* This could be a programming failure in the first
1763 * chunk followed by one or more good chunks
1765 for (i
= 0; i
< (int)(lim
/ 2); i
++)
1766 if (rawotp
[i
] == OTP_MAGIC
)
1769 if (i
< (int)(lim
/ 2)) {
1771 bound
= (i
* 2) + rawotp
[i
+ 1];
1772 OTP_MSG(("otp: trying chunk at 0x%x-0x%x\n", i
* 2, bound
));
1774 OTP_MSG(("otp: unprogrammed\n"));
1779 bound
= rawotp
[(lim
/ 2) + OTP_BOUNDARY_OFF
];
1781 /* There are two cases: 1) The whole otp is used as nvram
1782 * and 2) There is a hardware header followed by nvram.
1784 if (rawotp
[0] == OTP_MAGIC
) {
1786 if (bound
!= rawotp
[1])
1787 OTP_MSG(("otp: Bound 0x%x != chunk0 len 0x%x\n", bound
,
1793 /* Find and copy the data */
1799 while ((i
< (int)(lim
/ 2)) && (rawotp
[i
] == OTP_MAGIC
)) {
1800 int dsz
, rsz
= rawotp
[i
+ 1];
1802 if (((i
* 2) + rsz
) >= (int)lim
) {
1803 OTP_MSG((" bad chunk size, chunk %d, base 0x%x, size 0x%x\n",
1804 chunk
, i
* 2, rsz
));
1805 /* Bad length, try to find another chunk anyway */
1808 if (hndcrc16((uint8
*)&rawotp
[i
], rsz
,
1809 CRC16_INIT_VALUE
) == CRC16_GOOD_VALUE
) {
1810 /* Good crc, copy the vars */
1811 OTP_MSG((" good chunk %d, base 0x%x, size 0x%x\n",
1812 chunk
, i
* 2, rsz
));
1816 if (offset
+ dsz
>= *len
) {
1817 OTP_MSG(("Out of memory for otp\n"));
1820 bcopy((char *)&rawotp
[i
+ 2], &data
[offset
], dsz
);
1822 /* Remove extra null characters at the end */
1823 while (offset
> 1 &&
1824 data
[offset
- 1] == 0 && data
[offset
- 2] == 0)
1828 /* bad length or crc didn't check, try to find the next set */
1829 OTP_MSG((" chunk %d @ 0x%x size 0x%x: bad crc, ",
1830 chunk
, i
* 2, rsz
));
1831 if (rawotp
[i
+ (rsz
/ 2)] == OTP_MAGIC
) {
1832 /* Assume length is good */
1835 while (++i
< (int)(lim
/ 2))
1836 if (rawotp
[i
] == OTP_MAGIC
)
1839 if (i
< (int)(lim
/ 2))
1840 OTP_MSG(("trying next base 0x%x\n", i
* 2));
1842 OTP_MSG(("no more chunks\n"));
1847 OTP_MSG((" otp size = %d, boundary = 0x%x, nv base = 0x%x\n", lim
, bound
, base
));
1849 OTP_MSG((" Found %d bytes in %d good chunks out of %d\n", tsz
, gchunks
, chunk
));
1851 OTP_MSG((" No good chunks found out of %d\n", chunk
));
1858 MFREE(si_osh(oi
->sih
), rawotp
, lim
);
1859 si_setcoreidx(oi
->sih
, idx
);
1865 #if defined(BCMDBG) || defined(WLTEST)
1866 static uint st_n
, st_s
, st_hwm
, pp_hwm
;
1867 #ifdef OTP_FORCEFAIL
1868 static uint forcefail_bitcount
= 0;
1869 #endif /* OTP_FORCEFAIL */
1870 #endif /* BCMDBG || WLTEST */
1873 hndotp_write_bit(void *oh
, chipcregs_t
*cc
, int bn
, bool bit
, int no_retry
)
1875 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
1876 uint row
, col
, j
, k
;
1877 uint32 pwait
, init_pwait
, otpc
, otpp
, pst
, st
;
1880 osh
= si_osh(oi
->sih
);
1881 ASSERT((bit
>> 1) == 0);
1883 #ifdef OTP_FORCEFAIL
1884 OTP_MSG(("%s: [0x%x] = 0x%x\n", __FUNCTION__
, wn
* 2, data
));
1887 /* This is bit-at-a-time writing, future cores may do word-at-a-time */
1888 if (oi
->ccrev
== 12) {
1890 init_pwait
= 0x00000200;
1891 } else if (oi
->ccrev
== 22) {
1893 init_pwait
= 0x00000400;
1896 init_pwait
= 0x00004000;
1902 otpp
= OTPP_START_BUSY
|
1903 ((bit
<< OTPP_VALUE_SHIFT
) & OTPP_VALUE_MASK
) |
1904 ((row
<< OTPP_ROW_SHIFT
) & OTPP_ROW_MASK
) |
1905 (col
& OTPP_COL_MASK
);
1910 OTP_DBG(("row %d, col %d, val %d, otpc 0x%x, otpp 0x%x\n",
1911 row
, col
, bit
, (otpc
| pwait
), otpp
));
1913 W_REG(osh
, &cc
->otpcontrol
, otpc
| pwait
);
1914 W_REG(osh
, &cc
->otpprog
, otpp
);
1915 pst
= R_REG(osh
, &cc
->otpprog
);
1916 for (k
= 0; ((pst
& OTPP_START_BUSY
) == OTPP_START_BUSY
) && (k
< OTPP_TRIES
); k
++)
1917 pst
= R_REG(osh
, &cc
->otpprog
);
1918 #if defined(BCMDBG) || defined(WLTEST)
1921 #endif /* BCMDBG || WLTEST */
1922 if (k
>= OTPP_TRIES
) {
1923 OTP_ERR(("BUSY stuck: pst=0x%x, count=%d\n", pst
, k
));
1927 st
= R_REG(osh
, &cc
->otpstatus
);
1928 if (((st
& OTPS_PROGFAIL
) == 0) || (pwait
== OTPC_PROGWAIT
) || (no_retry
)) {
1931 if ((oi
->ccrev
== 12) || (oi
->ccrev
== 22))
1932 pwait
= (pwait
<< 3) & OTPC_PROGWAIT
;
1934 pwait
= (pwait
<< 1) & OTPC_PROGWAIT
;
1936 pwait
= OTPC_PROGWAIT
;
1939 #if defined(BCMDBG) || defined(WLTEST)
1944 #ifdef OTP_FORCEFAIL
1945 if (forcefail_bitcount
++ == OTP_FORCEFAIL
* 16) {
1946 OTP_DBG(("Forcing PROGFAIL on bit %d (FORCEFAIL = %d/0x%x)\n",
1947 forcefail_bitcount
, OTP_FORCEFAIL
, OTP_FORCEFAIL
));
1951 #endif /* BCMDBG || WLTEST */
1952 if (st
& OTPS_PROGFAIL
) {
1953 OTP_ERR(("After %d tries: otpc = 0x%x, otpp = 0x%x/0x%x, otps = 0x%x\n",
1954 j
, otpc
| pwait
, otpp
, pst
, st
));
1955 OTP_ERR(("otp prog failed. bit=%d, ppret=%d, ret=%d\n", bit
, k
, j
));
1963 hndotp_write_word(void *oh
, chipcregs_t
*cc
, int wn
, uint16 data
)
1968 OTP_MSG(("%s: wn %d data %x\n", __FUNCTION__
, wn
, data
));
1970 /* There is one test bit for each row */
1971 base
= (wn
* 16) + (wn
/ 4);
1973 for (i
= 0; i
< 16; i
++) {
1974 err
+= hndotp_write_bit(oh
, cc
, base
+ i
, data
& 1, 0);
1976 /* abort write after first error to avoid stress the charge-pump */
1978 OTP_DBG(("%s: wn %d fail on bit %d\n", __FUNCTION__
, wn
, i
));
1987 hndotp_valid_rce(void *oh
, chipcregs_t
*cc
, int i
)
1989 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
1991 uint32 hwv
, fw
, rce
, e
, sign
, row
, st
;
1993 ASSERT(oi
->ccrev
>= 18);
1996 osh
= si_osh(oi
->sih
);
1997 st
= R_REG(osh
, &cc
->otpstatus
);
1998 hwv
= (st
& OTPS_RCEV_MSK
) & (1 << (OTPS_RCEV_SHIFT
+ i
));
2002 fw
= hndotp_size(oh
)/2 + OTP_RC0_OFF
+ e
;
2005 fw
= hndotp_size(oh
)/2 + OTP_RC1_OFF
+ e
;
2008 rce
= hndotp_otpr(oh
, cc
, fw
+1) << 16 | hndotp_otpr(oh
, cc
, fw
);
2009 rce
>>= ((e
* OTP_RCE_BITS
) + OTP_RCE_BIT0
- (e
* 16));
2010 row
= rce
& OTP_RCE_ROW_MASK
;
2011 sign
= (rce
>> OTP_RCE_ROW_SZ
) & OTP_RCE_SIGN_MASK
;
2013 OTP_MSG(("rce %d sign %x row %d hwv %x\n", i
, sign
, row
, hwv
));
2015 return (sign
== OTP_SIGNATURE
) ? row
: -1;
2019 hndotp_write_rce(void *oh
, chipcregs_t
*cc
, int r
, uint16
* data
)
2024 ASSERT(((otpinfo_t
*)oh
)->ccrev
>= 18);
2025 ASSERT(r
>= 0 && r
< hndotp_size(oh
)/(2*OTP_WPR
));
2028 for (rce
= OTP_RCE_ROW_SZ
-1; rce
>= 0; rce
--) {
2029 int e
, rt
, rcr
, bit
, err
= 0;
2031 int rr
= hndotp_valid_rce(oh
, cc
, rce
);
2032 /* redundancy row in use already */
2035 OTP_MSG(("%s: row %d already replaced by RCE %d",
2036 __FUNCTION__
, r
, rce
));
2040 continue; /* If row used, go for the next row */
2044 * previously used bad rce entry maybe treaed as valid rce and used again, abort on
2045 * first bit error to avoid stress the charge pump
2048 /* Write the data to the redundant row */
2049 for (i
= 0; i
< OTP_WPR
; i
++) {
2050 err
+= hndotp_write_word(oh
, cc
, hndotp_size(oh
)/2+OTP_RD_OFF
+rce
*4+i
,
2053 OTP_MSG(("fail to write redundant row %d\n", rce
));
2058 /* Now write the redundant row index */
2061 rcr
= hndotp_size(oh
)/2 + OTP_RC0_OFF
;
2064 rcr
= hndotp_size(oh
)/2 + OTP_RC1_OFF
;
2067 /* Write row numer bit-by-bit */
2068 bit
= (rcr
* 16 + rcr
/ 4) + e
* OTP_RCE_BITS
+ OTP_RCE_BIT0
;
2070 for (i
= 0; i
< OTP_RCE_ROW_SZ
; i
++) {
2071 /* If any timeout happened, invalidate the subsequent bits with 0 */
2072 if (hndotp_write_bit(oh
, cc
, bit
, (rt
& (err
? 0 : 1)), err
)) {
2073 OTP_MSG(("%s: timeout fixing row %d with RCE %d - at row"
2074 " number bit %x\n", __FUNCTION__
, r
, rce
, i
));
2081 /* Write the RCE signature bit-by-bit */
2082 sign
= OTP_SIGNATURE
;
2083 for (i
= 0; i
< OTP_RCE_SIGN_SZ
; i
++) {
2084 /* If any timeout happened, invalidate the subsequent bits with 0 */
2085 if (hndotp_write_bit(oh
, cc
, bit
, (sign
& (err
? 0 : 1)), err
)) {
2086 OTP_MSG(("%s: timeout fixing row %d with RCE %d - at row"
2087 " number bit %x\n", __FUNCTION__
, r
, rce
, i
));
2095 OTP_ERR(("%s: row %d not fixed by RCE %d due to %d timeouts. try next"
2096 " RCE\n", __FUNCTION__
, r
, rce
, err
));
2099 OTP_MSG(("%s: Fixed row %d by RCE %d\n", __FUNCTION__
, r
, rce
));
2104 OTP_ERR(("All RCE's are in use. Failed fixing OTP.\n"));
2105 /* Fatal error, unfixable. MFGC will have to fail. Board needs to be discarded!! */
2106 return BCME_NORESOURCE
;
2109 /* Write a row and fix it with RCE if any error detected */
2111 hndotp_write_row(void *oh
, chipcregs_t
*cc
, int wn
, uint16
* data
, bool rewrite
)
2113 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
2116 ASSERT(wn
% OTP_WPR
== 0);
2118 /* Write the data */
2119 for (i
= 0; i
< OTP_WPR
; i
++) {
2120 if (rewrite
&& (data
[i
] == hndotp_otpr(oh
, cc
, wn
+i
)))
2123 err
+= hndotp_write_word(oh
, cc
, wn
+ i
, data
[i
]);
2126 /* Fix this row if any error */
2127 if (err
&& (oi
->ccrev
>= 18)) {
2128 OTP_DBG(("%s: %d write errors in row %d. Fixing...\n", __FUNCTION__
, err
, wn
/4));
2129 if ((err
= hndotp_write_rce(oh
, cc
, wn
/ OTP_WPR
, data
)))
2130 OTP_MSG(("%s: failed to fix row %d\n", __FUNCTION__
, wn
/4));
2136 /* expects the caller to disable interrupts before calling this routine */
2138 hndotp_write_region(void *oh
, int region
, uint16
*data
, uint wlen
)
2140 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
2142 uint wn
, base
= 0, lim
;
2146 bool rewrite
= FALSE
;
2149 ASSERT(wlen
% OTP_WPR
== 0);
2151 idx
= si_coreidx(oi
->sih
);
2152 cc
= si_setcoreidx(oi
->sih
, SI_CC_IDX
);
2155 /* Check valid region */
2156 if ((region
!= OTP_HW_REGION
) &&
2157 (region
!= OTP_SW_REGION
) &&
2158 (region
!= OTP_CID_REGION
)) {
2163 /* Region already written? */
2164 st
= oi
->hwprot
| oi
-> signvalid
;
2165 if ((st
& region
) != 0)
2168 /* HW and CID have to be written before SW */
2169 if ((((st
& (OTP_HW_REGION
| OTP_CID_REGION
)) == 0) &&
2170 (st
& OTP_SW_REGION
) != 0)) {
2171 OTP_ERR(("%s: HW/CID region should be programmed first\n", __FUNCTION__
));
2176 /* Bounds for the region */
2177 lim
= (oi
->size
/ 2) + OTP_SWLIM_OFF
;
2178 if (region
== OTP_HW_REGION
) {
2180 } else if (region
== OTP_SW_REGION
) {
2181 base
= oi
->boundary
/ 2;
2182 } else if (region
== OTP_CID_REGION
) {
2183 base
= (oi
->size
/ 2) + OTP_CID_OFF
;
2184 lim
= (oi
->size
/ 2) + OTP_LIM_OFF
;
2187 if (wlen
> (lim
- base
)) {
2188 ret
= BCME_BUFTOOLONG
;
2193 #if defined(BCMDBG) || defined(WLTEST)
2194 st_n
= st_s
= st_hwm
= pp_hwm
= 0;
2195 #endif /* BCMDBG || WLTEST */
2197 /* force ALP for progrramming stability */
2198 save_clk
= R_REG(oi
->osh
, &cc
->clk_ctl_st
);
2199 OR_REG(oi
->osh
, &cc
->clk_ctl_st
, CCS_FORCEALP
);
2202 /* Write the data row by row */
2203 for (wn
= base
; wn
< lim
; wn
+= OTP_WPR
, data
+= OTP_WPR
) {
2204 if ((ret
= hndotp_write_row(oh
, cc
, wn
, data
, rewrite
)) != 0) {
2205 if (ret
== BCME_NORESOURCE
) {
2206 OTP_ERR(("%s: Abort at word %x\n", __FUNCTION__
, wn
));
2212 /* Don't need to update signature & boundary if rewrite */
2216 /* Done with the data, write the signature & boundary if needed */
2217 if (region
== OTP_HW_REGION
) {
2218 if (hndotp_write_word(oh
, cc
, (oi
->size
/ 2) + OTP_BOUNDARY_OFF
, lim
* 2) != 0) {
2219 ret
= BCME_NORESOURCE
;
2222 if (hndotp_write_word(oh
, cc
, (oi
->size
/ 2) + OTP_HWSIGN_OFF
,
2223 OTP_SIGNATURE
) != 0) {
2224 ret
= BCME_NORESOURCE
;
2227 oi
->boundary
= lim
* 2;
2228 oi
->signvalid
|= OTP_HW_REGION
;
2229 } else if (region
== OTP_SW_REGION
) {
2230 if (hndotp_write_word(oh
, cc
, (oi
->size
/ 2) + OTP_SWSIGN_OFF
,
2231 OTP_SIGNATURE
) != 0) {
2232 ret
= BCME_NORESOURCE
;
2235 oi
->signvalid
|= OTP_SW_REGION
;
2236 } else if (region
== OTP_CID_REGION
) {
2237 if (hndotp_write_word(oh
, cc
, (oi
->size
/ 2) + OTP_CIDSIGN_OFF
,
2238 OTP_SIGNATURE
) != 0) {
2239 ret
= BCME_NORESOURCE
;
2242 oi
->signvalid
|= OTP_CID_REGION
;
2247 W_REG(oi
->osh
, &cc
->clk_ctl_st
, save_clk
);
2250 #if defined(BCMDBG) || defined(WLTEST)
2251 OTP_MSG(("bits written: %d, average (%d/%d): %d, max retry: %d, pp max: %d\n",
2252 st_n
, st_s
, st_n
, st_n
?(st_s
/ st_n
):0, st_hwm
, pp_hwm
));
2255 si_setcoreidx(oi
->sih
, idx
);
2260 /* For HND OTP, there's no space for appending after filling in SROM image */
2262 hndotp_cis_append_region(si_t
*sih
, int region
, char *vars
, int count
)
2264 return otp_write_region(sih
, region
, (uint16
*)vars
, count
/2);
2268 * Fill all unwritten RCE signature with 0 and return the number of them.
2269 * HNDOTP needs lock due to the randomness of unprogrammed content.
2272 hndotp_lock(void *oh
)
2274 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
2275 int i
, j
, e
, rcr
, bit
, ret
= 0;
2279 ASSERT(oi
->ccrev
>= 18);
2281 idx
= si_coreidx(oi
->sih
);
2282 cc
= si_setcoreidx(oi
->sih
, SI_CC_IDX
);
2285 /* Region already written? */
2286 st
= oi
->hwprot
| oi
-> signvalid
;
2287 if ((st
& (OTP_HW_REGION
| OTP_SW_REGION
)) == 0) {
2288 si_setcoreidx(oi
->sih
, idx
);
2289 return BCME_NOTREADY
; /* Don't lock unprogrammed OTP */
2292 /* Find the highest valid RCE */
2293 for (i
= 0; i
< OTP_RCE_ROW_SZ
-1; i
++) {
2294 if ((hndotp_valid_rce(oh
, cc
, i
) != -1))
2297 i
--; /* Start invalidating from the next RCE */
2299 for (; i
>= 0; i
--) {
2300 if ((hndotp_valid_rce(oh
, cc
, i
) == -1)) {
2302 ret
++; /* This is a unprogrammed row */
2304 /* Invalidate the row with 0 */
2307 rcr
= hndotp_size(oh
)/2 + OTP_RC0_OFF
;
2310 rcr
= hndotp_size(oh
)/2 + OTP_RC1_OFF
;
2313 /* Fill row numer and signature with 0 bit-by-bit */
2314 bit
= (rcr
* 16 + rcr
/ 4) + e
* OTP_RCE_BITS
+ OTP_RCE_BIT0
;
2315 for (j
= 0; j
< (OTP_RCE_ROW_SZ
+ OTP_RCE_SIGN_SZ
); j
++) {
2316 hndotp_write_bit(oh
, cc
, bit
, 0, 1);
2320 OTP_MSG(("locking rce %d\n", i
));
2324 si_setcoreidx(oi
->sih
, idx
);
2329 /* expects the caller to disable interrupts before calling this routine */
2331 hndotp_nvwrite(void *oh
, uint16
*data
, uint wlen
)
2333 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
2335 uint16 crc
, clen
, *p
, hdr
[2];
2336 uint wn
, base
= 0, lim
;
2341 /* otp already written? */
2342 st
= oi
->hwprot
| oi
-> signvalid
;
2343 if ((st
& (OTP_HW_REGION
| OTP_SW_REGION
)) == (OTP_HW_REGION
| OTP_SW_REGION
))
2346 /* save the orig core */
2347 idx
= si_coreidx(oi
->sih
);
2348 cc
= si_setcoreidx(oi
->sih
, SI_CC_IDX
);
2351 /* Bounds for the region */
2352 lim
= (oi
->size
/ 2) + OTP_SWLIM_OFF
;
2355 /* Look for possible chunks from the end down */
2359 if (hndotp_otpr(oh
, cc
, wn
) == OTP_MAGIC
) {
2360 base
= wn
+ (hndotp_otpr(oh
, cc
, wn
+ 1) / 2);
2365 OTP_MSG(("Unprogrammed otp\n"));
2367 OTP_MSG(("Found some chunks, skipping to 0x%x\n", base
* 2));
2369 if ((wlen
+ 3) > (lim
- base
)) {
2370 err
= BCME_NORESOURCE
;
2374 #if defined(BCMDBG) || defined(WLTEST)
2375 st_n
= st_s
= st_hwm
= pp_hwm
= 0;
2376 #endif /* BCMDBG || WLTEST */
2378 /* Prepare the header and crc */
2380 hdr
[1] = (wlen
+ 3) * 2;
2381 crc
= hndcrc16((uint8
*)hdr
, sizeof(hdr
), CRC16_INIT_VALUE
);
2382 crc
= hndcrc16((uint8
*)data
, wlen
* 2, crc
);
2388 lim
= base
+ wlen
+ 2;
2390 OTP_MSG(("writing chunk, 0x%x bytes @ 0x%x-0x%x\n", wlen
* 2,
2391 base
* 2, (lim
+ 1) * 2));
2393 /* Write the header */
2394 err
= hndotp_write_word(oh
, cc
, base
, hdr
[0]);
2396 /* Write the data */
2398 err
+= hndotp_write_word(oh
, cc
, wn
++, *p
++);
2400 /* If there has been an error, close this chunk */
2402 OTP_MSG(("closing early @ 0x%x\n", wn
* 2));
2407 /* If we wrote the whole chunk, write the crc */
2409 OTP_MSG((" whole chunk written, crc = 0x%x\n", crc
));
2410 err
+= hndotp_write_word(oh
, cc
, wn
++, crc
);
2413 /* If there was an error adjust the count to point to
2414 * the word after the error so we can start the next
2417 clen
= (wn
- base
) * 2;
2418 OTP_MSG((" partial chunk written, chunk len = 0x%x\n", clen
));
2420 /* And now write the chunk length */
2421 err
+= hndotp_write_word(oh
, cc
, base
+ 1, clen
);
2424 /* Write the signature and boundary if this is the HW region,
2425 * but don't report failure if either of these 2 writes fail.
2427 if (hndotp_write_word(oh
, cc
, (oi
->size
/ 2) + OTP_BOUNDARY_OFF
,
2429 gerr
+= hndotp_write_word(oh
, cc
, (oi
->size
/ 2) + OTP_HWSIGN_OFF
,
2433 oi
->boundary
= wn
* 2;
2434 oi
->signvalid
|= OTP_HW_REGION
;
2439 /* Errors, do it all over again if there is space left */
2440 if ((wlen
+ 3) <= ((oi
->size
/ 2) + OTP_SWLIM_OFF
- wn
)) {
2442 lim
= base
+ wlen
+ 2;
2443 OTP_ERR(("Programming errors, retry @ 0x%x\n", wn
* 2));
2445 OTP_ERR(("Programming errors, no space left ( 0x%x)\n", wn
* 2));
2451 OTP_MSG(("bits written: %d, average (%d/%d): %d, max retry: %d, pp max: %d\n",
2452 st_n
, st_s
, st_n
, st_s
/ st_n
, st_hwm
, pp_hwm
));
2455 OTP_MSG(("programming %s after %d errors\n", (err
== 0) ? "succedded" : "failed",
2459 si_setcoreidx(oi
->sih
, idx
);
2466 #endif /* BCMNVRAMW */
2470 hndotp_otprb16(void *oh
, chipcregs_t
*cc
, uint wn
)
2475 base
= (wn
* 16) + (wn
/ 4);
2477 for (i
= 0; i
< 16; i
++) {
2478 if ((bit
= hndotp_read_bit(oh
, cc
, base
+ i
)) == 0xffff)
2480 val
= val
| (bit
<< i
);
2488 hndotp_dump(void *oh
, int arg
, char *buf
, uint size
)
2490 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
2492 uint idx
, i
, count
, lil
;
2496 idx
= si_coreidx(oi
->sih
);
2497 cc
= si_setcoreidx(oi
->sih
, SI_CC_IDX
);
2507 count
= (oi
->size
/ 2) + OTP_RC_LIM_OFF
;
2511 OTP_MSG(("%s: arg %d, size %d, words %d\n", __FUNCTION__
, arg
, size
, count
));
2512 bcm_binit(&b
, buf
, size
);
2513 for (i
= 0; i
< count
; i
++) {
2515 bcm_bprintf(&b
, "0x%04x:", 2 * i
);
2518 val
= hndotp_otpr(oh
, cc
, i
);
2520 val
= hndotp_otprb16(oi
, cc
, i
);
2521 bcm_bprintf(&b
, " 0x%04x", val
);
2522 if ((i
& lil
) == lil
) {
2524 bcm_bprintf(&b
, " %d\n",
2525 hndotp_read_bit(oh
, cc
, ((i
/ 4) * 65) + 64) & 1);
2527 bcm_bprintf(&b
, "\n");
2531 if ((i
& lil
) != lil
)
2532 bcm_bprintf(&b
, "\n");
2534 OTP_MSG(("%s: returning %d, left %d, wn %d\n",
2535 __FUNCTION__
, (int)(b
.buf
- b
.origbuf
), b
.size
, i
));
2537 si_setcoreidx(oi
->sih
, idx
);
2539 return ((int)(b
.buf
- b
.origbuf
));
2543 static otp_fn_t hndotp_fn
= {
2544 (otp_size_t
)hndotp_size
,
2545 (otp_read_bit_t
)hndotp_read_bit
,
2547 (otp_init_t
)hndotp_init
,
2548 (otp_read_region_t
)hndotp_read_region
,
2549 (otp_nvread_t
)hndotp_nvread
,
2551 (otp_write_region_t
)hndotp_write_region
,
2552 (otp_cis_append_region_t
)hndotp_cis_append_region
,
2553 (otp_lock_t
)hndotp_lock
,
2554 (otp_nvwrite_t
)hndotp_nvwrite
,
2555 #endif /* BCMNVRAMW */
2558 (otp_dump_t
)hndotp_dump
,
2561 (otp_status_t
)hndotp_status
,
2563 (otp_write_word_t
)NULL
,
2564 #endif /* BCMNVRAMW */
2565 (otp_read_word_t
)hndotp_read_word
,
2568 #endif /* BCMHNDOTP */
2571 * Common Code: Compiled for IPX / HND / AUTO
2579 * otp_write_region()
2581 * otp_cis_append_region()
2588 otp_status(void *oh
)
2590 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
2592 return oi
->fn
->status(oh
);
2598 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
2600 return oi
->fn
->size(oh
);
2604 otp_read_bit(void *oh
, uint offset
)
2606 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
2607 uint idx
= si_coreidx(oi
->sih
);
2608 chipcregs_t
*cc
= si_setcoreidx(oi
->sih
, SI_CC_IDX
);
2609 uint16 readBit
= (uint16
)oi
->fn
->read_bit(oh
, cc
, offset
);
2610 si_setcoreidx(oi
->sih
, idx
);
2615 BCMNMIATTACHFN(otp_init
)(si_t
*sih
)
2621 bzero(oi
, sizeof(otpinfo_t
));
2623 oi
->ccrev
= sih
->ccrev
;
2626 if (OTPTYPE_IPX(oi
->ccrev
))
2627 oi
->fn
= &ipxotp_fn
;
2631 if (OTPTYPE_HND(oi
->ccrev
))
2632 oi
->fn
= &hndotp_fn
;
2635 if (oi
->fn
== NULL
) {
2636 OTP_ERR(("otp_init: unsupported OTP type\n"));
2641 oi
->osh
= si_osh(oi
->sih
);
2643 ret
= (oi
->fn
->init
)(sih
);
2649 BCMNMIATTACHFN(otp_read_region
)(si_t
*sih
, int region
, uint16
*data
, uint
*wlen
)
2655 if (!(wasup
= si_is_otp_powered(sih
)))
2656 si_otp_power(sih
, TRUE
);
2658 if (!si_is_otp_powered(sih
) || si_is_otp_disabled(sih
)) {
2659 err
= BCME_NOTREADY
;
2665 OTP_ERR(("otp_init failed.\n"));
2670 err
= (((otpinfo_t
*)oh
)->fn
->read_region
)(oh
, region
, data
, wlen
);
2674 si_otp_power(sih
, FALSE
);
2680 otp_read_word(si_t
*sih
, uint wn
, uint16
*data
)
2686 if (!(wasup
= si_is_otp_powered(sih
)))
2687 si_otp_power(sih
, TRUE
);
2689 if (!si_is_otp_powered(sih
) || si_is_otp_disabled(sih
)) {
2690 err
= BCME_NOTREADY
;
2696 OTP_ERR(("otp_init failed.\n"));
2701 if (((otpinfo_t
*)oh
)->fn
->read_word
== NULL
) {
2702 err
= BCME_UNSUPPORTED
;
2705 err
= (((otpinfo_t
*)oh
)->fn
->read_word
)(oh
, wn
, data
);
2709 si_otp_power(sih
, FALSE
);
2715 otp_nvread(void *oh
, char *data
, uint
*len
)
2717 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
2719 return oi
->fn
->nvread(oh
, data
, len
);
2724 BCMNMIATTACHFN(otp_write_region
)(si_t
*sih
, int region
, uint16
*data
, uint wlen
)
2730 if (!(wasup
= si_is_otp_powered(sih
)))
2731 si_otp_power(sih
, TRUE
);
2733 if (!si_is_otp_powered(sih
) || si_is_otp_disabled(sih
)) {
2734 err
= BCME_NOTREADY
;
2740 OTP_ERR(("otp_init failed.\n"));
2745 err
= (((otpinfo_t
*)oh
)->fn
->write_region
)(oh
, region
, data
, wlen
);
2749 si_otp_power(sih
, FALSE
);
2755 otp_write_word(si_t
*sih
, uint wn
, uint16 data
)
2761 if (!(wasup
= si_is_otp_powered(sih
)))
2762 si_otp_power(sih
, TRUE
);
2764 if (!si_is_otp_powered(sih
) || si_is_otp_disabled(sih
)) {
2765 err
= BCME_NOTREADY
;
2771 OTP_ERR(("otp_init failed.\n"));
2776 if (((otpinfo_t
*)oh
)->fn
->write_word
== NULL
) {
2777 err
= BCME_UNSUPPORTED
;
2780 err
= (((otpinfo_t
*)oh
)->fn
->write_word
)(oh
, wn
, data
);
2784 si_otp_power(sih
, FALSE
);
2790 otp_cis_append_region(si_t
*sih
, int region
, char *vars
, int count
)
2792 void *oh
= otp_init(sih
);
2795 OTP_ERR(("otp_init failed.\n"));
2798 return (((otpinfo_t
*)oh
)->fn
->cis_append_region
)(sih
, region
, vars
, count
);
2808 if (!(wasup
= si_is_otp_powered(sih
)))
2809 si_otp_power(sih
, TRUE
);
2811 if (!si_is_otp_powered(sih
) || si_is_otp_disabled(sih
)) {
2812 ret
= BCME_NOTREADY
;
2818 OTP_ERR(("otp_init failed.\n"));
2823 ret
= (((otpinfo_t
*)oh
)->fn
->lock
)(oh
);
2827 si_otp_power(sih
, FALSE
);
2833 otp_nvwrite(void *oh
, uint16
*data
, uint wlen
)
2835 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
2837 return oi
->fn
->nvwrite(oh
, data
, wlen
);
2839 #endif /* BCMNVRAMW */
2843 otp_dump(void *oh
, int arg
, char *buf
, uint size
)
2845 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
2847 return oi
->fn
->dump(oh
, arg
, buf
, size
);
2851 otp_dumpstats(void *oh
, int arg
, char *buf
, uint size
)
2853 otpinfo_t
*oi
= (otpinfo_t
*)oh
;
2856 bcm_binit(&b
, buf
, size
);
2858 bcm_bprintf(&b
, "\nOTP, ccrev 0x%04x\n", oi
->ccrev
);
2859 #if defined(BCMIPXOTP)
2860 bcm_bprintf(&b
, "wsize %d rows %d cols %d\n", oi
->wsize
, oi
->rows
, oi
->cols
);
2861 bcm_bprintf(&b
, "hwbase %d hwlim %d swbase %d swlim %d fusebits %d\n",
2862 oi
->hwbase
, oi
->hwlim
, oi
->swbase
, oi
->swlim
, oi
->fbase
, oi
->flim
, oi
->fusebits
);
2863 bcm_bprintf(&b
, "otpgu_base %d status %d\n", oi
->otpgu_base
, oi
->status
);
2865 #if defined(BCMHNDOTP)
2866 bcm_bprintf(&b
, "OLD OTP, size %d hwprot 0x%x signvalid 0x%x boundary %d\n",
2867 oi
->size
, oi
->hwprot
, oi
->signvalid
, oi
->boundary
);
2869 bcm_bprintf(&b
, "\n");
2871 return 200; /* real buf length, pick one to cover above print */