Merge branches 'upstream-fixes' and 'magicmouse' into for-linus
[pandora-kernel.git] / drivers / staging / brcm80211 / brcmsmac / otp.c
1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
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.
7  *
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.
15  */
16
17 #include <linux/io.h>
18 #include <linux/errno.h>
19 #include <linux/string.h>
20
21 #include <brcm_hw_ids.h>
22 #include <chipcommon.h>
23 #include "aiutils.h"
24 #include "otp.h"
25
26 #define OTPS_GUP_MASK           0x00000f00
27 #define OTPS_GUP_SHIFT          8
28 #define OTPS_GUP_HW             0x00000100      /* h/w subregion is programmed */
29 #define OTPS_GUP_SW             0x00000200      /* s/w subregion is programmed */
30 #define OTPS_GUP_CI             0x00000400      /* chipid/pkgopt subregion is programmed */
31 #define OTPS_GUP_FUSE           0x00000800      /* fuse subregion is programmed */
32
33 /* Fields in otpprog in rev >= 21 */
34 #define OTPP_COL_MASK           0x000000ff
35 #define OTPP_COL_SHIFT          0
36 #define OTPP_ROW_MASK           0x0000ff00
37 #define OTPP_ROW_SHIFT          8
38 #define OTPP_OC_MASK            0x0f000000
39 #define OTPP_OC_SHIFT           24
40 #define OTPP_READERR            0x10000000
41 #define OTPP_VALUE_MASK         0x20000000
42 #define OTPP_VALUE_SHIFT        29
43 #define OTPP_START_BUSY         0x80000000
44 #define OTPP_READ               0x40000000
45
46 /* Opcodes for OTPP_OC field */
47 #define OTPPOC_READ             0
48 #define OTPPOC_BIT_PROG         1
49 #define OTPPOC_VERIFY           3
50 #define OTPPOC_INIT             4
51 #define OTPPOC_SET              5
52 #define OTPPOC_RESET            6
53 #define OTPPOC_OCST             7
54 #define OTPPOC_ROW_LOCK         8
55 #define OTPPOC_PRESCN_TEST      9
56
57 #define OTPTYPE_IPX(ccrev)      ((ccrev) == 21 || (ccrev) >= 23)
58
59 #define OTPP_TRIES      10000000        /* # of tries for OTPP */
60
61 #define MAXNUMRDES              9       /* Maximum OTP redundancy entries */
62
63 /* OTP common function type */
64 typedef int (*otp_status_t) (void *oh);
65 typedef int (*otp_size_t) (void *oh);
66 typedef void *(*otp_init_t) (struct si_pub *sih);
67 typedef u16(*otp_read_bit_t) (void *oh, chipcregs_t *cc, uint off);
68 typedef int (*otp_read_region_t) (struct si_pub *sih, int region, u16 *data,
69                                   uint *wlen);
70 typedef int (*otp_nvread_t) (void *oh, char *data, uint *len);
71
72 /* OTP function struct */
73 struct otp_fn_s {
74         otp_size_t size;
75         otp_read_bit_t read_bit;
76         otp_init_t init;
77         otp_read_region_t read_region;
78         otp_nvread_t nvread;
79         otp_status_t status;
80 };
81
82 struct otpinfo {
83         uint ccrev;             /* chipc revision */
84         struct otp_fn_s *fn;            /* OTP functions */
85         struct si_pub *sih;             /* Saved sb handle */
86
87         /* IPX OTP section */
88         u16 wsize;              /* Size of otp in words */
89         u16 rows;               /* Geometry */
90         u16 cols;               /* Geometry */
91         u32 status;             /* Flag bits (lock/prog/rv).
92                                  * (Reflected only when OTP is power cycled)
93                                  */
94         u16 hwbase;             /* hardware subregion offset */
95         u16 hwlim;              /* hardware subregion boundary */
96         u16 swbase;             /* software subregion offset */
97         u16 swlim;              /* software subregion boundary */
98         u16 fbase;              /* fuse subregion offset */
99         u16 flim;               /* fuse subregion boundary */
100         int otpgu_base;         /* offset to General Use Region */
101 };
102
103 static struct otpinfo otpinfo;
104
105 /*
106  * IPX OTP Code
107  *
108  *   Exported functions:
109  *      ipxotp_status()
110  *      ipxotp_size()
111  *      ipxotp_init()
112  *      ipxotp_read_bit()
113  *      ipxotp_read_region()
114  *      ipxotp_nvread()
115  *
116  */
117
118 #define HWSW_RGN(rgn)           (((rgn) == OTP_HW_RGN) ? "h/w" : "s/w")
119
120 /* OTP layout */
121 /* CC revs 21, 24 and 27 OTP General Use Region word offset */
122 #define REVA4_OTPGU_BASE        12
123
124 /* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */
125 #define REVB8_OTPGU_BASE        20
126
127 /* CC rev 36 OTP General Use Region word offset */
128 #define REV36_OTPGU_BASE        12
129
130 /* Subregion word offsets in General Use region */
131 #define OTPGU_HSB_OFF           0
132 #define OTPGU_SFB_OFF           1
133 #define OTPGU_CI_OFF            2
134 #define OTPGU_P_OFF             3
135 #define OTPGU_SROM_OFF          4
136
137 /* Flag bit offsets in General Use region  */
138 #define OTPGU_HWP_OFF           60
139 #define OTPGU_SWP_OFF           61
140 #define OTPGU_CIP_OFF           62
141 #define OTPGU_FUSEP_OFF         63
142 #define OTPGU_CIP_MSK           0x4000
143 #define OTPGU_P_MSK             0xf000
144 #define OTPGU_P_SHIFT           (OTPGU_HWP_OFF % 16)
145
146 /* OTP Size */
147 #define OTP_SZ_FU_324           ((roundup(324, 8))/8)   /* 324 bits */
148 #define OTP_SZ_FU_288           (288/8) /* 288 bits */
149 #define OTP_SZ_FU_216           (216/8) /* 216 bits */
150 #define OTP_SZ_FU_72            (72/8)  /* 72 bits */
151 #define OTP_SZ_CHECKSUM         (16/8)  /* 16 bits */
152 #define OTP4315_SWREG_SZ        178     /* 178 bytes */
153 #define OTP_SZ_FU_144           (144/8) /* 144 bits */
154
155 static int ipxotp_status(void *oh)
156 {
157         struct otpinfo *oi = (struct otpinfo *) oh;
158         return (int)(oi->status);
159 }
160
161 /* Return size in bytes */
162 static int ipxotp_size(void *oh)
163 {
164         struct otpinfo *oi = (struct otpinfo *) oh;
165         return (int)oi->wsize * 2;
166 }
167
168 static u16 ipxotp_otpr(void *oh, chipcregs_t *cc, uint wn)
169 {
170         struct otpinfo *oi;
171
172         oi = (struct otpinfo *) oh;
173
174         return R_REG(&cc->sromotp[wn]);
175 }
176
177 static u16 ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off)
178 {
179         struct otpinfo *oi = (struct otpinfo *) oh;
180         uint k, row, col;
181         u32 otpp, st;
182
183         row = off / oi->cols;
184         col = off % oi->cols;
185
186         otpp = OTPP_START_BUSY |
187             ((OTPPOC_READ << OTPP_OC_SHIFT) & OTPP_OC_MASK) |
188             ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) |
189             ((col << OTPP_COL_SHIFT) & OTPP_COL_MASK);
190         W_REG(&cc->otpprog, otpp);
191
192         for (k = 0;
193              ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
194              && (k < OTPP_TRIES); k++)
195                 ;
196         if (k >= OTPP_TRIES) {
197                 return 0xffff;
198         }
199         if (st & OTPP_READERR) {
200                 return 0xffff;
201         }
202         st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
203
204         return (int)st;
205 }
206
207 /* Calculate max HW/SW region byte size by subtracting fuse region and checksum size,
208  * osizew is oi->wsize (OTP size - GU size) in words
209  */
210 static int ipxotp_max_rgnsz(struct si_pub *sih, int osizew)
211 {
212         int ret = 0;
213
214         switch (sih->chip) {
215         case BCM43224_CHIP_ID:
216         case BCM43225_CHIP_ID:
217                 ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
218                 break;
219         case BCM4313_CHIP_ID:
220                 ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
221                 break;
222         default:
223                 break;  /* Don't know about this chip */
224         }
225
226         return ret;
227 }
228
229 static void _ipxotp_init(struct otpinfo *oi, chipcregs_t *cc)
230 {
231         uint k;
232         u32 otpp, st;
233
234         /* record word offset of General Use Region for various chipcommon revs */
235         if (oi->sih->ccrev == 21 || oi->sih->ccrev == 24
236             || oi->sih->ccrev == 27) {
237                 oi->otpgu_base = REVA4_OTPGU_BASE;
238         } else if (oi->sih->ccrev == 36) {
239                 /* OTP size greater than equal to 2KB (128 words), otpgu_base is similar to rev23 */
240                 if (oi->wsize >= 128)
241                         oi->otpgu_base = REVB8_OTPGU_BASE;
242                 else
243                         oi->otpgu_base = REV36_OTPGU_BASE;
244         } else if (oi->sih->ccrev == 23 || oi->sih->ccrev >= 25) {
245                 oi->otpgu_base = REVB8_OTPGU_BASE;
246         }
247
248         /* First issue an init command so the status is up to date */
249         otpp =
250             OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK);
251
252         W_REG(&cc->otpprog, otpp);
253         for (k = 0;
254              ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
255              && (k < OTPP_TRIES); k++)
256                 ;
257         if (k >= OTPP_TRIES) {
258                 return;
259         }
260
261         /* Read OTP lock bits and subregion programmed indication bits */
262         oi->status = R_REG(&cc->otpstatus);
263
264         if ((oi->sih->chip == BCM43224_CHIP_ID)
265             || (oi->sih->chip == BCM43225_CHIP_ID)) {
266                 u32 p_bits;
267                 p_bits =
268                     (ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_P_OFF) &
269                      OTPGU_P_MSK)
270                     >> OTPGU_P_SHIFT;
271                 oi->status |= (p_bits << OTPS_GUP_SHIFT);
272         }
273
274         /*
275          * h/w region base and fuse region limit are fixed to the top and
276          * the bottom of the general use region. Everything else can be flexible.
277          */
278         oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF;
279         oi->hwlim = oi->wsize;
280         if (oi->status & OTPS_GUP_HW) {
281                 oi->hwlim =
282                     ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF) / 16;
283                 oi->swbase = oi->hwlim;
284         } else
285                 oi->swbase = oi->hwbase;
286
287         /* subtract fuse and checksum from beginning */
288         oi->swlim = ipxotp_max_rgnsz(oi->sih, oi->wsize) / 2;
289
290         if (oi->status & OTPS_GUP_SW) {
291                 oi->swlim =
292                     ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF) / 16;
293                 oi->fbase = oi->swlim;
294         } else
295                 oi->fbase = oi->swbase;
296
297         oi->flim = oi->wsize;
298 }
299
300 static void *ipxotp_init(struct si_pub *sih)
301 {
302         uint idx;
303         chipcregs_t *cc;
304         struct otpinfo *oi;
305
306         /* Make sure we're running IPX OTP */
307         if (!OTPTYPE_IPX(sih->ccrev))
308                 return NULL;
309
310         /* Make sure OTP is not disabled */
311         if (ai_is_otp_disabled(sih))
312                 return NULL;
313
314         /* OTP is always powered */
315         oi = &otpinfo;
316
317         /* Check for otp size */
318         switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
319         case 0:
320                 /* Nothing there */
321                 return NULL;
322         case 1:         /* 32x64 */
323                 oi->rows = 32;
324                 oi->cols = 64;
325                 oi->wsize = 128;
326                 break;
327         case 2:         /* 64x64 */
328                 oi->rows = 64;
329                 oi->cols = 64;
330                 oi->wsize = 256;
331                 break;
332         case 5:         /* 96x64 */
333                 oi->rows = 96;
334                 oi->cols = 64;
335                 oi->wsize = 384;
336                 break;
337         case 7:         /* 16x64 *//* 1024 bits */
338                 oi->rows = 16;
339                 oi->cols = 64;
340                 oi->wsize = 64;
341                 break;
342         default:
343                 /* Don't know the geometry */
344                 return NULL;
345         }
346
347         /* Retrieve OTP region info */
348         idx = ai_coreidx(sih);
349         cc = ai_setcoreidx(sih, SI_CC_IDX);
350
351         _ipxotp_init(oi, cc);
352
353         ai_setcoreidx(sih, idx);
354
355         return (void *)oi;
356 }
357
358 static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen)
359 {
360         struct otpinfo *oi = (struct otpinfo *) oh;
361         uint idx;
362         chipcregs_t *cc;
363         uint base, i, sz;
364
365         /* Validate region selection */
366         switch (region) {
367         case OTP_HW_RGN:
368                 sz = (uint) oi->hwlim - oi->hwbase;
369                 if (!(oi->status & OTPS_GUP_HW)) {
370                         *wlen = sz;
371                         return -ENODATA;
372                 }
373                 if (*wlen < sz) {
374                         *wlen = sz;
375                         return -EOVERFLOW;
376                 }
377                 base = oi->hwbase;
378                 break;
379         case OTP_SW_RGN:
380                 sz = ((uint) oi->swlim - oi->swbase);
381                 if (!(oi->status & OTPS_GUP_SW)) {
382                         *wlen = sz;
383                         return -ENODATA;
384                 }
385                 if (*wlen < sz) {
386                         *wlen = sz;
387                         return -EOVERFLOW;
388                 }
389                 base = oi->swbase;
390                 break;
391         case OTP_CI_RGN:
392                 sz = OTPGU_CI_SZ;
393                 if (!(oi->status & OTPS_GUP_CI)) {
394                         *wlen = sz;
395                         return -ENODATA;
396                 }
397                 if (*wlen < sz) {
398                         *wlen = sz;
399                         return -EOVERFLOW;
400                 }
401                 base = oi->otpgu_base + OTPGU_CI_OFF;
402                 break;
403         case OTP_FUSE_RGN:
404                 sz = (uint) oi->flim - oi->fbase;
405                 if (!(oi->status & OTPS_GUP_FUSE)) {
406                         *wlen = sz;
407                         return -ENODATA;
408                 }
409                 if (*wlen < sz) {
410                         *wlen = sz;
411                         return -EOVERFLOW;
412                 }
413                 base = oi->fbase;
414                 break;
415         case OTP_ALL_RGN:
416                 sz = ((uint) oi->flim - oi->hwbase);
417                 if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) {
418                         *wlen = sz;
419                         return -ENODATA;
420                 }
421                 if (*wlen < sz) {
422                         *wlen = sz;
423                         return -EOVERFLOW;
424                 }
425                 base = oi->hwbase;
426                 break;
427         default:
428                 return -EINVAL;
429         }
430
431         idx = ai_coreidx(oi->sih);
432         cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
433
434         /* Read the data */
435         for (i = 0; i < sz; i++)
436                 data[i] = ipxotp_otpr(oh, cc, base + i);
437
438         ai_setcoreidx(oi->sih, idx);
439         *wlen = sz;
440         return 0;
441 }
442
443 static int ipxotp_nvread(void *oh, char *data, uint *len)
444 {
445         return -ENOTSUPP;
446 }
447
448 static struct otp_fn_s ipxotp_fn = {
449         (otp_size_t) ipxotp_size,
450         (otp_read_bit_t) ipxotp_read_bit,
451
452         (otp_init_t) ipxotp_init,
453         (otp_read_region_t) ipxotp_read_region,
454         (otp_nvread_t) ipxotp_nvread,
455
456         (otp_status_t) ipxotp_status
457 };
458
459 /*
460  *      otp_status()
461  *      otp_size()
462  *      otp_read_bit()
463  *      otp_init()
464  *      otp_read_region()
465  *      otp_nvread()
466  */
467
468 int otp_status(void *oh)
469 {
470         struct otpinfo *oi = (struct otpinfo *) oh;
471
472         return oi->fn->status(oh);
473 }
474
475 int otp_size(void *oh)
476 {
477         struct otpinfo *oi = (struct otpinfo *) oh;
478
479         return oi->fn->size(oh);
480 }
481
482 u16 otp_read_bit(void *oh, uint offset)
483 {
484         struct otpinfo *oi = (struct otpinfo *) oh;
485         uint idx = ai_coreidx(oi->sih);
486         chipcregs_t *cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
487         u16 readBit = (u16) oi->fn->read_bit(oh, cc, offset);
488         ai_setcoreidx(oi->sih, idx);
489         return readBit;
490 }
491
492 void *otp_init(struct si_pub *sih)
493 {
494         struct otpinfo *oi;
495         void *ret = NULL;
496
497         oi = &otpinfo;
498         memset(oi, 0, sizeof(struct otpinfo));
499
500         oi->ccrev = sih->ccrev;
501
502         if (OTPTYPE_IPX(oi->ccrev))
503                 oi->fn = &ipxotp_fn;
504
505         if (oi->fn == NULL) {
506                 return NULL;
507         }
508
509         oi->sih = sih;
510
511         ret = (oi->fn->init) (sih);
512
513         return ret;
514 }
515
516 int
517 otp_read_region(struct si_pub *sih, int region, u16 *data,
518                                  uint *wlen) {
519         void *oh;
520         int err = 0;
521
522         if (ai_is_otp_disabled(sih)) {
523                 err = -EPERM;
524                 goto out;
525         }
526
527         oh = otp_init(sih);
528         if (oh == NULL) {
529                 err = -EBADE;
530                 goto out;
531         }
532
533         err = (((struct otpinfo *) oh)->fn->read_region)
534                                                 (oh, region, data, wlen);
535
536  out:
537         return err;
538 }
539
540 int otp_nvread(void *oh, char *data, uint *len)
541 {
542         struct otpinfo *oi = (struct otpinfo *) oh;
543
544         return oi->fn->nvread(oh, data, len);
545 }