aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ssb')
-rw-r--r--drivers/ssb/driver_chipcommon_pmu.c48
-rw-r--r--drivers/ssb/driver_mipscore.c3
-rw-r--r--drivers/ssb/main.c3
-rw-r--r--drivers/ssb/pci.c81
-rw-r--r--drivers/ssb/pcmcia.c12
-rw-r--r--drivers/ssb/scan.c3
-rw-r--r--drivers/ssb/sdio.c12
-rw-r--r--drivers/ssb/ssb_private.h4
8 files changed, 117 insertions, 49 deletions
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c
index e5a2e0e9bc19..b58fef780ea0 100644
--- a/drivers/ssb/driver_chipcommon_pmu.c
+++ b/drivers/ssb/driver_chipcommon_pmu.c
@@ -13,6 +13,9 @@
13#include <linux/ssb/ssb_driver_chipcommon.h> 13#include <linux/ssb/ssb_driver_chipcommon.h>
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/export.h> 15#include <linux/export.h>
16#ifdef CONFIG_BCM47XX
17#include <asm/mach-bcm47xx/nvram.h>
18#endif
16 19
17#include "ssb_private.h" 20#include "ssb_private.h"
18 21
@@ -92,10 +95,6 @@ static void ssb_pmu0_pllinit_r0(struct ssb_chipcommon *cc,
92 u32 pmuctl, tmp, pllctl; 95 u32 pmuctl, tmp, pllctl;
93 unsigned int i; 96 unsigned int i;
94 97
95 if ((bus->chip_id == 0x5354) && !crystalfreq) {
96 /* The 5354 crystal freq is 25MHz */
97 crystalfreq = 25000;
98 }
99 if (crystalfreq) 98 if (crystalfreq)
100 e = pmu0_plltab_find_entry(crystalfreq); 99 e = pmu0_plltab_find_entry(crystalfreq);
101 if (!e) 100 if (!e)
@@ -321,7 +320,11 @@ static void ssb_pmu_pll_init(struct ssb_chipcommon *cc)
321 u32 crystalfreq = 0; /* in kHz. 0 = keep default freq. */ 320 u32 crystalfreq = 0; /* in kHz. 0 = keep default freq. */
322 321
323 if (bus->bustype == SSB_BUSTYPE_SSB) { 322 if (bus->bustype == SSB_BUSTYPE_SSB) {
324 /* TODO: The user may override the crystal frequency. */ 323#ifdef CONFIG_BCM47XX
324 char buf[20];
325 if (nvram_getenv("xtalfreq", buf, sizeof(buf)) >= 0)
326 crystalfreq = simple_strtoul(buf, NULL, 0);
327#endif
325 } 328 }
326 329
327 switch (bus->chip_id) { 330 switch (bus->chip_id) {
@@ -330,7 +333,11 @@ static void ssb_pmu_pll_init(struct ssb_chipcommon *cc)
330 ssb_pmu1_pllinit_r0(cc, crystalfreq); 333 ssb_pmu1_pllinit_r0(cc, crystalfreq);
331 break; 334 break;
332 case 0x4328: 335 case 0x4328:
336 ssb_pmu0_pllinit_r0(cc, crystalfreq);
337 break;
333 case 0x5354: 338 case 0x5354:
339 if (crystalfreq == 0)
340 crystalfreq = 25000;
334 ssb_pmu0_pllinit_r0(cc, crystalfreq); 341 ssb_pmu0_pllinit_r0(cc, crystalfreq);
335 break; 342 break;
336 case 0x4322: 343 case 0x4322:
@@ -607,3 +614,34 @@ void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on)
607 614
608EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage); 615EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage);
609EXPORT_SYMBOL(ssb_pmu_set_ldo_paref); 616EXPORT_SYMBOL(ssb_pmu_set_ldo_paref);
617
618u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc)
619{
620 struct ssb_bus *bus = cc->dev->bus;
621
622 switch (bus->chip_id) {
623 case 0x5354:
624 /* 5354 chip uses a non programmable PLL of frequency 240MHz */
625 return 240000000;
626 default:
627 ssb_printk(KERN_ERR PFX
628 "ERROR: PMU cpu clock unknown for device %04X\n",
629 bus->chip_id);
630 return 0;
631 }
632}
633
634u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc)
635{
636 struct ssb_bus *bus = cc->dev->bus;
637
638 switch (bus->chip_id) {
639 case 0x5354:
640 return 120000000;
641 default:
642 ssb_printk(KERN_ERR PFX
643 "ERROR: PMU controlclock unknown for device %04X\n",
644 bus->chip_id);
645 return 0;
646 }
647}
diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c
index ced501568594..7e2ddc042f5b 100644
--- a/drivers/ssb/driver_mipscore.c
+++ b/drivers/ssb/driver_mipscore.c
@@ -208,6 +208,9 @@ u32 ssb_cpu_clock(struct ssb_mipscore *mcore)
208 struct ssb_bus *bus = mcore->dev->bus; 208 struct ssb_bus *bus = mcore->dev->bus;
209 u32 pll_type, n, m, rate = 0; 209 u32 pll_type, n, m, rate = 0;
210 210
211 if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)
212 return ssb_pmu_get_cpu_clock(&bus->chipco);
213
211 if (bus->extif.dev) { 214 if (bus->extif.dev) {
212 ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m); 215 ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m);
213 } else if (bus->chipco.dev) { 216 } else if (bus->chipco.dev) {
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index ff109ae94767..df0f145c22fc 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -1078,6 +1078,9 @@ u32 ssb_clockspeed(struct ssb_bus *bus)
1078 u32 plltype; 1078 u32 plltype;
1079 u32 clkctl_n, clkctl_m; 1079 u32 clkctl_n, clkctl_m;
1080 1080
1081 if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)
1082 return ssb_pmu_get_controlclock(&bus->chipco);
1083
1081 if (ssb_extif_available(&bus->extif)) 1084 if (ssb_extif_available(&bus->extif))
1082 ssb_extif_get_clockcontrol(&bus->extif, &plltype, 1085 ssb_extif_get_clockcontrol(&bus->extif, &plltype,
1083 &clkctl_n, &clkctl_m); 1086 &clkctl_n, &clkctl_m);
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index 973223f5de8e..ed4124469a3a 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -331,7 +331,6 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
331{ 331{
332 int i; 332 int i;
333 u16 v; 333 u16 v;
334 s8 gain;
335 u16 loc[3]; 334 u16 loc[3];
336 335
337 if (out->revision == 3) /* rev 3 moved MAC */ 336 if (out->revision == 3) /* rev 3 moved MAC */
@@ -390,20 +389,12 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
390 SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0); 389 SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
391 390
392 /* Extract the antenna gain values. */ 391 /* Extract the antenna gain values. */
393 gain = r123_extract_antgain(out->revision, in, 392 out->antenna_gain.a0 = r123_extract_antgain(out->revision, in,
394 SSB_SPROM1_AGAIN_BG, 393 SSB_SPROM1_AGAIN_BG,
395 SSB_SPROM1_AGAIN_BG_SHIFT); 394 SSB_SPROM1_AGAIN_BG_SHIFT);
396 out->antenna_gain.ghz24.a0 = gain; 395 out->antenna_gain.a1 = r123_extract_antgain(out->revision, in,
397 out->antenna_gain.ghz24.a1 = gain; 396 SSB_SPROM1_AGAIN_A,
398 out->antenna_gain.ghz24.a2 = gain; 397 SSB_SPROM1_AGAIN_A_SHIFT);
399 out->antenna_gain.ghz24.a3 = gain;
400 gain = r123_extract_antgain(out->revision, in,
401 SSB_SPROM1_AGAIN_A,
402 SSB_SPROM1_AGAIN_A_SHIFT);
403 out->antenna_gain.ghz5.a0 = gain;
404 out->antenna_gain.ghz5.a1 = gain;
405 out->antenna_gain.ghz5.a2 = gain;
406 out->antenna_gain.ghz5.a3 = gain;
407} 398}
408 399
409/* Revs 4 5 and 8 have partially shared layout */ 400/* Revs 4 5 and 8 have partially shared layout */
@@ -504,16 +495,14 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
504 } 495 }
505 496
506 /* Extract the antenna gain values. */ 497 /* Extract the antenna gain values. */
507 SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01, 498 SPEX(antenna_gain.a0, SSB_SPROM4_AGAIN01,
508 SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT); 499 SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT);
509 SPEX(antenna_gain.ghz24.a1, SSB_SPROM4_AGAIN01, 500 SPEX(antenna_gain.a1, SSB_SPROM4_AGAIN01,
510 SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT); 501 SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT);
511 SPEX(antenna_gain.ghz24.a2, SSB_SPROM4_AGAIN23, 502 SPEX(antenna_gain.a2, SSB_SPROM4_AGAIN23,
512 SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT); 503 SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT);
513 SPEX(antenna_gain.ghz24.a3, SSB_SPROM4_AGAIN23, 504 SPEX(antenna_gain.a3, SSB_SPROM4_AGAIN23,
514 SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT); 505 SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT);
515 memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
516 sizeof(out->antenna_gain.ghz5));
517 506
518 sprom_extract_r458(out, in); 507 sprom_extract_r458(out, in);
519 508
@@ -523,7 +512,13 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
523static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) 512static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
524{ 513{
525 int i; 514 int i;
526 u16 v; 515 u16 v, o;
516 u16 pwr_info_offset[] = {
517 SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
518 SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
519 };
520 BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
521 ARRAY_SIZE(out->core_pwr_info));
527 522
528 /* extract the MAC address */ 523 /* extract the MAC address */
529 for (i = 0; i < 3; i++) { 524 for (i = 0; i < 3; i++) {
@@ -596,16 +591,46 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
596 SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0); 591 SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
597 592
598 /* Extract the antenna gain values. */ 593 /* Extract the antenna gain values. */
599 SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01, 594 SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
600 SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT); 595 SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
601 SPEX(antenna_gain.ghz24.a1, SSB_SPROM8_AGAIN01, 596 SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
602 SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT); 597 SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
603 SPEX(antenna_gain.ghz24.a2, SSB_SPROM8_AGAIN23, 598 SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
604 SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT); 599 SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
605 SPEX(antenna_gain.ghz24.a3, SSB_SPROM8_AGAIN23, 600 SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
606 SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT); 601 SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
607 memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24, 602
608 sizeof(out->antenna_gain.ghz5)); 603 /* Extract cores power info info */
604 for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
605 o = pwr_info_offset[i];
606 SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
607 SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
608 SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
609 SSB_SPROM8_2G_MAXP, 0);
610
611 SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
612 SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
613 SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
614
615 SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
616 SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
617 SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
618 SSB_SPROM8_5G_MAXP, 0);
619 SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
620 SSB_SPROM8_5GH_MAXP, 0);
621 SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
622 SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
623
624 SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
625 SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
626 SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
627 SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
628 SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
629 SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
630 SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
631 SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
632 SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
633 }
609 634
610 /* Extract FEM info */ 635 /* Extract FEM info */
611 SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, 636 SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G,
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c
index c821c6b2a6a0..fbafed5b729b 100644
--- a/drivers/ssb/pcmcia.c
+++ b/drivers/ssb/pcmcia.c
@@ -676,14 +676,10 @@ static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev,
676 case SSB_PCMCIA_CIS_ANTGAIN: 676 case SSB_PCMCIA_CIS_ANTGAIN:
677 GOTO_ERROR_ON(tuple->TupleDataLen != 2, 677 GOTO_ERROR_ON(tuple->TupleDataLen != 2,
678 "antg tpl size"); 678 "antg tpl size");
679 sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1]; 679 sprom->antenna_gain.a0 = tuple->TupleData[1];
680 sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1]; 680 sprom->antenna_gain.a1 = tuple->TupleData[1];
681 sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1]; 681 sprom->antenna_gain.a2 = tuple->TupleData[1];
682 sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1]; 682 sprom->antenna_gain.a3 = tuple->TupleData[1];
683 sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1];
684 sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1];
685 sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1];
686 sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1];
687 break; 683 break;
688 case SSB_PCMCIA_CIS_BFLAGS: 684 case SSB_PCMCIA_CIS_BFLAGS:
689 GOTO_ERROR_ON((tuple->TupleDataLen != 3) && 685 GOTO_ERROR_ON((tuple->TupleDataLen != 3) &&
diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c
index 3e844874631f..266c7c5c86dc 100644
--- a/drivers/ssb/scan.c
+++ b/drivers/ssb/scan.c
@@ -318,6 +318,9 @@ int ssb_bus_scan(struct ssb_bus *bus,
318 bus->chip_package = 0; 318 bus->chip_package = 0;
319 } 319 }
320 } 320 }
321 ssb_printk(KERN_INFO PFX "Found chip with id 0x%04X, rev 0x%02X and "
322 "package 0x%02X\n", bus->chip_id, bus->chip_rev,
323 bus->chip_package);
321 if (!bus->nr_devices) 324 if (!bus->nr_devices)
322 bus->nr_devices = chipid_to_nrcores(bus->chip_id); 325 bus->nr_devices = chipid_to_nrcores(bus->chip_id);
323 if (bus->nr_devices > ARRAY_SIZE(bus->devices)) { 326 if (bus->nr_devices > ARRAY_SIZE(bus->devices)) {
diff --git a/drivers/ssb/sdio.c b/drivers/ssb/sdio.c
index 63fd709038ca..b2d36f7736c5 100644
--- a/drivers/ssb/sdio.c
+++ b/drivers/ssb/sdio.c
@@ -551,14 +551,10 @@ int ssb_sdio_get_invariants(struct ssb_bus *bus,
551 case SSB_SDIO_CIS_ANTGAIN: 551 case SSB_SDIO_CIS_ANTGAIN:
552 GOTO_ERROR_ON(tuple->size != 2, 552 GOTO_ERROR_ON(tuple->size != 2,
553 "antg tpl size"); 553 "antg tpl size");
554 sprom->antenna_gain.ghz24.a0 = tuple->data[1]; 554 sprom->antenna_gain.a0 = tuple->data[1];
555 sprom->antenna_gain.ghz24.a1 = tuple->data[1]; 555 sprom->antenna_gain.a1 = tuple->data[1];
556 sprom->antenna_gain.ghz24.a2 = tuple->data[1]; 556 sprom->antenna_gain.a2 = tuple->data[1];
557 sprom->antenna_gain.ghz24.a3 = tuple->data[1]; 557 sprom->antenna_gain.a3 = tuple->data[1];
558 sprom->antenna_gain.ghz5.a0 = tuple->data[1];
559 sprom->antenna_gain.ghz5.a1 = tuple->data[1];
560 sprom->antenna_gain.ghz5.a2 = tuple->data[1];
561 sprom->antenna_gain.ghz5.a3 = tuple->data[1];
562 break; 558 break;
563 case SSB_SDIO_CIS_BFLAGS: 559 case SSB_SDIO_CIS_BFLAGS:
564 GOTO_ERROR_ON((tuple->size != 3) && 560 GOTO_ERROR_ON((tuple->size != 3) &&
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h
index 77653014db0b..a305550b4b65 100644
--- a/drivers/ssb/ssb_private.h
+++ b/drivers/ssb/ssb_private.h
@@ -207,4 +207,8 @@ static inline void b43_pci_ssb_bridge_exit(void)
207} 207}
208#endif /* CONFIG_SSB_B43_PCI_BRIDGE */ 208#endif /* CONFIG_SSB_B43_PCI_BRIDGE */
209 209
210/* driver_chipcommon_pmu.c */
211extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc);
212extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc);
213
210#endif /* LINUX_SSB_PRIVATE_H_ */ 214#endif /* LINUX_SSB_PRIVATE_H_ */