aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2011-04-27 11:39:47 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-28 14:53:21 -0400
commit6e914101d47c76e09b0568d094ef44257dd3d6e9 (patch)
tree0a768dbe25013a26ae0ad7a62efb56b673e88a7b /drivers/ssb
parentaac6af5534fade2b18682a0b9efad1a6c04c34c6 (diff)
ssb: pci: separate workarounds
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/ssb')
-rw-r--r--drivers/ssb/driver_pcicore.c98
1 files changed, 58 insertions, 40 deletions
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c
index dbda168e501b..adde4f060fd8 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{
@@ -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
435static 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
461static 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;
693out: 711out: