diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2011-04-27 11:39:47 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-04-28 14:53:21 -0400 |
commit | 6e914101d47c76e09b0568d094ef44257dd3d6e9 (patch) | |
tree | 0a768dbe25013a26ae0ad7a62efb56b673e88a7b | |
parent | aac6af5534fade2b18682a0b9efad1a6c04c34c6 (diff) |
ssb: pci: separate workarounds
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/ssb/driver_pcicore.c | 98 |
1 files changed, 58 insertions, 40 deletions
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index dbda168e501..adde4f060fd 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); | |||
21 | static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device, | 21 | static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device, |
22 | u8 address, u16 data); | 22 | u8 address, u16 data); |
23 | 23 | ||
24 | static void ssb_commit_settings(struct ssb_bus *bus); | ||
25 | |||
24 | static inline | 26 | static inline |
25 | u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset) | 27 | u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset) |
26 | { | 28 | { |
@@ -430,6 +432,60 @@ static void ssb_pcicore_serdes_workaround(struct ssb_pcicore *pc) | |||
430 | ssb_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000); | 432 | ssb_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000); |
431 | } | 433 | } |
432 | 434 | ||
435 | static void ssb_pcicore_pci_setup_workarounds(struct ssb_pcicore *pc) | ||
436 | { | ||
437 | struct ssb_device *pdev = pc->dev; | ||
438 | struct ssb_bus *bus = pdev->bus; | ||
439 | u32 tmp; | ||
440 | |||
441 | tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2); | ||
442 | tmp |= SSB_PCICORE_SBTOPCI_PREF; | ||
443 | tmp |= SSB_PCICORE_SBTOPCI_BURST; | ||
444 | pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp); | ||
445 | |||
446 | if (pdev->id.revision < 5) { | ||
447 | tmp = ssb_read32(pdev, SSB_IMCFGLO); | ||
448 | tmp &= ~SSB_IMCFGLO_SERTO; | ||
449 | tmp |= 2; | ||
450 | tmp &= ~SSB_IMCFGLO_REQTO; | ||
451 | tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT; | ||
452 | ssb_write32(pdev, SSB_IMCFGLO, tmp); | ||
453 | ssb_commit_settings(bus); | ||
454 | } else if (pdev->id.revision >= 11) { | ||
455 | tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2); | ||
456 | tmp |= SSB_PCICORE_SBTOPCI_MRM; | ||
457 | pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp); | ||
458 | } | ||
459 | } | ||
460 | |||
461 | static void ssb_pcicore_pcie_setup_workarounds(struct ssb_pcicore *pc) | ||
462 | { | ||
463 | struct ssb_device *pdev = pc->dev; | ||
464 | u32 tmp; | ||
465 | |||
466 | if ((pdev->id.revision == 0) || (pdev->id.revision == 1)) { | ||
467 | /* TLP Workaround register. */ | ||
468 | tmp = ssb_pcie_read(pc, 0x4); | ||
469 | tmp |= 0x8; | ||
470 | ssb_pcie_write(pc, 0x4, tmp); | ||
471 | } | ||
472 | if (pdev->id.revision == 0) { | ||
473 | const u8 serdes_rx_device = 0x1F; | ||
474 | |||
475 | ssb_pcie_mdio_write(pc, serdes_rx_device, | ||
476 | 2 /* Timer */, 0x8128); | ||
477 | ssb_pcie_mdio_write(pc, serdes_rx_device, | ||
478 | 6 /* CDR */, 0x0100); | ||
479 | ssb_pcie_mdio_write(pc, serdes_rx_device, | ||
480 | 7 /* CDR BW */, 0x1466); | ||
481 | } else if (pdev->id.revision == 1) { | ||
482 | /* DLLP Link Control register. */ | ||
483 | tmp = ssb_pcie_read(pc, 0x100); | ||
484 | tmp |= 0x40; | ||
485 | ssb_pcie_write(pc, 0x100, tmp); | ||
486 | } | ||
487 | } | ||
488 | |||
433 | /************************************************** | 489 | /************************************************** |
434 | * Generic and Clientmode operation code. | 490 | * Generic and Clientmode operation code. |
435 | **************************************************/ | 491 | **************************************************/ |
@@ -646,48 +702,10 @@ int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc, | |||
646 | if (pc->setup_done) | 702 | if (pc->setup_done) |
647 | goto out; | 703 | goto out; |
648 | if (pdev->id.coreid == SSB_DEV_PCI) { | 704 | if (pdev->id.coreid == SSB_DEV_PCI) { |
649 | tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2); | 705 | 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 { | 706 | } else { |
668 | WARN_ON(pdev->id.coreid != SSB_DEV_PCIE); | 707 | WARN_ON(pdev->id.coreid != SSB_DEV_PCIE); |
669 | //TODO: Better make defines for all these magic PCIE values. | 708 | 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 | } | 709 | } |
692 | pc->setup_done = 1; | 710 | pc->setup_done = 1; |
693 | out: | 711 | out: |