/* Initialize the PCI core. It's caller's responsibility to make sure that this is done * only once */ void * pcicore_init(si_t *sih, osl_t *osh, void *regs) { pcicore_info_t *pi; ASSERT(sih->bustype == PCI_BUS); /* alloc pcicore_info_t */ if ((pi = MALLOC(osh, sizeof(pcicore_info_t))) == NULL) { PCI_ERROR(("pci_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh))); return (NULL); } bzero(pi, sizeof(pcicore_info_t)); pi->sih = sih; pi->osh = osh; if (sih->buscoretype == PCIE_CORE_ID) { uint8 cap_ptr; pi->regs.pcieregs = (sbpcieregs_t*)regs; cap_ptr = pcicore_find_pci_capability(pi->osh, PCI_CAP_PCIECAP_ID, NULL, NULL); ASSERT(cap_ptr); pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET; } else pi->regs.pciregs = (sbpciregs_t*)regs; return pi; }
/* return TRUE if PM capability exists in the pci config space * Uses and caches the information using core handle */ static bool pcicore_pmecap(pcicore_info_t *pi) { uint8 cap_ptr; uint32 pmecap; sbpcieregs_t *pcieregs = pi->regs.pcieregs; uint16*reg16; if (!pi->pmecap_offset) { cap_ptr = pcicore_find_pci_capability(pi->osh, PCI_CAP_POWERMGMTCAP_ID, NULL, NULL); if (!cap_ptr) return FALSE; pi->pmecap_offset = cap_ptr; reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV8]; pi->pmebits = R_REG(pi->osh, reg16); pmecap = OSL_PCI_READ_CONFIG(pi->osh, pi->pmecap_offset, sizeof(uint32)); /* At least one state can generate PME */ pi->pmecap = (pmecap & PME_CAP_PM_STATES) != 0; } return (pi->pmecap); }
/** * Initialize the PCI core. It's caller's responsibility to make sure that this is done * only once */ void * pcicore_init(si_t *sih, osl_t *osh, void *regs) { pcicore_info_t *pi; uint8 cap_ptr; ASSERT(sih->bustype == PCI_BUS); /* alloc pcicore_info_t */ if ((pi = MALLOC(osh, sizeof(pcicore_info_t))) == NULL) { PCI_ERROR(("pci_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh))); return (NULL); } bzero(pi, sizeof(pcicore_info_t)); pi->sih = sih; pi->osh = osh; if (sih->buscoretype == PCIE2_CORE_ID) { pi->regs.pcieregs = (sbpcieregs_t*)regs; cap_ptr = pcicore_find_pci_capability(pi->osh, PCI_CAP_PCIECAP_ID, NULL, NULL); ASSERT(cap_ptr); pi->pciecap_devctrl_offset = cap_ptr + PCIE_CAP_DEVCTRL_OFFSET; pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET; pi->pciecap_devctrl2_offset = cap_ptr + PCIE_CAP_DEVCTRL2_OFFSET; pi->pciecap_ltr0_reg_offset = cap_ptr + PCIE_CAP_LTR0_REG_OFFSET; pi->pciecap_ltr1_reg_offset = cap_ptr + PCIE_CAP_LTR1_REG_OFFSET; pi->pciecap_ltr2_reg_offset = cap_ptr + PCIE_CAP_LTR2_REG_OFFSET; } else if (sih->buscoretype == PCIE_CORE_ID) { pi->regs.pcieregs = (sbpcieregs_t*)regs; cap_ptr = pcicore_find_pci_capability(pi->osh, PCI_CAP_PCIECAP_ID, NULL, NULL); ASSERT(cap_ptr); pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET; pi->pciecap_devctrl_offset = cap_ptr + PCIE_CAP_DEVCTRL_OFFSET; pi->pciecap_devctrl2_offset = cap_ptr + PCIE_CAP_DEVCTRL2_OFFSET; pi->pciecap_ltr0_reg_offset = cap_ptr + PCIE_CAP_LTR0_REG_OFFSET; pi->pciecap_ltr1_reg_offset = cap_ptr + PCIE_CAP_LTR1_REG_OFFSET; pi->pciecap_ltr2_reg_offset = cap_ptr + PCIE_CAP_LTR2_REG_OFFSET; pi->pcie_power_save = TRUE; /* Enable pcie_power_save by default */ } else pi->regs.pciregs = (sbpciregs_t*)regs; return pi; }
/* Just uses PCI config accesses to find out, when needed before sb_attach is done */ bool pcicore_pmecap_fast(osl_t *osh) { uint8 cap_ptr; uint32 pmecap; cap_ptr = pcicore_find_pci_capability(osh, PCI_CAP_POWERMGMTCAP_ID, NULL, NULL); if (!cap_ptr) return FALSE; pmecap = OSL_PCI_READ_CONFIG(osh, cap_ptr, sizeof(uint32)); return ((pmecap & PME_CAP_PM_STATES) != 0); }
/* Initialize the PCI core. * It's caller's responsibility to make sure that this is done only once */ struct pcicore_info *pcicore_init(struct si_pub *sih, struct bcma_device *core) { struct pcicore_info *pi; /* alloc struct pcicore_info */ pi = kzalloc(sizeof(struct pcicore_info), GFP_ATOMIC); if (pi == NULL) return NULL; pi->sih = sih; pi->dev = core->bus->host_pci; pi->core = core; if (core->id.id == PCIE_CORE_ID) { u8 cap_ptr; cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_EXP, NULL, NULL); pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET; } return pi; }
/* return TRUE if PM capability exists in the pci config space * Uses and caches the information using core handle */ static bool pcicore_pmecap(pcicore_info_t *pi) { uint8 cap_ptr; uint32 pmecap; if (!pi->pmecap_offset) { cap_ptr = pcicore_find_pci_capability(pi->osh, PCI_CAP_POWERMGMTCAP_ID, NULL, NULL); if (!cap_ptr) return FALSE; pi->pmecap_offset = cap_ptr; pmecap = OSL_PCI_READ_CONFIG(pi->osh, pi->pmecap_offset, sizeof(uint32)); /* At least one state can generate PME */ pi->pmecap = (pmecap & PME_CAP_PM_STATES) != 0; } return (pi->pmecap); }