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 pciecap_lcreg_offset;/* PCIE capability LCreg offset
215 				 * in the config space
216 				 */
217 	bool pcie_pr42767;
218 	u8 pcie_polarity;
219 	u8 pcie_war_aspm_ovr;	/* Override ASPM/Clkreq settings */
220 
221 	u8 pmecap_offset;	/* PM Capability offset in the config space */
222 	bool pmecap;		/* Capable of generating PME */
223 };
224 
225 #define PCIE_ASPM(sih)							\
226 	((ai_get_buscoretype(sih) == PCIE_CORE_ID) &&			\
227 	 ((ai_get_buscorerev(sih) >= 3) &&				\
228 	  (ai_get_buscorerev(sih) <= 5)))
229 
230 
231 /* delay needed between the mdio control/ mdiodata register data access */
pr28829_delay(void)232 static void pr28829_delay(void)
233 {
234 	udelay(10);
235 }
236 
237 /* Initialize the PCI core.
238  * It's caller's responsibility to make sure that this is done only once
239  */
pcicore_init(struct si_pub * sih,struct bcma_device * core)240 struct pcicore_info *pcicore_init(struct si_pub *sih, struct bcma_device *core)
241 {
242 	struct pcicore_info *pi;
243 
244 	/* alloc struct pcicore_info */
245 	pi = kzalloc(sizeof(struct pcicore_info), GFP_ATOMIC);
246 	if (pi == NULL)
247 		return NULL;
248 
249 	pi->sih = sih;
250 	pi->dev = core->bus->host_pci;
251 	pi->core = core;
252 
253 	if (core->id.id == PCIE_CORE_ID) {
254 		u8 cap_ptr;
255 		cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_EXP,
256 						      NULL, NULL);
257 		pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET;
258 	}
259 	return pi;
260 }
261 
pcicore_deinit(struct pcicore_info * pch)262 void pcicore_deinit(struct pcicore_info *pch)
263 {
264 	kfree(pch);
265 }
266 
267 /* return cap_offset if requested capability exists in the PCI config space */
268 /* Note that it's caller's responsibility to make sure it's a pci bus */
269 u8
pcicore_find_pci_capability(struct pci_dev * dev,u8 req_cap_id,unsigned char * buf,u32 * buflen)270 pcicore_find_pci_capability(struct pci_dev *dev, u8 req_cap_id,
271 			    unsigned char *buf, u32 *buflen)
272 {
273 	u8 cap_id;
274 	u8 cap_ptr = 0;
275 	u32 bufsize;
276 	u8 byte_val;
277 
278 	/* check for Header type 0 */
279 	pci_read_config_byte(dev, PCI_HEADER_TYPE, &byte_val);
280 	if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
281 		goto end;
282 
283 	/* check if the capability pointer field exists */
284 	pci_read_config_byte(dev, PCI_STATUS, &byte_val);
285 	if (!(byte_val & PCI_STATUS_CAP_LIST))
286 		goto end;
287 
288 	pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &cap_ptr);
289 	/* check if the capability pointer is 0x00 */
290 	if (cap_ptr == 0x00)
291 		goto end;
292 
293 	/* loop thru the capability list
294 	 * and see if the pcie capability exists
295 	 */
296 
297 	pci_read_config_byte(dev, cap_ptr, &cap_id);
298 
299 	while (cap_id != req_cap_id) {
300 		pci_read_config_byte(dev, cap_ptr + 1, &cap_ptr);
301 		if (cap_ptr == 0x00)
302 			break;
303 		pci_read_config_byte(dev, cap_ptr, &cap_id);
304 	}
305 	if (cap_id != req_cap_id)
306 		goto end;
307 
308 	/* found the caller requested capability */
309 	if (buf != NULL && buflen != NULL) {
310 		u8 cap_data;
311 
312 		bufsize = *buflen;
313 		if (!bufsize)
314 			goto end;
315 		*buflen = 0;
316 		/* copy the capability data excluding cap ID and next ptr */
317 		cap_data = cap_ptr + 2;
318 		if ((bufsize + cap_data) > PCI_SZPCR)
319 			bufsize = PCI_SZPCR - cap_data;
320 		*buflen = bufsize;
321 		while (bufsize--) {
322 			pci_read_config_byte(dev, cap_data, buf);
323 			cap_data++;
324 			buf++;
325 		}
326 	}
327 end:
328 	return cap_ptr;
329 }
330 
331 /* ***** Register Access API */
332 static uint
pcie_readreg(struct bcma_device * core,uint addrtype,uint offset)333 pcie_readreg(struct bcma_device *core, uint addrtype, uint offset)
334 {
335 	uint retval = 0xFFFFFFFF;
336 
337 	switch (addrtype) {
338 	case PCIE_CONFIGREGS:
339 		bcma_write32(core, PCIEREGOFFS(configaddr), offset);
340 		(void)bcma_read32(core, PCIEREGOFFS(configaddr));
341 		retval = bcma_read32(core, PCIEREGOFFS(configdata));
342 		break;
343 	case PCIE_PCIEREGS:
344 		bcma_write32(core, PCIEREGOFFS(pcieindaddr), offset);
345 		(void)bcma_read32(core, PCIEREGOFFS(pcieindaddr));
346 		retval = bcma_read32(core, PCIEREGOFFS(pcieinddata));
347 		break;
348 	}
349 
350 	return retval;
351 }
352 
pcie_writereg(struct bcma_device * core,uint addrtype,uint offset,uint val)353 static uint pcie_writereg(struct bcma_device *core, uint addrtype,
354 			  uint offset, uint val)
355 {
356 	switch (addrtype) {
357 	case PCIE_CONFIGREGS:
358 		bcma_write32(core, PCIEREGOFFS(configaddr), offset);
359 		bcma_write32(core, PCIEREGOFFS(configdata), val);
360 		break;
361 	case PCIE_PCIEREGS:
362 		bcma_write32(core, PCIEREGOFFS(pcieindaddr), offset);
363 		bcma_write32(core, PCIEREGOFFS(pcieinddata), val);
364 		break;
365 	default:
366 		break;
367 	}
368 	return 0;
369 }
370 
pcie_mdiosetblock(struct pcicore_info * pi,uint blk)371 static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk)
372 {
373 	uint mdiodata, i = 0;
374 	uint pcie_serdes_spinwait = 200;
375 
376 	mdiodata = (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
377 		    (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
378 		    (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) |
379 		    (blk << 4));
380 	bcma_write32(pi->core, PCIEREGOFFS(mdiodata), mdiodata);
381 
382 	pr28829_delay();
383 	/* retry till the transaction is complete */
384 	while (i < pcie_serdes_spinwait) {
385 		if (bcma_read32(pi->core, PCIEREGOFFS(mdiocontrol)) &
386 		    MDIOCTL_ACCESS_DONE)
387 			break;
388 
389 		udelay(1000);
390 		i++;
391 	}
392 
393 	if (i >= pcie_serdes_spinwait)
394 		return false;
395 
396 	return true;
397 }
398 
399 static int
pcie_mdioop(struct pcicore_info * pi,uint physmedia,uint regaddr,bool write,uint * val)400 pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write,
401 	    uint *val)
402 {
403 	uint mdiodata;
404 	uint i = 0;
405 	uint pcie_serdes_spinwait = 10;
406 
407 	/* enable mdio access to SERDES */
408 	bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol),
409 		     MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
410 
411 	if (ai_get_buscorerev(pi->sih) >= 10) {
412 		/* new serdes is slower in rw,
413 		 * using two layers of reg address mapping
414 		 */
415 		if (!pcie_mdiosetblock(pi, physmedia))
416 			return 1;
417 		mdiodata = ((MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
418 			    (regaddr << MDIODATA_REGADDR_SHF));
419 		pcie_serdes_spinwait *= 20;
420 	} else {
421 		mdiodata = ((physmedia << MDIODATA_DEVADDR_SHF_OLD) |
422 			    (regaddr << MDIODATA_REGADDR_SHF_OLD));
423 	}
424 
425 	if (!write)
426 		mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA);
427 	else
428 		mdiodata |= (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
429 			     *val);
430 
431 	bcma_write32(pi->core, PCIEREGOFFS(mdiodata), mdiodata);
432 
433 	pr28829_delay();
434 
435 	/* retry till the transaction is complete */
436 	while (i < pcie_serdes_spinwait) {
437 		if (bcma_read32(pi->core, PCIEREGOFFS(mdiocontrol)) &
438 		    MDIOCTL_ACCESS_DONE) {
439 			if (!write) {
440 				pr28829_delay();
441 				*val = (bcma_read32(pi->core,
442 						    PCIEREGOFFS(mdiodata)) &
443 					MDIODATA_MASK);
444 			}
445 			/* Disable mdio access to SERDES */
446 			bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
447 			return 0;
448 		}
449 		udelay(1000);
450 		i++;
451 	}
452 
453 	/* Timed out. Disable mdio access to SERDES. */
454 	bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
455 	return 1;
456 }
457 
458 /* use the mdio interface to read from mdio slaves */
459 static int
pcie_mdioread(struct pcicore_info * pi,uint physmedia,uint regaddr,uint * regval)460 pcie_mdioread(struct pcicore_info *pi, uint physmedia, uint regaddr,
461 	      uint *regval)
462 {
463 	return pcie_mdioop(pi, physmedia, regaddr, false, regval);
464 }
465 
466 /* use the mdio interface to write to mdio slaves */
467 static int
pcie_mdiowrite(struct pcicore_info * pi,uint physmedia,uint regaddr,uint val)468 pcie_mdiowrite(struct pcicore_info *pi, uint physmedia, uint regaddr, uint val)
469 {
470 	return pcie_mdioop(pi, physmedia, regaddr, true, &val);
471 }
472 
473 /* ***** Support functions ***** */
pcie_clkreq(struct pcicore_info * pi,u32 mask,u32 val)474 static u8 pcie_clkreq(struct pcicore_info *pi, u32 mask, u32 val)
475 {
476 	u32 reg_val;
477 	u8 offset;
478 
479 	offset = pi->pciecap_lcreg_offset;
480 	if (!offset)
481 		return 0;
482 
483 	pci_read_config_dword(pi->dev, offset, &reg_val);
484 	/* set operation */
485 	if (mask) {
486 		if (val)
487 			reg_val |= PCIE_CLKREQ_ENAB;
488 		else
489 			reg_val &= ~PCIE_CLKREQ_ENAB;
490 		pci_write_config_dword(pi->dev, offset, reg_val);
491 		pci_read_config_dword(pi->dev, offset, &reg_val);
492 	}
493 	if (reg_val & PCIE_CLKREQ_ENAB)
494 		return 1;
495 	else
496 		return 0;
497 }
498 
pcie_extendL1timer(struct pcicore_info * pi,bool extend)499 static void pcie_extendL1timer(struct pcicore_info *pi, bool extend)
500 {
501 	u32 w;
502 	struct si_pub *sih = pi->sih;
503 
504 	if (ai_get_buscoretype(sih) != PCIE_CORE_ID ||
505 	    ai_get_buscorerev(sih) < 7)
506 		return;
507 
508 	w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
509 	if (extend)
510 		w |= PCIE_ASPMTIMER_EXTEND;
511 	else
512 		w &= ~PCIE_ASPMTIMER_EXTEND;
513 	pcie_writereg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
514 	w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
515 }
516 
517 /* centralized clkreq control policy */
pcie_clkreq_upd(struct pcicore_info * pi,uint state)518 static void pcie_clkreq_upd(struct pcicore_info *pi, uint state)
519 {
520 	struct si_pub *sih = pi->sih;
521 
522 	switch (state) {
523 	case SI_DOATTACH:
524 		if (PCIE_ASPM(sih))
525 			pcie_clkreq(pi, 1, 0);
526 		break;
527 	case SI_PCIDOWN:
528 		/* turn on serdes PLL down */
529 		if (ai_get_buscorerev(sih) == 6) {
530 			ai_cc_reg(sih,
531 				  offsetof(struct chipcregs, chipcontrol_addr),
532 				  ~0, 0);
533 			ai_cc_reg(sih,
534 				  offsetof(struct chipcregs, chipcontrol_data),
535 				  ~0x40, 0);
536 		} else if (pi->pcie_pr42767) {
537 			pcie_clkreq(pi, 1, 1);
538 		}
539 		break;
540 	case SI_PCIUP:
541 		/* turn off serdes PLL down */
542 		if (ai_get_buscorerev(sih) == 6) {
543 			ai_cc_reg(sih,
544 				  offsetof(struct chipcregs, chipcontrol_addr),
545 				  ~0, 0);
546 			ai_cc_reg(sih,
547 				  offsetof(struct chipcregs, chipcontrol_data),
548 				  ~0x40, 0x40);
549 		} else if (PCIE_ASPM(sih)) {	/* disable clkreq */
550 			pcie_clkreq(pi, 1, 0);
551 		}
552 		break;
553 	}
554 }
555 
556 /* ***** PCI core WARs ***** */
557 /* Done only once at attach time */
pcie_war_polarity(struct pcicore_info * pi)558 static void pcie_war_polarity(struct pcicore_info *pi)
559 {
560 	u32 w;
561 
562 	if (pi->pcie_polarity != 0)
563 		return;
564 
565 	w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_PLP_STATUSREG);
566 
567 	/* Detect the current polarity at attach and force that polarity and
568 	 * disable changing the polarity
569 	 */
570 	if ((w & PCIE_PLP_POLARITYINV_STAT) == 0)
571 		pi->pcie_polarity = SERDES_RX_CTRL_FORCE;
572 	else
573 		pi->pcie_polarity = (SERDES_RX_CTRL_FORCE |
574 				     SERDES_RX_CTRL_POLARITY);
575 }
576 
577 /* enable ASPM and CLKREQ if srom doesn't have it */
578 /* Needs to happen when update to shadow SROM is needed
579  *   : Coming out of 'standby'/'hibernate'
580  *   : If pcie_war_aspm_ovr state changed
581  */
pcie_war_aspm_clkreq(struct pcicore_info * pi)582 static void pcie_war_aspm_clkreq(struct pcicore_info *pi)
583 {
584 	struct si_pub *sih = pi->sih;
585 	u16 val16;
586 	u32 w;
587 
588 	if (!PCIE_ASPM(sih))
589 		return;
590 
591 	/* bypass this on QT or VSIM */
592 	val16 = bcma_read16(pi->core, PCIEREGOFFS(sprom[SRSH_ASPM_OFFSET]));
593 
594 	val16 &= ~SRSH_ASPM_ENB;
595 	if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB)
596 		val16 |= SRSH_ASPM_ENB;
597 	else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L1_ENAB)
598 		val16 |= SRSH_ASPM_L1_ENB;
599 	else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB)
600 		val16 |= SRSH_ASPM_L0s_ENB;
601 
602 	bcma_write16(pi->core, PCIEREGOFFS(sprom[SRSH_ASPM_OFFSET]), val16);
603 
604 	pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
605 	w &= ~PCIE_ASPM_ENAB;
606 	w |= pi->pcie_war_aspm_ovr;
607 	pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
608 
609 	val16 = bcma_read16(pi->core,
610 			    PCIEREGOFFS(sprom[SRSH_CLKREQ_OFFSET_REV5]));
611 
612 	if (pi->pcie_war_aspm_ovr != PCIE_ASPM_DISAB) {
613 		val16 |= SRSH_CLKREQ_ENB;
614 		pi->pcie_pr42767 = true;
615 	} else
616 		val16 &= ~SRSH_CLKREQ_ENB;
617 
618 	bcma_write16(pi->core, PCIEREGOFFS(sprom[SRSH_CLKREQ_OFFSET_REV5]),
619 		     val16);
620 }
621 
622 /* Apply the polarity determined at the start */
623 /* Needs to happen when coming out of 'standby'/'hibernate' */
pcie_war_serdes(struct pcicore_info * pi)624 static void pcie_war_serdes(struct pcicore_info *pi)
625 {
626 	u32 w = 0;
627 
628 	if (pi->pcie_polarity != 0)
629 		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CTRL,
630 			       pi->pcie_polarity);
631 
632 	pcie_mdioread(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, &w);
633 	if (w & PLL_CTRL_FREQDET_EN) {
634 		w &= ~PLL_CTRL_FREQDET_EN;
635 		pcie_mdiowrite(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, w);
636 	}
637 }
638 
639 /* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
640 /* Needs to happen when coming out of 'standby'/'hibernate' */
pcie_misc_config_fixup(struct pcicore_info * pi)641 static void pcie_misc_config_fixup(struct pcicore_info *pi)
642 {
643 	u16 val16;
644 
645 	val16 = bcma_read16(pi->core,
646 			    PCIEREGOFFS(sprom[SRSH_PCIE_MISC_CONFIG]));
647 
648 	if ((val16 & SRSH_L23READY_EXIT_NOPERST) == 0) {
649 		val16 |= SRSH_L23READY_EXIT_NOPERST;
650 		bcma_write16(pi->core,
651 			     PCIEREGOFFS(sprom[SRSH_PCIE_MISC_CONFIG]), val16);
652 	}
653 }
654 
655 /* quick hack for testing */
656 /* Needs to happen when coming out of 'standby'/'hibernate' */
pcie_war_noplldown(struct pcicore_info * pi)657 static void pcie_war_noplldown(struct pcicore_info *pi)
658 {
659 	/* turn off serdes PLL down */
660 	ai_cc_reg(pi->sih, offsetof(struct chipcregs, chipcontrol),
661 		  CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN);
662 
663 	/* clear srom shadow backdoor */
664 	bcma_write16(pi->core, PCIEREGOFFS(sprom[SRSH_BD_OFFSET]), 0);
665 }
666 
667 /* Needs to happen when coming out of 'standby'/'hibernate' */
pcie_war_pci_setup(struct pcicore_info * pi)668 static void pcie_war_pci_setup(struct pcicore_info *pi)
669 {
670 	struct si_pub *sih = pi->sih;
671 	u32 w;
672 
673 	if (ai_get_buscorerev(sih) == 0 || ai_get_buscorerev(sih) == 1) {
674 		w = pcie_readreg(pi->core, PCIE_PCIEREGS,
675 				 PCIE_TLP_WORKAROUNDSREG);
676 		w |= 0x8;
677 		pcie_writereg(pi->core, PCIE_PCIEREGS,
678 			      PCIE_TLP_WORKAROUNDSREG, w);
679 	}
680 
681 	if (ai_get_buscorerev(sih) == 1) {
682 		w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_LCREG);
683 		w |= 0x40;
684 		pcie_writereg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w);
685 	}
686 
687 	if (ai_get_buscorerev(sih) == 0) {
688 		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128);
689 		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100);
690 		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466);
691 	} else if (PCIE_ASPM(sih)) {
692 		/* Change the L1 threshold for better performance */
693 		w = pcie_readreg(pi->core, PCIE_PCIEREGS,
694 				 PCIE_DLLP_PMTHRESHREG);
695 		w &= ~PCIE_L1THRESHOLDTIME_MASK;
696 		w |= PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT;
697 		pcie_writereg(pi->core, PCIE_PCIEREGS,
698 			      PCIE_DLLP_PMTHRESHREG, w);
699 
700 		pcie_war_serdes(pi);
701 
702 		pcie_war_aspm_clkreq(pi);
703 	} else if (ai_get_buscorerev(pi->sih) == 7)
704 		pcie_war_noplldown(pi);
705 
706 	/* Note that the fix is actually in the SROM,
707 	 * that's why this is open-ended
708 	 */
709 	if (ai_get_buscorerev(pi->sih) >= 6)
710 		pcie_misc_config_fixup(pi);
711 }
712 
713 /* ***** Functions called during driver state changes ***** */
pcicore_attach(struct pcicore_info * pi,int state)714 void pcicore_attach(struct pcicore_info *pi, int state)
715 {
716 	struct si_pub *sih = pi->sih;
717 	u32 bfl2 = (u32)getintvar(sih, BRCMS_SROM_BOARDFLAGS2);
718 
719 	/* Determine if this board needs override */
720 	if (PCIE_ASPM(sih)) {
721 		if (bfl2 & BFL2_PCIEWAR_OVR)
722 			pi->pcie_war_aspm_ovr = PCIE_ASPM_DISAB;
723 		else
724 			pi->pcie_war_aspm_ovr = PCIE_ASPM_ENAB;
725 	}
726 
727 	/* These need to happen in this order only */
728 	pcie_war_polarity(pi);
729 
730 	pcie_war_serdes(pi);
731 
732 	pcie_war_aspm_clkreq(pi);
733 
734 	pcie_clkreq_upd(pi, state);
735 
736 }
737 
pcicore_hwup(struct pcicore_info * pi)738 void pcicore_hwup(struct pcicore_info *pi)
739 {
740 	if (!pi || ai_get_buscoretype(pi->sih) != PCIE_CORE_ID)
741 		return;
742 
743 	pcie_war_pci_setup(pi);
744 }
745 
pcicore_up(struct pcicore_info * pi,int state)746 void pcicore_up(struct pcicore_info *pi, int state)
747 {
748 	if (!pi || ai_get_buscoretype(pi->sih) != PCIE_CORE_ID)
749 		return;
750 
751 	/* Restore L1 timer for better performance */
752 	pcie_extendL1timer(pi, true);
753 
754 	pcie_clkreq_upd(pi, state);
755 }
756 
757 /* When the device is going to enter D3 state
758  * (or the system is going to enter S3/S4 states)
759  */
pcicore_sleep(struct pcicore_info * pi)760 void pcicore_sleep(struct pcicore_info *pi)
761 {
762 	u32 w;
763 
764 	if (!pi || !PCIE_ASPM(pi->sih))
765 		return;
766 
767 	pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
768 	w &= ~PCIE_CAP_LCREG_ASPML1;
769 	pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
770 
771 	pi->pcie_pr42767 = false;
772 }
773 
pcicore_down(struct pcicore_info * pi,int state)774 void pcicore_down(struct pcicore_info *pi, int state)
775 {
776 	if (!pi || ai_get_buscoretype(pi->sih) != PCIE_CORE_ID)
777 		return;
778 
779 	pcie_clkreq_upd(pi, state);
780 
781 	/* Reduce L1 timer for better power savings */
782 	pcie_extendL1timer(pi, false);
783 }
784 
pcicore_fixcfg(struct pcicore_info * pi)785 void pcicore_fixcfg(struct pcicore_info *pi)
786 {
787 	struct bcma_device *core = pi->core;
788 	u16 val16;
789 	uint regoff;
790 
791 	switch (pi->core->id.id) {
792 	case BCMA_CORE_PCI:
793 		regoff = PCIREGOFFS(sprom[SRSH_PI_OFFSET]);
794 		break;
795 
796 	case BCMA_CORE_PCIE:
797 		regoff = PCIEREGOFFS(sprom[SRSH_PI_OFFSET]);
798 		break;
799 
800 	default:
801 		return;
802 	}
803 
804 	val16 = bcma_read16(pi->core, regoff);
805 	if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) !=
806 	    (u16)core->core_index) {
807 		val16 = ((u16)core->core_index << SRSH_PI_SHIFT) |
808 			(val16 & ~SRSH_PI_MASK);
809 		bcma_write16(pi->core, regoff, val16);
810 	}
811 }
812 
813 /* precondition: current core is pci core */
814 void
pcicore_pci_setup(struct pcicore_info * pi)815 pcicore_pci_setup(struct pcicore_info *pi)
816 {
817 	bcma_set32(pi->core, PCIREGOFFS(sbtopci2),
818 		   SBTOPCI_PREF | SBTOPCI_BURST);
819 
820 	if (pi->core->id.rev >= 11) {
821 		bcma_set32(pi->core, PCIREGOFFS(sbtopci2),
822 			   SBTOPCI_RC_READMULTI);
823 		bcma_set32(pi->core, PCIREGOFFS(clkrun), PCI_CLKRUN_DSBL);
824 		(void)bcma_read32(pi->core, PCIREGOFFS(clkrun));
825 	}
826 }
827