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