Message ID | 20181209141744.4787-8-vaibhav@linux.ibm.com |
---|---|
State | Superseded |
Headers | show |
Series | Enable fast-reboot support for CAPI-2 | expand |
Context | Check | Description |
---|---|---|
snowpatch_ozlabs/apply_patch | success | master/apply_patch Successfully applied |
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot | success | Test snowpatch/job/snowpatch-skiboot on branch master |
On 10/12/18 1:17 am, Vaibhav Jain wrote: > We implement h/w sequence to disable CAPP in disable_capi_mode() and > with it also enable fast-reset for CAPI mode in phb4_set_capi_mode(). > > Sequence to disable CAPP is executed in three phases. The first two > phase is implemented in disable_capi_mode() where we reset the CAPP > registers followed by PEC registers to their init values. The final > third final phase is to reset the PHB CAPI Compare/Mask Register and > is done in phb4_init_ioda3(). The reason to move the PHB reset to > phb4_init_ioda3() is because by the time Opal PCI reset state machine > reaches this function the PHB is already un-fenced and its > configuration registers accessible via mmio. > > Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com> I can't guarantee that the reset sequence is entirely correct but nothing jumped out as wrong to me, so: Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com> > --- > Change-log: > v2 Instead of using the 'PHB4_CAPP_REG_OFFSET' macro use the > 'struct capp->capp_xscom_offset' member. > --- > hw/phb4.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- > 1 file changed, 74 insertions(+), 3 deletions(-) > > diff --git a/hw/phb4.c b/hw/phb4.c > index 447ba902..36353b74 100644 > --- a/hw/phb4.c > +++ b/hw/phb4.c > @@ -3219,7 +3219,77 @@ static void disable_capi_mode(struct phb4 *p) > > PHBINF(p, "CAPP: Disabling CAPI mode\n"); > > - /* Implement procedure to disable CAPP based on h/w sequence */ > + /* First Phase Reset CAPP Registers */ > + /* CAPP about to be disabled mark TLBI_FENCED and tlbi_psl_is_dead */ > + xscom_write(p->chip_id, capp->capp_xscom_offset + > + CAPP_ERR_STATUS_CTRL, PPC_BIT(3) | PPC_BIT(4)); > + > + /* Flush SUE uOP1 Register */ > + if (!(p->rev == PHB4_REV_NIMBUS_DD10)) The != operator is a thing :) > + xscom_write(p->chip_id, capp->capp_xscom_offset + > + FLUSH_SUE_UOP1, 0); > + > + /* Release DMA/STQ engines */ > + xscom_write(p->chip_id, capp->capp_xscom_offset + > + APC_FSM_READ_MASK, 0ull); > + xscom_write(p->chip_id, capp->capp_xscom_offset + > + XPT_FSM_RMM, 0ull); > + > + /* Disable snoop */ > + xscom_write(p->chip_id, capp->capp_xscom_offset + SNOOP_CAPI_CONFIG, 0); > + > + /* Clear flush SUE state map register */ > + xscom_write(p->chip_id, capp->capp_xscom_offset + > + FLUSH_SUE_STATE_MAP, 0); > + > + /* Disable epoch timer */ > + xscom_write(p->chip_id, capp->capp_xscom_offset + > + EPOCH_RECOVERY_TIMERS_CTRL, 0); > + > + /* CAPP Transport Control Register */ > + xscom_write(p->chip_id, capp->capp_xscom_offset + > + TRANSPORT_CONTROL, PPC_BIT(15)); > + > + /* Disable snooping */ > + xscom_write(p->chip_id, capp->capp_xscom_offset + > + SNOOP_CONTROL, 0); > + xscom_write(p->chip_id, capp->capp_xscom_offset + > + SNOOP_CAPI_CONFIG, 0); > + > + /* APC Master PB Control Register - disable examining cResps */ > + xscom_write(p->chip_id, capp->capp_xscom_offset + > + APC_MASTER_PB_CTRL, 0); > + > + /* APC Master Config Register - de-select PHBs */ > + xscom_write_mask(p->chip_id, capp->capp_xscom_offset + > + APC_MASTER_CAPI_CTRL, 0, PPC_BITMASK(2, 3)); > + > + /* Clear all error registers */ > + xscom_write(p->chip_id, capp->capp_xscom_offset + CAPP_ERR_RPT_CLR, 0); > + xscom_write(p->chip_id, capp->capp_xscom_offset + CAPP_FIR, 0); > + xscom_write(p->chip_id, capp->capp_xscom_offset + CAPP_FIR_ACTION0, 0); > + xscom_write(p->chip_id, capp->capp_xscom_offset + CAPP_FIR_ACTION1, 0); > + xscom_write(p->chip_id, capp->capp_xscom_offset + CAPP_FIR_MASK, 0); > + > + /* Second Phase Reset PEC/PHB Registers */ > + > + /* Reset the stack overrides if any */ > + xscom_write(p->chip_id, p->pci_xscom + XPEC_PCI_PRDSTKOVR, 0); > + xscom_write(p->chip_id, p->pe_xscom + > + XPEC_NEST_READ_STACK_OVERRIDE, 0); > + > + /* PE Bus AIB Mode Bits. Disable Tracing. Leave HOL Blocking as it is */ > + if (!(p->rev == PHB4_REV_NIMBUS_DD10) && p->index == CAPP1_PHB_INDEX) > + xscom_write_mask(p->chip_id, > + p->pci_xscom + XPEC_PCI_PBAIB_HW_CONFIG, 0, > + PPC_BIT(30)); > + > + /* Reset for PCI to PB data movement */ > + xscom_write_mask(p->chip_id, p->pe_xscom + XPEC_NEST_PBCQ_HW_CONFIG, > + 0, XPEC_NEST_PBCQ_HW_CONFIG_PBINIT); > + > + /* Disable CAPP mode in PEC CAPP Control Register */ > + xscom_write(p->chip_id, p->pe_xscom + XPEC_NEST_CAPP_CNTL, 0ull); > } > > static int64_t phb4_creset(struct pci_slot *slot) > @@ -4623,8 +4693,6 @@ static int64_t phb4_set_capi_mode(struct phb *phb, uint64_t mode, > /* register notification on system shutdown */ > opal_add_host_sync_notifier(&phb4_host_sync_reset, p); > > - /* Disable fast reboot for CAPP */ > - disable_fast_reboot("CAPP being enabled"); > } else { > /* In case of an error mark the PHB detached */ > capp->phb = NULL; > @@ -4840,6 +4908,9 @@ static void phb4_init_ioda3(struct phb4 *p) > > /* Init_26 - CAPI Compare/Mask */ > /* See enable_capi_mode() */ > + /* if CAPP being disabled then reset CAPI Compare/Mask Register */ > + if (p->flags & PHB4_CAPP_DISABLE) > + out_be64(p->regs + PHB_CAPI_CMPM, 0); > > /* Init_27 - PCIE Outbound upper address */ > out_be64(p->regs + PHB_M64_UPPER_BITS, 0); >
diff --git a/hw/phb4.c b/hw/phb4.c index 447ba902..36353b74 100644 --- a/hw/phb4.c +++ b/hw/phb4.c @@ -3219,7 +3219,77 @@ static void disable_capi_mode(struct phb4 *p) PHBINF(p, "CAPP: Disabling CAPI mode\n"); - /* Implement procedure to disable CAPP based on h/w sequence */ + /* First Phase Reset CAPP Registers */ + /* CAPP about to be disabled mark TLBI_FENCED and tlbi_psl_is_dead */ + xscom_write(p->chip_id, capp->capp_xscom_offset + + CAPP_ERR_STATUS_CTRL, PPC_BIT(3) | PPC_BIT(4)); + + /* Flush SUE uOP1 Register */ + if (!(p->rev == PHB4_REV_NIMBUS_DD10)) + xscom_write(p->chip_id, capp->capp_xscom_offset + + FLUSH_SUE_UOP1, 0); + + /* Release DMA/STQ engines */ + xscom_write(p->chip_id, capp->capp_xscom_offset + + APC_FSM_READ_MASK, 0ull); + xscom_write(p->chip_id, capp->capp_xscom_offset + + XPT_FSM_RMM, 0ull); + + /* Disable snoop */ + xscom_write(p->chip_id, capp->capp_xscom_offset + SNOOP_CAPI_CONFIG, 0); + + /* Clear flush SUE state map register */ + xscom_write(p->chip_id, capp->capp_xscom_offset + + FLUSH_SUE_STATE_MAP, 0); + + /* Disable epoch timer */ + xscom_write(p->chip_id, capp->capp_xscom_offset + + EPOCH_RECOVERY_TIMERS_CTRL, 0); + + /* CAPP Transport Control Register */ + xscom_write(p->chip_id, capp->capp_xscom_offset + + TRANSPORT_CONTROL, PPC_BIT(15)); + + /* Disable snooping */ + xscom_write(p->chip_id, capp->capp_xscom_offset + + SNOOP_CONTROL, 0); + xscom_write(p->chip_id, capp->capp_xscom_offset + + SNOOP_CAPI_CONFIG, 0); + + /* APC Master PB Control Register - disable examining cResps */ + xscom_write(p->chip_id, capp->capp_xscom_offset + + APC_MASTER_PB_CTRL, 0); + + /* APC Master Config Register - de-select PHBs */ + xscom_write_mask(p->chip_id, capp->capp_xscom_offset + + APC_MASTER_CAPI_CTRL, 0, PPC_BITMASK(2, 3)); + + /* Clear all error registers */ + xscom_write(p->chip_id, capp->capp_xscom_offset + CAPP_ERR_RPT_CLR, 0); + xscom_write(p->chip_id, capp->capp_xscom_offset + CAPP_FIR, 0); + xscom_write(p->chip_id, capp->capp_xscom_offset + CAPP_FIR_ACTION0, 0); + xscom_write(p->chip_id, capp->capp_xscom_offset + CAPP_FIR_ACTION1, 0); + xscom_write(p->chip_id, capp->capp_xscom_offset + CAPP_FIR_MASK, 0); + + /* Second Phase Reset PEC/PHB Registers */ + + /* Reset the stack overrides if any */ + xscom_write(p->chip_id, p->pci_xscom + XPEC_PCI_PRDSTKOVR, 0); + xscom_write(p->chip_id, p->pe_xscom + + XPEC_NEST_READ_STACK_OVERRIDE, 0); + + /* PE Bus AIB Mode Bits. Disable Tracing. Leave HOL Blocking as it is */ + if (!(p->rev == PHB4_REV_NIMBUS_DD10) && p->index == CAPP1_PHB_INDEX) + xscom_write_mask(p->chip_id, + p->pci_xscom + XPEC_PCI_PBAIB_HW_CONFIG, 0, + PPC_BIT(30)); + + /* Reset for PCI to PB data movement */ + xscom_write_mask(p->chip_id, p->pe_xscom + XPEC_NEST_PBCQ_HW_CONFIG, + 0, XPEC_NEST_PBCQ_HW_CONFIG_PBINIT); + + /* Disable CAPP mode in PEC CAPP Control Register */ + xscom_write(p->chip_id, p->pe_xscom + XPEC_NEST_CAPP_CNTL, 0ull); } static int64_t phb4_creset(struct pci_slot *slot) @@ -4623,8 +4693,6 @@ static int64_t phb4_set_capi_mode(struct phb *phb, uint64_t mode, /* register notification on system shutdown */ opal_add_host_sync_notifier(&phb4_host_sync_reset, p); - /* Disable fast reboot for CAPP */ - disable_fast_reboot("CAPP being enabled"); } else { /* In case of an error mark the PHB detached */ capp->phb = NULL; @@ -4840,6 +4908,9 @@ static void phb4_init_ioda3(struct phb4 *p) /* Init_26 - CAPI Compare/Mask */ /* See enable_capi_mode() */ + /* if CAPP being disabled then reset CAPI Compare/Mask Register */ + if (p->flags & PHB4_CAPP_DISABLE) + out_be64(p->regs + PHB_CAPI_CMPM, 0); /* Init_27 - PCIE Outbound upper address */ out_be64(p->regs + PHB_M64_UPPER_BITS, 0);
We implement h/w sequence to disable CAPP in disable_capi_mode() and with it also enable fast-reset for CAPI mode in phb4_set_capi_mode(). Sequence to disable CAPP is executed in three phases. The first two phase is implemented in disable_capi_mode() where we reset the CAPP registers followed by PEC registers to their init values. The final third final phase is to reset the PHB CAPI Compare/Mask Register and is done in phb4_init_ioda3(). The reason to move the PHB reset to phb4_init_ioda3() is because by the time Opal PCI reset state machine reaches this function the PHB is already un-fenced and its configuration registers accessible via mmio. Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com> --- Change-log: v2 Instead of using the 'PHB4_CAPP_REG_OFFSET' macro use the 'struct capp->capp_xscom_offset' member. --- hw/phb4.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 3 deletions(-)