/* ***** Functions called during driver state changes ***** */ void BCMATTACHFN(pcicore_attach)(void *pch, char *pvars, int state) { pcicore_info_t *pi = (pcicore_info_t *)pch; si_t *sih = pi->sih; if (!PCIE_GEN1(sih)) { if ((BCM4360_CHIP_ID == CHIPID(sih->chip)) || (BCM43460_CHIP_ID == CHIPID(sih->chip)) || (BCM4350_CHIP_ID == CHIPID(sih->chip)) || (BCM4352_CHIP_ID == CHIPID(sih->chip)) || (BCM4335_CHIP_ID == CHIPID(sih->chip))) pi->pcie_reqsize = PCIE_CAP_DEVCTRL_MRRS_1024B; return; } if (PCIEGEN1_ASPM(sih)) { if (((sih->boardvendor == VENDOR_APPLE) && ((uint8)getintvar(pvars, "sromrev") == 4) && ((uint8)getintvar(pvars, "boardrev") <= 0x71)) || ((uint32)getintvar(pvars, "boardflags2") & BFL2_PCIEWAR_OVR)) { pi->pcie_war_aspm_ovr = PCIE_ASPM_DISAB; } else { pi->pcie_war_aspm_ovr = PCIE_ASPM_ENAB; } } pi->pcie_reqsize = PCIE_CAP_DEVCTRL_MRRS_128B; if (BCM4331_CHIP_ID == CHIPID(sih->chip)) pi->pcie_reqsize = PCIE_CAP_DEVCTRL_MRRS_512B; bzero(pi->pcie_configspace, PCI_CONFIG_SPACE_SIZE); /* These need to happen in this order only */ pcie_war_polarity(pi); pcie_war_serdes(pi); pcie_war_aspm_clkreq(pi); pcie_clkreq_upd(pi, state); pcie_war_pmebits(pi); /* Alter default TX drive strength setting */ if (sih->boardvendor == VENDOR_APPLE) { if (sih->boardtype == 0x8d) /* change the TX drive strength to max */ pcicore_pcieserdesreg(pch, MDIO_DEV_TXCTRL0, 0x18, 0xff, 0x7f); else if (PCIE_DRIVE_STRENGTH_OVERRIDE(sih)) /* change the drive strength to 700mv */ pcicore_pcieserdesreg(pch, MDIO_DEV_TXCTRL0, 0x18, 0xff, 0x70); } }
/* Needs to happen when coming out of 'standby'/'hibernate' */ static void pcie_war_pci_setup(pcicore_info_t *pi) { si_t *sih = pi->sih; osl_t *osh = pi->osh; sbpcieregs_t *pcieregs = pi->regs.pcieregs; uint32 w; /* PR 29224 enable_9715_fix bit in the TLP workaround register should be set */ if ((sih->buscorerev == 0) || (sih->buscorerev == 1)) { w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG); w |= 0x8; pcie_writereg(osh, pcieregs, PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG, w); } /* PR 34651 set bit6 to enable pcie-pm power mgmt in DLLP LC Reg, default is off */ if (sih->buscorerev == 1) { w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG); w |= (0x40); pcie_writereg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w); } if (sih->buscorerev == 0) { /* PR30841 WAR */ pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128); pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100); pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466); } else if (PCIE_ASPM(sih)) { /* PR42766 WAR */ /* Change the L1 threshold for better performance */ w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG); w &= ~(PCIE_L1THRESHOLDTIME_MASK); w |= (PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT); pcie_writereg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w); pcie_war_serdes(pi); pcie_war_aspm_clkreq(pi); } else if (pi->sih->buscorerev == 7) pcie_war_noplldown(pi); /* Note that the fix is actually in the SROM, that's why this is open-ended */ if (pi->sih->buscorerev >= 6) pcie_misc_config_fixup(pi); }
/* ***** Functions called during driver state changes ***** */ void pcicore_attach(void *pch, char *pvars, int state) { pcicore_info_t *pi = (pcicore_info_t *)pch; si_t *sih = pi->sih; /* Determine if this board needs override */ pi->pcie_war_aspm_ovr = ((uint32)getintvar(pvars, "boardflags2") & BFL2_PCIEWAR_OVR); /* These need to happen in this order only */ pcie_war_polarity(pi); pcie_war_serdes(pi); pcie_war_aspm_clkreq(pi); pcie_clkreq_upd(pi, state); }
/* Needs to happen when coming out of 'standby'/'hibernate' */ static void pcie_war_pci_setup(pcicore_info_t *pi) { si_t *sih = pi->sih; osl_t *osh = pi->osh; sbpcieregs_t *pcieregs = pi->regs.pcieregs; uint32 w; if ((sih->buscorerev == 0) || (sih->buscorerev == 1)) { w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG); w |= 0x8; pcie_writereg(osh, pcieregs, PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG, w); } if (sih->buscorerev == 1) { w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG); w |= (0x40); pcie_writereg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w); } if (sih->buscorerev == 0) { pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128); pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100); pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466); } else if (PCIE_ASPM(sih)) { /* Change the L1 threshold for better performance */ w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG); w &= ~(PCIE_L1THRESHOLDTIME_MASK); w |= (PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT); pcie_writereg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w); pcie_war_serdes(pi); pcie_war_aspm_clkreq(pi); } else if (pi->sih->buscorerev == 7) pcie_war_noplldown(pi); /* Note that the fix is actually in the SROM, that's why this is open-ended */ if (pi->sih->buscorerev >= 6) pcie_misc_config_fixup(pi); }