diff options
author | Michael Neuling <mikey@neuling.org> | 2017-10-23 21:22:19 +1100 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2017-10-23 12:37:52 -0500 |
commit | 0c2f39eabd99162a6a3656ba2123be57aa89d16c (patch) | |
tree | 2ce6967d993dc9457bda657b0cf1ea30e15b7d63 | |
parent | 1554038d4c368e2df5fb0982d8c450b26a755244 (diff) | |
download | skiboot-0c2f39eabd99162a6a3656ba2123be57aa89d16c.zip skiboot-0c2f39eabd99162a6a3656ba2123be57aa89d16c.tar.gz skiboot-0c2f39eabd99162a6a3656ba2123be57aa89d16c.tar.bz2 |
phb4: Enable PHB MMIO in phb4_root_port_init()
Linux EEH flow is somewhat broken. It saves the PCIe config space of
the PHB on boot, which it then uses to restore on EEH recovery. It
does this to restore MMIO bars and some other pieces.
Unfortunately this save is done before any drivers are bound to
devices under the PHB. A number of other things are configured in the
PHB after drivers start, hence some configuration space settings
aren't saved correctly. These include bus master and MMIO bits in the
command register.
Linux tried to hack around this in this linux commit
bf898ec5cb powerpc/eeh: Enable PCI_COMMAND_MASTER for PCI bridges
This sets the bus master bit but ignores the MMIO bit.
Hence we lose MMIO after a full PHB reset. This causes the next MMIO
access to the device to fail and for us to perform a PE freeze
recovery, which still doesn't set the MMIO bit and hence we still
fail.
This works around this by forcing MMIO on during
phb4_root_port_init().
With this we can recovery from a PHB fence event on POWER9.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r-- | hw/phb4.c | 4 |
1 files changed, 2 insertions, 2 deletions
@@ -139,7 +139,6 @@ static void phb4_init_hw(struct phb4 *p, bool first_init); #define PHBERR(p, fmt, a...) prlog(PR_ERR, "PHB#%04x[%d:%d]: " fmt, \ (p)->phb.opal_id, (p)->chip_id, \ (p)->index, ## a) - #ifdef LOG_CFG #define PHBLOGCFG(p, fmt, a...) PHBDBG(p, fmt, ## a) #else @@ -639,7 +638,8 @@ static void phb4_root_port_init(struct phb *phb, struct pci_device *dev, /* Enable SERR and parity checking */ pci_cfg_read16(phb, bdfn, PCI_CFG_CMD, &val16); - val16 |= (PCI_CFG_CMD_SERR_EN | PCI_CFG_CMD_PERR_RESP); + val16 |= (PCI_CFG_CMD_SERR_EN | PCI_CFG_CMD_PERR_RESP | + PCI_CFG_CMD_MEM_EN); pci_cfg_write16(phb, bdfn, PCI_CFG_CMD, val16); /* Enable reporting various errors */ |