diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2017-07-12 12:06:44 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2017-07-13 10:19:45 +1000 |
commit | d63ed063f5dcb443be3226d2c7a48f2f4326e717 (patch) | |
tree | 905da36d5bc7dbe2912d951ae1dda67c60c22eb3 /hw | |
parent | c5f23f29b6eef8e6c413d066e3bec5a8300a7cb8 (diff) | |
download | skiboot-d63ed063f5dcb443be3226d2c7a48f2f4326e717.zip skiboot-d63ed063f5dcb443be3226d2c7a48f2f4326e717.tar.gz skiboot-d63ed063f5dcb443be3226d2c7a48f2f4326e717.tar.bz2 |
phb4: Fix PHB4 fence recovery
We had a few problems:
- We used the wrong register to trigger the reset (spec bug)
- We should clear the PFIR and NFIR while the reset is asserted
- ... and in the right order !
- We should only apply the DD1 workaround after the reset has
been lifted.
- We should ensure we use ASB whenever we are fenced or doing a
CRESET
- Make config ops write with ASB
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/phb4.c | 33 |
1 files changed, 20 insertions, 13 deletions
@@ -1854,9 +1854,6 @@ static void phb4_read_phb_status(struct phb4 *p, phb4_pcicfg_read32(&p->phb, 0, p->aercap + PCIECAP_AER_SRCID, &stat->sourceId); - /* Restore config space to MMIO instead of ASB */ - p->flags &= ~PHB4_CFG_USE_ASB; - /* PEC NFIR, same as P8/PHB3 */ xscom_read(p->chip_id, p->pe_stk_xscom + 0x0, &stat->nFir); xscom_read(p->chip_id, p->pe_stk_xscom + 0x3, &stat->nFirMask); @@ -2410,19 +2407,22 @@ static int64_t phb4_creset(struct pci_slot *slot) xscom_write(p->chip_id, p->pe_stk_xscom + 0x2, 0x000000f000000000); + /* + * Force use of ASB for register access until the PHB has + * been fully reset. + */ + p->flags |= PHB4_CFG_USE_ASB; + /* Clear errors, following the proper sequence */ phb4_err_clear(p); - /* Clear errors in NFIR and raise ETU reset */ - xscom_read(p->chip_id, p->pe_stk_xscom + 0x0, &p->nfir_cache); - xscom_read(p->chip_id, p->pci_stk_xscom + 0x0, &p->pfir_cache); - - xscom_write(p->chip_id, p->pci_stk_xscom + 0x0, + /* Actual reset */ + xscom_write(p->chip_id, p->pci_stk_xscom + XPEC_PCI_STK_ETU_RESET, 0x8000000000000000); - /* DD1 errata: write to PEST to force update */ - phb4_ioda_sel(p, IODA3_TBL_PESTA, PHB4_RESERVED_PE_NUM(p), false); - out_be64(p->regs + PHB_IODA_DATA0, 0); + /* Clear errors in PFIR and NFIR */ + xscom_read(p->chip_id, p->pci_stk_xscom + 0x0, &p->pfir_cache); + xscom_read(p->chip_id, p->pe_stk_xscom + 0x0, &p->nfir_cache); pci_slot_set_state(slot, PHB4_SLOT_CRESET_WAIT_CQ); slot->retries = 500; @@ -2438,8 +2438,14 @@ static int64_t phb4_creset(struct pci_slot *slot) xscom_write(p->chip_id, p->pci_stk_xscom + 0x1, ~p->pfir_cache); - // Clear PHB from reset - xscom_write(p->chip_id, p->pci_stk_xscom + 0x0, 0x0); + /* Clear PHB from reset */ + xscom_write(p->chip_id, + p->pci_stk_xscom + XPEC_PCI_STK_ETU_RESET, 0x0); + + /* DD1 errata: write to PEST to force update */ + phb4_ioda_sel(p, IODA3_TBL_PESTA, PHB4_RESERVED_PE_NUM(p), + false); + phb4_write_reg(p, PHB_IODA_DATA0, 0); pci_slot_set_state(slot, PHB4_SLOT_CRESET_REINIT); return pci_slot_set_sm_timeout(slot, msecs_to_tb(100)); @@ -2455,6 +2461,7 @@ static int64_t phb4_creset(struct pci_slot *slot) PHBDBG(p, "CRESET: Reinitialization\n"); p->flags &= ~PHB4_AIB_FENCED; p->flags &= ~PHB4_CAPP_RECOVERY; + p->flags &= ~PHB4_CFG_USE_ASB; phb4_init_hw(p, false); pci_slot_set_state(slot, PHB4_SLOT_CRESET_FRESET); return pci_slot_set_sm_timeout(slot, msecs_to_tb(100)); |