brcm80211: fmac: add iscoreup function for bcm4330 chip
[linux-2.6-block.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/ssb/ssb_regs.h>
22 #include <linux/bcma/bcma.h>
23
24 #include <chipcommon.h>
25 #include <brcm_hw_ids.h>
26 #include <brcmu_wifi.h>
27 #include <brcmu_utils.h>
28 #include <soc.h>
29 #include "dhd.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 #define SBCOREREV(sbidh) \
45         ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
46           ((sbidh) & SSB_IDHIGH_RCLO))
47
48 /* SOC Interconnect types (aka chip types) */
49 #define SOCI_SB         0
50 #define SOCI_AI         1
51
52 #define SDIOD_DRVSTR_KEY(chip, pmu)     (((chip) << 16) | (pmu))
53 /* SDIO Pad drive strength to select value mappings */
54 struct sdiod_drive_str {
55         u8 strength;    /* Pad Drive Strength in mA */
56         u8 sel;         /* Chip-specific select value */
57 };
58 /* SDIO Drive Strength to sel value table for PMU Rev 1 */
59 static const struct sdiod_drive_str sdiod_drive_strength_tab1[] = {
60         {
61         4, 0x2}, {
62         2, 0x3}, {
63         1, 0x0}, {
64         0, 0x0}
65         };
66 /* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
67 static const struct sdiod_drive_str sdiod_drive_strength_tab2[] = {
68         {
69         12, 0x7}, {
70         10, 0x6}, {
71         8, 0x5}, {
72         6, 0x4}, {
73         4, 0x2}, {
74         2, 0x1}, {
75         0, 0x0}
76         };
77 /* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
78 static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = {
79         {
80         32, 0x7}, {
81         26, 0x6}, {
82         22, 0x5}, {
83         16, 0x4}, {
84         12, 0x3}, {
85         8, 0x2}, {
86         4, 0x1}, {
87         0, 0x0}
88         };
89
90 u8
91 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid)
92 {
93         u8 idx;
94
95         for (idx = 0; idx < BRCMF_MAX_CORENUM; idx++)
96                 if (coreid == ci->c_inf[idx].id)
97                         return idx;
98
99         return BRCMF_MAX_CORENUM;
100 }
101
102 static u32
103 brcmf_sdio_chip_corerev(struct brcmf_sdio_dev *sdiodev,
104                         u32 corebase)
105 {
106         u32 regdata;
107
108         regdata = brcmf_sdcard_reg_read(sdiodev,
109                         CORE_SB(corebase, sbidhigh), 4);
110         return SBCOREREV(regdata);
111 }
112
113 static bool
114 brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev,
115                        struct chip_info *ci, u16 coreid)
116 {
117         u32 regdata;
118         u8 idx;
119
120         idx = brcmf_sdio_chip_getinfidx(ci, coreid);
121
122         regdata = brcmf_sdcard_reg_read(sdiodev,
123                         CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
124         regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
125                     SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
126         return (SSB_TMSLOW_CLOCK == regdata);
127 }
128
129 static bool
130 brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
131                        struct chip_info *ci, u16 coreid)
132 {
133         u32 regdata;
134         u8 idx;
135         bool ret;
136
137         idx = brcmf_sdio_chip_getinfidx(ci, coreid);
138
139         regdata = brcmf_sdcard_reg_read(sdiodev,
140                                         ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4);
141         ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
142
143         regdata = brcmf_sdcard_reg_read(sdiodev,
144                                         ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
145                                         4);
146         ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
147
148         return ret;
149 }
150
151 void
152 brcmf_sdio_chip_coredisable(struct brcmf_sdio_dev *sdiodev, u32 corebase)
153 {
154         u32 regdata;
155
156         regdata = brcmf_sdcard_reg_read(sdiodev,
157                 CORE_SB(corebase, sbtmstatelow), 4);
158         if (regdata & SSB_TMSLOW_RESET)
159                 return;
160
161         regdata = brcmf_sdcard_reg_read(sdiodev,
162                 CORE_SB(corebase, sbtmstatelow), 4);
163         if ((regdata & SSB_TMSLOW_CLOCK) != 0) {
164                 /*
165                  * set target reject and spin until busy is clear
166                  * (preserve core-specific bits)
167                  */
168                 regdata = brcmf_sdcard_reg_read(sdiodev,
169                         CORE_SB(corebase, sbtmstatelow), 4);
170                 brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow),
171                                        4, regdata | SSB_TMSLOW_REJECT);
172
173                 regdata = brcmf_sdcard_reg_read(sdiodev,
174                         CORE_SB(corebase, sbtmstatelow), 4);
175                 udelay(1);
176                 SPINWAIT((brcmf_sdcard_reg_read(sdiodev,
177                         CORE_SB(corebase, sbtmstatehigh), 4) &
178                         SSB_TMSHIGH_BUSY), 100000);
179
180                 regdata = brcmf_sdcard_reg_read(sdiodev,
181                         CORE_SB(corebase, sbtmstatehigh), 4);
182                 if (regdata & SSB_TMSHIGH_BUSY)
183                         brcmf_dbg(ERROR, "core state still busy\n");
184
185                 regdata = brcmf_sdcard_reg_read(sdiodev,
186                         CORE_SB(corebase, sbidlow), 4);
187                 if (regdata & SSB_IDLOW_INITIATOR) {
188                         regdata = brcmf_sdcard_reg_read(sdiodev,
189                                 CORE_SB(corebase, sbimstate), 4) |
190                                 SSB_IMSTATE_REJECT;
191                         brcmf_sdcard_reg_write(sdiodev,
192                                 CORE_SB(corebase, sbimstate), 4,
193                                 regdata);
194                         regdata = brcmf_sdcard_reg_read(sdiodev,
195                                 CORE_SB(corebase, sbimstate), 4);
196                         udelay(1);
197                         SPINWAIT((brcmf_sdcard_reg_read(sdiodev,
198                                 CORE_SB(corebase, sbimstate), 4) &
199                                 SSB_IMSTATE_BUSY), 100000);
200                 }
201
202                 /* set reset and reject while enabling the clocks */
203                 brcmf_sdcard_reg_write(sdiodev,
204                         CORE_SB(corebase, sbtmstatelow), 4,
205                         (SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
206                         SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET));
207                 regdata = brcmf_sdcard_reg_read(sdiodev,
208                         CORE_SB(corebase, sbtmstatelow), 4);
209                 udelay(10);
210
211                 /* clear the initiator reject bit */
212                 regdata = brcmf_sdcard_reg_read(sdiodev,
213                         CORE_SB(corebase, sbidlow), 4);
214                 if (regdata & SSB_IDLOW_INITIATOR) {
215                         regdata = brcmf_sdcard_reg_read(sdiodev,
216                                 CORE_SB(corebase, sbimstate), 4) &
217                                 ~SSB_IMSTATE_REJECT;
218                         brcmf_sdcard_reg_write(sdiodev,
219                                 CORE_SB(corebase, sbimstate), 4,
220                                 regdata);
221                 }
222         }
223
224         /* leave reset and reject asserted */
225         brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4,
226                 (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET));
227         udelay(1);
228 }
229
230 void
231 brcmf_sdio_chip_resetcore(struct brcmf_sdio_dev *sdiodev, u32 corebase)
232 {
233         u32 regdata;
234
235         /*
236          * Must do the disable sequence first to work for
237          * arbitrary current core state.
238          */
239         brcmf_sdio_chip_coredisable(sdiodev, corebase);
240
241         /*
242          * Now do the initialization sequence.
243          * set reset while enabling the clock and
244          * forcing them on throughout the core
245          */
246         brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4,
247                 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET);
248         udelay(1);
249
250         regdata = brcmf_sdcard_reg_read(sdiodev,
251                                         CORE_SB(corebase, sbtmstatehigh), 4);
252         if (regdata & SSB_TMSHIGH_SERR)
253                 brcmf_sdcard_reg_write(sdiodev,
254                                        CORE_SB(corebase, sbtmstatehigh), 4, 0);
255
256         regdata = brcmf_sdcard_reg_read(sdiodev,
257                                         CORE_SB(corebase, sbimstate), 4);
258         if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO))
259                 brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbimstate), 4,
260                         regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO));
261
262         /* clear reset and allow it to propagate throughout the core */
263         brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4,
264                 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK);
265         udelay(1);
266
267         /* leave clock enabled */
268         brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow),
269                                4, SSB_TMSLOW_CLOCK);
270         udelay(1);
271 }
272
273 static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
274                                        struct chip_info *ci, u32 regs)
275 {
276         u32 regdata;
277
278         /*
279          * Get CC core rev
280          * Chipid is assume to be at offset 0 from regs arg
281          * For different chiptypes or old sdio hosts w/o chipcommon,
282          * other ways of recognition should be added here.
283          */
284         ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
285         ci->c_inf[0].base = regs;
286         regdata = brcmf_sdcard_reg_read(sdiodev,
287                         CORE_CC_REG(ci->c_inf[0].base, chipid), 4);
288         ci->chip = regdata & CID_ID_MASK;
289         ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
290         ci->socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
291
292         brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev);
293
294         /* Address of cores for new chips should be added here */
295         switch (ci->chip) {
296         case BCM4329_CHIP_ID:
297                 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
298                 ci->c_inf[1].base = BCM4329_CORE_BUS_BASE;
299                 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
300                 ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE;
301                 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
302                 ci->c_inf[3].base = BCM4329_CORE_ARM_BASE;
303                 ci->ramsize = BCM4329_RAMSIZE;
304                 break;
305         default:
306                 brcmf_dbg(ERROR, "chipid 0x%x is not supported\n", ci->chip);
307                 return -ENODEV;
308         }
309
310         switch (ci->socitype) {
311         case SOCI_SB:
312                 ci->iscoreup = brcmf_sdio_sb_iscoreup;
313                 break;
314         case SOCI_AI:
315                 ci->iscoreup = brcmf_sdio_ai_iscoreup;
316                 break;
317         default:
318                 brcmf_dbg(ERROR, "socitype %u not supported\n", ci->socitype);
319                 return -ENODEV;
320         }
321
322         return 0;
323 }
324
325 static int
326 brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
327 {
328         int err = 0;
329         u8 clkval, clkset;
330
331         /* Try forcing SDIO core to do ALPAvail request only */
332         clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
333         brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
334                                SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
335         if (err) {
336                 brcmf_dbg(ERROR, "error writing for HT off\n");
337                 return err;
338         }
339
340         /* If register supported, wait for ALPAvail and then force ALP */
341         /* This may take up to 15 milliseconds */
342         clkval = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_1,
343                                        SBSDIO_FUNC1_CHIPCLKCSR, NULL);
344
345         if ((clkval & ~SBSDIO_AVBITS) != clkset) {
346                 brcmf_dbg(ERROR, "ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
347                           clkset, clkval);
348                 return -EACCES;
349         }
350
351         SPINWAIT(((clkval = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_1,
352                                 SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
353                         !SBSDIO_ALPAV(clkval)),
354                         PMU_MAX_TRANSITION_DLY);
355         if (!SBSDIO_ALPAV(clkval)) {
356                 brcmf_dbg(ERROR, "timeout on ALPAV wait, clkval 0x%02x\n",
357                           clkval);
358                 return -EBUSY;
359         }
360
361         clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
362         brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
363                                SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
364         udelay(65);
365
366         /* Also, disable the extra SDIO pull-ups */
367         brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
368                                SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
369
370         return 0;
371 }
372
373 static void
374 brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
375                              struct chip_info *ci)
376 {
377         u32 regdata;
378         u8 idx;
379
380         /* get chipcommon rev */
381         ci->c_inf[0].rev =
382                 brcmf_sdio_chip_corerev(sdiodev, ci->c_inf[0].base);
383
384         /* get chipcommon capabilites */
385         ci->c_inf[0].caps =
386                 brcmf_sdcard_reg_read(sdiodev,
387                 CORE_CC_REG(ci->c_inf[0].base, capabilities), 4);
388
389         /* get pmu caps & rev */
390         if (ci->c_inf[0].caps & CC_CAP_PMU) {
391                 ci->pmucaps = brcmf_sdcard_reg_read(sdiodev,
392                         CORE_CC_REG(ci->c_inf[0].base, pmucapabilities), 4);
393                 ci->pmurev = ci->pmucaps & PCAP_REV_MASK;
394         }
395
396         ci->c_inf[1].rev = brcmf_sdio_chip_corerev(sdiodev, ci->c_inf[1].base);
397         regdata = brcmf_sdcard_reg_read(sdiodev,
398                                 CORE_SB(ci->c_inf[1].base, sbidhigh), 4);
399         ci->c_inf[1].id = (regdata & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT;
400
401         brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
402                   ci->c_inf[0].rev, ci->pmurev,
403                   ci->c_inf[1].rev, ci->c_inf[1].id);
404
405         /*
406          * Make sure any on-chip ARM is off (in case strapping is wrong),
407          * or downloaded code was already running.
408          */
409         idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
410         brcmf_sdio_chip_coredisable(sdiodev, ci->c_inf[idx].base);
411 }
412
413 int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
414                            struct chip_info **ci_ptr, u32 regs)
415 {
416         int ret;
417         struct chip_info *ci;
418
419         brcmf_dbg(TRACE, "Enter\n");
420
421         /* alloc chip_info_t */
422         ci = kzalloc(sizeof(struct chip_info), GFP_ATOMIC);
423         if (!ci)
424                 return -ENOMEM;
425
426         ret = brcmf_sdio_chip_buscoreprep(sdiodev);
427         if (ret != 0)
428                 goto err;
429
430         ret = brcmf_sdio_chip_recognition(sdiodev, ci, regs);
431         if (ret != 0)
432                 goto err;
433
434         brcmf_sdio_chip_buscoresetup(sdiodev, ci);
435
436         brcmf_sdcard_reg_write(sdiodev,
437                 CORE_CC_REG(ci->c_inf[0].base, gpiopullup), 4, 0);
438         brcmf_sdcard_reg_write(sdiodev,
439                 CORE_CC_REG(ci->c_inf[0].base, gpiopulldown), 4, 0);
440
441         *ci_ptr = ci;
442         return 0;
443
444 err:
445         kfree(ci);
446         return ret;
447 }
448
449 void
450 brcmf_sdio_chip_detach(struct chip_info **ci_ptr)
451 {
452         brcmf_dbg(TRACE, "Enter\n");
453
454         kfree(*ci_ptr);
455         *ci_ptr = NULL;
456 }
457
458 static char *brcmf_sdio_chip_name(uint chipid, char *buf, uint len)
459 {
460         const char *fmt;
461
462         fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
463         snprintf(buf, len, fmt, chipid);
464         return buf;
465 }
466
467 void
468 brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
469                                   struct chip_info *ci, u32 drivestrength)
470 {
471         struct sdiod_drive_str *str_tab = NULL;
472         u32 str_mask = 0;
473         u32 str_shift = 0;
474         char chn[8];
475
476         if (!(ci->c_inf[0].caps & CC_CAP_PMU))
477                 return;
478
479         switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
480         case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1):
481                 str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab1;
482                 str_mask = 0x30000000;
483                 str_shift = 28;
484                 break;
485         case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2):
486         case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3):
487                 str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab2;
488                 str_mask = 0x00003800;
489                 str_shift = 11;
490                 break;
491         case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8):
492                 str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab3;
493                 str_mask = 0x00003800;
494                 str_shift = 11;
495                 break;
496         default:
497                 brcmf_dbg(ERROR, "No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
498                           brcmf_sdio_chip_name(ci->chip, chn, 8),
499                           ci->chiprev, ci->pmurev);
500                 break;
501         }
502
503         if (str_tab != NULL) {
504                 u32 drivestrength_sel = 0;
505                 u32 cc_data_temp;
506                 int i;
507
508                 for (i = 0; str_tab[i].strength != 0; i++) {
509                         if (drivestrength >= str_tab[i].strength) {
510                                 drivestrength_sel = str_tab[i].sel;
511                                 break;
512                         }
513                 }
514
515                 brcmf_sdcard_reg_write(sdiodev,
516                         CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr),
517                         4, 1);
518                 cc_data_temp = brcmf_sdcard_reg_read(sdiodev,
519                         CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr), 4);
520                 cc_data_temp &= ~str_mask;
521                 drivestrength_sel <<= str_shift;
522                 cc_data_temp |= drivestrength_sel;
523                 brcmf_sdcard_reg_write(sdiodev,
524                         CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr),
525                         4, cc_data_temp);
526
527                 brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n",
528                           drivestrength, cc_data_temp);
529         }
530 }