diff options
author | Ryan Grimm <grimm@linux.vnet.ibm.com> | 2014-09-29 23:51:35 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-09-30 14:45:48 +1000 |
commit | f68bd30f5bc58a21533d834b315f880bfb54e0db (patch) | |
tree | 53f349a7e2bff9475cbaad2d8091f8eb37eb5d0b /hw | |
parent | 8b925076b139a973b25ef88d3d701a810b38f1c0 (diff) | |
download | skiboot-f68bd30f5bc58a21533d834b315f880bfb54e0db.zip skiboot-f68bd30f5bc58a21533d834b315f880bfb54e0db.tar.gz skiboot-f68bd30f5bc58a21533d834b315f880bfb54e0db.tar.bz2 |
phb3/capi: Add two new modes to opal_pci_set_phb_capi_mode
For user initiated capp recovery, provide a mode to turn snoops off. The perst
alone does not turn snoops off and we need to do this as part of the capp
recovery procedure before reinitializing the phb.
A second mode turns snoops back on after recovery. The driver needs to do this
after it reinitializes the PSL otherwise tlbies could come in before the psl is
initialized. Also write 0 to capp error status and control as part of the
recovery procedure.
Put modes as flag defines in opal.h so the driver can pick them up.
Add a dt property "ibm,capi-modes" which tells the driver which modes sapphire
supports. For backwards compatibility with older opals. Also, the driver can
disable reset in sysfs if not supported.
Move the mode checking into phb3.c so it's all in one place.
Signed-off-by: Ryan Grimm <grimm@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/phb3.c | 36 |
1 files changed, 34 insertions, 2 deletions
@@ -2916,8 +2916,37 @@ static int64_t phb3_set_capi_mode(struct phb *phb, uint64_t mode, uint64_t reg; int i; - if (mode != 1) - return OPAL_PARAMETER; + xscom_read(p->chip_id, CAPP_ERR_STATUS_CTRL, ®); + if ((reg & PPC_BIT(5))) { + PHBERR(p, "CAPP recovery failed (%016llx)\n", reg); + return OPAL_HARDWARE; + } else if ((reg & PPC_BIT(0)) && (!(reg & PPC_BIT(1)))) { + PHBDBG(p, "CAPP recovery in progress\n"); + return OPAL_BUSY; + } + + if (mode == OPAL_PHB_MODE_PCIE) + return OPAL_UNSUPPORTED; + + if (mode == OPAL_PHB_MODE_SNOOP_OFF) { + xscom_write(p->chip_id, SNOOP_CAPI_CONFIG, 0x0000000000000000); + return OPAL_SUCCESS; + } + + if (mode == OPAL_PHB_MODE_SNOOP_ON) { + xscom_write(p->chip_id, CAPP_ERR_STATUS_CTRL, 0x0000000000000000); + xscom_write(p->chip_id, SNOOP_CAPI_CONFIG, 0xA1F0000000000000); + return OPAL_SUCCESS; + } + + if (mode != OPAL_PHB_MODE_CAPI) + return OPAL_UNSUPPORTED; + + xscom_read(p->chip_id, 0x9013c03, ®); + if (reg & PPC_BIT(0)) { + PHBDBG(p, "Already in CAPP mode\n"); + return OPAL_SUCCESS; + } if (!p->capp_ucode_loaded) { PHBERR(p, "capp ucode not loaded into capp unit\n"); @@ -4087,6 +4116,9 @@ static void phb3_probe_pbcq(struct dt_node *pbcq) } max_link_speed = dt_prop_get_u32_def(pbcq, "ibm,max-link-speed", 3); dt_add_property_cells(np, "ibm,max-link-speed", max_link_speed); + dt_add_property_cells(np, "ibm,capi-modes", OPAL_PHB_MODE_CAPI | + OPAL_PHB_MODE_SNOOP_ON | + OPAL_PHB_MODE_SNOOP_OFF); add_chip_dev_associativity(np); } |