2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 #include <linux/errno.h>
19 #include <linux/string.h>
21 #include <brcm_hw_ids.h>
22 #include <chipcommon.h>
26 #define OTPS_GUP_MASK 0x00000f00
27 #define OTPS_GUP_SHIFT 8
28 /* h/w subregion is programmed */
29 #define OTPS_GUP_HW 0x00000100
30 /* s/w subregion is programmed */
31 #define OTPS_GUP_SW 0x00000200
32 /* chipid/pkgopt subregion is programmed */
33 #define OTPS_GUP_CI 0x00000400
34 /* fuse subregion is programmed */
35 #define OTPS_GUP_FUSE 0x00000800
37 /* Fields in otpprog in rev >= 21 */
38 #define OTPP_COL_MASK 0x000000ff
39 #define OTPP_COL_SHIFT 0
40 #define OTPP_ROW_MASK 0x0000ff00
41 #define OTPP_ROW_SHIFT 8
42 #define OTPP_OC_MASK 0x0f000000
43 #define OTPP_OC_SHIFT 24
44 #define OTPP_READERR 0x10000000
45 #define OTPP_VALUE_MASK 0x20000000
46 #define OTPP_VALUE_SHIFT 29
47 #define OTPP_START_BUSY 0x80000000
48 #define OTPP_READ 0x40000000
50 /* Opcodes for OTPP_OC field */
52 #define OTPPOC_BIT_PROG 1
53 #define OTPPOC_VERIFY 3
56 #define OTPPOC_RESET 6
58 #define OTPPOC_ROW_LOCK 8
59 #define OTPPOC_PRESCN_TEST 9
61 #define OTPTYPE_IPX(ccrev) ((ccrev) == 21 || (ccrev) >= 23)
63 #define OTPP_TRIES 10000000 /* # of tries for OTPP */
65 #define MAXNUMRDES 9 /* Maximum OTP redundancy entries */
67 /* Fixed size subregions sizes in words */
70 /* OTP function struct */
72 int (*size)(struct otpinfo *oi);
73 u16 (*read_bit)(struct otpinfo *oi, struct chipcregs *cc, uint off);
74 struct otpinfo *(*init)(struct si_pub *sih);
75 int (*read_region)(struct otpinfo *oi, int region, u16 *data,
77 int (*nvread)(struct otpinfo *oi, char *data, uint *len);
78 int (*status)(struct otpinfo *oi);
82 uint ccrev; /* chipc revision */
83 const struct otp_fn_s *fn; /* OTP functions */
84 struct si_pub *sih; /* Saved sb handle */
87 u16 wsize; /* Size of otp in words */
88 u16 rows; /* Geometry */
89 u16 cols; /* Geometry */
90 u32 status; /* Flag bits (lock/prog/rv).
91 * (Reflected only when OTP is power cycled)
93 u16 hwbase; /* hardware subregion offset */
94 u16 hwlim; /* hardware subregion boundary */
95 u16 swbase; /* software subregion offset */
96 u16 swlim; /* software subregion boundary */
97 u16 fbase; /* fuse subregion offset */
98 u16 flim; /* fuse subregion boundary */
99 int otpgu_base; /* offset to General Use Region */
102 static struct otpinfo otpinfo;
107 * Exported functions:
112 * ipxotp_read_region()
118 /* CC revs 21, 24 and 27 OTP General Use Region word offset */
119 #define REVA4_OTPGU_BASE 12
121 /* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */
122 #define REVB8_OTPGU_BASE 20
124 /* CC rev 36 OTP General Use Region word offset */
125 #define REV36_OTPGU_BASE 12
127 /* Subregion word offsets in General Use region */
128 #define OTPGU_HSB_OFF 0
129 #define OTPGU_SFB_OFF 1
130 #define OTPGU_CI_OFF 2
131 #define OTPGU_P_OFF 3
132 #define OTPGU_SROM_OFF 4
134 /* Flag bit offsets in General Use region */
135 #define OTPGU_HWP_OFF 60
136 #define OTPGU_SWP_OFF 61
137 #define OTPGU_CIP_OFF 62
138 #define OTPGU_FUSEP_OFF 63
139 #define OTPGU_CIP_MSK 0x4000
140 #define OTPGU_P_MSK 0xf000
141 #define OTPGU_P_SHIFT (OTPGU_HWP_OFF % 16)
144 #define OTP_SZ_FU_324 ((roundup(324, 8))/8) /* 324 bits */
145 #define OTP_SZ_FU_288 (288/8) /* 288 bits */
146 #define OTP_SZ_FU_216 (216/8) /* 216 bits */
147 #define OTP_SZ_FU_72 (72/8) /* 72 bits */
148 #define OTP_SZ_CHECKSUM (16/8) /* 16 bits */
149 #define OTP4315_SWREG_SZ 178 /* 178 bytes */
150 #define OTP_SZ_FU_144 (144/8) /* 144 bits */
152 static int ipxotp_status(struct otpinfo *oi)
154 return (int)(oi->status);
157 /* Return size in bytes */
158 static int ipxotp_size(struct otpinfo *oi)
160 return (int)oi->wsize * 2;
163 static u16 ipxotp_otpr(struct otpinfo *oi, struct chipcregs *cc, uint wn)
165 return R_REG(&cc->sromotp[wn]);
168 static u16 ipxotp_read_bit(struct otpinfo *oi, struct chipcregs *cc, uint off)
173 row = off / oi->cols;
174 col = off % oi->cols;
176 otpp = OTPP_START_BUSY |
177 ((OTPPOC_READ << OTPP_OC_SHIFT) & OTPP_OC_MASK) |
178 ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) |
179 ((col << OTPP_COL_SHIFT) & OTPP_COL_MASK);
180 W_REG(&cc->otpprog, otpp);
183 ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
184 && (k < OTPP_TRIES); k++)
189 if (st & OTPP_READERR)
192 st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
198 * Calculate max HW/SW region byte size by subtracting fuse region
199 * and checksum size, osizew is oi->wsize (OTP size - GU size) in words
201 static int ipxotp_max_rgnsz(struct si_pub *sih, int osizew)
206 case BCM43224_CHIP_ID:
207 case BCM43225_CHIP_ID:
208 ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
210 case BCM4313_CHIP_ID:
211 ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
214 break; /* Don't know about this chip */
220 static void _ipxotp_init(struct otpinfo *oi, struct chipcregs *cc)
226 * record word offset of General Use Region
227 * for various chipcommon revs
229 if (oi->sih->ccrev == 21 || oi->sih->ccrev == 24
230 || oi->sih->ccrev == 27) {
231 oi->otpgu_base = REVA4_OTPGU_BASE;
232 } else if (oi->sih->ccrev == 36) {
234 * OTP size greater than equal to 2KB (128 words),
235 * otpgu_base is similar to rev23
237 if (oi->wsize >= 128)
238 oi->otpgu_base = REVB8_OTPGU_BASE;
240 oi->otpgu_base = REV36_OTPGU_BASE;
241 } else if (oi->sih->ccrev == 23 || oi->sih->ccrev >= 25) {
242 oi->otpgu_base = REVB8_OTPGU_BASE;
245 /* First issue an init command so the status is up to date */
247 OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK);
249 W_REG(&cc->otpprog, otpp);
251 ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
252 && (k < OTPP_TRIES); k++)
257 /* Read OTP lock bits and subregion programmed indication bits */
258 oi->status = R_REG(&cc->otpstatus);
260 if ((oi->sih->chip == BCM43224_CHIP_ID)
261 || (oi->sih->chip == BCM43225_CHIP_ID)) {
264 (ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_P_OFF) &
267 oi->status |= (p_bits << OTPS_GUP_SHIFT);
271 * h/w region base and fuse region limit are fixed to
272 * the top and the bottom of the general use region.
273 * Everything else can be flexible.
275 oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF;
276 oi->hwlim = oi->wsize;
277 if (oi->status & OTPS_GUP_HW) {
279 ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF) / 16;
280 oi->swbase = oi->hwlim;
282 oi->swbase = oi->hwbase;
284 /* subtract fuse and checksum from beginning */
285 oi->swlim = ipxotp_max_rgnsz(oi->sih, oi->wsize) / 2;
287 if (oi->status & OTPS_GUP_SW) {
289 ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF) / 16;
290 oi->fbase = oi->swlim;
292 oi->fbase = oi->swbase;
294 oi->flim = oi->wsize;
297 static struct otpinfo *ipxotp_init(struct si_pub *sih)
300 struct chipcregs *cc;
303 /* Make sure we're running IPX OTP */
304 if (!OTPTYPE_IPX(sih->ccrev))
307 /* Make sure OTP is not disabled */
308 if (ai_is_otp_disabled(sih))
311 /* OTP is always powered */
314 /* Check for otp size */
315 switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
334 case 7: /* 16x64 *//* 1024 bits */
340 /* Don't know the geometry */
344 /* Retrieve OTP region info */
345 idx = ai_coreidx(sih);
346 cc = ai_setcoreidx(sih, SI_CC_IDX);
348 _ipxotp_init(oi, cc);
350 ai_setcoreidx(sih, idx);
356 ipxotp_read_region(struct otpinfo *oi, int region, u16 *data, uint *wlen)
359 struct chipcregs *cc;
362 /* Validate region selection */
365 sz = (uint) oi->hwlim - oi->hwbase;
366 if (!(oi->status & OTPS_GUP_HW)) {
377 sz = ((uint) oi->swlim - oi->swbase);
378 if (!(oi->status & OTPS_GUP_SW)) {
390 if (!(oi->status & OTPS_GUP_CI)) {
398 base = oi->otpgu_base + OTPGU_CI_OFF;
401 sz = (uint) oi->flim - oi->fbase;
402 if (!(oi->status & OTPS_GUP_FUSE)) {
413 sz = ((uint) oi->flim - oi->hwbase);
414 if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) {
428 idx = ai_coreidx(oi->sih);
429 cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
432 for (i = 0; i < sz; i++)
433 data[i] = ipxotp_otpr(oi, cc, base + i);
435 ai_setcoreidx(oi->sih, idx);
440 static int ipxotp_nvread(struct otpinfo *oi, char *data, uint *len)
445 static const struct otp_fn_s ipxotp_fn = {
446 (int (*)(struct otpinfo *)) ipxotp_size,
447 (u16 (*)(struct otpinfo *, struct chipcregs *, uint)) ipxotp_read_bit,
449 (struct otpinfo *(*)(struct si_pub *)) ipxotp_init,
450 (int (*)(struct otpinfo *, int, u16 *, uint *)) ipxotp_read_region,
451 (int (*)(struct otpinfo *, char *, uint *)) ipxotp_nvread,
453 (int (*)(struct otpinfo *)) ipxotp_status
465 int otp_status(struct otpinfo *oi)
467 return oi->fn->status(oi);
470 int otp_size(struct otpinfo *oi)
472 return oi->fn->size(oi);
475 u16 otp_read_bit(struct otpinfo *oi, uint offset)
477 uint idx = ai_coreidx(oi->sih);
478 struct chipcregs *cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
479 u16 readBit = (u16) oi->fn->read_bit(oi, cc, offset);
480 ai_setcoreidx(oi->sih, idx);
484 struct otpinfo *otp_init(struct si_pub *sih)
487 struct otpinfo *ret = NULL;
490 memset(oi, 0, sizeof(struct otpinfo));
492 oi->ccrev = sih->ccrev;
494 if (OTPTYPE_IPX(oi->ccrev))
502 ret = (oi->fn->init) (sih);
508 otp_read_region(struct si_pub *sih, int region, u16 *data, uint *wlen) {
512 if (ai_is_otp_disabled(sih)) {
523 err = ((oi)->fn->read_region)(oi, region, data, wlen);
529 int otp_nvread(struct otpinfo *oi, char *data, uint *len)
531 return oi->fn->nvread(oi, data, len);