brcmsmac: remove pcicore_hwup()
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / brcm80211 / brcmsmac / nicpci.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/slab.h>
18 #include <linux/delay.h>
19 #include <linux/pci.h>
20
21 #include <defs.h>
22 #include <soc.h>
23 #include <chipcommon.h>
24 #include "aiutils.h"
25 #include "pub.h"
26 #include "nicpci.h"
27
28 /* SPROM offsets */
29 #define SRSH_ASPM_OFFSET                4       /* word 4 */
30 #define SRSH_ASPM_ENB                   0x18    /* bit 3, 4 */
31 #define SRSH_ASPM_L1_ENB                0x10    /* bit 4 */
32 #define SRSH_ASPM_L0s_ENB               0x8     /* bit 3 */
33
34 #define SRSH_PCIE_MISC_CONFIG           5       /* word 5 */
35 #define SRSH_L23READY_EXIT_NOPERST      0x8000  /* bit 15 */
36 #define SRSH_CLKREQ_OFFSET_REV5         20      /* word 20 for srom rev <= 5 */
37 #define SRSH_CLKREQ_ENB                 0x0800  /* bit 11 */
38 #define SRSH_BD_OFFSET                  6       /* word 6 */
39
40 /* chipcontrol */
41 #define CHIPCTRL_4321_PLL_DOWN          0x800000/* serdes PLL down override */
42
43 /* MDIO control */
44 #define MDIOCTL_DIVISOR_MASK            0x7f    /* clock to be used on MDIO */
45 #define MDIOCTL_DIVISOR_VAL             0x2
46 #define MDIOCTL_PREAM_EN                0x80    /* Enable preamble sequnce */
47 #define MDIOCTL_ACCESS_DONE             0x100   /* Transaction complete */
48
49 /* MDIO Data */
50 #define MDIODATA_MASK                   0x0000ffff      /* data 2 bytes */
51 #define MDIODATA_TA                     0x00020000      /* Turnaround */
52
53 #define MDIODATA_REGADDR_SHF            18              /* Regaddr shift */
54 #define MDIODATA_REGADDR_MASK           0x007c0000      /* Regaddr Mask */
55 #define MDIODATA_DEVADDR_SHF            23      /* Physmedia devaddr shift */
56 #define MDIODATA_DEVADDR_MASK           0x0f800000
57                                                 /* Physmedia devaddr Mask */
58
59 /* MDIO Data for older revisions < 10 */
60 #define MDIODATA_REGADDR_SHF_OLD        18      /* Regaddr shift */
61 #define MDIODATA_REGADDR_MASK_OLD       0x003c0000
62                                                 /* Regaddr Mask */
63 #define MDIODATA_DEVADDR_SHF_OLD        22      /* Physmedia devaddr shift  */
64 #define MDIODATA_DEVADDR_MASK_OLD       0x0fc00000
65                                                 /* Physmedia devaddr Mask */
66
67 /* Transactions flags */
68 #define MDIODATA_WRITE                  0x10000000
69 #define MDIODATA_READ                   0x20000000
70 #define MDIODATA_START                  0x40000000
71
72 #define MDIODATA_DEV_ADDR               0x0     /* dev address for serdes */
73 #define MDIODATA_BLK_ADDR               0x1F    /* blk address for serdes */
74
75 /* serdes regs (rev < 10) */
76 #define MDIODATA_DEV_PLL                0x1d    /* SERDES PLL Dev */
77 #define MDIODATA_DEV_TX                 0x1e    /* SERDES TX Dev */
78 #define MDIODATA_DEV_RX                 0x1f    /* SERDES RX Dev */
79
80 /* SERDES RX registers */
81 #define SERDES_RX_CTRL                  1       /* Rx cntrl */
82 #define SERDES_RX_TIMER1                2       /* Rx Timer1 */
83 #define SERDES_RX_CDR                   6       /* CDR */
84 #define SERDES_RX_CDRBW                 7       /* CDR BW */
85 /* SERDES RX control register */
86 #define SERDES_RX_CTRL_FORCE            0x80    /* rxpolarity_force */
87 #define SERDES_RX_CTRL_POLARITY         0x40    /* rxpolarity_value */
88
89 /* SERDES PLL registers */
90 #define SERDES_PLL_CTRL                 1       /* PLL control reg */
91 #define PLL_CTRL_FREQDET_EN             0x4000  /* bit 14 is FREQDET on */
92
93 /* Linkcontrol reg offset in PCIE Cap */
94 #define PCIE_CAP_LINKCTRL_OFFSET        16      /* offset in pcie cap */
95 #define PCIE_CAP_LCREG_ASPML0s          0x01    /* ASPM L0s in linkctrl */
96 #define PCIE_CAP_LCREG_ASPML1           0x02    /* ASPM L1 in linkctrl */
97 #define PCIE_CLKREQ_ENAB                0x100   /* CLKREQ Enab in linkctrl */
98
99 #define PCIE_ASPM_ENAB                  3       /* ASPM L0s & L1 in linkctrl */
100 #define PCIE_ASPM_L1_ENAB               2       /* ASPM L0s & L1 in linkctrl */
101 #define PCIE_ASPM_L0s_ENAB              1       /* ASPM L0s & L1 in linkctrl */
102 #define PCIE_ASPM_DISAB                 0       /* ASPM L0s & L1 in linkctrl */
103
104 /* Power management threshold */
105 #define PCIE_L1THRESHOLDTIME_MASK       0xFF00  /* bits 8 - 15 */
106 #define PCIE_L1THRESHOLDTIME_SHIFT      8       /* PCIE_L1THRESHOLDTIME_SHIFT */
107 #define PCIE_L1THRESHOLD_WARVAL         0x72    /* WAR value */
108 #define PCIE_ASPMTIMER_EXTEND           0x01000000
109                                                 /* > rev7:
110                                                  * enable extend ASPM timer
111                                                  */
112
113 /* different register spaces to access thru pcie indirect access */
114 #define PCIE_CONFIGREGS         1       /* Access to config space */
115 #define PCIE_PCIEREGS           2       /* Access to pcie registers */
116
117 /* PCIE protocol PHY diagnostic registers */
118 #define PCIE_PLP_STATUSREG              0x204   /* Status */
119
120 /* Status reg PCIE_PLP_STATUSREG */
121 #define PCIE_PLP_POLARITYINV_STAT       0x10
122
123 /* PCIE protocol DLLP diagnostic registers */
124 #define PCIE_DLLP_LCREG                 0x100   /* Link Control */
125 #define PCIE_DLLP_PMTHRESHREG           0x128   /* Power Management Threshold */
126
127 /* PCIE protocol TLP diagnostic registers */
128 #define PCIE_TLP_WORKAROUNDSREG         0x004   /* TLP Workarounds */
129
130 /* Sonics to PCI translation types */
131 #define SBTOPCI_PREF    0x4             /* prefetch enable */
132 #define SBTOPCI_BURST   0x8             /* burst enable */
133 #define SBTOPCI_RC_READMULTI    0x20    /* memory read multiple */
134
135 #define PCI_CLKRUN_DSBL 0x8000  /* Bit 15 forceClkrun */
136
137 /* PCI core index in SROM shadow area */
138 #define SRSH_PI_OFFSET  0       /* first word */
139 #define SRSH_PI_MASK    0xf000  /* bit 15:12 */
140 #define SRSH_PI_SHIFT   12      /* bit 15:12 */
141
142 #define PCIREGOFFS(field)       offsetof(struct sbpciregs, field)
143 #define PCIEREGOFFS(field)      offsetof(struct sbpcieregs, field)
144
145 /* Sonics side: PCI core and host control registers */
146 struct sbpciregs {
147         u32 control;            /* PCI control */
148         u32 PAD[3];
149         u32 arbcontrol;         /* PCI arbiter control */
150         u32 clkrun;             /* Clkrun Control (>=rev11) */
151         u32 PAD[2];
152         u32 intstatus;          /* Interrupt status */
153         u32 intmask;            /* Interrupt mask */
154         u32 sbtopcimailbox;     /* Sonics to PCI mailbox */
155         u32 PAD[9];
156         u32 bcastaddr;          /* Sonics broadcast address */
157         u32 bcastdata;          /* Sonics broadcast data */
158         u32 PAD[2];
159         u32 gpioin;             /* ro: gpio input (>=rev2) */
160         u32 gpioout;            /* rw: gpio output (>=rev2) */
161         u32 gpioouten;          /* rw: gpio output enable (>= rev2) */
162         u32 gpiocontrol;        /* rw: gpio control (>= rev2) */
163         u32 PAD[36];
164         u32 sbtopci0;           /* Sonics to PCI translation 0 */
165         u32 sbtopci1;           /* Sonics to PCI translation 1 */
166         u32 sbtopci2;           /* Sonics to PCI translation 2 */
167         u32 PAD[189];
168         u32 pcicfg[4][64];      /* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */
169         u16 sprom[36];          /* SPROM shadow Area */
170         u32 PAD[46];
171 };
172
173 /* SB side: PCIE core and host control registers */
174 struct sbpcieregs {
175         u32 control;            /* host mode only */
176         u32 PAD[2];
177         u32 biststatus;         /* bist Status: 0x00C */
178         u32 gpiosel;            /* PCIE gpio sel: 0x010 */
179         u32 gpioouten;          /* PCIE gpio outen: 0x14 */
180         u32 PAD[2];
181         u32 intstatus;          /* Interrupt status: 0x20 */
182         u32 intmask;            /* Interrupt mask: 0x24 */
183         u32 sbtopcimailbox;     /* sb to pcie mailbox: 0x028 */
184         u32 PAD[53];
185         u32 sbtopcie0;          /* sb to pcie translation 0: 0x100 */
186         u32 sbtopcie1;          /* sb to pcie translation 1: 0x104 */
187         u32 sbtopcie2;          /* sb to pcie translation 2: 0x108 */
188         u32 PAD[5];
189
190         /* pcie core supports in direct access to config space */
191         u32 configaddr; /* pcie config space access: Address field: 0x120 */
192         u32 configdata; /* pcie config space access: Data field: 0x124 */
193
194         /* mdio access to serdes */
195         u32 mdiocontrol;        /* controls the mdio access: 0x128 */
196         u32 mdiodata;           /* Data to the mdio access: 0x12c */
197
198         /* pcie protocol phy/dllp/tlp register indirect access mechanism */
199         u32 pcieindaddr;        /* indirect access to
200                                  * the internal register: 0x130
201                                  */
202         u32 pcieinddata;        /* Data to/from the internal regsiter: 0x134 */
203
204         u32 clkreqenctrl;       /* >= rev 6, Clkreq rdma control : 0x138 */
205         u32 PAD[177];
206         u32 pciecfg[4][64];     /* 0x400 - 0x7FF, PCIE Cfg Space */
207         u16 sprom[64];          /* SPROM shadow Area */
208 };
209
210 struct pcicore_info {
211         struct bcma_device *core;
212         struct si_pub *sih;     /* System interconnect handle */
213         struct pci_dev *dev;
214         u8 pcie_polarity;
215
216         u8 pmecap_offset;       /* PM Capability offset in the config space */
217         bool pmecap;            /* Capable of generating PME */
218 };
219
220 /* delay needed between the mdio control/ mdiodata register data access */
221 static void pr28829_delay(void)
222 {
223         udelay(10);
224 }
225
226 /* Initialize the PCI core.
227  * It's caller's responsibility to make sure that this is done only once
228  */
229 struct pcicore_info *pcicore_init(struct si_pub *sih, struct bcma_device *core)
230 {
231         struct pcicore_info *pi;
232
233         /* alloc struct pcicore_info */
234         pi = kzalloc(sizeof(struct pcicore_info), GFP_ATOMIC);
235         if (pi == NULL)
236                 return NULL;
237
238         pi->sih = sih;
239         pi->dev = core->bus->host_pci;
240         pi->core = core;
241
242         return pi;
243 }
244
245 void pcicore_deinit(struct pcicore_info *pch)
246 {
247         kfree(pch);
248 }
249
250 /* return cap_offset if requested capability exists in the PCI config space */
251 /* Note that it's caller's responsibility to make sure it's a pci bus */
252 u8
253 pcicore_find_pci_capability(struct pci_dev *dev, u8 req_cap_id,
254                             unsigned char *buf, u32 *buflen)
255 {
256         u8 cap_id;
257         u8 cap_ptr = 0;
258         u32 bufsize;
259         u8 byte_val;
260
261         /* check for Header type 0 */
262         pci_read_config_byte(dev, PCI_HEADER_TYPE, &byte_val);
263         if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
264                 goto end;
265
266         /* check if the capability pointer field exists */
267         pci_read_config_byte(dev, PCI_STATUS, &byte_val);
268         if (!(byte_val & PCI_STATUS_CAP_LIST))
269                 goto end;
270
271         pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &cap_ptr);
272         /* check if the capability pointer is 0x00 */
273         if (cap_ptr == 0x00)
274                 goto end;
275
276         /* loop thru the capability list
277          * and see if the pcie capability exists
278          */
279
280         pci_read_config_byte(dev, cap_ptr, &cap_id);
281
282         while (cap_id != req_cap_id) {
283                 pci_read_config_byte(dev, cap_ptr + 1, &cap_ptr);
284                 if (cap_ptr == 0x00)
285                         break;
286                 pci_read_config_byte(dev, cap_ptr, &cap_id);
287         }
288         if (cap_id != req_cap_id)
289                 goto end;
290
291         /* found the caller requested capability */
292         if (buf != NULL && buflen != NULL) {
293                 u8 cap_data;
294
295                 bufsize = *buflen;
296                 if (!bufsize)
297                         goto end;
298                 *buflen = 0;
299                 /* copy the capability data excluding cap ID and next ptr */
300                 cap_data = cap_ptr + 2;
301                 if ((bufsize + cap_data) > PCI_SZPCR)
302                         bufsize = PCI_SZPCR - cap_data;
303                 *buflen = bufsize;
304                 while (bufsize--) {
305                         pci_read_config_byte(dev, cap_data, buf);
306                         cap_data++;
307                         buf++;
308                 }
309         }
310 end:
311         return cap_ptr;
312 }
313
314 /* ***** Register Access API */
315 static uint
316 pcie_readreg(struct bcma_device *core, uint addrtype, uint offset)
317 {
318         uint retval = 0xFFFFFFFF;
319
320         switch (addrtype) {
321         case PCIE_CONFIGREGS:
322                 bcma_write32(core, PCIEREGOFFS(configaddr), offset);
323                 (void)bcma_read32(core, PCIEREGOFFS(configaddr));
324                 retval = bcma_read32(core, PCIEREGOFFS(configdata));
325                 break;
326         case PCIE_PCIEREGS:
327                 bcma_write32(core, PCIEREGOFFS(pcieindaddr), offset);
328                 (void)bcma_read32(core, PCIEREGOFFS(pcieindaddr));
329                 retval = bcma_read32(core, PCIEREGOFFS(pcieinddata));
330                 break;
331         }
332
333         return retval;
334 }
335
336 static uint pcie_writereg(struct bcma_device *core, uint addrtype,
337                           uint offset, uint val)
338 {
339         switch (addrtype) {
340         case PCIE_CONFIGREGS:
341                 bcma_write32(core, PCIEREGOFFS(configaddr), offset);
342                 bcma_write32(core, PCIEREGOFFS(configdata), val);
343                 break;
344         case PCIE_PCIEREGS:
345                 bcma_write32(core, PCIEREGOFFS(pcieindaddr), offset);
346                 bcma_write32(core, PCIEREGOFFS(pcieinddata), val);
347                 break;
348         default:
349                 break;
350         }
351         return 0;
352 }
353
354 static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk)
355 {
356         uint mdiodata, i = 0;
357         uint pcie_serdes_spinwait = 200;
358
359         mdiodata = (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
360                     (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
361                     (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) |
362                     (blk << 4));
363         bcma_write32(pi->core, PCIEREGOFFS(mdiodata), mdiodata);
364
365         pr28829_delay();
366         /* retry till the transaction is complete */
367         while (i < pcie_serdes_spinwait) {
368                 if (bcma_read32(pi->core, PCIEREGOFFS(mdiocontrol)) &
369                     MDIOCTL_ACCESS_DONE)
370                         break;
371
372                 udelay(1000);
373                 i++;
374         }
375
376         if (i >= pcie_serdes_spinwait)
377                 return false;
378
379         return true;
380 }
381
382 static int
383 pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write,
384             uint *val)
385 {
386         uint mdiodata;
387         uint i = 0;
388         uint pcie_serdes_spinwait = 10;
389
390         /* enable mdio access to SERDES */
391         bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol),
392                      MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
393
394         /* new serdes is slower in rw,
395          * using two layers of reg address mapping
396          */
397         if (!pcie_mdiosetblock(pi, physmedia))
398                 return 1;
399         mdiodata = ((MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
400                     (regaddr << MDIODATA_REGADDR_SHF));
401         pcie_serdes_spinwait *= 20;
402
403         if (!write)
404                 mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA);
405         else
406                 mdiodata |= (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
407                              *val);
408
409         bcma_write32(pi->core, PCIEREGOFFS(mdiodata), mdiodata);
410
411         pr28829_delay();
412
413         /* retry till the transaction is complete */
414         while (i < pcie_serdes_spinwait) {
415                 if (bcma_read32(pi->core, PCIEREGOFFS(mdiocontrol)) &
416                     MDIOCTL_ACCESS_DONE) {
417                         if (!write) {
418                                 pr28829_delay();
419                                 *val = (bcma_read32(pi->core,
420                                                     PCIEREGOFFS(mdiodata)) &
421                                         MDIODATA_MASK);
422                         }
423                         /* Disable mdio access to SERDES */
424                         bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
425                         return 0;
426                 }
427                 udelay(1000);
428                 i++;
429         }
430
431         /* Timed out. Disable mdio access to SERDES. */
432         bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
433         return 1;
434 }
435
436 /* use the mdio interface to read from mdio slaves */
437 static int
438 pcie_mdioread(struct pcicore_info *pi, uint physmedia, uint regaddr,
439               uint *regval)
440 {
441         return pcie_mdioop(pi, physmedia, regaddr, false, regval);
442 }
443
444 /* use the mdio interface to write to mdio slaves */
445 static int
446 pcie_mdiowrite(struct pcicore_info *pi, uint physmedia, uint regaddr, uint val)
447 {
448         return pcie_mdioop(pi, physmedia, regaddr, true, &val);
449 }
450
451 /* ***** Support functions ***** */
452 static void pcie_extendL1timer(struct pcicore_info *pi, bool extend)
453 {
454         u32 w;
455
456         w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
457         if (extend)
458                 w |= PCIE_ASPMTIMER_EXTEND;
459         else
460                 w &= ~PCIE_ASPMTIMER_EXTEND;
461         pcie_writereg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
462         w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
463 }
464
465 /* ***** PCI core WARs ***** */
466 /* Done only once at attach time */
467 static void pcie_war_polarity(struct pcicore_info *pi)
468 {
469         u32 w;
470
471         if (pi->pcie_polarity != 0)
472                 return;
473
474         w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_PLP_STATUSREG);
475
476         /* Detect the current polarity at attach and force that polarity and
477          * disable changing the polarity
478          */
479         if ((w & PCIE_PLP_POLARITYINV_STAT) == 0)
480                 pi->pcie_polarity = SERDES_RX_CTRL_FORCE;
481         else
482                 pi->pcie_polarity = (SERDES_RX_CTRL_FORCE |
483                                      SERDES_RX_CTRL_POLARITY);
484 }
485
486 /* Apply the polarity determined at the start */
487 /* Needs to happen when coming out of 'standby'/'hibernate' */
488 static void pcie_war_serdes(struct pcicore_info *pi)
489 {
490         u32 w = 0;
491
492         if (pi->pcie_polarity != 0)
493                 pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CTRL,
494                                pi->pcie_polarity);
495
496         pcie_mdioread(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, &w);
497         if (w & PLL_CTRL_FREQDET_EN) {
498                 w &= ~PLL_CTRL_FREQDET_EN;
499                 pcie_mdiowrite(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, w);
500         }
501 }
502
503 /* ***** Functions called during driver state changes ***** */
504 void pcicore_attach(struct pcicore_info *pi, int state)
505 {
506         /* These need to happen in this order only */
507         pcie_war_polarity(pi);
508
509         pcie_war_serdes(pi);
510 }
511
512 void pcicore_up(struct pcicore_info *pi, int state)
513 {
514         if (!pi || ai_get_buscoretype(pi->sih) != PCIE_CORE_ID)
515                 return;
516
517         /* Restore L1 timer for better performance */
518         pcie_extendL1timer(pi, true);
519 }
520
521 void pcicore_down(struct pcicore_info *pi, int state)
522 {
523         if (!pi || ai_get_buscoretype(pi->sih) != PCIE_CORE_ID)
524                 return;
525
526         /* Reduce L1 timer for better power savings */
527         pcie_extendL1timer(pi, false);
528 }
529
530 void pcicore_fixcfg(struct pcicore_info *pi)
531 {
532         struct bcma_device *core = pi->core;
533         u16 val16;
534         uint regoff;
535
536         regoff = PCIEREGOFFS(sprom[SRSH_PI_OFFSET]);
537
538         val16 = bcma_read16(pi->core, regoff);
539         if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) !=
540             (u16)core->core_index) {
541                 val16 = ((u16)core->core_index << SRSH_PI_SHIFT) |
542                         (val16 & ~SRSH_PI_MASK);
543                 bcma_write16(pi->core, regoff, val16);
544         }
545 }