aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-20 16:43:21 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-20 16:43:21 -0400
commit06f4e926d256d902dd9a53dcb400fd74974ce087 (patch)
tree0b438b67f5f0eff6fd617bc497a9dace6164a488 /drivers/ssb
parent8e7bfcbab3825d1b404d615cb1b54f44ff81f981 (diff)
parentd93515611bbc70c2fe4db232e5feb448ed8e4cc9 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1446 commits) macvlan: fix panic if lowerdev in a bond tg3: Add braces around 5906 workaround. tg3: Fix NETIF_F_LOOPBACK error macvlan: remove one synchronize_rcu() call networking: NET_CLS_ROUTE4 depends on INET irda: Fix error propagation in ircomm_lmp_connect_response() irda: Kill set but unused variable 'bytes' in irlan_check_command_param() irda: Kill set but unused variable 'clen' in ircomm_connect_indication() rxrpc: Fix set but unused variable 'usage' in rxrpc_get_transport() be2net: Kill set but unused variable 'req' in lancer_fw_download() irda: Kill set but unused vars 'saddr' and 'daddr' in irlan_provider_connect_indication() atl1c: atl1c_resume() is only used when CONFIG_PM_SLEEP is defined. rxrpc: Fix set but unused variable 'usage' in rxrpc_get_peer(). rxrpc: Kill set but unused variable 'local' in rxrpc_UDP_error_handler() rxrpc: Kill set but unused variable 'sp' in rxrpc_process_connection() rxrpc: Kill set but unused variable 'sp' in rxrpc_rotate_tx_window() pkt_sched: Kill set but unused variable 'protocol' in tc_classify() isdn: capi: Use pr_debug() instead of ifdefs. tg3: Update version to 3.119 tg3: Apply rx_discards fix to 5719/5720 ... Fix up trivial conflicts in arch/x86/Kconfig and net/mac80211/agg-tx.c as per Davem.
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.c255
-rw-r--r--drivers/ssb/main.c54
-rw-r--r--drivers/ssb/scan.c7
5 files changed, 286 insertions, 100 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 0e8d35224614..82feb348c8bb 100644
--- a/drivers/ssb/driver_pcicore.c
+++ b/drivers/ssb/driver_pcicore.c
@@ -15,6 +15,11 @@
15 15
16#include "ssb_private.h" 16#include "ssb_private.h"
17 17
18static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address);
19static void ssb_pcie_write(struct ssb_pcicore *pc, u32 address, u32 data);
20static 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,
22 u8 address, u16 data);
18 23
19static inline 24static inline
20u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset) 25u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset)
@@ -403,6 +408,107 @@ static int pcicore_is_in_hostmode(struct ssb_pcicore *pc)
403} 408}
404#endif /* CONFIG_SSB_PCICORE_HOSTMODE */ 409#endif /* CONFIG_SSB_PCICORE_HOSTMODE */
405 410
411/**************************************************
412 * Workarounds.
413 **************************************************/
414
415static void ssb_pcicore_fix_sprom_core_index(struct ssb_pcicore *pc)
416{
417 u16 tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(0));
418 if (((tmp & 0xF000) >> 12) != pc->dev->core_index) {
419 tmp &= ~0xF000;
420 tmp |= (pc->dev->core_index << 12);
421 pcicore_write16(pc, SSB_PCICORE_SPROM(0), tmp);
422 }
423}
424
425static u8 ssb_pcicore_polarity_workaround(struct ssb_pcicore *pc)
426{
427 return (ssb_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
428}
429
430static void ssb_pcicore_serdes_workaround(struct ssb_pcicore *pc)
431{
432 const u8 serdes_pll_device = 0x1D;
433 const u8 serdes_rx_device = 0x1F;
434 u16 tmp;
435
436 ssb_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
437 ssb_pcicore_polarity_workaround(pc));
438 tmp = ssb_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
439 if (tmp & 0x4000)
440 ssb_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
441}
442
443static void ssb_pcicore_pci_setup_workarounds(struct ssb_pcicore *pc)
444{
445 struct ssb_device *pdev = pc->dev;
446 struct ssb_bus *bus = pdev->bus;
447 u32 tmp;
448
449 tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
450 tmp |= SSB_PCICORE_SBTOPCI_PREF;
451 tmp |= SSB_PCICORE_SBTOPCI_BURST;
452 pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
453
454 if (pdev->id.revision < 5) {
455 tmp = ssb_read32(pdev, SSB_IMCFGLO);
456 tmp &= ~SSB_IMCFGLO_SERTO;
457 tmp |= 2;
458 tmp &= ~SSB_IMCFGLO_REQTO;
459 tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT;
460 ssb_write32(pdev, SSB_IMCFGLO, tmp);
461 ssb_commit_settings(bus);
462 } else if (pdev->id.revision >= 11) {
463 tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
464 tmp |= SSB_PCICORE_SBTOPCI_MRM;
465 pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
466 }
467}
468
469static void ssb_pcicore_pcie_setup_workarounds(struct ssb_pcicore *pc)
470{
471 u32 tmp;
472 u8 rev = pc->dev->id.revision;
473
474 if (rev == 0 || rev == 1) {
475 /* TLP Workaround register. */
476 tmp = ssb_pcie_read(pc, 0x4);
477 tmp |= 0x8;
478 ssb_pcie_write(pc, 0x4, tmp);
479 }
480 if (rev == 1) {
481 /* DLLP Link Control register. */
482 tmp = ssb_pcie_read(pc, 0x100);
483 tmp |= 0x40;
484 ssb_pcie_write(pc, 0x100, tmp);
485 }
486
487 if (rev == 0) {
488 const u8 serdes_rx_device = 0x1F;
489
490 ssb_pcie_mdio_write(pc, serdes_rx_device,
491 2 /* Timer */, 0x8128);
492 ssb_pcie_mdio_write(pc, serdes_rx_device,
493 6 /* CDR */, 0x0100);
494 ssb_pcie_mdio_write(pc, serdes_rx_device,
495 7 /* CDR BW */, 0x1466);
496 } else if (rev == 3 || rev == 4 || rev == 5) {
497 /* TODO: DLLP Power Management Threshold */
498 ssb_pcicore_serdes_workaround(pc);
499 /* TODO: ASPM */
500 } else if (rev == 7) {
501 /* TODO: No PLL down */
502 }
503
504 if (rev >= 6) {
505 /* Miscellaneous Configuration Fixup */
506 tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(5));
507 if (!(tmp & 0x8000))
508 pcicore_write16(pc, SSB_PCICORE_SPROM(5),
509 tmp | 0x8000);
510 }
511}
406 512
407/************************************************** 513/**************************************************
408 * Generic and Clientmode operation code. 514 * Generic and Clientmode operation code.
@@ -417,14 +523,14 @@ static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc)
417void ssb_pcicore_init(struct ssb_pcicore *pc) 523void ssb_pcicore_init(struct ssb_pcicore *pc)
418{ 524{
419 struct ssb_device *dev = pc->dev; 525 struct ssb_device *dev = pc->dev;
420 struct ssb_bus *bus;
421 526
422 if (!dev) 527 if (!dev)
423 return; 528 return;
424 bus = dev->bus;
425 if (!ssb_device_is_enabled(dev)) 529 if (!ssb_device_is_enabled(dev))
426 ssb_device_enable(dev, 0); 530 ssb_device_enable(dev, 0);
427 531
532 ssb_pcicore_fix_sprom_core_index(pc);
533
428#ifdef CONFIG_SSB_PCICORE_HOSTMODE 534#ifdef CONFIG_SSB_PCICORE_HOSTMODE
429 pc->hostmode = pcicore_is_in_hostmode(pc); 535 pc->hostmode = pcicore_is_in_hostmode(pc);
430 if (pc->hostmode) 536 if (pc->hostmode)
@@ -432,6 +538,11 @@ void ssb_pcicore_init(struct ssb_pcicore *pc)
432#endif /* CONFIG_SSB_PCICORE_HOSTMODE */ 538#endif /* CONFIG_SSB_PCICORE_HOSTMODE */
433 if (!pc->hostmode) 539 if (!pc->hostmode)
434 ssb_pcicore_init_clientmode(pc); 540 ssb_pcicore_init_clientmode(pc);
541
542 /* Additional always once-executed workarounds */
543 ssb_pcicore_serdes_workaround(pc);
544 /* TODO: ASPM */
545 /* TODO: Clock Request Update */
435} 546}
436 547
437static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address) 548static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address)
@@ -446,58 +557,104 @@ static void ssb_pcie_write(struct ssb_pcicore *pc, u32 address, u32 data)
446 pcicore_write32(pc, 0x134, data); 557 pcicore_write32(pc, 0x134, data);
447} 558}
448 559
449static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device, 560static void ssb_pcie_mdio_set_phy(struct ssb_pcicore *pc, u8 phy)
450 u8 address, u16 data)
451{ 561{
452 const u16 mdio_control = 0x128; 562 const u16 mdio_control = 0x128;
453 const u16 mdio_data = 0x12C; 563 const u16 mdio_data = 0x12C;
454 u32 v; 564 u32 v;
455 int i; 565 int i;
456 566
567 v = (1 << 30); /* Start of Transaction */
568 v |= (1 << 28); /* Write Transaction */
569 v |= (1 << 17); /* Turnaround */
570 v |= (0x1F << 18);
571 v |= (phy << 4);
572 pcicore_write32(pc, mdio_data, v);
573
574 udelay(10);
575 for (i = 0; i < 200; i++) {
576 v = pcicore_read32(pc, mdio_control);
577 if (v & 0x100 /* Trans complete */)
578 break;
579 msleep(1);
580 }
581}
582
583static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address)
584{
585 const u16 mdio_control = 0x128;
586 const u16 mdio_data = 0x12C;
587 int max_retries = 10;
588 u16 ret = 0;
589 u32 v;
590 int i;
591
457 v = 0x80; /* Enable Preamble Sequence */ 592 v = 0x80; /* Enable Preamble Sequence */
458 v |= 0x2; /* MDIO Clock Divisor */ 593 v |= 0x2; /* MDIO Clock Divisor */
459 pcicore_write32(pc, mdio_control, v); 594 pcicore_write32(pc, mdio_control, v);
460 595
596 if (pc->dev->id.revision >= 10) {
597 max_retries = 200;
598 ssb_pcie_mdio_set_phy(pc, device);
599 }
600
461 v = (1 << 30); /* Start of Transaction */ 601 v = (1 << 30); /* Start of Transaction */
462 v |= (1 << 28); /* Write Transaction */ 602 v |= (1 << 29); /* Read Transaction */
463 v |= (1 << 17); /* Turnaround */ 603 v |= (1 << 17); /* Turnaround */
464 v |= (u32)device << 22; 604 if (pc->dev->id.revision < 10)
605 v |= (u32)device << 22;
465 v |= (u32)address << 18; 606 v |= (u32)address << 18;
466 v |= data;
467 pcicore_write32(pc, mdio_data, v); 607 pcicore_write32(pc, mdio_data, v);
468 /* Wait for the device to complete the transaction */ 608 /* Wait for the device to complete the transaction */
469 udelay(10); 609 udelay(10);
470 for (i = 0; i < 10; i++) { 610 for (i = 0; i < max_retries; i++) {
471 v = pcicore_read32(pc, mdio_control); 611 v = pcicore_read32(pc, mdio_control);
472 if (v & 0x100 /* Trans complete */) 612 if (v & 0x100 /* Trans complete */) {
613 udelay(10);
614 ret = pcicore_read32(pc, mdio_data);
473 break; 615 break;
616 }
474 msleep(1); 617 msleep(1);
475 } 618 }
476 pcicore_write32(pc, mdio_control, 0); 619 pcicore_write32(pc, mdio_control, 0);
620 return ret;
477} 621}
478 622
479static void ssb_broadcast_value(struct ssb_device *dev, 623static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
480 u32 address, u32 data) 624 u8 address, u16 data)
481{ 625{
482 /* This is used for both, PCI and ChipCommon core, so be careful. */ 626 const u16 mdio_control = 0x128;
483 BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR); 627 const u16 mdio_data = 0x12C;
484 BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA); 628 int max_retries = 10;
485 629 u32 v;
486 ssb_write32(dev, SSB_PCICORE_BCAST_ADDR, address); 630 int i;
487 ssb_read32(dev, SSB_PCICORE_BCAST_ADDR); /* flush */
488 ssb_write32(dev, SSB_PCICORE_BCAST_DATA, data);
489 ssb_read32(dev, SSB_PCICORE_BCAST_DATA); /* flush */
490}
491 631
492static void ssb_commit_settings(struct ssb_bus *bus) 632 v = 0x80; /* Enable Preamble Sequence */
493{ 633 v |= 0x2; /* MDIO Clock Divisor */
494 struct ssb_device *dev; 634 pcicore_write32(pc, mdio_control, v);
495 635
496 dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev; 636 if (pc->dev->id.revision >= 10) {
497 if (WARN_ON(!dev)) 637 max_retries = 200;
498 return; 638 ssb_pcie_mdio_set_phy(pc, device);
499 /* This forces an update of the cached registers. */ 639 }
500 ssb_broadcast_value(dev, 0xFD8, 0); 640
641 v = (1 << 30); /* Start of Transaction */
642 v |= (1 << 28); /* Write Transaction */
643 v |= (1 << 17); /* Turnaround */
644 if (pc->dev->id.revision < 10)
645 v |= (u32)device << 22;
646 v |= (u32)address << 18;
647 v |= data;
648 pcicore_write32(pc, mdio_data, v);
649 /* Wait for the device to complete the transaction */
650 udelay(10);
651 for (i = 0; i < max_retries; i++) {
652 v = pcicore_read32(pc, mdio_control);
653 if (v & 0x100 /* Trans complete */)
654 break;
655 msleep(1);
656 }
657 pcicore_write32(pc, mdio_control, 0);
501} 658}
502 659
503int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc, 660int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
@@ -550,48 +707,10 @@ int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
550 if (pc->setup_done) 707 if (pc->setup_done)
551 goto out; 708 goto out;
552 if (pdev->id.coreid == SSB_DEV_PCI) { 709 if (pdev->id.coreid == SSB_DEV_PCI) {
553 tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2); 710 ssb_pcicore_pci_setup_workarounds(pc);
554 tmp |= SSB_PCICORE_SBTOPCI_PREF;
555 tmp |= SSB_PCICORE_SBTOPCI_BURST;
556 pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
557
558 if (pdev->id.revision < 5) {
559 tmp = ssb_read32(pdev, SSB_IMCFGLO);
560 tmp &= ~SSB_IMCFGLO_SERTO;
561 tmp |= 2;
562 tmp &= ~SSB_IMCFGLO_REQTO;
563 tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT;
564 ssb_write32(pdev, SSB_IMCFGLO, tmp);
565 ssb_commit_settings(bus);
566 } else if (pdev->id.revision >= 11) {
567 tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
568 tmp |= SSB_PCICORE_SBTOPCI_MRM;
569 pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
570 }
571 } else { 711 } else {
572 WARN_ON(pdev->id.coreid != SSB_DEV_PCIE); 712 WARN_ON(pdev->id.coreid != SSB_DEV_PCIE);
573 //TODO: Better make defines for all these magic PCIE values. 713 ssb_pcicore_pcie_setup_workarounds(pc);
574 if ((pdev->id.revision == 0) || (pdev->id.revision == 1)) {
575 /* TLP Workaround register. */
576 tmp = ssb_pcie_read(pc, 0x4);
577 tmp |= 0x8;
578 ssb_pcie_write(pc, 0x4, tmp);
579 }
580 if (pdev->id.revision == 0) {
581 const u8 serdes_rx_device = 0x1F;
582
583 ssb_pcie_mdio_write(pc, serdes_rx_device,
584 2 /* Timer */, 0x8128);
585 ssb_pcie_mdio_write(pc, serdes_rx_device,
586 6 /* CDR */, 0x0100);
587 ssb_pcie_mdio_write(pc, serdes_rx_device,
588 7 /* CDR BW */, 0x1466);
589 } else if (pdev->id.revision == 1) {
590 /* DLLP Link Control register. */
591 tmp = ssb_pcie_read(pc, 0x100);
592 tmp |= 0x40;
593 ssb_pcie_write(pc, 0x100, tmp);
594 }
595 } 714 }
596 pc->setup_done = 1; 715 pc->setup_done = 1;
597out: 716out:
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index e05ba6eefc7e..f8a13f863217 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");
@@ -1330,6 +1329,37 @@ error:
1330} 1329}
1331EXPORT_SYMBOL(ssb_bus_powerup); 1330EXPORT_SYMBOL(ssb_bus_powerup);
1332 1331
1332static void ssb_broadcast_value(struct ssb_device *dev,
1333 u32 address, u32 data)
1334{
1335#ifdef CONFIG_SSB_DRIVER_PCICORE
1336 /* This is used for both, PCI and ChipCommon core, so be careful. */
1337 BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR);
1338 BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA);
1339#endif
1340
1341 ssb_write32(dev, SSB_CHIPCO_BCAST_ADDR, address);
1342 ssb_read32(dev, SSB_CHIPCO_BCAST_ADDR); /* flush */
1343 ssb_write32(dev, SSB_CHIPCO_BCAST_DATA, data);
1344 ssb_read32(dev, SSB_CHIPCO_BCAST_DATA); /* flush */
1345}
1346
1347void ssb_commit_settings(struct ssb_bus *bus)
1348{
1349 struct ssb_device *dev;
1350
1351#ifdef CONFIG_SSB_DRIVER_PCICORE
1352 dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
1353#else
1354 dev = bus->chipco.dev;
1355#endif
1356 if (WARN_ON(!dev))
1357 return;
1358 /* This forces an update of the cached registers. */
1359 ssb_broadcast_value(dev, 0xFD8, 0);
1360}
1361EXPORT_SYMBOL(ssb_commit_settings);
1362
1333u32 ssb_admatch_base(u32 adm) 1363u32 ssb_admatch_base(u32 adm)
1334{ 1364{
1335 u32 base = 0; 1365 u32 base = 0;
diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c
index 29884c00c4d5..45e5babd3961 100644
--- a/drivers/ssb/scan.c
+++ b/drivers/ssb/scan.c
@@ -258,7 +258,10 @@ static int we_support_multiple_80211_cores(struct ssb_bus *bus)
258#ifdef CONFIG_SSB_PCIHOST 258#ifdef CONFIG_SSB_PCIHOST
259 if (bus->bustype == SSB_BUSTYPE_PCI) { 259 if (bus->bustype == SSB_BUSTYPE_PCI) {
260 if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM && 260 if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM &&
261 bus->host_pci->device == 0x4324) 261 ((bus->host_pci->device == 0x4313) ||
262 (bus->host_pci->device == 0x431A) ||
263 (bus->host_pci->device == 0x4321) ||
264 (bus->host_pci->device == 0x4324)))
262 return 1; 265 return 1;
263 } 266 }
264#endif /* CONFIG_SSB_PCIHOST */ 267#endif /* CONFIG_SSB_PCIHOST */
@@ -307,7 +310,7 @@ int ssb_bus_scan(struct ssb_bus *bus,
307 } else { 310 } else {
308 if (bus->bustype == SSB_BUSTYPE_PCI) { 311 if (bus->bustype == SSB_BUSTYPE_PCI) {
309 bus->chip_id = pcidev_to_chipid(bus->host_pci); 312 bus->chip_id = pcidev_to_chipid(bus->host_pci);
310 pci_read_config_word(bus->host_pci, PCI_REVISION_ID, 313 pci_read_config_byte(bus->host_pci, PCI_REVISION_ID,
311 &bus->chip_rev); 314 &bus->chip_rev);
312 bus->chip_package = 0; 315 bus->chip_package = 0;
313 } else { 316 } else {