e6dec49b05cdd7f0f846cc982d1d78c28aaa6695
[openwrt/svn-archive/archive.git] / target / linux / generic / patches-2.6.39 / 020-ssb_update.patch
1 --- a/drivers/ssb/b43_pci_bridge.c
2 +++ b/drivers/ssb/b43_pci_bridge.c
3 @@ -5,12 +5,13 @@
4 * because of its small size we include it in the SSB core
5 * instead of creating a standalone module.
6 *
7 - * Copyright 2007 Michael Buesch <mb@bu3sch.de>
8 + * Copyright 2007 Michael Buesch <m@bues.ch>
9 *
10 * Licensed under the GNU/GPL. See COPYING for details.
11 */
12
13 #include <linux/pci.h>
14 +#include <linux/module.h>
15 #include <linux/ssb/ssb.h>
16
17 #include "ssb_private.h"
18 @@ -28,6 +29,8 @@ static const struct pci_device_id b43_pc
19 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) },
20 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) },
21 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) },
22 + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4322) },
23 + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43222) },
24 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4324) },
25 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4325) },
26 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4328) },
27 --- a/drivers/ssb/driver_chipcommon.c
28 +++ b/drivers/ssb/driver_chipcommon.c
29 @@ -3,7 +3,7 @@
30 * Broadcom ChipCommon core driver
31 *
32 * Copyright 2005, Broadcom Corporation
33 - * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
34 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
35 *
36 * Licensed under the GNU/GPL. See COPYING for details.
37 */
38 @@ -46,40 +46,66 @@ void ssb_chipco_set_clockmode(struct ssb
39 if (!ccdev)
40 return;
41 bus = ccdev->bus;
42 +
43 + /* We support SLOW only on 6..9 */
44 + if (ccdev->id.revision >= 10 && mode == SSB_CLKMODE_SLOW)
45 + mode = SSB_CLKMODE_DYNAMIC;
46 +
47 + if (cc->capabilities & SSB_CHIPCO_CAP_PMU)
48 + return; /* PMU controls clockmode, separated function needed */
49 + SSB_WARN_ON(ccdev->id.revision >= 20);
50 +
51 /* chipcommon cores prior to rev6 don't support dynamic clock control */
52 if (ccdev->id.revision < 6)
53 return;
54 - /* chipcommon cores rev10 are a whole new ball game */
55 +
56 + /* ChipCommon cores rev10+ need testing */
57 if (ccdev->id.revision >= 10)
58 return;
59 +
60 if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))
61 return;
62
63 switch (mode) {
64 - case SSB_CLKMODE_SLOW:
65 + case SSB_CLKMODE_SLOW: /* For revs 6..9 only */
66 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
67 tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW;
68 chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
69 break;
70 case SSB_CLKMODE_FAST:
71 - ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
72 - tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
73 - tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
74 - tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;
75 - chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
76 + if (ccdev->id.revision < 10) {
77 + ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
78 + tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
79 + tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
80 + tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;
81 + chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
82 + } else {
83 + chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,
84 + (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) |
85 + SSB_CHIPCO_SYSCLKCTL_FORCEHT));
86 + /* udelay(150); TODO: not available in early init */
87 + }
88 break;
89 case SSB_CLKMODE_DYNAMIC:
90 - tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
91 - tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
92 - tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
93 - tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
94 - if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) != SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
95 - tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
96 - chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
97 -
98 - /* for dynamic control, we have to release our xtal_pu "force on" */
99 - if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
100 - ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
101 + if (ccdev->id.revision < 10) {
102 + tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
103 + tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
104 + tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
105 + tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
106 + if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) !=
107 + SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
108 + tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
109 + chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
110 +
111 + /* For dynamic control, we have to release our xtal_pu
112 + * "force on" */
113 + if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
114 + ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
115 + } else {
116 + chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,
117 + (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) &
118 + ~SSB_CHIPCO_SYSCLKCTL_FORCEHT));
119 + }
120 break;
121 default:
122 SSB_WARN_ON(1);
123 @@ -260,6 +286,12 @@ void ssb_chipcommon_init(struct ssb_chip
124 if (cc->dev->id.revision >= 11)
125 cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
126 ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status);
127 +
128 + if (cc->dev->id.revision >= 20) {
129 + chipco_write32(cc, SSB_CHIPCO_GPIOPULLUP, 0);
130 + chipco_write32(cc, SSB_CHIPCO_GPIOPULLDOWN, 0);
131 + }
132 +
133 ssb_pmu_init(cc);
134 chipco_powercontrol_init(cc);
135 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
136 --- a/drivers/ssb/driver_chipcommon_pmu.c
137 +++ b/drivers/ssb/driver_chipcommon_pmu.c
138 @@ -2,7 +2,7 @@
139 * Sonics Silicon Backplane
140 * Broadcom ChipCommon Power Management Unit driver
141 *
142 - * Copyright 2009, Michael Buesch <mb@bu3sch.de>
143 + * Copyright 2009, Michael Buesch <m@bues.ch>
144 * Copyright 2007, Broadcom Corporation
145 *
146 * Licensed under the GNU/GPL. See COPYING for details.
147 @@ -12,6 +12,9 @@
148 #include <linux/ssb/ssb_regs.h>
149 #include <linux/ssb/ssb_driver_chipcommon.h>
150 #include <linux/delay.h>
151 +#ifdef CONFIG_BCM47XX
152 +#include <asm/mach-bcm47xx/nvram.h>
153 +#endif
154
155 #include "ssb_private.h"
156
157 @@ -91,10 +94,6 @@ static void ssb_pmu0_pllinit_r0(struct s
158 u32 pmuctl, tmp, pllctl;
159 unsigned int i;
160
161 - if ((bus->chip_id == 0x5354) && !crystalfreq) {
162 - /* The 5354 crystal freq is 25MHz */
163 - crystalfreq = 25000;
164 - }
165 if (crystalfreq)
166 e = pmu0_plltab_find_entry(crystalfreq);
167 if (!e)
168 @@ -320,7 +319,11 @@ static void ssb_pmu_pll_init(struct ssb_
169 u32 crystalfreq = 0; /* in kHz. 0 = keep default freq. */
170
171 if (bus->bustype == SSB_BUSTYPE_SSB) {
172 - /* TODO: The user may override the crystal frequency. */
173 +#ifdef CONFIG_BCM47XX
174 + char buf[20];
175 + if (nvram_getenv("xtalfreq", buf, sizeof(buf)) >= 0)
176 + crystalfreq = simple_strtoul(buf, NULL, 0);
177 +#endif
178 }
179
180 switch (bus->chip_id) {
181 @@ -329,7 +332,11 @@ static void ssb_pmu_pll_init(struct ssb_
182 ssb_pmu1_pllinit_r0(cc, crystalfreq);
183 break;
184 case 0x4328:
185 + ssb_pmu0_pllinit_r0(cc, crystalfreq);
186 + break;
187 case 0x5354:
188 + if (crystalfreq == 0)
189 + crystalfreq = 25000;
190 ssb_pmu0_pllinit_r0(cc, crystalfreq);
191 break;
192 case 0x4322:
193 @@ -417,12 +424,14 @@ static void ssb_pmu_resources_init(struc
194 u32 min_msk = 0, max_msk = 0;
195 unsigned int i;
196 const struct pmu_res_updown_tab_entry *updown_tab = NULL;
197 - unsigned int updown_tab_size;
198 + unsigned int updown_tab_size = 0;
199 const struct pmu_res_depend_tab_entry *depend_tab = NULL;
200 - unsigned int depend_tab_size;
201 + unsigned int depend_tab_size = 0;
202
203 switch (bus->chip_id) {
204 case 0x4312:
205 + min_msk = 0xCBB;
206 + break;
207 case 0x4322:
208 /* We keep the default settings:
209 * min_msk = 0xCBB
210 @@ -604,3 +613,34 @@ void ssb_pmu_set_ldo_paref(struct ssb_ch
211
212 EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage);
213 EXPORT_SYMBOL(ssb_pmu_set_ldo_paref);
214 +
215 +u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc)
216 +{
217 + struct ssb_bus *bus = cc->dev->bus;
218 +
219 + switch (bus->chip_id) {
220 + case 0x5354:
221 + /* 5354 chip uses a non programmable PLL of frequency 240MHz */
222 + return 240000000;
223 + default:
224 + ssb_printk(KERN_ERR PFX
225 + "ERROR: PMU cpu clock unknown for device %04X\n",
226 + bus->chip_id);
227 + return 0;
228 + }
229 +}
230 +
231 +u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc)
232 +{
233 + struct ssb_bus *bus = cc->dev->bus;
234 +
235 + switch (bus->chip_id) {
236 + case 0x5354:
237 + return 120000000;
238 + default:
239 + ssb_printk(KERN_ERR PFX
240 + "ERROR: PMU controlclock unknown for device %04X\n",
241 + bus->chip_id);
242 + return 0;
243 + }
244 +}
245 --- a/drivers/ssb/driver_extif.c
246 +++ b/drivers/ssb/driver_extif.c
247 @@ -3,7 +3,7 @@
248 * Broadcom EXTIF core driver
249 *
250 * Copyright 2005, Broadcom Corporation
251 - * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
252 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
253 * Copyright 2006, 2007, Felix Fietkau <nbd@openwrt.org>
254 * Copyright 2007, Aurelien Jarno <aurelien@aurel32.net>
255 *
256 --- a/drivers/ssb/driver_gige.c
257 +++ b/drivers/ssb/driver_gige.c
258 @@ -3,7 +3,7 @@
259 * Broadcom Gigabit Ethernet core driver
260 *
261 * Copyright 2008, Broadcom Corporation
262 - * Copyright 2008, Michael Buesch <mb@bu3sch.de>
263 + * Copyright 2008, Michael Buesch <m@bues.ch>
264 *
265 * Licensed under the GNU/GPL. See COPYING for details.
266 */
267 @@ -106,8 +106,9 @@ void gige_pcicfg_write32(struct ssb_gige
268 gige_write32(dev, SSB_GIGE_PCICFG + offset, value);
269 }
270
271 -static int ssb_gige_pci_read_config(struct pci_bus *bus, unsigned int devfn,
272 - int reg, int size, u32 *val)
273 +static int __devinit ssb_gige_pci_read_config(struct pci_bus *bus,
274 + unsigned int devfn, int reg,
275 + int size, u32 *val)
276 {
277 struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops);
278 unsigned long flags;
279 @@ -136,8 +137,9 @@ static int ssb_gige_pci_read_config(stru
280 return PCIBIOS_SUCCESSFUL;
281 }
282
283 -static int ssb_gige_pci_write_config(struct pci_bus *bus, unsigned int devfn,
284 - int reg, int size, u32 val)
285 +static int __devinit ssb_gige_pci_write_config(struct pci_bus *bus,
286 + unsigned int devfn, int reg,
287 + int size, u32 val)
288 {
289 struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops);
290 unsigned long flags;
291 @@ -166,7 +168,8 @@ static int ssb_gige_pci_write_config(str
292 return PCIBIOS_SUCCESSFUL;
293 }
294
295 -static int ssb_gige_probe(struct ssb_device *sdev, const struct ssb_device_id *id)
296 +static int __devinit ssb_gige_probe(struct ssb_device *sdev,
297 + const struct ssb_device_id *id)
298 {
299 struct ssb_gige *dev;
300 u32 base, tmslow, tmshigh;
301 --- a/drivers/ssb/driver_mipscore.c
302 +++ b/drivers/ssb/driver_mipscore.c
303 @@ -3,7 +3,7 @@
304 * Broadcom MIPS core driver
305 *
306 * Copyright 2005, Broadcom Corporation
307 - * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
308 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
309 *
310 * Licensed under the GNU/GPL. See COPYING for details.
311 */
312 @@ -208,6 +208,9 @@ u32 ssb_cpu_clock(struct ssb_mipscore *m
313 struct ssb_bus *bus = mcore->dev->bus;
314 u32 pll_type, n, m, rate = 0;
315
316 + if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)
317 + return ssb_pmu_get_cpu_clock(&bus->chipco);
318 +
319 if (bus->extif.dev) {
320 ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m);
321 } else if (bus->chipco.dev) {
322 --- a/drivers/ssb/driver_pcicore.c
323 +++ b/drivers/ssb/driver_pcicore.c
324 @@ -3,7 +3,7 @@
325 * Broadcom PCI-core driver
326 *
327 * Copyright 2005, Broadcom Corporation
328 - * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
329 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
330 *
331 * Licensed under the GNU/GPL. See COPYING for details.
332 */
333 @@ -15,6 +15,11 @@
334
335 #include "ssb_private.h"
336
337 +static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address);
338 +static void ssb_pcie_write(struct ssb_pcicore *pc, u32 address, u32 data);
339 +static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address);
340 +static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
341 + u8 address, u16 data);
342
343 static inline
344 u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset)
345 @@ -69,7 +74,7 @@ static u32 get_cfgspace_addr(struct ssb_
346 u32 tmp;
347
348 /* We do only have one cardbus device behind the bridge. */
349 - if (pc->cardbusmode && (dev >= 1))
350 + if (pc->cardbusmode && (dev > 1))
351 goto out;
352
353 if (bus == 0) {
354 @@ -309,7 +314,7 @@ int ssb_pcicore_pcibios_map_irq(const st
355 return ssb_mips_irq(extpci_core->dev) + 2;
356 }
357
358 -static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
359 +static void __devinit ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
360 {
361 u32 val;
362
363 @@ -374,7 +379,7 @@ static void ssb_pcicore_init_hostmode(st
364 register_pci_controller(&ssb_pcicore_controller);
365 }
366
367 -static int pcicore_is_in_hostmode(struct ssb_pcicore *pc)
368 +static int __devinit pcicore_is_in_hostmode(struct ssb_pcicore *pc)
369 {
370 struct ssb_bus *bus = pc->dev->bus;
371 u16 chipid_top;
372 @@ -403,25 +408,137 @@ static int pcicore_is_in_hostmode(struct
373 }
374 #endif /* CONFIG_SSB_PCICORE_HOSTMODE */
375
376 +/**************************************************
377 + * Workarounds.
378 + **************************************************/
379 +
380 +static void __devinit ssb_pcicore_fix_sprom_core_index(struct ssb_pcicore *pc)
381 +{
382 + u16 tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(0));
383 + if (((tmp & 0xF000) >> 12) != pc->dev->core_index) {
384 + tmp &= ~0xF000;
385 + tmp |= (pc->dev->core_index << 12);
386 + pcicore_write16(pc, SSB_PCICORE_SPROM(0), tmp);
387 + }
388 +}
389 +
390 +static u8 ssb_pcicore_polarity_workaround(struct ssb_pcicore *pc)
391 +{
392 + return (ssb_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
393 +}
394 +
395 +static void ssb_pcicore_serdes_workaround(struct ssb_pcicore *pc)
396 +{
397 + const u8 serdes_pll_device = 0x1D;
398 + const u8 serdes_rx_device = 0x1F;
399 + u16 tmp;
400 +
401 + ssb_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
402 + ssb_pcicore_polarity_workaround(pc));
403 + tmp = ssb_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
404 + if (tmp & 0x4000)
405 + ssb_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
406 +}
407 +
408 +static void ssb_pcicore_pci_setup_workarounds(struct ssb_pcicore *pc)
409 +{
410 + struct ssb_device *pdev = pc->dev;
411 + struct ssb_bus *bus = pdev->bus;
412 + u32 tmp;
413 +
414 + tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
415 + tmp |= SSB_PCICORE_SBTOPCI_PREF;
416 + tmp |= SSB_PCICORE_SBTOPCI_BURST;
417 + pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
418 +
419 + if (pdev->id.revision < 5) {
420 + tmp = ssb_read32(pdev, SSB_IMCFGLO);
421 + tmp &= ~SSB_IMCFGLO_SERTO;
422 + tmp |= 2;
423 + tmp &= ~SSB_IMCFGLO_REQTO;
424 + tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT;
425 + ssb_write32(pdev, SSB_IMCFGLO, tmp);
426 + ssb_commit_settings(bus);
427 + } else if (pdev->id.revision >= 11) {
428 + tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
429 + tmp |= SSB_PCICORE_SBTOPCI_MRM;
430 + pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
431 + }
432 +}
433 +
434 +static void ssb_pcicore_pcie_setup_workarounds(struct ssb_pcicore *pc)
435 +{
436 + u32 tmp;
437 + u8 rev = pc->dev->id.revision;
438 +
439 + if (rev == 0 || rev == 1) {
440 + /* TLP Workaround register. */
441 + tmp = ssb_pcie_read(pc, 0x4);
442 + tmp |= 0x8;
443 + ssb_pcie_write(pc, 0x4, tmp);
444 + }
445 + if (rev == 1) {
446 + /* DLLP Link Control register. */
447 + tmp = ssb_pcie_read(pc, 0x100);
448 + tmp |= 0x40;
449 + ssb_pcie_write(pc, 0x100, tmp);
450 + }
451 +
452 + if (rev == 0) {
453 + const u8 serdes_rx_device = 0x1F;
454 +
455 + ssb_pcie_mdio_write(pc, serdes_rx_device,
456 + 2 /* Timer */, 0x8128);
457 + ssb_pcie_mdio_write(pc, serdes_rx_device,
458 + 6 /* CDR */, 0x0100);
459 + ssb_pcie_mdio_write(pc, serdes_rx_device,
460 + 7 /* CDR BW */, 0x1466);
461 + } else if (rev == 3 || rev == 4 || rev == 5) {
462 + /* TODO: DLLP Power Management Threshold */
463 + ssb_pcicore_serdes_workaround(pc);
464 + /* TODO: ASPM */
465 + } else if (rev == 7) {
466 + /* TODO: No PLL down */
467 + }
468 +
469 + if (rev >= 6) {
470 + /* Miscellaneous Configuration Fixup */
471 + tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(5));
472 + if (!(tmp & 0x8000))
473 + pcicore_write16(pc, SSB_PCICORE_SPROM(5),
474 + tmp | 0x8000);
475 + }
476 +}
477
478 /**************************************************
479 * Generic and Clientmode operation code.
480 **************************************************/
481
482 -static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc)
483 +static void __devinit ssb_pcicore_init_clientmode(struct ssb_pcicore *pc)
484 {
485 + struct ssb_device *pdev = pc->dev;
486 + struct ssb_bus *bus = pdev->bus;
487 +
488 + if (bus->bustype == SSB_BUSTYPE_PCI)
489 + ssb_pcicore_fix_sprom_core_index(pc);
490 +
491 /* Disable PCI interrupts. */
492 - ssb_write32(pc->dev, SSB_INTVEC, 0);
493 + ssb_write32(pdev, SSB_INTVEC, 0);
494 +
495 + /* Additional PCIe always once-executed workarounds */
496 + if (pc->dev->id.coreid == SSB_DEV_PCIE) {
497 + ssb_pcicore_serdes_workaround(pc);
498 + /* TODO: ASPM */
499 + /* TODO: Clock Request Update */
500 + }
501 }
502
503 -void ssb_pcicore_init(struct ssb_pcicore *pc)
504 +void __devinit ssb_pcicore_init(struct ssb_pcicore *pc)
505 {
506 struct ssb_device *dev = pc->dev;
507 - struct ssb_bus *bus;
508
509 if (!dev)
510 return;
511 - bus = dev->bus;
512 if (!ssb_device_is_enabled(dev))
513 ssb_device_enable(dev, 0);
514
515 @@ -446,11 +563,35 @@ static void ssb_pcie_write(struct ssb_pc
516 pcicore_write32(pc, 0x134, data);
517 }
518
519 -static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
520 - u8 address, u16 data)
521 +static void ssb_pcie_mdio_set_phy(struct ssb_pcicore *pc, u8 phy)
522 +{
523 + const u16 mdio_control = 0x128;
524 + const u16 mdio_data = 0x12C;
525 + u32 v;
526 + int i;
527 +
528 + v = (1 << 30); /* Start of Transaction */
529 + v |= (1 << 28); /* Write Transaction */
530 + v |= (1 << 17); /* Turnaround */
531 + v |= (0x1F << 18);
532 + v |= (phy << 4);
533 + pcicore_write32(pc, mdio_data, v);
534 +
535 + udelay(10);
536 + for (i = 0; i < 200; i++) {
537 + v = pcicore_read32(pc, mdio_control);
538 + if (v & 0x100 /* Trans complete */)
539 + break;
540 + msleep(1);
541 + }
542 +}
543 +
544 +static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address)
545 {
546 const u16 mdio_control = 0x128;
547 const u16 mdio_data = 0x12C;
548 + int max_retries = 10;
549 + u16 ret = 0;
550 u32 v;
551 int i;
552
553 @@ -458,46 +599,68 @@ static void ssb_pcie_mdio_write(struct s
554 v |= 0x2; /* MDIO Clock Divisor */
555 pcicore_write32(pc, mdio_control, v);
556
557 + if (pc->dev->id.revision >= 10) {
558 + max_retries = 200;
559 + ssb_pcie_mdio_set_phy(pc, device);
560 + }
561 +
562 v = (1 << 30); /* Start of Transaction */
563 - v |= (1 << 28); /* Write Transaction */
564 + v |= (1 << 29); /* Read Transaction */
565 v |= (1 << 17); /* Turnaround */
566 - v |= (u32)device << 22;
567 + if (pc->dev->id.revision < 10)
568 + v |= (u32)device << 22;
569 v |= (u32)address << 18;
570 - v |= data;
571 pcicore_write32(pc, mdio_data, v);
572 /* Wait for the device to complete the transaction */
573 udelay(10);
574 - for (i = 0; i < 10; i++) {
575 + for (i = 0; i < max_retries; i++) {
576 v = pcicore_read32(pc, mdio_control);
577 - if (v & 0x100 /* Trans complete */)
578 + if (v & 0x100 /* Trans complete */) {
579 + udelay(10);
580 + ret = pcicore_read32(pc, mdio_data);
581 break;
582 + }
583 msleep(1);
584 }
585 pcicore_write32(pc, mdio_control, 0);
586 + return ret;
587 }
588
589 -static void ssb_broadcast_value(struct ssb_device *dev,
590 - u32 address, u32 data)
591 +static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
592 + u8 address, u16 data)
593 {
594 - /* This is used for both, PCI and ChipCommon core, so be careful. */
595 - BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR);
596 - BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA);
597 + const u16 mdio_control = 0x128;
598 + const u16 mdio_data = 0x12C;
599 + int max_retries = 10;
600 + u32 v;
601 + int i;
602
603 - ssb_write32(dev, SSB_PCICORE_BCAST_ADDR, address);
604 - ssb_read32(dev, SSB_PCICORE_BCAST_ADDR); /* flush */
605 - ssb_write32(dev, SSB_PCICORE_BCAST_DATA, data);
606 - ssb_read32(dev, SSB_PCICORE_BCAST_DATA); /* flush */
607 -}
608 + v = 0x80; /* Enable Preamble Sequence */
609 + v |= 0x2; /* MDIO Clock Divisor */
610 + pcicore_write32(pc, mdio_control, v);
611
612 -static void ssb_commit_settings(struct ssb_bus *bus)
613 -{
614 - struct ssb_device *dev;
615 + if (pc->dev->id.revision >= 10) {
616 + max_retries = 200;
617 + ssb_pcie_mdio_set_phy(pc, device);
618 + }
619
620 - dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
621 - if (WARN_ON(!dev))
622 - return;
623 - /* This forces an update of the cached registers. */
624 - ssb_broadcast_value(dev, 0xFD8, 0);
625 + v = (1 << 30); /* Start of Transaction */
626 + v |= (1 << 28); /* Write Transaction */
627 + v |= (1 << 17); /* Turnaround */
628 + if (pc->dev->id.revision < 10)
629 + v |= (u32)device << 22;
630 + v |= (u32)address << 18;
631 + v |= data;
632 + pcicore_write32(pc, mdio_data, v);
633 + /* Wait for the device to complete the transaction */
634 + udelay(10);
635 + for (i = 0; i < max_retries; i++) {
636 + v = pcicore_read32(pc, mdio_control);
637 + if (v & 0x100 /* Trans complete */)
638 + break;
639 + msleep(1);
640 + }
641 + pcicore_write32(pc, mdio_control, 0);
642 }
643
644 int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
645 @@ -550,48 +713,10 @@ int ssb_pcicore_dev_irqvecs_enable(struc
646 if (pc->setup_done)
647 goto out;
648 if (pdev->id.coreid == SSB_DEV_PCI) {
649 - tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
650 - tmp |= SSB_PCICORE_SBTOPCI_PREF;
651 - tmp |= SSB_PCICORE_SBTOPCI_BURST;
652 - pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
653 -
654 - if (pdev->id.revision < 5) {
655 - tmp = ssb_read32(pdev, SSB_IMCFGLO);
656 - tmp &= ~SSB_IMCFGLO_SERTO;
657 - tmp |= 2;
658 - tmp &= ~SSB_IMCFGLO_REQTO;
659 - tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT;
660 - ssb_write32(pdev, SSB_IMCFGLO, tmp);
661 - ssb_commit_settings(bus);
662 - } else if (pdev->id.revision >= 11) {
663 - tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
664 - tmp |= SSB_PCICORE_SBTOPCI_MRM;
665 - pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
666 - }
667 + ssb_pcicore_pci_setup_workarounds(pc);
668 } else {
669 WARN_ON(pdev->id.coreid != SSB_DEV_PCIE);
670 - //TODO: Better make defines for all these magic PCIE values.
671 - if ((pdev->id.revision == 0) || (pdev->id.revision == 1)) {
672 - /* TLP Workaround register. */
673 - tmp = ssb_pcie_read(pc, 0x4);
674 - tmp |= 0x8;
675 - ssb_pcie_write(pc, 0x4, tmp);
676 - }
677 - if (pdev->id.revision == 0) {
678 - const u8 serdes_rx_device = 0x1F;
679 -
680 - ssb_pcie_mdio_write(pc, serdes_rx_device,
681 - 2 /* Timer */, 0x8128);
682 - ssb_pcie_mdio_write(pc, serdes_rx_device,
683 - 6 /* CDR */, 0x0100);
684 - ssb_pcie_mdio_write(pc, serdes_rx_device,
685 - 7 /* CDR BW */, 0x1466);
686 - } else if (pdev->id.revision == 1) {
687 - /* DLLP Link Control register. */
688 - tmp = ssb_pcie_read(pc, 0x100);
689 - tmp |= 0x40;
690 - ssb_pcie_write(pc, 0x100, tmp);
691 - }
692 + ssb_pcicore_pcie_setup_workarounds(pc);
693 }
694 pc->setup_done = 1;
695 out:
696 --- a/drivers/ssb/embedded.c
697 +++ b/drivers/ssb/embedded.c
698 @@ -3,7 +3,7 @@
699 * Embedded systems support code
700 *
701 * Copyright 2005-2008, Broadcom Corporation
702 - * Copyright 2006-2008, Michael Buesch <mb@bu3sch.de>
703 + * Copyright 2006-2008, Michael Buesch <m@bues.ch>
704 *
705 * Licensed under the GNU/GPL. See COPYING for details.
706 */
707 --- a/drivers/ssb/main.c
708 +++ b/drivers/ssb/main.c
709 @@ -3,7 +3,7 @@
710 * Subsystem core
711 *
712 * Copyright 2005, Broadcom Corporation
713 - * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
714 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
715 *
716 * Licensed under the GNU/GPL. See COPYING for details.
717 */
718 @@ -12,6 +12,7 @@
719
720 #include <linux/delay.h>
721 #include <linux/io.h>
722 +#include <linux/module.h>
723 #include <linux/ssb/ssb.h>
724 #include <linux/ssb/ssb_regs.h>
725 #include <linux/ssb/ssb_driver_gige.h>
726 @@ -139,19 +140,6 @@ static void ssb_device_put(struct ssb_de
727 put_device(dev->dev);
728 }
729
730 -static inline struct ssb_driver *ssb_driver_get(struct ssb_driver *drv)
731 -{
732 - if (drv)
733 - get_driver(&drv->drv);
734 - return drv;
735 -}
736 -
737 -static inline void ssb_driver_put(struct ssb_driver *drv)
738 -{
739 - if (drv)
740 - put_driver(&drv->drv);
741 -}
742 -
743 static int ssb_device_resume(struct device *dev)
744 {
745 struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
746 @@ -249,11 +237,9 @@ int ssb_devices_freeze(struct ssb_bus *b
747 ssb_device_put(sdev);
748 continue;
749 }
750 - sdrv = ssb_driver_get(drv_to_ssb_drv(sdev->dev->driver));
751 - if (!sdrv || SSB_WARN_ON(!sdrv->remove)) {
752 - ssb_device_put(sdev);
753 + sdrv = drv_to_ssb_drv(sdev->dev->driver);
754 + if (SSB_WARN_ON(!sdrv->remove))
755 continue;
756 - }
757 sdrv->remove(sdev);
758 ctx->device_frozen[i] = 1;
759 }
760 @@ -292,7 +278,6 @@ int ssb_devices_thaw(struct ssb_freeze_c
761 dev_name(sdev->dev));
762 result = err;
763 }
764 - ssb_driver_put(sdrv);
765 ssb_device_put(sdev);
766 }
767
768 @@ -557,7 +542,7 @@ error:
769 }
770
771 /* Needs ssb_buses_lock() */
772 -static int ssb_attach_queued_buses(void)
773 +static int __devinit ssb_attach_queued_buses(void)
774 {
775 struct ssb_bus *bus, *n;
776 int err = 0;
777 @@ -768,9 +753,9 @@ out:
778 return err;
779 }
780
781 -static int ssb_bus_register(struct ssb_bus *bus,
782 - ssb_invariants_func_t get_invariants,
783 - unsigned long baseaddr)
784 +static int __devinit ssb_bus_register(struct ssb_bus *bus,
785 + ssb_invariants_func_t get_invariants,
786 + unsigned long baseaddr)
787 {
788 int err;
789
790 @@ -851,8 +836,8 @@ err_disable_xtal:
791 }
792
793 #ifdef CONFIG_SSB_PCIHOST
794 -int ssb_bus_pcibus_register(struct ssb_bus *bus,
795 - struct pci_dev *host_pci)
796 +int __devinit ssb_bus_pcibus_register(struct ssb_bus *bus,
797 + struct pci_dev *host_pci)
798 {
799 int err;
800
801 @@ -875,9 +860,9 @@ EXPORT_SYMBOL(ssb_bus_pcibus_register);
802 #endif /* CONFIG_SSB_PCIHOST */
803
804 #ifdef CONFIG_SSB_PCMCIAHOST
805 -int ssb_bus_pcmciabus_register(struct ssb_bus *bus,
806 - struct pcmcia_device *pcmcia_dev,
807 - unsigned long baseaddr)
808 +int __devinit ssb_bus_pcmciabus_register(struct ssb_bus *bus,
809 + struct pcmcia_device *pcmcia_dev,
810 + unsigned long baseaddr)
811 {
812 int err;
813
814 @@ -897,8 +882,9 @@ EXPORT_SYMBOL(ssb_bus_pcmciabus_register
815 #endif /* CONFIG_SSB_PCMCIAHOST */
816
817 #ifdef CONFIG_SSB_SDIOHOST
818 -int ssb_bus_sdiobus_register(struct ssb_bus *bus, struct sdio_func *func,
819 - unsigned int quirks)
820 +int __devinit ssb_bus_sdiobus_register(struct ssb_bus *bus,
821 + struct sdio_func *func,
822 + unsigned int quirks)
823 {
824 int err;
825
826 @@ -918,9 +904,9 @@ int ssb_bus_sdiobus_register(struct ssb_
827 EXPORT_SYMBOL(ssb_bus_sdiobus_register);
828 #endif /* CONFIG_SSB_PCMCIAHOST */
829
830 -int ssb_bus_ssbbus_register(struct ssb_bus *bus,
831 - unsigned long baseaddr,
832 - ssb_invariants_func_t get_invariants)
833 +int __devinit ssb_bus_ssbbus_register(struct ssb_bus *bus,
834 + unsigned long baseaddr,
835 + ssb_invariants_func_t get_invariants)
836 {
837 int err;
838
839 @@ -1001,8 +987,8 @@ u32 ssb_calc_clock_rate(u32 plltype, u32
840 switch (plltype) {
841 case SSB_PLLTYPE_6: /* 100/200 or 120/240 only */
842 if (m & SSB_CHIPCO_CLK_T6_MMASK)
843 - return SSB_CHIPCO_CLK_T6_M0;
844 - return SSB_CHIPCO_CLK_T6_M1;
845 + return SSB_CHIPCO_CLK_T6_M1;
846 + return SSB_CHIPCO_CLK_T6_M0;
847 case SSB_PLLTYPE_1: /* 48Mhz base, 3 dividers */
848 case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
849 case SSB_PLLTYPE_4: /* 48Mhz, 4 dividers */
850 @@ -1092,6 +1078,9 @@ u32 ssb_clockspeed(struct ssb_bus *bus)
851 u32 plltype;
852 u32 clkctl_n, clkctl_m;
853
854 + if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)
855 + return ssb_pmu_get_controlclock(&bus->chipco);
856 +
857 if (ssb_extif_available(&bus->extif))
858 ssb_extif_get_clockcontrol(&bus->extif, &plltype,
859 &clkctl_n, &clkctl_m);
860 @@ -1117,23 +1106,22 @@ static u32 ssb_tmslow_reject_bitmask(str
861 {
862 u32 rev = ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV;
863
864 - /* The REJECT bit changed position in TMSLOW between
865 - * Backplane revisions. */
866 + /* The REJECT bit seems to be different for Backplane rev 2.3 */
867 switch (rev) {
868 case SSB_IDLOW_SSBREV_22:
869 - return SSB_TMSLOW_REJECT_22;
870 + case SSB_IDLOW_SSBREV_24:
871 + case SSB_IDLOW_SSBREV_26:
872 + return SSB_TMSLOW_REJECT;
873 case SSB_IDLOW_SSBREV_23:
874 return SSB_TMSLOW_REJECT_23;
875 - case SSB_IDLOW_SSBREV_24: /* TODO - find the proper REJECT bits */
876 - case SSB_IDLOW_SSBREV_25: /* same here */
877 - case SSB_IDLOW_SSBREV_26: /* same here */
878 + case SSB_IDLOW_SSBREV_25: /* TODO - find the proper REJECT bit */
879 case SSB_IDLOW_SSBREV_27: /* same here */
880 - return SSB_TMSLOW_REJECT_23; /* this is a guess */
881 + return SSB_TMSLOW_REJECT; /* this is a guess */
882 default:
883 printk(KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev);
884 WARN_ON(1);
885 }
886 - return (SSB_TMSLOW_REJECT_22 | SSB_TMSLOW_REJECT_23);
887 + return (SSB_TMSLOW_REJECT | SSB_TMSLOW_REJECT_23);
888 }
889
890 int ssb_device_is_enabled(struct ssb_device *dev)
891 @@ -1260,13 +1248,34 @@ void ssb_device_disable(struct ssb_devic
892 }
893 EXPORT_SYMBOL(ssb_device_disable);
894
895 +/* Some chipsets need routing known for PCIe and 64-bit DMA */
896 +static bool ssb_dma_translation_special_bit(struct ssb_device *dev)
897 +{
898 + u16 chip_id = dev->bus->chip_id;
899 +
900 + if (dev->id.coreid == SSB_DEV_80211) {
901 + return (chip_id == 0x4322 || chip_id == 43221 ||
902 + chip_id == 43231 || chip_id == 43222);
903 + }
904 +
905 + return 0;
906 +}
907 +
908 u32 ssb_dma_translation(struct ssb_device *dev)
909 {
910 switch (dev->bus->bustype) {
911 case SSB_BUSTYPE_SSB:
912 return 0;
913 case SSB_BUSTYPE_PCI:
914 - return SSB_PCI_DMA;
915 + if (pci_is_pcie(dev->bus->host_pci) &&
916 + ssb_read32(dev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64) {
917 + return SSB_PCIE_DMA_H32;
918 + } else {
919 + if (ssb_dma_translation_special_bit(dev))
920 + return SSB_PCIE_DMA_H32;
921 + else
922 + return SSB_PCI_DMA;
923 + }
924 default:
925 __ssb_dma_not_implemented(dev);
926 }
927 @@ -1309,20 +1318,20 @@ EXPORT_SYMBOL(ssb_bus_may_powerdown);
928
929 int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl)
930 {
931 - struct ssb_chipcommon *cc;
932 int err;
933 enum ssb_clkmode mode;
934
935 err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
936 if (err)
937 goto error;
938 - cc = &bus->chipco;
939 - mode = dynamic_pctl ? SSB_CLKMODE_DYNAMIC : SSB_CLKMODE_FAST;
940 - ssb_chipco_set_clockmode(cc, mode);
941
942 #ifdef CONFIG_SSB_DEBUG
943 bus->powered_up = 1;
944 #endif
945 +
946 + mode = dynamic_pctl ? SSB_CLKMODE_DYNAMIC : SSB_CLKMODE_FAST;
947 + ssb_chipco_set_clockmode(&bus->chipco, mode);
948 +
949 return 0;
950 error:
951 ssb_printk(KERN_ERR PFX "Bus powerup failed\n");
952 @@ -1330,6 +1339,37 @@ error:
953 }
954 EXPORT_SYMBOL(ssb_bus_powerup);
955
956 +static void ssb_broadcast_value(struct ssb_device *dev,
957 + u32 address, u32 data)
958 +{
959 +#ifdef CONFIG_SSB_DRIVER_PCICORE
960 + /* This is used for both, PCI and ChipCommon core, so be careful. */
961 + BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR);
962 + BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA);
963 +#endif
964 +
965 + ssb_write32(dev, SSB_CHIPCO_BCAST_ADDR, address);
966 + ssb_read32(dev, SSB_CHIPCO_BCAST_ADDR); /* flush */
967 + ssb_write32(dev, SSB_CHIPCO_BCAST_DATA, data);
968 + ssb_read32(dev, SSB_CHIPCO_BCAST_DATA); /* flush */
969 +}
970 +
971 +void ssb_commit_settings(struct ssb_bus *bus)
972 +{
973 + struct ssb_device *dev;
974 +
975 +#ifdef CONFIG_SSB_DRIVER_PCICORE
976 + dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
977 +#else
978 + dev = bus->chipco.dev;
979 +#endif
980 + if (WARN_ON(!dev))
981 + return;
982 + /* This forces an update of the cached registers. */
983 + ssb_broadcast_value(dev, 0xFD8, 0);
984 +}
985 +EXPORT_SYMBOL(ssb_commit_settings);
986 +
987 u32 ssb_admatch_base(u32 adm)
988 {
989 u32 base = 0;
990 --- a/drivers/ssb/pci.c
991 +++ b/drivers/ssb/pci.c
992 @@ -1,7 +1,7 @@
993 /*
994 * Sonics Silicon Backplane PCI-Hostbus related functions.
995 *
996 - * Copyright (C) 2005-2006 Michael Buesch <mb@bu3sch.de>
997 + * Copyright (C) 2005-2006 Michael Buesch <m@bues.ch>
998 * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
999 * Copyright (C) 2005 Stefano Brivio <st3@riseup.net>
1000 * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
1001 @@ -178,6 +178,18 @@ err_pci:
1002 #define SPEX(_outvar, _offset, _mask, _shift) \
1003 SPEX16(_outvar, _offset, _mask, _shift)
1004
1005 +#define SPEX_ARRAY8(_field, _offset, _mask, _shift) \
1006 + do { \
1007 + SPEX(_field[0], _offset + 0, _mask, _shift); \
1008 + SPEX(_field[1], _offset + 2, _mask, _shift); \
1009 + SPEX(_field[2], _offset + 4, _mask, _shift); \
1010 + SPEX(_field[3], _offset + 6, _mask, _shift); \
1011 + SPEX(_field[4], _offset + 8, _mask, _shift); \
1012 + SPEX(_field[5], _offset + 10, _mask, _shift); \
1013 + SPEX(_field[6], _offset + 12, _mask, _shift); \
1014 + SPEX(_field[7], _offset + 14, _mask, _shift); \
1015 + } while (0)
1016 +
1017
1018 static inline u8 ssb_crc8(u8 crc, u8 data)
1019 {
1020 @@ -331,7 +343,6 @@ static void sprom_extract_r123(struct ss
1021 {
1022 int i;
1023 u16 v;
1024 - s8 gain;
1025 u16 loc[3];
1026
1027 if (out->revision == 3) /* rev 3 moved MAC */
1028 @@ -361,8 +372,9 @@ static void sprom_extract_r123(struct ss
1029 SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14);
1030 SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15);
1031 SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
1032 - SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
1033 - SSB_SPROM1_BINF_CCODE_SHIFT);
1034 + if (out->revision == 1)
1035 + SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
1036 + SSB_SPROM1_BINF_CCODE_SHIFT);
1037 SPEX(ant_available_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA,
1038 SSB_SPROM1_BINF_ANTA_SHIFT);
1039 SPEX(ant_available_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG,
1040 @@ -388,22 +400,16 @@ static void sprom_extract_r123(struct ss
1041 SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
1042 if (out->revision >= 2)
1043 SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
1044 + SPEX(alpha2[0], SSB_SPROM1_CCODE, 0xff00, 8);
1045 + SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0);
1046
1047 /* Extract the antenna gain values. */
1048 - gain = r123_extract_antgain(out->revision, in,
1049 - SSB_SPROM1_AGAIN_BG,
1050 - SSB_SPROM1_AGAIN_BG_SHIFT);
1051 - out->antenna_gain.ghz24.a0 = gain;
1052 - out->antenna_gain.ghz24.a1 = gain;
1053 - out->antenna_gain.ghz24.a2 = gain;
1054 - out->antenna_gain.ghz24.a3 = gain;
1055 - gain = r123_extract_antgain(out->revision, in,
1056 - SSB_SPROM1_AGAIN_A,
1057 - SSB_SPROM1_AGAIN_A_SHIFT);
1058 - out->antenna_gain.ghz5.a0 = gain;
1059 - out->antenna_gain.ghz5.a1 = gain;
1060 - out->antenna_gain.ghz5.a2 = gain;
1061 - out->antenna_gain.ghz5.a3 = gain;
1062 + out->antenna_gain.a0 = r123_extract_antgain(out->revision, in,
1063 + SSB_SPROM1_AGAIN_BG,
1064 + SSB_SPROM1_AGAIN_BG_SHIFT);
1065 + out->antenna_gain.a1 = r123_extract_antgain(out->revision, in,
1066 + SSB_SPROM1_AGAIN_A,
1067 + SSB_SPROM1_AGAIN_A_SHIFT);
1068 }
1069
1070 /* Revs 4 5 and 8 have partially shared layout */
1071 @@ -464,14 +470,17 @@ static void sprom_extract_r45(struct ssb
1072 SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0);
1073 SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A,
1074 SSB_SPROM4_ETHPHY_ET1A_SHIFT);
1075 + SPEX(board_rev, SSB_SPROM4_BOARDREV, 0xFFFF, 0);
1076 if (out->revision == 4) {
1077 - SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0);
1078 + SPEX(alpha2[0], SSB_SPROM4_CCODE, 0xff00, 8);
1079 + SPEX(alpha2[1], SSB_SPROM4_CCODE, 0x00ff, 0);
1080 SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0);
1081 SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0);
1082 SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0);
1083 SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0);
1084 } else {
1085 - SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0);
1086 + SPEX(alpha2[0], SSB_SPROM5_CCODE, 0xff00, 8);
1087 + SPEX(alpha2[1], SSB_SPROM5_CCODE, 0x00ff, 0);
1088 SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0);
1089 SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0);
1090 SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0);
1091 @@ -504,16 +513,14 @@ static void sprom_extract_r45(struct ssb
1092 }
1093
1094 /* Extract the antenna gain values. */
1095 - SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01,
1096 + SPEX(antenna_gain.a0, SSB_SPROM4_AGAIN01,
1097 SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT);
1098 - SPEX(antenna_gain.ghz24.a1, SSB_SPROM4_AGAIN01,
1099 + SPEX(antenna_gain.a1, SSB_SPROM4_AGAIN01,
1100 SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT);
1101 - SPEX(antenna_gain.ghz24.a2, SSB_SPROM4_AGAIN23,
1102 + SPEX(antenna_gain.a2, SSB_SPROM4_AGAIN23,
1103 SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT);
1104 - SPEX(antenna_gain.ghz24.a3, SSB_SPROM4_AGAIN23,
1105 + SPEX(antenna_gain.a3, SSB_SPROM4_AGAIN23,
1106 SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT);
1107 - memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
1108 - sizeof(out->antenna_gain.ghz5));
1109
1110 sprom_extract_r458(out, in);
1111
1112 @@ -523,14 +530,22 @@ static void sprom_extract_r45(struct ssb
1113 static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
1114 {
1115 int i;
1116 - u16 v;
1117 + u16 v, o;
1118 + u16 pwr_info_offset[] = {
1119 + SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
1120 + SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
1121 + };
1122 + BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
1123 + ARRAY_SIZE(out->core_pwr_info));
1124
1125 /* extract the MAC address */
1126 for (i = 0; i < 3; i++) {
1127 v = in[SPOFF(SSB_SPROM8_IL0MAC) + i];
1128 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
1129 }
1130 - SPEX(country_code, SSB_SPROM8_CCODE, 0xFFFF, 0);
1131 + SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0);
1132 + SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
1133 + SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0);
1134 SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0);
1135 SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0);
1136 SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, 0xFFFF, 0);
1137 @@ -596,17 +611,127 @@ static void sprom_extract_r8(struct ssb_
1138 SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
1139
1140 /* Extract the antenna gain values. */
1141 - SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01,
1142 + SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
1143 SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
1144 - SPEX(antenna_gain.ghz24.a1, SSB_SPROM8_AGAIN01,
1145 + SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
1146 SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
1147 - SPEX(antenna_gain.ghz24.a2, SSB_SPROM8_AGAIN23,
1148 + SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
1149 SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
1150 - SPEX(antenna_gain.ghz24.a3, SSB_SPROM8_AGAIN23,
1151 + SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
1152 SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
1153 - memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
1154 - sizeof(out->antenna_gain.ghz5));
1155
1156 + /* Extract cores power info info */
1157 + for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
1158 + o = pwr_info_offset[i];
1159 + SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
1160 + SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
1161 + SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
1162 + SSB_SPROM8_2G_MAXP, 0);
1163 +
1164 + SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
1165 + SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
1166 + SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
1167 +
1168 + SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
1169 + SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
1170 + SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
1171 + SSB_SPROM8_5G_MAXP, 0);
1172 + SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
1173 + SSB_SPROM8_5GH_MAXP, 0);
1174 + SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
1175 + SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
1176 +
1177 + SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
1178 + SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
1179 + SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
1180 + SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
1181 + SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
1182 + SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
1183 + SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
1184 + SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
1185 + SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
1186 + }
1187 +
1188 + /* Extract FEM info */
1189 + SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G,
1190 + SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT);
1191 + SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G,
1192 + SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
1193 + SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G,
1194 + SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT);
1195 + SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G,
1196 + SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT);
1197 + SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G,
1198 + SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT);
1199 +
1200 + SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G,
1201 + SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT);
1202 + SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G,
1203 + SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
1204 + SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G,
1205 + SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT);
1206 + SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G,
1207 + SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT);
1208 + SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G,
1209 + SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT);
1210 +
1211 + SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON,
1212 + SSB_SPROM8_LEDDC_ON_SHIFT);
1213 + SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF,
1214 + SSB_SPROM8_LEDDC_OFF_SHIFT);
1215 +
1216 + SPEX(txchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_TXCHAIN,
1217 + SSB_SPROM8_TXRXC_TXCHAIN_SHIFT);
1218 + SPEX(rxchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_RXCHAIN,
1219 + SSB_SPROM8_TXRXC_RXCHAIN_SHIFT);
1220 + SPEX(antswitch, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_SWITCH,
1221 + SSB_SPROM8_TXRXC_SWITCH_SHIFT);
1222 +
1223 + SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0);
1224 +
1225 + SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0);
1226 + SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0);
1227 + SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0);
1228 + SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0);
1229 +
1230 + SPEX(rawtempsense, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_RAWTEMP,
1231 + SSB_SPROM8_RAWTS_RAWTEMP_SHIFT);
1232 + SPEX(measpower, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_MEASPOWER,
1233 + SSB_SPROM8_RAWTS_MEASPOWER_SHIFT);
1234 + SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX,
1235 + SSB_SPROM8_OPT_CORRX_TEMP_SLOPE,
1236 + SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT);
1237 + SPEX(tempcorrx, SSB_SPROM8_OPT_CORRX, SSB_SPROM8_OPT_CORRX_TEMPCORRX,
1238 + SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT);
1239 + SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX,
1240 + SSB_SPROM8_OPT_CORRX_TEMP_OPTION,
1241 + SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT);
1242 + SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP,
1243 + SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR,
1244 + SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT);
1245 + SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP,
1246 + SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP,
1247 + SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT);
1248 + SPEX(hw_iqcal_en, SSB_SPROM8_HWIQ_IQSWP, SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL,
1249 + SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT);
1250 +
1251 + SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0);
1252 + SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0);
1253 + SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0);
1254 + SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0);
1255 +
1256 + SPEX(tempthresh, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_TRESH,
1257 + SSB_SPROM8_THERMAL_TRESH_SHIFT);
1258 + SPEX(tempoffset, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_OFFSET,
1259 + SSB_SPROM8_THERMAL_OFFSET_SHIFT);
1260 + SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA,
1261 + SSB_SPROM8_TEMPDELTA_PHYCAL,
1262 + SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT);
1263 + SPEX(temps_period, SSB_SPROM8_TEMPDELTA, SSB_SPROM8_TEMPDELTA_PERIOD,
1264 + SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT);
1265 + SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA,
1266 + SSB_SPROM8_TEMPDELTA_HYSTERESIS,
1267 + SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT);
1268 sprom_extract_r458(out, in);
1269
1270 /* TODO - get remaining rev 8 stuff needed */
1271 @@ -662,7 +787,6 @@ static int sprom_extract(struct ssb_bus
1272 static int ssb_pci_sprom_get(struct ssb_bus *bus,
1273 struct ssb_sprom *sprom)
1274 {
1275 - const struct ssb_sprom *fallback;
1276 int err;
1277 u16 *buf;
1278
1279 @@ -707,10 +831,17 @@ static int ssb_pci_sprom_get(struct ssb_
1280 if (err) {
1281 /* All CRC attempts failed.
1282 * Maybe there is no SPROM on the device?
1283 - * If we have a fallback, use that. */
1284 - fallback = ssb_get_fallback_sprom();
1285 - if (fallback) {
1286 - memcpy(sprom, fallback, sizeof(*sprom));
1287 + * Now we ask the arch code if there is some sprom
1288 + * available for this device in some other storage */
1289 + err = ssb_fill_sprom_with_fallback(bus, sprom);
1290 + if (err) {
1291 + ssb_printk(KERN_WARNING PFX "WARNING: Using"
1292 + " fallback SPROM failed (err %d)\n",
1293 + err);
1294 + } else {
1295 + ssb_dprintk(KERN_DEBUG PFX "Using SPROM"
1296 + " revision %d provided by"
1297 + " platform.\n", sprom->revision);
1298 err = 0;
1299 goto out_free;
1300 }
1301 @@ -728,12 +859,8 @@ out_free:
1302 static void ssb_pci_get_boardinfo(struct ssb_bus *bus,
1303 struct ssb_boardinfo *bi)
1304 {
1305 - pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_VENDOR_ID,
1306 - &bi->vendor);
1307 - pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_ID,
1308 - &bi->type);
1309 - pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
1310 - &bi->rev);
1311 + bi->vendor = bus->host_pci->subsystem_vendor;
1312 + bi->type = bus->host_pci->subsystem_device;
1313 }
1314
1315 int ssb_pci_get_invariants(struct ssb_bus *bus,
1316 --- a/drivers/ssb/pcihost_wrapper.c
1317 +++ b/drivers/ssb/pcihost_wrapper.c
1318 @@ -6,7 +6,7 @@
1319 * Copyright (c) 2005 Stefano Brivio <st3@riseup.net>
1320 * Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
1321 * Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
1322 - * Copyright (c) 2005-2007 Michael Buesch <mbuesch@freenet.de>
1323 + * Copyright (c) 2005-2007 Michael Buesch <m@bues.ch>
1324 *
1325 * Licensed under the GNU/GPL. See COPYING for details.
1326 */
1327 @@ -53,8 +53,8 @@ static int ssb_pcihost_resume(struct pci
1328 # define ssb_pcihost_resume NULL
1329 #endif /* CONFIG_PM */
1330
1331 -static int ssb_pcihost_probe(struct pci_dev *dev,
1332 - const struct pci_device_id *id)
1333 +static int __devinit ssb_pcihost_probe(struct pci_dev *dev,
1334 + const struct pci_device_id *id)
1335 {
1336 struct ssb_bus *ssb;
1337 int err = -ENOMEM;
1338 @@ -110,7 +110,7 @@ static void ssb_pcihost_remove(struct pc
1339 pci_set_drvdata(dev, NULL);
1340 }
1341
1342 -int ssb_pcihost_register(struct pci_driver *driver)
1343 +int __devinit ssb_pcihost_register(struct pci_driver *driver)
1344 {
1345 driver->probe = ssb_pcihost_probe;
1346 driver->remove = ssb_pcihost_remove;
1347 --- a/drivers/ssb/pcmcia.c
1348 +++ b/drivers/ssb/pcmcia.c
1349 @@ -3,7 +3,7 @@
1350 * PCMCIA-Hostbus related functions
1351 *
1352 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
1353 - * Copyright 2007-2008 Michael Buesch <mb@bu3sch.de>
1354 + * Copyright 2007-2008 Michael Buesch <m@bues.ch>
1355 *
1356 * Licensed under the GNU/GPL. See COPYING for details.
1357 */
1358 @@ -676,14 +676,10 @@ static int ssb_pcmcia_do_get_invariants(
1359 case SSB_PCMCIA_CIS_ANTGAIN:
1360 GOTO_ERROR_ON(tuple->TupleDataLen != 2,
1361 "antg tpl size");
1362 - sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1];
1363 - sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1];
1364 - sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1];
1365 - sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1];
1366 - sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1];
1367 - sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1];
1368 - sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1];
1369 - sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1];
1370 + sprom->antenna_gain.a0 = tuple->TupleData[1];
1371 + sprom->antenna_gain.a1 = tuple->TupleData[1];
1372 + sprom->antenna_gain.a2 = tuple->TupleData[1];
1373 + sprom->antenna_gain.a3 = tuple->TupleData[1];
1374 break;
1375 case SSB_PCMCIA_CIS_BFLAGS:
1376 GOTO_ERROR_ON((tuple->TupleDataLen != 3) &&
1377 --- a/drivers/ssb/scan.c
1378 +++ b/drivers/ssb/scan.c
1379 @@ -2,7 +2,7 @@
1380 * Sonics Silicon Backplane
1381 * Bus scanning
1382 *
1383 - * Copyright (C) 2005-2007 Michael Buesch <mb@bu3sch.de>
1384 + * Copyright (C) 2005-2007 Michael Buesch <m@bues.ch>
1385 * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
1386 * Copyright (C) 2005 Stefano Brivio <st3@riseup.net>
1387 * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
1388 @@ -258,7 +258,10 @@ static int we_support_multiple_80211_cor
1389 #ifdef CONFIG_SSB_PCIHOST
1390 if (bus->bustype == SSB_BUSTYPE_PCI) {
1391 if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM &&
1392 - bus->host_pci->device == 0x4324)
1393 + ((bus->host_pci->device == 0x4313) ||
1394 + (bus->host_pci->device == 0x431A) ||
1395 + (bus->host_pci->device == 0x4321) ||
1396 + (bus->host_pci->device == 0x4324)))
1397 return 1;
1398 }
1399 #endif /* CONFIG_SSB_PCIHOST */
1400 @@ -307,8 +310,7 @@ int ssb_bus_scan(struct ssb_bus *bus,
1401 } else {
1402 if (bus->bustype == SSB_BUSTYPE_PCI) {
1403 bus->chip_id = pcidev_to_chipid(bus->host_pci);
1404 - pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
1405 - &bus->chip_rev);
1406 + bus->chip_rev = bus->host_pci->revision;
1407 bus->chip_package = 0;
1408 } else {
1409 bus->chip_id = 0x4710;
1410 @@ -316,6 +318,9 @@ int ssb_bus_scan(struct ssb_bus *bus,
1411 bus->chip_package = 0;
1412 }
1413 }
1414 + ssb_printk(KERN_INFO PFX "Found chip with id 0x%04X, rev 0x%02X and "
1415 + "package 0x%02X\n", bus->chip_id, bus->chip_rev,
1416 + bus->chip_package);
1417 if (!bus->nr_devices)
1418 bus->nr_devices = chipid_to_nrcores(bus->chip_id);
1419 if (bus->nr_devices > ARRAY_SIZE(bus->devices)) {
1420 --- a/drivers/ssb/sdio.c
1421 +++ b/drivers/ssb/sdio.c
1422 @@ -6,7 +6,7 @@
1423 *
1424 * Based on drivers/ssb/pcmcia.c
1425 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
1426 - * Copyright 2007-2008 Michael Buesch <mb@bu3sch.de>
1427 + * Copyright 2007-2008 Michael Buesch <m@bues.ch>
1428 *
1429 * Licensed under the GNU/GPL. See COPYING for details.
1430 *
1431 @@ -551,14 +551,10 @@ int ssb_sdio_get_invariants(struct ssb_b
1432 case SSB_SDIO_CIS_ANTGAIN:
1433 GOTO_ERROR_ON(tuple->size != 2,
1434 "antg tpl size");
1435 - sprom->antenna_gain.ghz24.a0 = tuple->data[1];
1436 - sprom->antenna_gain.ghz24.a1 = tuple->data[1];
1437 - sprom->antenna_gain.ghz24.a2 = tuple->data[1];
1438 - sprom->antenna_gain.ghz24.a3 = tuple->data[1];
1439 - sprom->antenna_gain.ghz5.a0 = tuple->data[1];
1440 - sprom->antenna_gain.ghz5.a1 = tuple->data[1];
1441 - sprom->antenna_gain.ghz5.a2 = tuple->data[1];
1442 - sprom->antenna_gain.ghz5.a3 = tuple->data[1];
1443 + sprom->antenna_gain.a0 = tuple->data[1];
1444 + sprom->antenna_gain.a1 = tuple->data[1];
1445 + sprom->antenna_gain.a2 = tuple->data[1];
1446 + sprom->antenna_gain.a3 = tuple->data[1];
1447 break;
1448 case SSB_SDIO_CIS_BFLAGS:
1449 GOTO_ERROR_ON((tuple->size != 3) &&
1450 --- a/drivers/ssb/sprom.c
1451 +++ b/drivers/ssb/sprom.c
1452 @@ -2,7 +2,7 @@
1453 * Sonics Silicon Backplane
1454 * Common SPROM support routines
1455 *
1456 - * Copyright (C) 2005-2008 Michael Buesch <mb@bu3sch.de>
1457 + * Copyright (C) 2005-2008 Michael Buesch <m@bues.ch>
1458 * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
1459 * Copyright (C) 2005 Stefano Brivio <st3@riseup.net>
1460 * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
1461 @@ -17,7 +17,7 @@
1462 #include <linux/slab.h>
1463
1464
1465 -static const struct ssb_sprom *fallback_sprom;
1466 +static int(*get_fallback_sprom)(struct ssb_bus *dev, struct ssb_sprom *out);
1467
1468
1469 static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len,
1470 @@ -145,36 +145,43 @@ out:
1471 }
1472
1473 /**
1474 - * ssb_arch_set_fallback_sprom - Set a fallback SPROM for use if no SPROM is found.
1475 + * ssb_arch_register_fallback_sprom - Registers a method providing a
1476 + * fallback SPROM if no SPROM is found.
1477 *
1478 - * @sprom: The SPROM data structure to register.
1479 + * @sprom_callback: The callback function.
1480 *
1481 - * With this function the architecture implementation may register a fallback
1482 - * SPROM data structure. The fallback is only used for PCI based SSB devices,
1483 - * where no valid SPROM can be found in the shadow registers.
1484 + * With this function the architecture implementation may register a
1485 + * callback handler which fills the SPROM data structure. The fallback is
1486 + * only used for PCI based SSB devices, where no valid SPROM can be found
1487 + * in the shadow registers.
1488 + *
1489 + * This function is useful for weird architectures that have a half-assed
1490 + * SSB device hardwired to their PCI bus.
1491 + *
1492 + * Note that it does only work with PCI attached SSB devices. PCMCIA
1493 + * devices currently don't use this fallback.
1494 + * Architectures must provide the SPROM for native SSB devices anyway, so
1495 + * the fallback also isn't used for native devices.
1496 *
1497 - * This function is useful for weird architectures that have a half-assed SSB device
1498 - * hardwired to their PCI bus.
1499 - *
1500 - * Note that it does only work with PCI attached SSB devices. PCMCIA devices currently
1501 - * don't use this fallback.
1502 - * Architectures must provide the SPROM for native SSB devices anyway,
1503 - * so the fallback also isn't used for native devices.
1504 - *
1505 - * This function is available for architecture code, only. So it is not exported.
1506 + * This function is available for architecture code, only. So it is not
1507 + * exported.
1508 */
1509 -int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom)
1510 +int ssb_arch_register_fallback_sprom(int (*sprom_callback)(struct ssb_bus *bus,
1511 + struct ssb_sprom *out))
1512 {
1513 - if (fallback_sprom)
1514 + if (get_fallback_sprom)
1515 return -EEXIST;
1516 - fallback_sprom = sprom;
1517 + get_fallback_sprom = sprom_callback;
1518
1519 return 0;
1520 }
1521
1522 -const struct ssb_sprom *ssb_get_fallback_sprom(void)
1523 +int ssb_fill_sprom_with_fallback(struct ssb_bus *bus, struct ssb_sprom *out)
1524 {
1525 - return fallback_sprom;
1526 + if (!get_fallback_sprom)
1527 + return -ENOENT;
1528 +
1529 + return get_fallback_sprom(bus, out);
1530 }
1531
1532 /* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */
1533 --- a/drivers/ssb/ssb_private.h
1534 +++ b/drivers/ssb/ssb_private.h
1535 @@ -171,7 +171,8 @@ ssize_t ssb_attr_sprom_store(struct ssb_
1536 const char *buf, size_t count,
1537 int (*sprom_check_crc)(const u16 *sprom, size_t size),
1538 int (*sprom_write)(struct ssb_bus *bus, const u16 *sprom));
1539 -extern const struct ssb_sprom *ssb_get_fallback_sprom(void);
1540 +extern int ssb_fill_sprom_with_fallback(struct ssb_bus *bus,
1541 + struct ssb_sprom *out);
1542
1543
1544 /* core.c */
1545 @@ -206,4 +207,8 @@ static inline void b43_pci_ssb_bridge_ex
1546 }
1547 #endif /* CONFIG_SSB_B43_PCI_BRIDGE */
1548
1549 +/* driver_chipcommon_pmu.c */
1550 +extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc);
1551 +extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc);
1552 +
1553 #endif /* LINUX_SSB_PRIVATE_H_ */
1554 --- a/include/linux/ssb/ssb.h
1555 +++ b/include/linux/ssb/ssb.h
1556 @@ -16,6 +16,12 @@ struct pcmcia_device;
1557 struct ssb_bus;
1558 struct ssb_driver;
1559
1560 +struct ssb_sprom_core_pwr_info {
1561 + u8 itssi_2g, itssi_5g;
1562 + u8 maxpwr_2g, maxpwr_5gl, maxpwr_5g, maxpwr_5gh;
1563 + u16 pa_2g[4], pa_5gl[4], pa_5g[4], pa_5gh[4];
1564 +};
1565 +
1566 struct ssb_sprom {
1567 u8 revision;
1568 u8 il0mac[6]; /* MAC address for 802.11b/g */
1569 @@ -25,8 +31,13 @@ struct ssb_sprom {
1570 u8 et1phyaddr; /* MII address for enet1 */
1571 u8 et0mdcport; /* MDIO for enet0 */
1572 u8 et1mdcport; /* MDIO for enet1 */
1573 - u8 board_rev; /* Board revision number from SPROM. */
1574 + u16 board_rev; /* Board revision number from SPROM. */
1575 + u16 board_num; /* Board number from SPROM. */
1576 + u16 board_type; /* Board type from SPROM. */
1577 u8 country_code; /* Country Code */
1578 + char alpha2[2]; /* Country Code as two chars like EU or US */
1579 + u8 leddc_on_time; /* LED Powersave Duty Cycle On Count */
1580 + u8 leddc_off_time; /* LED Powersave Duty Cycle Off Count */
1581 u8 ant_available_a; /* 2GHz antenna available bits (up to 4) */
1582 u8 ant_available_bg; /* 5GHz antenna available bits (up to 4) */
1583 u16 pa0b0;
1584 @@ -45,10 +56,10 @@ struct ssb_sprom {
1585 u8 gpio1; /* GPIO pin 1 */
1586 u8 gpio2; /* GPIO pin 2 */
1587 u8 gpio3; /* GPIO pin 3 */
1588 - u16 maxpwr_bg; /* 2.4GHz Amplifier Max Power (in dBm Q5.2) */
1589 - u16 maxpwr_al; /* 5.2GHz Amplifier Max Power (in dBm Q5.2) */
1590 - u16 maxpwr_a; /* 5.3GHz Amplifier Max Power (in dBm Q5.2) */
1591 - u16 maxpwr_ah; /* 5.8GHz Amplifier Max Power (in dBm Q5.2) */
1592 + u8 maxpwr_bg; /* 2.4GHz Amplifier Max Power (in dBm Q5.2) */
1593 + u8 maxpwr_al; /* 5.2GHz Amplifier Max Power (in dBm Q5.2) */
1594 + u8 maxpwr_a; /* 5.3GHz Amplifier Max Power (in dBm Q5.2) */
1595 + u8 maxpwr_ah; /* 5.8GHz Amplifier Max Power (in dBm Q5.2) */
1596 u8 itssi_a; /* Idle TSSI Target for A-PHY */
1597 u8 itssi_bg; /* Idle TSSI Target for B/G-PHY */
1598 u8 tri2g; /* 2.4GHz TX isolation */
1599 @@ -59,8 +70,8 @@ struct ssb_sprom {
1600 u8 txpid5gl[4]; /* 4.9 - 5.1GHz TX power index */
1601 u8 txpid5g[4]; /* 5.1 - 5.5GHz TX power index */
1602 u8 txpid5gh[4]; /* 5.5 - ...GHz TX power index */
1603 - u8 rxpo2g; /* 2GHz RX power offset */
1604 - u8 rxpo5g; /* 5GHz RX power offset */
1605 + s8 rxpo2g; /* 2GHz RX power offset */
1606 + s8 rxpo5g; /* 5GHz RX power offset */
1607 u8 rssisav2g; /* 2GHz RSSI params */
1608 u8 rssismc2g;
1609 u8 rssismf2g;
1610 @@ -80,26 +91,103 @@ struct ssb_sprom {
1611 u16 boardflags2_hi; /* Board flags (bits 48-63) */
1612 /* TODO store board flags in a single u64 */
1613
1614 + struct ssb_sprom_core_pwr_info core_pwr_info[4];
1615 +
1616 /* Antenna gain values for up to 4 antennas
1617 * on each band. Values in dBm/4 (Q5.2). Negative gain means the
1618 * loss in the connectors is bigger than the gain. */
1619 struct {
1620 - struct {
1621 - s8 a0, a1, a2, a3;
1622 - } ghz24; /* 2.4GHz band */
1623 - struct {
1624 - s8 a0, a1, a2, a3;
1625 - } ghz5; /* 5GHz band */
1626 + s8 a0, a1, a2, a3;
1627 } antenna_gain;
1628
1629 - /* TODO - add any parameters needed from rev 2, 3, 4, 5 or 8 SPROMs */
1630 + struct {
1631 + struct {
1632 + u8 tssipos, extpa_gain, pdet_range, tr_iso, antswlut;
1633 + } ghz2;
1634 + struct {
1635 + u8 tssipos, extpa_gain, pdet_range, tr_iso, antswlut;
1636 + } ghz5;
1637 + } fem;
1638 +
1639 + u16 mcs2gpo[8];
1640 + u16 mcs5gpo[8];
1641 + u16 mcs5glpo[8];
1642 + u16 mcs5ghpo[8];
1643 + u8 opo;
1644 +
1645 + u8 rxgainerr2ga[3];
1646 + u8 rxgainerr5gla[3];
1647 + u8 rxgainerr5gma[3];
1648 + u8 rxgainerr5gha[3];
1649 + u8 rxgainerr5gua[3];
1650 +
1651 + u8 noiselvl2ga[3];
1652 + u8 noiselvl5gla[3];
1653 + u8 noiselvl5gma[3];
1654 + u8 noiselvl5gha[3];
1655 + u8 noiselvl5gua[3];
1656 +
1657 + u8 regrev;
1658 + u8 txchain;
1659 + u8 rxchain;
1660 + u8 antswitch;
1661 + u16 cddpo;
1662 + u16 stbcpo;
1663 + u16 bw40po;
1664 + u16 bwduppo;
1665 +
1666 + u8 tempthresh;
1667 + u8 tempoffset;
1668 + u16 rawtempsense;
1669 + u8 measpower;
1670 + u8 tempsense_slope;
1671 + u8 tempcorrx;
1672 + u8 tempsense_option;
1673 + u8 freqoffset_corr;
1674 + u8 iqcal_swp_dis;
1675 + u8 hw_iqcal_en;
1676 + u8 elna2g;
1677 + u8 elna5g;
1678 + u8 phycal_tempdelta;
1679 + u8 temps_period;
1680 + u8 temps_hysteresis;
1681 + u8 measpower1;
1682 + u8 measpower2;
1683 + u8 pcieingress_war;
1684 +
1685 + /* power per rate from sromrev 9 */
1686 + u16 cckbw202gpo;
1687 + u16 cckbw20ul2gpo;
1688 + u32 legofdmbw202gpo;
1689 + u32 legofdmbw20ul2gpo;
1690 + u32 legofdmbw205glpo;
1691 + u32 legofdmbw20ul5glpo;
1692 + u32 legofdmbw205gmpo;
1693 + u32 legofdmbw20ul5gmpo;
1694 + u32 legofdmbw205ghpo;
1695 + u32 legofdmbw20ul5ghpo;
1696 + u32 mcsbw202gpo;
1697 + u32 mcsbw20ul2gpo;
1698 + u32 mcsbw402gpo;
1699 + u32 mcsbw205glpo;
1700 + u32 mcsbw20ul5glpo;
1701 + u32 mcsbw405glpo;
1702 + u32 mcsbw205gmpo;
1703 + u32 mcsbw20ul5gmpo;
1704 + u32 mcsbw405gmpo;
1705 + u32 mcsbw205ghpo;
1706 + u32 mcsbw20ul5ghpo;
1707 + u32 mcsbw405ghpo;
1708 + u16 mcs32po;
1709 + u16 legofdm40duppo;
1710 + u8 sar2g;
1711 + u8 sar5g;
1712 };
1713
1714 /* Information about the PCB the circuitry is soldered on. */
1715 struct ssb_boardinfo {
1716 u16 vendor;
1717 u16 type;
1718 - u16 rev;
1719 };
1720
1721
1722 @@ -229,10 +317,9 @@ struct ssb_driver {
1723 #define drv_to_ssb_drv(_drv) container_of(_drv, struct ssb_driver, drv)
1724
1725 extern int __ssb_driver_register(struct ssb_driver *drv, struct module *owner);
1726 -static inline int ssb_driver_register(struct ssb_driver *drv)
1727 -{
1728 - return __ssb_driver_register(drv, THIS_MODULE);
1729 -}
1730 +#define ssb_driver_register(drv) \
1731 + __ssb_driver_register(drv, THIS_MODULE)
1732 +
1733 extern void ssb_driver_unregister(struct ssb_driver *drv);
1734
1735
1736 @@ -308,7 +395,7 @@ struct ssb_bus {
1737
1738 /* ID information about the Chip. */
1739 u16 chip_id;
1740 - u16 chip_rev;
1741 + u8 chip_rev;
1742 u16 sprom_offset;
1743 u16 sprom_size; /* number of words in sprom */
1744 u8 chip_package;
1745 @@ -404,7 +491,9 @@ extern bool ssb_is_sprom_available(struc
1746
1747 /* Set a fallback SPROM.
1748 * See kdoc at the function definition for complete documentation. */
1749 -extern int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom);
1750 +extern int ssb_arch_register_fallback_sprom(
1751 + int (*sprom_callback)(struct ssb_bus *bus,
1752 + struct ssb_sprom *out));
1753
1754 /* Suspend a SSB bus.
1755 * Call this from the parent bus suspend routine. */
1756 @@ -518,6 +607,7 @@ extern int ssb_bus_may_powerdown(struct
1757 * Otherwise static always-on powercontrol will be used. */
1758 extern int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl);
1759
1760 +extern void ssb_commit_settings(struct ssb_bus *bus);
1761
1762 /* Various helper functions */
1763 extern u32 ssb_admatch_base(u32 adm);
1764 --- a/include/linux/ssb/ssb_driver_chipcommon.h
1765 +++ b/include/linux/ssb/ssb_driver_chipcommon.h
1766 @@ -8,7 +8,7 @@
1767 * gpio interface, extbus, and support for serial and parallel flashes.
1768 *
1769 * Copyright 2005, Broadcom Corporation
1770 - * Copyright 2006, Michael Buesch <mb@bu3sch.de>
1771 + * Copyright 2006, Michael Buesch <m@bues.ch>
1772 *
1773 * Licensed under the GPL version 2. See COPYING for details.
1774 */
1775 @@ -123,6 +123,8 @@
1776 #define SSB_CHIPCO_FLASHDATA 0x0048
1777 #define SSB_CHIPCO_BCAST_ADDR 0x0050
1778 #define SSB_CHIPCO_BCAST_DATA 0x0054
1779 +#define SSB_CHIPCO_GPIOPULLUP 0x0058 /* Rev >= 20 only */
1780 +#define SSB_CHIPCO_GPIOPULLDOWN 0x005C /* Rev >= 20 only */
1781 #define SSB_CHIPCO_GPIOIN 0x0060
1782 #define SSB_CHIPCO_GPIOOUT 0x0064
1783 #define SSB_CHIPCO_GPIOOUTEN 0x0068
1784 @@ -131,6 +133,9 @@
1785 #define SSB_CHIPCO_GPIOIRQ 0x0074
1786 #define SSB_CHIPCO_WATCHDOG 0x0080
1787 #define SSB_CHIPCO_GPIOTIMER 0x0088 /* LED powersave (corerev >= 16) */
1788 +#define SSB_CHIPCO_GPIOTIMER_OFFTIME 0x0000FFFF
1789 +#define SSB_CHIPCO_GPIOTIMER_OFFTIME_SHIFT 0
1790 +#define SSB_CHIPCO_GPIOTIMER_ONTIME 0xFFFF0000
1791 #define SSB_CHIPCO_GPIOTIMER_ONTIME_SHIFT 16
1792 #define SSB_CHIPCO_GPIOTOUTM 0x008C /* LED powersave (corerev >= 16) */
1793 #define SSB_CHIPCO_CLOCK_N 0x0090
1794 @@ -189,8 +194,10 @@
1795 #define SSB_CHIPCO_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */
1796 #define SSB_CHIPCO_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */
1797 #define SSB_CHIPCO_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */
1798 -#define SSB_CHIPCO_CLKCTLST_HAVEHT 0x00010000 /* HT available */
1799 -#define SSB_CHIPCO_CLKCTLST_HAVEALP 0x00020000 /* APL available */
1800 +#define SSB_CHIPCO_CLKCTLST_HAVEALP 0x00010000 /* ALP available */
1801 +#define SSB_CHIPCO_CLKCTLST_HAVEHT 0x00020000 /* HT available */
1802 +#define SSB_CHIPCO_CLKCTLST_4328A0_HAVEHT 0x00010000 /* 4328a0 has reversed bits */
1803 +#define SSB_CHIPCO_CLKCTLST_4328A0_HAVEALP 0x00020000 /* 4328a0 has reversed bits */
1804 #define SSB_CHIPCO_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */
1805 #define SSB_CHIPCO_UART0_DATA 0x0300
1806 #define SSB_CHIPCO_UART0_IMR 0x0304
1807 --- a/include/linux/ssb/ssb_driver_gige.h
1808 +++ b/include/linux/ssb/ssb_driver_gige.h
1809 @@ -2,6 +2,7 @@
1810 #define LINUX_SSB_DRIVER_GIGE_H_
1811
1812 #include <linux/ssb/ssb.h>
1813 +#include <linux/bug.h>
1814 #include <linux/pci.h>
1815 #include <linux/spinlock.h>
1816
1817 --- a/include/linux/ssb/ssb_regs.h
1818 +++ b/include/linux/ssb/ssb_regs.h
1819 @@ -97,7 +97,7 @@
1820 #define SSB_INTVEC_ENET1 0x00000040 /* Enable interrupts for enet 1 */
1821 #define SSB_TMSLOW 0x0F98 /* SB Target State Low */
1822 #define SSB_TMSLOW_RESET 0x00000001 /* Reset */
1823 -#define SSB_TMSLOW_REJECT_22 0x00000002 /* Reject (Backplane rev 2.2) */
1824 +#define SSB_TMSLOW_REJECT 0x00000002 /* Reject (Standard Backplane) */
1825 #define SSB_TMSLOW_REJECT_23 0x00000004 /* Reject (Backplane rev 2.3) */
1826 #define SSB_TMSLOW_CLOCK 0x00010000 /* Clock Enable */
1827 #define SSB_TMSLOW_FGC 0x00020000 /* Force Gated Clocks On */
1828 @@ -228,6 +228,7 @@
1829 #define SSB_SPROM1_AGAIN_BG_SHIFT 0
1830 #define SSB_SPROM1_AGAIN_A 0xFF00 /* A-PHY */
1831 #define SSB_SPROM1_AGAIN_A_SHIFT 8
1832 +#define SSB_SPROM1_CCODE 0x0076
1833
1834 /* SPROM Revision 2 (inherits from rev 1) */
1835 #define SSB_SPROM2_BFLHI 0x0038 /* Boardflags (high 16 bits) */
1836 @@ -267,6 +268,7 @@
1837 #define SSB_SPROM3_OFDMGPO 0x107A /* G-PHY OFDM Power Offset (4 bytes, BigEndian) */
1838
1839 /* SPROM Revision 4 */
1840 +#define SSB_SPROM4_BOARDREV 0x0042 /* Board revision */
1841 #define SSB_SPROM4_BFLLO 0x0044 /* Boardflags (low 16 bits) */
1842 #define SSB_SPROM4_BFLHI 0x0046 /* Board Flags Hi */
1843 #define SSB_SPROM4_BFL2LO 0x0048 /* Board flags 2 (low 16 bits) */
1844 @@ -389,6 +391,11 @@
1845 #define SSB_SPROM8_GPIOB_P2 0x00FF /* Pin 2 */
1846 #define SSB_SPROM8_GPIOB_P3 0xFF00 /* Pin 3 */
1847 #define SSB_SPROM8_GPIOB_P3_SHIFT 8
1848 +#define SSB_SPROM8_LEDDC 0x009A
1849 +#define SSB_SPROM8_LEDDC_ON 0xFF00 /* oncount */
1850 +#define SSB_SPROM8_LEDDC_ON_SHIFT 8
1851 +#define SSB_SPROM8_LEDDC_OFF 0x00FF /* offcount */
1852 +#define SSB_SPROM8_LEDDC_OFF_SHIFT 0
1853 #define SSB_SPROM8_ANTAVAIL 0x009C /* Antenna available bitfields*/
1854 #define SSB_SPROM8_ANTAVAIL_A 0xFF00 /* A-PHY bitfield */
1855 #define SSB_SPROM8_ANTAVAIL_A_SHIFT 8
1856 @@ -404,6 +411,13 @@
1857 #define SSB_SPROM8_AGAIN2_SHIFT 0
1858 #define SSB_SPROM8_AGAIN3 0xFF00 /* Antenna 3 */
1859 #define SSB_SPROM8_AGAIN3_SHIFT 8
1860 +#define SSB_SPROM8_TXRXC 0x00A2
1861 +#define SSB_SPROM8_TXRXC_TXCHAIN 0x000f
1862 +#define SSB_SPROM8_TXRXC_TXCHAIN_SHIFT 0
1863 +#define SSB_SPROM8_TXRXC_RXCHAIN 0x00f0
1864 +#define SSB_SPROM8_TXRXC_RXCHAIN_SHIFT 4
1865 +#define SSB_SPROM8_TXRXC_SWITCH 0xff00
1866 +#define SSB_SPROM8_TXRXC_SWITCH_SHIFT 8
1867 #define SSB_SPROM8_RSSIPARM2G 0x00A4 /* RSSI params for 2GHz */
1868 #define SSB_SPROM8_RSSISMF2G 0x000F
1869 #define SSB_SPROM8_RSSISMC2G 0x00F0
1870 @@ -430,8 +444,87 @@
1871 #define SSB_SPROM8_TRI5GH_SHIFT 8
1872 #define SSB_SPROM8_RXPO 0x00AC /* RX power offsets */
1873 #define SSB_SPROM8_RXPO2G 0x00FF /* 2GHz RX power offset */
1874 +#define SSB_SPROM8_RXPO2G_SHIFT 0
1875 #define SSB_SPROM8_RXPO5G 0xFF00 /* 5GHz RX power offset */
1876 #define SSB_SPROM8_RXPO5G_SHIFT 8
1877 +#define SSB_SPROM8_FEM2G 0x00AE
1878 +#define SSB_SPROM8_FEM5G 0x00B0
1879 +#define SSB_SROM8_FEM_TSSIPOS 0x0001
1880 +#define SSB_SROM8_FEM_TSSIPOS_SHIFT 0
1881 +#define SSB_SROM8_FEM_EXTPA_GAIN 0x0006
1882 +#define SSB_SROM8_FEM_EXTPA_GAIN_SHIFT 1
1883 +#define SSB_SROM8_FEM_PDET_RANGE 0x00F8
1884 +#define SSB_SROM8_FEM_PDET_RANGE_SHIFT 3
1885 +#define SSB_SROM8_FEM_TR_ISO 0x0700
1886 +#define SSB_SROM8_FEM_TR_ISO_SHIFT 8
1887 +#define SSB_SROM8_FEM_ANTSWLUT 0xF800
1888 +#define SSB_SROM8_FEM_ANTSWLUT_SHIFT 11
1889 +#define SSB_SPROM8_THERMAL 0x00B2
1890 +#define SSB_SPROM8_THERMAL_OFFSET 0x00ff
1891 +#define SSB_SPROM8_THERMAL_OFFSET_SHIFT 0
1892 +#define SSB_SPROM8_THERMAL_TRESH 0xff00
1893 +#define SSB_SPROM8_THERMAL_TRESH_SHIFT 8
1894 +/* Temp sense related entries */
1895 +#define SSB_SPROM8_RAWTS 0x00B4
1896 +#define SSB_SPROM8_RAWTS_RAWTEMP 0x01ff
1897 +#define SSB_SPROM8_RAWTS_RAWTEMP_SHIFT 0
1898 +#define SSB_SPROM8_RAWTS_MEASPOWER 0xfe00
1899 +#define SSB_SPROM8_RAWTS_MEASPOWER_SHIFT 9
1900 +#define SSB_SPROM8_OPT_CORRX 0x00B6
1901 +#define SSB_SPROM8_OPT_CORRX_TEMP_SLOPE 0x00ff
1902 +#define SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT 0
1903 +#define SSB_SPROM8_OPT_CORRX_TEMPCORRX 0xfc00
1904 +#define SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT 10
1905 +#define SSB_SPROM8_OPT_CORRX_TEMP_OPTION 0x0300
1906 +#define SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT 8
1907 +/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable, IQSWP: IQ CAL swap disable */
1908 +#define SSB_SPROM8_HWIQ_IQSWP 0x00B8
1909 +#define SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR 0x000f
1910 +#define SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT 0
1911 +#define SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP 0x0010
1912 +#define SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT 4
1913 +#define SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL 0x0020
1914 +#define SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT 5
1915 +#define SSB_SPROM8_TEMPDELTA 0x00BA
1916 +#define SSB_SPROM8_TEMPDELTA_PHYCAL 0x00ff
1917 +#define SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT 0
1918 +#define SSB_SPROM8_TEMPDELTA_PERIOD 0x0f00
1919 +#define SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT 8
1920 +#define SSB_SPROM8_TEMPDELTA_HYSTERESIS 0xf000
1921 +#define SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT 12
1922 +
1923 +/* There are 4 blocks with power info sharing the same layout */
1924 +#define SSB_SROM8_PWR_INFO_CORE0 0x00C0
1925 +#define SSB_SROM8_PWR_INFO_CORE1 0x00E0
1926 +#define SSB_SROM8_PWR_INFO_CORE2 0x0100
1927 +#define SSB_SROM8_PWR_INFO_CORE3 0x0120
1928 +
1929 +#define SSB_SROM8_2G_MAXP_ITSSI 0x00
1930 +#define SSB_SPROM8_2G_MAXP 0x00FF
1931 +#define SSB_SPROM8_2G_ITSSI 0xFF00
1932 +#define SSB_SPROM8_2G_ITSSI_SHIFT 8
1933 +#define SSB_SROM8_2G_PA_0 0x02 /* 2GHz power amp settings */
1934 +#define SSB_SROM8_2G_PA_1 0x04
1935 +#define SSB_SROM8_2G_PA_2 0x06
1936 +#define SSB_SROM8_5G_MAXP_ITSSI 0x08 /* 5GHz ITSSI and 5.3GHz Max Power */
1937 +#define SSB_SPROM8_5G_MAXP 0x00FF
1938 +#define SSB_SPROM8_5G_ITSSI 0xFF00
1939 +#define SSB_SPROM8_5G_ITSSI_SHIFT 8
1940 +#define SSB_SPROM8_5GHL_MAXP 0x0A /* 5.2GHz and 5.8GHz Max Power */
1941 +#define SSB_SPROM8_5GH_MAXP 0x00FF
1942 +#define SSB_SPROM8_5GL_MAXP 0xFF00
1943 +#define SSB_SPROM8_5GL_MAXP_SHIFT 8
1944 +#define SSB_SROM8_5G_PA_0 0x0C /* 5.3GHz power amp settings */
1945 +#define SSB_SROM8_5G_PA_1 0x0E
1946 +#define SSB_SROM8_5G_PA_2 0x10
1947 +#define SSB_SROM8_5GL_PA_0 0x12 /* 5.2GHz power amp settings */
1948 +#define SSB_SROM8_5GL_PA_1 0x14
1949 +#define SSB_SROM8_5GL_PA_2 0x16
1950 +#define SSB_SROM8_5GH_PA_0 0x18 /* 5.8GHz power amp settings */
1951 +#define SSB_SROM8_5GH_PA_1 0x1A
1952 +#define SSB_SROM8_5GH_PA_2 0x1C
1953 +
1954 +/* TODO: Make it deprecated */
1955 #define SSB_SPROM8_MAXP_BG 0x00C0 /* Max Power 2GHz in path 1 */
1956 #define SSB_SPROM8_MAXP_BG_MASK 0x00FF /* Mask for Max Power 2GHz */
1957 #define SSB_SPROM8_ITSSI_BG 0xFF00 /* Mask for path 1 itssi_bg */
1958 @@ -456,12 +549,63 @@
1959 #define SSB_SPROM8_PA1HIB0 0x00D8 /* 5.8GHz power amp settings */
1960 #define SSB_SPROM8_PA1HIB1 0x00DA
1961 #define SSB_SPROM8_PA1HIB2 0x00DC
1962 +
1963 #define SSB_SPROM8_CCK2GPO 0x0140 /* CCK power offset */
1964 #define SSB_SPROM8_OFDM2GPO 0x0142 /* 2.4GHz OFDM power offset */
1965 #define SSB_SPROM8_OFDM5GPO 0x0146 /* 5.3GHz OFDM power offset */
1966 #define SSB_SPROM8_OFDM5GLPO 0x014A /* 5.2GHz OFDM power offset */
1967 #define SSB_SPROM8_OFDM5GHPO 0x014E /* 5.8GHz OFDM power offset */
1968
1969 +#define SSB_SPROM8_2G_MCSPO 0x0152
1970 +#define SSB_SPROM8_5G_MCSPO 0x0162
1971 +#define SSB_SPROM8_5GL_MCSPO 0x0172
1972 +#define SSB_SPROM8_5GH_MCSPO 0x0182
1973 +
1974 +#define SSB_SPROM8_CDDPO 0x0192
1975 +#define SSB_SPROM8_STBCPO 0x0194
1976 +#define SSB_SPROM8_BW40PO 0x0196
1977 +#define SSB_SPROM8_BWDUPPO 0x0198
1978 +
1979 +/* Values for boardflags_lo read from SPROM */
1980 +#define SSB_BFL_BTCOEXIST 0x0001 /* implements Bluetooth coexistance */
1981 +#define SSB_BFL_PACTRL 0x0002 /* GPIO 9 controlling the PA */
1982 +#define SSB_BFL_AIRLINEMODE 0x0004 /* implements GPIO 13 radio disable indication */
1983 +#define SSB_BFL_RSSI 0x0008 /* software calculates nrssi slope. */
1984 +#define SSB_BFL_ENETSPI 0x0010 /* has ephy roboswitch spi */
1985 +#define SSB_BFL_XTAL_NOSLOW 0x0020 /* no slow clock available */
1986 +#define SSB_BFL_CCKHIPWR 0x0040 /* can do high power CCK transmission */
1987 +#define SSB_BFL_ENETADM 0x0080 /* has ADMtek switch */
1988 +#define SSB_BFL_ENETVLAN 0x0100 /* can do vlan */
1989 +#define SSB_BFL_AFTERBURNER 0x0200 /* supports Afterburner mode */
1990 +#define SSB_BFL_NOPCI 0x0400 /* board leaves PCI floating */
1991 +#define SSB_BFL_FEM 0x0800 /* supports the Front End Module */
1992 +#define SSB_BFL_EXTLNA 0x1000 /* has an external LNA */
1993 +#define SSB_BFL_HGPA 0x2000 /* had high gain PA */
1994 +#define SSB_BFL_BTCMOD 0x4000 /* BFL_BTCOEXIST is given in alternate GPIOs */
1995 +#define SSB_BFL_ALTIQ 0x8000 /* alternate I/Q settings */
1996 +
1997 +/* Values for boardflags_hi read from SPROM */
1998 +#define SSB_BFH_NOPA 0x0001 /* has no PA */
1999 +#define SSB_BFH_RSSIINV 0x0002 /* RSSI uses positive slope (not TSSI) */
2000 +#define SSB_BFH_PAREF 0x0004 /* uses the PARef LDO */
2001 +#define SSB_BFH_3TSWITCH 0x0008 /* uses a triple throw switch shared with bluetooth */
2002 +#define SSB_BFH_PHASESHIFT 0x0010 /* can support phase shifter */
2003 +#define SSB_BFH_BUCKBOOST 0x0020 /* has buck/booster */
2004 +#define SSB_BFH_FEM_BT 0x0040 /* has FEM and switch to share antenna with bluetooth */
2005 +
2006 +/* Values for boardflags2_lo read from SPROM */
2007 +#define SSB_BFL2_RXBB_INT_REG_DIS 0x0001 /* external RX BB regulator present */
2008 +#define SSB_BFL2_APLL_WAR 0x0002 /* alternative A-band PLL settings implemented */
2009 +#define SSB_BFL2_TXPWRCTRL_EN 0x0004 /* permits enabling TX Power Control */
2010 +#define SSB_BFL2_2X4_DIV 0x0008 /* 2x4 diversity switch */
2011 +#define SSB_BFL2_5G_PWRGAIN 0x0010 /* supports 5G band power gain */
2012 +#define SSB_BFL2_PCIEWAR_OVR 0x0020 /* overrides ASPM and Clkreq settings */
2013 +#define SSB_BFL2_CAESERS_BRD 0x0040 /* is Caesers board (unused) */
2014 +#define SSB_BFL2_BTC3WIRE 0x0080 /* used 3-wire bluetooth coexist */
2015 +#define SSB_BFL2_SKWRKFEM_BRD 0x0100 /* 4321mcm93 uses Skyworks FEM */
2016 +#define SSB_BFL2_SPUR_WAR 0x0200 /* has a workaround for clock-harmonic spurs */
2017 +#define SSB_BFL2_GPLL_WAR 0x0400 /* altenative G-band PLL settings implemented */
2018 +
2019 /* Values for SSB_SPROM1_BINF_CCODE */
2020 enum {
2021 SSB_SPROM1CCODE_WORLD = 0,