2096a14ef1fba5fcaf156140a64b2f52f4b67757
[linux-drm-fsl-dcu.git] / drivers / net / wireless / brcm80211 / brcmfmac / sdio_chip.c
1 /*
2  * Copyright (c) 2011 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 /* ***** SDIO interface chip backplane handle functions ***** */
17
18 #include <linux/types.h>
19 #include <linux/netdevice.h>
20 #include <linux/mmc/card.h>
21 #include <linux/mmc/sdio_func.h>
22 #include <linux/ssb/ssb_regs.h>
23 #include <linux/bcma/bcma.h>
24
25 #include <chipcommon.h>
26 #include <brcm_hw_ids.h>
27 #include <brcmu_wifi.h>
28 #include <brcmu_utils.h>
29 #include <soc.h>
30 #include "dhd_dbg.h"
31 #include "sdio_host.h"
32 #include "sdio_chip.h"
33
34 /* chip core base & ramsize */
35 /* bcm4329 */
36 /* SDIO device core, ID 0x829 */
37 #define BCM4329_CORE_BUS_BASE           0x18011000
38 /* internal memory core, ID 0x80e */
39 #define BCM4329_CORE_SOCRAM_BASE        0x18003000
40 /* ARM Cortex M3 core, ID 0x82a */
41 #define BCM4329_CORE_ARM_BASE           0x18002000
42 #define BCM4329_RAMSIZE                 0x48000
43
44 /* bcm43143 */
45 /* SDIO device core */
46 #define BCM43143_CORE_BUS_BASE          0x18002000
47 /* internal memory core */
48 #define BCM43143_CORE_SOCRAM_BASE       0x18004000
49 /* ARM Cortex M3 core, ID 0x82a */
50 #define BCM43143_CORE_ARM_BASE          0x18003000
51 #define BCM43143_RAMSIZE                0x70000
52
53 #define SBCOREREV(sbidh) \
54         ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
55           ((sbidh) & SSB_IDHIGH_RCLO))
56
57 /* SOC Interconnect types (aka chip types) */
58 #define SOCI_SB         0
59 #define SOCI_AI         1
60
61 /* EROM CompIdentB */
62 #define CIB_REV_MASK            0xff000000
63 #define CIB_REV_SHIFT           24
64
65 /* ARM CR4 core specific control flag bits */
66 #define ARMCR4_BCMA_IOCTL_CPUHALT       0x0020
67
68 #define SDIOD_DRVSTR_KEY(chip, pmu)     (((chip) << 16) | (pmu))
69 /* SDIO Pad drive strength to select value mappings */
70 struct sdiod_drive_str {
71         u8 strength;    /* Pad Drive Strength in mA */
72         u8 sel;         /* Chip-specific select value */
73 };
74 /* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8V) */
75 static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = {
76         {32, 0x6},
77         {26, 0x7},
78         {22, 0x4},
79         {16, 0x5},
80         {12, 0x2},
81         {8, 0x3},
82         {4, 0x0},
83         {0, 0x1}
84 };
85
86 /* SDIO Drive Strength to sel value table for 43143 PMU Rev 17 (3.3V) */
87 static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = {
88         {16, 0x7},
89         {12, 0x5},
90         {8,  0x3},
91         {4,  0x1}
92 };
93
94 u8
95 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid)
96 {
97         u8 idx;
98
99         for (idx = 0; idx < BRCMF_MAX_CORENUM; idx++)
100                 if (coreid == ci->c_inf[idx].id)
101                         return idx;
102
103         return BRCMF_MAX_CORENUM;
104 }
105
106 static u32
107 brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev,
108                       struct chip_info *ci, u16 coreid)
109 {
110         u32 regdata;
111         u8 idx;
112
113         idx = brcmf_sdio_chip_getinfidx(ci, coreid);
114
115         regdata = brcmf_sdio_regrl(sdiodev,
116                                    CORE_SB(ci->c_inf[idx].base, sbidhigh),
117                                    NULL);
118         return SBCOREREV(regdata);
119 }
120
121 static u32
122 brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev,
123                       struct chip_info *ci, u16 coreid)
124 {
125         u8 idx;
126
127         idx = brcmf_sdio_chip_getinfidx(ci, coreid);
128
129         return (ci->c_inf[idx].cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
130 }
131
132 static bool
133 brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev,
134                        struct chip_info *ci, u16 coreid)
135 {
136         u32 regdata;
137         u8 idx;
138
139         idx = brcmf_sdio_chip_getinfidx(ci, coreid);
140         if (idx == BRCMF_MAX_CORENUM)
141                 return false;
142
143         regdata = brcmf_sdio_regrl(sdiodev,
144                                    CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
145                                    NULL);
146         regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
147                     SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
148         return (SSB_TMSLOW_CLOCK == regdata);
149 }
150
151 static bool
152 brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
153                        struct chip_info *ci, u16 coreid)
154 {
155         u32 regdata;
156         u8 idx;
157         bool ret;
158
159         idx = brcmf_sdio_chip_getinfidx(ci, coreid);
160         if (idx == BRCMF_MAX_CORENUM)
161                 return false;
162
163         regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
164                                    NULL);
165         ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
166
167         regdata = brcmf_sdio_regrl(sdiodev,
168                                    ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
169                                    NULL);
170         ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
171
172         return ret;
173 }
174
175 static void
176 brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev,
177                           struct chip_info *ci, u16 coreid, u32 core_bits)
178 {
179         u32 regdata, base;
180         u8 idx;
181
182         idx = brcmf_sdio_chip_getinfidx(ci, coreid);
183         base = ci->c_inf[idx].base;
184
185         regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
186         if (regdata & SSB_TMSLOW_RESET)
187                 return;
188
189         regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
190         if ((regdata & SSB_TMSLOW_CLOCK) != 0) {
191                 /*
192                  * set target reject and spin until busy is clear
193                  * (preserve core-specific bits)
194                  */
195                 regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow),
196                                            NULL);
197                 brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
198                                  regdata | SSB_TMSLOW_REJECT, NULL);
199
200                 regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow),
201                                            NULL);
202                 udelay(1);
203                 SPINWAIT((brcmf_sdio_regrl(sdiodev,
204                                            CORE_SB(base, sbtmstatehigh),
205                                            NULL) &
206                         SSB_TMSHIGH_BUSY), 100000);
207
208                 regdata = brcmf_sdio_regrl(sdiodev,
209                                            CORE_SB(base, sbtmstatehigh),
210                                            NULL);
211                 if (regdata & SSB_TMSHIGH_BUSY)
212                         brcmf_err("core state still busy\n");
213
214                 regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbidlow),
215                                            NULL);
216                 if (regdata & SSB_IDLOW_INITIATOR) {
217                         regdata = brcmf_sdio_regrl(sdiodev,
218                                                    CORE_SB(base, sbimstate),
219                                                    NULL);
220                         regdata |= SSB_IMSTATE_REJECT;
221                         brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbimstate),
222                                          regdata, NULL);
223                         regdata = brcmf_sdio_regrl(sdiodev,
224                                                    CORE_SB(base, sbimstate),
225                                                    NULL);
226                         udelay(1);
227                         SPINWAIT((brcmf_sdio_regrl(sdiodev,
228                                                    CORE_SB(base, sbimstate),
229                                                    NULL) &
230                                 SSB_IMSTATE_BUSY), 100000);
231                 }
232
233                 /* set reset and reject while enabling the clocks */
234                 regdata = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
235                           SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET;
236                 brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
237                                  regdata, NULL);
238                 regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow),
239                                            NULL);
240                 udelay(10);
241
242                 /* clear the initiator reject bit */
243                 regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbidlow),
244                                            NULL);
245                 if (regdata & SSB_IDLOW_INITIATOR) {
246                         regdata = brcmf_sdio_regrl(sdiodev,
247                                                    CORE_SB(base, sbimstate),
248                                                    NULL);
249                         regdata &= ~SSB_IMSTATE_REJECT;
250                         brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbimstate),
251                                          regdata, NULL);
252                 }
253         }
254
255         /* leave reset and reject asserted */
256         brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
257                          (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET), NULL);
258         udelay(1);
259 }
260
261 static void
262 brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev,
263                           struct chip_info *ci, u16 coreid, u32 core_bits)
264 {
265         u8 idx;
266         u32 regdata;
267
268         idx = brcmf_sdio_chip_getinfidx(ci, coreid);
269         if (idx == BRCMF_MAX_CORENUM)
270                 return;
271
272         /* if core is already in reset, just return */
273         regdata = brcmf_sdio_regrl(sdiodev,
274                                    ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
275                                    NULL);
276         if ((regdata & BCMA_RESET_CTL_RESET) != 0)
277                 return;
278
279         /* ensure no pending backplane operation
280          * 300uc should be sufficient for backplane ops to be finish
281          * extra 10ms is taken into account for firmware load stage
282          * after 10300us carry on disabling the core anyway
283          */
284         SPINWAIT(brcmf_sdio_regrl(sdiodev,
285                                   ci->c_inf[idx].wrapbase+BCMA_RESET_ST,
286                                   NULL), 10300);
287         regdata = brcmf_sdio_regrl(sdiodev,
288                                    ci->c_inf[idx].wrapbase+BCMA_RESET_ST,
289                                    NULL);
290         if (regdata)
291                 brcmf_err("disabling core 0x%x with reset status %x\n",
292                           coreid, regdata);
293
294         brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
295                          BCMA_RESET_CTL_RESET, NULL);
296         udelay(1);
297
298         brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
299                          core_bits, NULL);
300         regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
301                                    NULL);
302         usleep_range(10, 20);
303
304 }
305
306 static void
307 brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
308                         struct chip_info *ci, u16 coreid, u32 core_bits)
309 {
310         u32 regdata;
311         u8 idx;
312
313         idx = brcmf_sdio_chip_getinfidx(ci, coreid);
314         if (idx == BRCMF_MAX_CORENUM)
315                 return;
316
317         /*
318          * Must do the disable sequence first to work for
319          * arbitrary current core state.
320          */
321         brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, 0);
322
323         /*
324          * Now do the initialization sequence.
325          * set reset while enabling the clock and
326          * forcing them on throughout the core
327          */
328         brcmf_sdio_regwl(sdiodev,
329                          CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
330                          SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET,
331                          NULL);
332         regdata = brcmf_sdio_regrl(sdiodev,
333                                    CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
334                                    NULL);
335         udelay(1);
336
337         /* clear any serror */
338         regdata = brcmf_sdio_regrl(sdiodev,
339                                    CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
340                                    NULL);
341         if (regdata & SSB_TMSHIGH_SERR)
342                 brcmf_sdio_regwl(sdiodev,
343                                  CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
344                                  0, NULL);
345
346         regdata = brcmf_sdio_regrl(sdiodev,
347                                    CORE_SB(ci->c_inf[idx].base, sbimstate),
348                                    NULL);
349         if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO))
350                 brcmf_sdio_regwl(sdiodev,
351                                  CORE_SB(ci->c_inf[idx].base, sbimstate),
352                                  regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO),
353                                  NULL);
354
355         /* clear reset and allow it to propagate throughout the core */
356         brcmf_sdio_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
357                          SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK, NULL);
358         regdata = brcmf_sdio_regrl(sdiodev,
359                                    CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
360                                    NULL);
361         udelay(1);
362
363         /* leave clock enabled */
364         brcmf_sdio_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
365                          SSB_TMSLOW_CLOCK, NULL);
366         regdata = brcmf_sdio_regrl(sdiodev,
367                                    CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
368                                    NULL);
369         udelay(1);
370 }
371
372 static void
373 brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev,
374                         struct chip_info *ci, u16 coreid, u32 core_bits)
375 {
376         u8 idx;
377         u32 regdata;
378
379         idx = brcmf_sdio_chip_getinfidx(ci, coreid);
380         if (idx == BRCMF_MAX_CORENUM)
381                 return;
382
383         /* must disable first to work for arbitrary current core state */
384         brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, core_bits);
385
386         /* now do initialization sequence */
387         brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
388                          core_bits | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
389         regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
390                                    NULL);
391         brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
392                          0, NULL);
393         regdata = brcmf_sdio_regrl(sdiodev,
394                                    ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
395                                    NULL);
396         udelay(1);
397
398         brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
399                          core_bits | BCMA_IOCTL_CLK, NULL);
400         regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
401                                    NULL);
402         udelay(1);
403 }
404
405 #ifdef DEBUG
406 /* safety check for chipinfo */
407 static int brcmf_sdio_chip_cichk(struct chip_info *ci)
408 {
409         u8 core_idx;
410
411         /* check RAM core presence for ARM CM3 core */
412         core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
413         if (BRCMF_MAX_CORENUM != core_idx) {
414                 core_idx = brcmf_sdio_chip_getinfidx(ci,
415                                                      BCMA_CORE_INTERNAL_MEM);
416                 if (BRCMF_MAX_CORENUM == core_idx) {
417                         brcmf_err("RAM core not provided with ARM CM3 core\n");
418                         return -ENODEV;
419                 }
420         }
421
422         /* check RAM base for ARM CR4 core */
423         core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CR4);
424         if (BRCMF_MAX_CORENUM != core_idx) {
425                 if (ci->rambase == 0) {
426                         brcmf_err("RAM base not provided with ARM CR4 core\n");
427                         return -ENOMEM;
428                 }
429         }
430
431         return 0;
432 }
433 #else   /* DEBUG */
434 static inline int brcmf_sdio_chip_cichk(struct chip_info *ci)
435 {
436         return 0;
437 }
438 #endif
439
440 static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
441                                        struct chip_info *ci, u32 regs)
442 {
443         u32 regdata;
444         int ret;
445
446         /* Get CC core rev
447          * Chipid is assume to be at offset 0 from regs arg
448          * For different chiptypes or old sdio hosts w/o chipcommon,
449          * other ways of recognition should be added here.
450          */
451         ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
452         ci->c_inf[0].base = regs;
453         regdata = brcmf_sdio_regrl(sdiodev,
454                                    CORE_CC_REG(ci->c_inf[0].base, chipid),
455                                    NULL);
456         ci->chip = regdata & CID_ID_MASK;
457         ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
458         if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 &&
459             ci->chiprev >= 2)
460                 ci->chip = BCM4339_CHIP_ID;
461         ci->socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
462
463         brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev);
464
465         /* Address of cores for new chips should be added here */
466         switch (ci->chip) {
467         case BCM43143_CHIP_ID:
468                 ci->c_inf[0].wrapbase = ci->c_inf[0].base + 0x00100000;
469                 ci->c_inf[0].cib = 0x2b000000;
470                 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
471                 ci->c_inf[1].base = BCM43143_CORE_BUS_BASE;
472                 ci->c_inf[1].wrapbase = ci->c_inf[1].base + 0x00100000;
473                 ci->c_inf[1].cib = 0x18000000;
474                 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
475                 ci->c_inf[2].base = BCM43143_CORE_SOCRAM_BASE;
476                 ci->c_inf[2].wrapbase = ci->c_inf[2].base + 0x00100000;
477                 ci->c_inf[2].cib = 0x14000000;
478                 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
479                 ci->c_inf[3].base = BCM43143_CORE_ARM_BASE;
480                 ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
481                 ci->c_inf[3].cib = 0x07000000;
482                 ci->ramsize = BCM43143_RAMSIZE;
483                 break;
484         case BCM43241_CHIP_ID:
485                 ci->c_inf[0].wrapbase = 0x18100000;
486                 ci->c_inf[0].cib = 0x2a084411;
487                 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
488                 ci->c_inf[1].base = 0x18002000;
489                 ci->c_inf[1].wrapbase = 0x18102000;
490                 ci->c_inf[1].cib = 0x0e004211;
491                 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
492                 ci->c_inf[2].base = 0x18004000;
493                 ci->c_inf[2].wrapbase = 0x18104000;
494                 ci->c_inf[2].cib = 0x14080401;
495                 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
496                 ci->c_inf[3].base = 0x18003000;
497                 ci->c_inf[3].wrapbase = 0x18103000;
498                 ci->c_inf[3].cib = 0x07004211;
499                 ci->ramsize = 0x90000;
500                 break;
501         case BCM4329_CHIP_ID:
502                 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
503                 ci->c_inf[1].base = BCM4329_CORE_BUS_BASE;
504                 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
505                 ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE;
506                 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
507                 ci->c_inf[3].base = BCM4329_CORE_ARM_BASE;
508                 ci->ramsize = BCM4329_RAMSIZE;
509                 break;
510         case BCM4330_CHIP_ID:
511                 ci->c_inf[0].wrapbase = 0x18100000;
512                 ci->c_inf[0].cib = 0x27004211;
513                 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
514                 ci->c_inf[1].base = 0x18002000;
515                 ci->c_inf[1].wrapbase = 0x18102000;
516                 ci->c_inf[1].cib = 0x07004211;
517                 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
518                 ci->c_inf[2].base = 0x18004000;
519                 ci->c_inf[2].wrapbase = 0x18104000;
520                 ci->c_inf[2].cib = 0x0d080401;
521                 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
522                 ci->c_inf[3].base = 0x18003000;
523                 ci->c_inf[3].wrapbase = 0x18103000;
524                 ci->c_inf[3].cib = 0x03004211;
525                 ci->ramsize = 0x48000;
526                 break;
527         case BCM4334_CHIP_ID:
528                 ci->c_inf[0].wrapbase = 0x18100000;
529                 ci->c_inf[0].cib = 0x29004211;
530                 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
531                 ci->c_inf[1].base = 0x18002000;
532                 ci->c_inf[1].wrapbase = 0x18102000;
533                 ci->c_inf[1].cib = 0x0d004211;
534                 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
535                 ci->c_inf[2].base = 0x18004000;
536                 ci->c_inf[2].wrapbase = 0x18104000;
537                 ci->c_inf[2].cib = 0x13080401;
538                 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
539                 ci->c_inf[3].base = 0x18003000;
540                 ci->c_inf[3].wrapbase = 0x18103000;
541                 ci->c_inf[3].cib = 0x07004211;
542                 ci->ramsize = 0x80000;
543                 break;
544         case BCM4335_CHIP_ID:
545                 ci->c_inf[0].wrapbase = 0x18100000;
546                 ci->c_inf[0].cib = 0x2b084411;
547                 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
548                 ci->c_inf[1].base = 0x18005000;
549                 ci->c_inf[1].wrapbase = 0x18105000;
550                 ci->c_inf[1].cib = 0x0f004211;
551                 ci->c_inf[2].id = BCMA_CORE_ARM_CR4;
552                 ci->c_inf[2].base = 0x18002000;
553                 ci->c_inf[2].wrapbase = 0x18102000;
554                 ci->c_inf[2].cib = 0x01084411;
555                 ci->ramsize = 0xc0000;
556                 ci->rambase = 0x180000;
557                 break;
558         case BCM4339_CHIP_ID:
559                 ci->c_inf[0].wrapbase = 0x18100000;
560                 ci->c_inf[0].cib = 0x2e084411;
561                 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
562                 ci->c_inf[1].base = 0x18005000;
563                 ci->c_inf[1].wrapbase = 0x18105000;
564                 ci->c_inf[1].cib = 0x15004211;
565                 ci->c_inf[2].id = BCMA_CORE_ARM_CR4;
566                 ci->c_inf[2].base = 0x18002000;
567                 ci->c_inf[2].wrapbase = 0x18102000;
568                 ci->c_inf[2].cib = 0x04084411;
569                 ci->ramsize = 0xc0000;
570                 ci->rambase = 0x180000;
571                 break;
572         default:
573                 brcmf_err("chipid 0x%x is not supported\n", ci->chip);
574                 return -ENODEV;
575         }
576
577         ret = brcmf_sdio_chip_cichk(ci);
578         if (ret)
579                 return ret;
580
581         switch (ci->socitype) {
582         case SOCI_SB:
583                 ci->iscoreup = brcmf_sdio_sb_iscoreup;
584                 ci->corerev = brcmf_sdio_sb_corerev;
585                 ci->coredisable = brcmf_sdio_sb_coredisable;
586                 ci->resetcore = brcmf_sdio_sb_resetcore;
587                 break;
588         case SOCI_AI:
589                 ci->iscoreup = brcmf_sdio_ai_iscoreup;
590                 ci->corerev = brcmf_sdio_ai_corerev;
591                 ci->coredisable = brcmf_sdio_ai_coredisable;
592                 ci->resetcore = brcmf_sdio_ai_resetcore;
593                 break;
594         default:
595                 brcmf_err("socitype %u not supported\n", ci->socitype);
596                 return -ENODEV;
597         }
598
599         return 0;
600 }
601
602 static int
603 brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
604 {
605         int err = 0;
606         u8 clkval, clkset;
607
608         /* Try forcing SDIO core to do ALPAvail request only */
609         clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
610         brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
611         if (err) {
612                 brcmf_err("error writing for HT off\n");
613                 return err;
614         }
615
616         /* If register supported, wait for ALPAvail and then force ALP */
617         /* This may take up to 15 milliseconds */
618         clkval = brcmf_sdio_regrb(sdiodev,
619                                   SBSDIO_FUNC1_CHIPCLKCSR, NULL);
620
621         if ((clkval & ~SBSDIO_AVBITS) != clkset) {
622                 brcmf_err("ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
623                           clkset, clkval);
624                 return -EACCES;
625         }
626
627         SPINWAIT(((clkval = brcmf_sdio_regrb(sdiodev,
628                                              SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
629                         !SBSDIO_ALPAV(clkval)),
630                         PMU_MAX_TRANSITION_DLY);
631         if (!SBSDIO_ALPAV(clkval)) {
632                 brcmf_err("timeout on ALPAV wait, clkval 0x%02x\n",
633                           clkval);
634                 return -EBUSY;
635         }
636
637         clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
638         brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
639         udelay(65);
640
641         /* Also, disable the extra SDIO pull-ups */
642         brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
643
644         return 0;
645 }
646
647 static void
648 brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
649                              struct chip_info *ci)
650 {
651         u32 base = ci->c_inf[0].base;
652
653         /* get chipcommon rev */
654         ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id);
655
656         /* get chipcommon capabilites */
657         ci->c_inf[0].caps = brcmf_sdio_regrl(sdiodev,
658                                              CORE_CC_REG(base, capabilities),
659                                              NULL);
660
661         /* get pmu caps & rev */
662         if (ci->c_inf[0].caps & CC_CAP_PMU) {
663                 ci->pmucaps =
664                         brcmf_sdio_regrl(sdiodev,
665                                          CORE_CC_REG(base, pmucapabilities),
666                                          NULL);
667                 ci->pmurev = ci->pmucaps & PCAP_REV_MASK;
668         }
669
670         ci->c_inf[1].rev = ci->corerev(sdiodev, ci, ci->c_inf[1].id);
671
672         brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
673                   ci->c_inf[0].rev, ci->pmurev,
674                   ci->c_inf[1].rev, ci->c_inf[1].id);
675
676         /*
677          * Make sure any on-chip ARM is off (in case strapping is wrong),
678          * or downloaded code was already running.
679          */
680         ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0);
681 }
682
683 int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
684                            struct chip_info **ci_ptr, u32 regs)
685 {
686         int ret;
687         struct chip_info *ci;
688
689         brcmf_dbg(TRACE, "Enter\n");
690
691         /* alloc chip_info_t */
692         ci = kzalloc(sizeof(struct chip_info), GFP_ATOMIC);
693         if (!ci)
694                 return -ENOMEM;
695
696         ret = brcmf_sdio_chip_buscoreprep(sdiodev);
697         if (ret != 0)
698                 goto err;
699
700         ret = brcmf_sdio_chip_recognition(sdiodev, ci, regs);
701         if (ret != 0)
702                 goto err;
703
704         brcmf_sdio_chip_buscoresetup(sdiodev, ci);
705
706         brcmf_sdio_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopullup),
707                          0, NULL);
708         brcmf_sdio_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopulldown),
709                          0, NULL);
710
711         *ci_ptr = ci;
712         return 0;
713
714 err:
715         kfree(ci);
716         return ret;
717 }
718
719 void
720 brcmf_sdio_chip_detach(struct chip_info **ci_ptr)
721 {
722         brcmf_dbg(TRACE, "Enter\n");
723
724         kfree(*ci_ptr);
725         *ci_ptr = NULL;
726 }
727
728 static char *brcmf_sdio_chip_name(uint chipid, char *buf, uint len)
729 {
730         const char *fmt;
731
732         fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
733         snprintf(buf, len, fmt, chipid);
734         return buf;
735 }
736
737 void
738 brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
739                                   struct chip_info *ci, u32 drivestrength)
740 {
741         const struct sdiod_drive_str *str_tab = NULL;
742         u32 str_mask;
743         u32 str_shift;
744         char chn[8];
745         u32 base = ci->c_inf[0].base;
746         u32 i;
747         u32 drivestrength_sel = 0;
748         u32 cc_data_temp;
749         u32 addr;
750
751         if (!(ci->c_inf[0].caps & CC_CAP_PMU))
752                 return;
753
754         switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
755         case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12):
756                 str_tab = sdiod_drvstr_tab1_1v8;
757                 str_mask = 0x00003800;
758                 str_shift = 11;
759                 break;
760         case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17):
761                 /* note: 43143 does not support tristate */
762                 i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1;
763                 if (drivestrength >= sdiod_drvstr_tab2_3v3[i].strength) {
764                         str_tab = sdiod_drvstr_tab2_3v3;
765                         str_mask = 0x00000007;
766                         str_shift = 0;
767                 } else
768                         brcmf_err("Invalid SDIO Drive strength for chip %s, strength=%d\n",
769                                   brcmf_sdio_chip_name(ci->chip, chn, 8),
770                                   drivestrength);
771                 break;
772         default:
773                 brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
774                           brcmf_sdio_chip_name(ci->chip, chn, 8),
775                           ci->chiprev, ci->pmurev);
776                 break;
777         }
778
779         if (str_tab != NULL) {
780                 for (i = 0; str_tab[i].strength != 0; i++) {
781                         if (drivestrength >= str_tab[i].strength) {
782                                 drivestrength_sel = str_tab[i].sel;
783                                 break;
784                         }
785                 }
786                 addr = CORE_CC_REG(base, chipcontrol_addr);
787                 brcmf_sdio_regwl(sdiodev, addr, 1, NULL);
788                 cc_data_temp = brcmf_sdio_regrl(sdiodev, addr, NULL);
789                 cc_data_temp &= ~str_mask;
790                 drivestrength_sel <<= str_shift;
791                 cc_data_temp |= drivestrength_sel;
792                 brcmf_sdio_regwl(sdiodev, addr, cc_data_temp, NULL);
793
794                 brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n",
795                           str_tab[i].strength, drivestrength, cc_data_temp);
796         }
797 }
798
799 #ifdef DEBUG
800 static bool
801 brcmf_sdio_chip_verifynvram(struct brcmf_sdio_dev *sdiodev, u32 nvram_addr,
802                             char *nvram_dat, uint nvram_sz)
803 {
804         char *nvram_ularray;
805         int err;
806         bool ret = true;
807
808         /* read back and verify */
809         brcmf_dbg(INFO, "Compare NVRAM dl & ul; size=%d\n", nvram_sz);
810         nvram_ularray = kmalloc(nvram_sz, GFP_KERNEL);
811         /* do not proceed while no memory but  */
812         if (!nvram_ularray)
813                 return true;
814
815         /* Upload image to verify downloaded contents. */
816         memset(nvram_ularray, 0xaa, nvram_sz);
817
818         /* Read the vars list to temp buffer for comparison */
819         err = brcmf_sdio_ramrw(sdiodev, false, nvram_addr, nvram_ularray,
820                                nvram_sz);
821         if (err) {
822                 brcmf_err("error %d on reading %d nvram bytes at 0x%08x\n",
823                           err, nvram_sz, nvram_addr);
824         } else if (memcmp(nvram_dat, nvram_ularray, nvram_sz)) {
825                 brcmf_err("Downloaded NVRAM image is corrupted\n");
826                 ret = false;
827         }
828         kfree(nvram_ularray);
829
830         return ret;
831 }
832 #else   /* DEBUG */
833 static inline bool
834 brcmf_sdio_chip_verifynvram(struct brcmf_sdio_dev *sdiodev, u32 nvram_addr,
835                             char *nvram_dat, uint nvram_sz)
836 {
837         return true;
838 }
839 #endif  /* DEBUG */
840
841 static bool brcmf_sdio_chip_writenvram(struct brcmf_sdio_dev *sdiodev,
842                                        struct chip_info *ci,
843                                        char *nvram_dat, uint nvram_sz)
844 {
845         int err;
846         u32 nvram_addr;
847         u32 token;
848         __le32 token_le;
849
850         nvram_addr = (ci->ramsize - 4) - nvram_sz + ci->rambase;
851
852         /* Write the vars list */
853         err = brcmf_sdio_ramrw(sdiodev, true, nvram_addr, nvram_dat, nvram_sz);
854         if (err) {
855                 brcmf_err("error %d on writing %d nvram bytes at 0x%08x\n",
856                           err, nvram_sz, nvram_addr);
857                 return false;
858         }
859
860         if (!brcmf_sdio_chip_verifynvram(sdiodev, nvram_addr,
861                                          nvram_dat, nvram_sz))
862                 return false;
863
864         /* generate token:
865          * nvram size, converted to words, in lower 16-bits, checksum
866          * in upper 16-bits.
867          */
868         token = nvram_sz / 4;
869         token = (~token << 16) | (token & 0x0000FFFF);
870         token_le = cpu_to_le32(token);
871
872         brcmf_dbg(INFO, "RAM size: %d\n", ci->ramsize);
873         brcmf_dbg(INFO, "nvram is placed at %d, size %d, token=0x%08x\n",
874                   nvram_addr, nvram_sz, token);
875
876         /* Write the length token to the last word */
877         if (brcmf_sdio_ramrw(sdiodev, true, (ci->ramsize - 4 + ci->rambase),
878                              (u8 *)&token_le, 4))
879                 return false;
880
881         return true;
882 }
883
884 static void
885 brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev,
886                             struct chip_info *ci)
887 {
888         u32 zeros = 0;
889
890         ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0);
891         ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0);
892
893         /* clear length token */
894         brcmf_sdio_ramrw(sdiodev, true, ci->ramsize - 4, (u8 *)&zeros, 4);
895 }
896
897 static bool
898 brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci,
899                            char *nvram_dat, uint nvram_sz)
900 {
901         u8 core_idx;
902         u32 reg_addr;
903
904         if (!ci->iscoreup(sdiodev, ci, BCMA_CORE_INTERNAL_MEM)) {
905                 brcmf_err("SOCRAM core is down after reset?\n");
906                 return false;
907         }
908
909         if (!brcmf_sdio_chip_writenvram(sdiodev, ci, nvram_dat, nvram_sz))
910                 return false;
911
912         /* clear all interrupts */
913         core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV);
914         reg_addr = ci->c_inf[core_idx].base;
915         reg_addr += offsetof(struct sdpcmd_regs, intstatus);
916         brcmf_sdio_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
917
918         ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0);
919
920         return true;
921 }
922
923 static inline void
924 brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev,
925                             struct chip_info *ci)
926 {
927         ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4,
928                       ARMCR4_BCMA_IOCTL_CPUHALT);
929 }
930
931 static bool
932 brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci,
933                            char *nvram_dat, uint nvram_sz)
934 {
935         u8 core_idx;
936         u32 reg_addr;
937
938         if (!brcmf_sdio_chip_writenvram(sdiodev, ci, nvram_dat, nvram_sz))
939                 return false;
940
941         /* clear all interrupts */
942         core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV);
943         reg_addr = ci->c_inf[core_idx].base;
944         reg_addr += offsetof(struct sdpcmd_regs, intstatus);
945         brcmf_sdio_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
946
947         /* Write reset vector to address 0 */
948         brcmf_sdio_ramrw(sdiodev, true, 0, (void *)&ci->rst_vec,
949                          sizeof(ci->rst_vec));
950
951         /* restore ARM */
952         ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, 0);
953
954         return true;
955 }
956
957 void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev,
958                                     struct chip_info *ci)
959 {
960         u8 arm_core_idx;
961
962         arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
963         if (BRCMF_MAX_CORENUM != arm_core_idx) {
964                 brcmf_sdio_chip_cm3_enterdl(sdiodev, ci);
965                 return;
966         }
967
968         brcmf_sdio_chip_cr4_enterdl(sdiodev, ci);
969 }
970
971 bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev,
972                                    struct chip_info *ci, char *nvram_dat,
973                                    uint nvram_sz)
974 {
975         u8 arm_core_idx;
976
977         arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
978         if (BRCMF_MAX_CORENUM != arm_core_idx)
979                 return brcmf_sdio_chip_cm3_exitdl(sdiodev, ci, nvram_dat,
980                                                   nvram_sz);
981
982         return brcmf_sdio_chip_cr4_exitdl(sdiodev, ci, nvram_dat, nvram_sz);
983 }