aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-05-05 13:32:35 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-05-05 13:32:35 -0400
commita70171dce9cd44cb06c7d299eba9fa87a8933045 (patch)
tree5425df5f33fadc617c7dec99578d06f0d933578e /drivers/ssb
parent5a412ad7f4c95bb5b756aa12b52646e857e7c75d (diff)
parenteaef6a93bd52a2cc47b9fce201310010707afdb4 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: drivers/net/wireless/libertas/if_cs.c drivers/net/wireless/rtlwifi/pci.c net/bluetooth/l2cap_sock.c
Diffstat (limited to 'drivers/ssb')
-rw-r--r--drivers/ssb/driver_chipcommon.c68
-rw-r--r--drivers/ssb/driver_chipcommon_pmu.c2
-rw-r--r--drivers/ssb/driver_pcicore.c131
-rw-r--r--drivers/ssb/main.c23
4 files changed, 153 insertions, 71 deletions
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
index 7c031fdc8205..06d15b6f2215 100644
--- a/drivers/ssb/driver_chipcommon.c
+++ b/drivers/ssb/driver_chipcommon.c
@@ -46,40 +46,66 @@ void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc,
46 if (!ccdev) 46 if (!ccdev)
47 return; 47 return;
48 bus = ccdev->bus; 48 bus = ccdev->bus;
49
50 /* We support SLOW only on 6..9 */
51 if (ccdev->id.revision >= 10 && mode == SSB_CLKMODE_SLOW)
52 mode = SSB_CLKMODE_DYNAMIC;
53
54 if (cc->capabilities & SSB_CHIPCO_CAP_PMU)
55 return; /* PMU controls clockmode, separated function needed */
56 SSB_WARN_ON(ccdev->id.revision >= 20);
57
49 /* chipcommon cores prior to rev6 don't support dynamic clock control */ 58 /* chipcommon cores prior to rev6 don't support dynamic clock control */
50 if (ccdev->id.revision < 6) 59 if (ccdev->id.revision < 6)
51 return; 60 return;
52 /* chipcommon cores rev10 are a whole new ball game */ 61
62 /* ChipCommon cores rev10+ need testing */
53 if (ccdev->id.revision >= 10) 63 if (ccdev->id.revision >= 10)
54 return; 64 return;
65
55 if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL)) 66 if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))
56 return; 67 return;
57 68
58 switch (mode) { 69 switch (mode) {
59 case SSB_CLKMODE_SLOW: 70 case SSB_CLKMODE_SLOW: /* For revs 6..9 only */
60 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); 71 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
61 tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW; 72 tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW;
62 chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp); 73 chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
63 break; 74 break;
64 case SSB_CLKMODE_FAST: 75 case SSB_CLKMODE_FAST:
65 ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */ 76 if (ccdev->id.revision < 10) {
66 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); 77 ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
67 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW; 78 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
68 tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL; 79 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
69 chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp); 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 }
70 break; 88 break;
71 case SSB_CLKMODE_DYNAMIC: 89 case SSB_CLKMODE_DYNAMIC:
72 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); 90 if (ccdev->id.revision < 10) {
73 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW; 91 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
74 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL; 92 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
75 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL; 93 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
76 if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) != SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL) 94 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
77 tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL; 95 if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) !=
78 chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp); 96 SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
79 97 tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
80 /* for dynamic control, we have to release our xtal_pu "force on" */ 98 chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
81 if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL) 99
82 ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0); 100 /* For dynamic control, we have to release our xtal_pu
101 * "force on" */
102 if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
103 ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
104 } else {
105 chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,
106 (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) &
107 ~SSB_CHIPCO_SYSCLKCTL_FORCEHT));
108 }
83 break; 109 break;
84 default: 110 default:
85 SSB_WARN_ON(1); 111 SSB_WARN_ON(1);
@@ -260,6 +286,12 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc)
260 if (cc->dev->id.revision >= 11) 286 if (cc->dev->id.revision >= 11)
261 cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); 287 cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
262 ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status); 288 ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status);
289
290 if (cc->dev->id.revision >= 20) {
291 chipco_write32(cc, SSB_CHIPCO_GPIOPULLUP, 0);
292 chipco_write32(cc, SSB_CHIPCO_GPIOPULLDOWN, 0);
293 }
294
263 ssb_pmu_init(cc); 295 ssb_pmu_init(cc);
264 chipco_powercontrol_init(cc); 296 chipco_powercontrol_init(cc);
265 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); 297 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c
index 5732bb2c3578..305ade7825f7 100644
--- a/drivers/ssb/driver_chipcommon_pmu.c
+++ b/drivers/ssb/driver_chipcommon_pmu.c
@@ -423,6 +423,8 @@ static void ssb_pmu_resources_init(struct ssb_chipcommon *cc)
423 423
424 switch (bus->chip_id) { 424 switch (bus->chip_id) {
425 case 0x4312: 425 case 0x4312:
426 min_msk = 0xCBB;
427 break;
426 case 0x4322: 428 case 0x4322:
427 /* We keep the default settings: 429 /* We keep the default settings:
428 * min_msk = 0xCBB 430 * min_msk = 0xCBB
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c
index 1ba9f0ee6f94..8fde1220bc89 100644
--- a/drivers/ssb/driver_pcicore.c
+++ b/drivers/ssb/driver_pcicore.c
@@ -21,6 +21,8 @@ static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address);
21static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device, 21static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
22 u8 address, u16 data); 22 u8 address, u16 data);
23 23
24static void ssb_commit_settings(struct ssb_bus *bus);
25
24static inline 26static inline
25u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset) 27u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset)
26{ 28{
@@ -412,6 +414,16 @@ static int pcicore_is_in_hostmode(struct ssb_pcicore *pc)
412 * Workarounds. 414 * Workarounds.
413 **************************************************/ 415 **************************************************/
414 416
417static void ssb_pcicore_fix_sprom_core_index(struct ssb_pcicore *pc)
418{
419 u16 tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(0));
420 if (((tmp & 0xF000) >> 12) != pc->dev->core_index) {
421 tmp &= ~0xF000;
422 tmp |= (pc->dev->core_index << 12);
423 pcicore_write16(pc, SSB_PCICORE_SPROM(0), tmp);
424 }
425}
426
415static u8 ssb_pcicore_polarity_workaround(struct ssb_pcicore *pc) 427static u8 ssb_pcicore_polarity_workaround(struct ssb_pcicore *pc)
416{ 428{
417 return (ssb_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80; 429 return (ssb_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
@@ -430,6 +442,76 @@ static void ssb_pcicore_serdes_workaround(struct ssb_pcicore *pc)
430 ssb_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000); 442 ssb_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
431} 443}
432 444
445static void ssb_pcicore_pci_setup_workarounds(struct ssb_pcicore *pc)
446{
447 struct ssb_device *pdev = pc->dev;
448 struct ssb_bus *bus = pdev->bus;
449 u32 tmp;
450
451 tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
452 tmp |= SSB_PCICORE_SBTOPCI_PREF;
453 tmp |= SSB_PCICORE_SBTOPCI_BURST;
454 pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
455
456 if (pdev->id.revision < 5) {
457 tmp = ssb_read32(pdev, SSB_IMCFGLO);
458 tmp &= ~SSB_IMCFGLO_SERTO;
459 tmp |= 2;
460 tmp &= ~SSB_IMCFGLO_REQTO;
461 tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT;
462 ssb_write32(pdev, SSB_IMCFGLO, tmp);
463 ssb_commit_settings(bus);
464 } else if (pdev->id.revision >= 11) {
465 tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
466 tmp |= SSB_PCICORE_SBTOPCI_MRM;
467 pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
468 }
469}
470
471static void ssb_pcicore_pcie_setup_workarounds(struct ssb_pcicore *pc)
472{
473 u32 tmp;
474 u8 rev = pc->dev->id.revision;
475
476 if (rev == 0 || rev == 1) {
477 /* TLP Workaround register. */
478 tmp = ssb_pcie_read(pc, 0x4);
479 tmp |= 0x8;
480 ssb_pcie_write(pc, 0x4, tmp);
481 }
482 if (rev == 1) {
483 /* DLLP Link Control register. */
484 tmp = ssb_pcie_read(pc, 0x100);
485 tmp |= 0x40;
486 ssb_pcie_write(pc, 0x100, tmp);
487 }
488
489 if (rev == 0) {
490 const u8 serdes_rx_device = 0x1F;
491
492 ssb_pcie_mdio_write(pc, serdes_rx_device,
493 2 /* Timer */, 0x8128);
494 ssb_pcie_mdio_write(pc, serdes_rx_device,
495 6 /* CDR */, 0x0100);
496 ssb_pcie_mdio_write(pc, serdes_rx_device,
497 7 /* CDR BW */, 0x1466);
498 } else if (rev == 3 || rev == 4 || rev == 5) {
499 /* TODO: DLLP Power Management Threshold */
500 ssb_pcicore_serdes_workaround(pc);
501 /* TODO: ASPM */
502 } else if (rev == 7) {
503 /* TODO: No PLL down */
504 }
505
506 if (rev >= 6) {
507 /* Miscellaneous Configuration Fixup */
508 tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(5));
509 if (!(tmp & 0x8000))
510 pcicore_write16(pc, SSB_PCICORE_SPROM(5),
511 tmp | 0x8000);
512 }
513}
514
433/************************************************** 515/**************************************************
434 * Generic and Clientmode operation code. 516 * Generic and Clientmode operation code.
435 **************************************************/ 517 **************************************************/
@@ -449,6 +531,8 @@ void ssb_pcicore_init(struct ssb_pcicore *pc)
449 if (!ssb_device_is_enabled(dev)) 531 if (!ssb_device_is_enabled(dev))
450 ssb_device_enable(dev, 0); 532 ssb_device_enable(dev, 0);
451 533
534 ssb_pcicore_fix_sprom_core_index(pc);
535
452#ifdef CONFIG_SSB_PCICORE_HOSTMODE 536#ifdef CONFIG_SSB_PCICORE_HOSTMODE
453 pc->hostmode = pcicore_is_in_hostmode(pc); 537 pc->hostmode = pcicore_is_in_hostmode(pc);
454 if (pc->hostmode) 538 if (pc->hostmode)
@@ -457,7 +541,10 @@ void ssb_pcicore_init(struct ssb_pcicore *pc)
457 if (!pc->hostmode) 541 if (!pc->hostmode)
458 ssb_pcicore_init_clientmode(pc); 542 ssb_pcicore_init_clientmode(pc);
459 543
544 /* Additional always once-executed workarounds */
460 ssb_pcicore_serdes_workaround(pc); 545 ssb_pcicore_serdes_workaround(pc);
546 /* TODO: ASPM */
547 /* TODO: Clock Request Update */
461} 548}
462 549
463static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address) 550static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address)
@@ -522,7 +609,7 @@ static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address)
522 pcicore_write32(pc, mdio_data, v); 609 pcicore_write32(pc, mdio_data, v);
523 /* Wait for the device to complete the transaction */ 610 /* Wait for the device to complete the transaction */
524 udelay(10); 611 udelay(10);
525 for (i = 0; i < 200; i++) { 612 for (i = 0; i < max_retries; i++) {
526 v = pcicore_read32(pc, mdio_control); 613 v = pcicore_read32(pc, mdio_control);
527 if (v & 0x100 /* Trans complete */) { 614 if (v & 0x100 /* Trans complete */) {
528 udelay(10); 615 udelay(10);
@@ -646,48 +733,10 @@ int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
646 if (pc->setup_done) 733 if (pc->setup_done)
647 goto out; 734 goto out;
648 if (pdev->id.coreid == SSB_DEV_PCI) { 735 if (pdev->id.coreid == SSB_DEV_PCI) {
649 tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2); 736 ssb_pcicore_pci_setup_workarounds(pc);
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 } else { 737 } else {
668 WARN_ON(pdev->id.coreid != SSB_DEV_PCIE); 738 WARN_ON(pdev->id.coreid != SSB_DEV_PCIE);
669 //TODO: Better make defines for all these magic PCIE values. 739 ssb_pcicore_pcie_setup_workarounds(pc);
670 if ((pdev->id.revision == 0) || (pdev->id.revision == 1)) {
671 /* TLP Workaround register. */
672 tmp = ssb_pcie_read(pc, 0x4);
673 tmp |= 0x8;
674 ssb_pcie_write(pc, 0x4, tmp);
675 }
676 if (pdev->id.revision == 0) {
677 const u8 serdes_rx_device = 0x1F;
678
679 ssb_pcie_mdio_write(pc, serdes_rx_device,
680 2 /* Timer */, 0x8128);
681 ssb_pcie_mdio_write(pc, serdes_rx_device,
682 6 /* CDR */, 0x0100);
683 ssb_pcie_mdio_write(pc, serdes_rx_device,
684 7 /* CDR BW */, 0x1466);
685 } else if (pdev->id.revision == 1) {
686 /* DLLP Link Control register. */
687 tmp = ssb_pcie_read(pc, 0x100);
688 tmp |= 0x40;
689 ssb_pcie_write(pc, 0x100, tmp);
690 }
691 } 740 }
692 pc->setup_done = 1; 741 pc->setup_done = 1;
693out: 742out:
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index e05ba6eefc7e..ad3da93a428c 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -1117,23 +1117,22 @@ static u32 ssb_tmslow_reject_bitmask(struct ssb_device *dev)
1117{ 1117{
1118 u32 rev = ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV; 1118 u32 rev = ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV;
1119 1119
1120 /* The REJECT bit changed position in TMSLOW between 1120 /* The REJECT bit seems to be different for Backplane rev 2.3 */
1121 * Backplane revisions. */
1122 switch (rev) { 1121 switch (rev) {
1123 case SSB_IDLOW_SSBREV_22: 1122 case SSB_IDLOW_SSBREV_22:
1124 return SSB_TMSLOW_REJECT_22; 1123 case SSB_IDLOW_SSBREV_24:
1124 case SSB_IDLOW_SSBREV_26:
1125 return SSB_TMSLOW_REJECT;
1125 case SSB_IDLOW_SSBREV_23: 1126 case SSB_IDLOW_SSBREV_23:
1126 return SSB_TMSLOW_REJECT_23; 1127 return SSB_TMSLOW_REJECT_23;
1127 case SSB_IDLOW_SSBREV_24: /* TODO - find the proper REJECT bits */ 1128 case SSB_IDLOW_SSBREV_25: /* TODO - find the proper REJECT bit */
1128 case SSB_IDLOW_SSBREV_25: /* same here */
1129 case SSB_IDLOW_SSBREV_26: /* same here */
1130 case SSB_IDLOW_SSBREV_27: /* same here */ 1129 case SSB_IDLOW_SSBREV_27: /* same here */
1131 return SSB_TMSLOW_REJECT_23; /* this is a guess */ 1130 return SSB_TMSLOW_REJECT; /* this is a guess */
1132 default: 1131 default:
1133 printk(KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev); 1132 printk(KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev);
1134 WARN_ON(1); 1133 WARN_ON(1);
1135 } 1134 }
1136 return (SSB_TMSLOW_REJECT_22 | SSB_TMSLOW_REJECT_23); 1135 return (SSB_TMSLOW_REJECT | SSB_TMSLOW_REJECT_23);
1137} 1136}
1138 1137
1139int ssb_device_is_enabled(struct ssb_device *dev) 1138int ssb_device_is_enabled(struct ssb_device *dev)
@@ -1309,20 +1308,20 @@ EXPORT_SYMBOL(ssb_bus_may_powerdown);
1309 1308
1310int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl) 1309int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl)
1311{ 1310{
1312 struct ssb_chipcommon *cc;
1313 int err; 1311 int err;
1314 enum ssb_clkmode mode; 1312 enum ssb_clkmode mode;
1315 1313
1316 err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1); 1314 err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
1317 if (err) 1315 if (err)
1318 goto error; 1316 goto error;
1319 cc = &bus->chipco;
1320 mode = dynamic_pctl ? SSB_CLKMODE_DYNAMIC : SSB_CLKMODE_FAST;
1321 ssb_chipco_set_clockmode(cc, mode);
1322 1317
1323#ifdef CONFIG_SSB_DEBUG 1318#ifdef CONFIG_SSB_DEBUG
1324 bus->powered_up = 1; 1319 bus->powered_up = 1;
1325#endif 1320#endif
1321
1322 mode = dynamic_pctl ? SSB_CLKMODE_DYNAMIC : SSB_CLKMODE_FAST;
1323 ssb_chipco_set_clockmode(&bus->chipco, mode);
1324
1326 return 0; 1325 return 0;
1327error: 1326error:
1328 ssb_printk(KERN_ERR PFX "Bus powerup failed\n"); 1327 ssb_printk(KERN_ERR PFX "Bus powerup failed\n");