diff mbox series

[v3,7/8] phb4/capp: Implement sequence to disable CAPP and enable fast-reset

Message ID 20190108095902.24718-8-vaibhav@linux.ibm.com
State Superseded
Headers show
Series Enable fast-reboot support for CAPI-2 | expand

Checks

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

Commit Message

Vaibhav Jain Jan. 8, 2019, 9:59 a.m. UTC
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.

Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
---
Change-log

v3:	Use the capp_xscom_write() instead of xscom_write().

	Minor change of a branch condition [ Andrew ]

v2:	Instead of using the 'PHB4_CAPP_REG_OFFSET' macro use the
	'struct capp->capp_xscom_offset' member.
---
 hw/phb4.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 64 insertions(+), 3 deletions(-)

Comments

Christophe Lombard Jan. 9, 2019, 12:55 p.m. UTC | #1
Le 08/01/2019 à 10:59, Vaibhav Jain a écrit :
> 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.
> 
> Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
> Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
> ---
> Change-log
> 
> v3:	Use the capp_xscom_write() instead of xscom_write().
> 
> 	Minor change of a branch condition [ Andrew ]
> 
> v2:	Instead of using the 'PHB4_CAPP_REG_OFFSET' macro use the
> 	'struct capp->capp_xscom_offset' member.
> ---

Without going into details, it sounds good. Thanks.

Reviewed-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
Frederic Barrat Jan. 10, 2019, 1:49 p.m. UTC | #2
Le 08/01/2019 à 10:59, Vaibhav Jain a écrit :
> 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.
> 
> Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
> Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
> ---

I'll admit not being able to follow every single bits being reset in 
that patch, but since you tested it with kexec loops, it looks reasonable.

Reviewed-by: Frederic Barrat <fbarrat@linux.ibm.com>

> Change-log
> 
> v3:	Use the capp_xscom_write() instead of xscom_write().
> 
> 	Minor change of a branch condition [ Andrew ]
> 
> v2:	Instead of using the 'PHB4_CAPP_REG_OFFSET' macro use the
> 	'struct capp->capp_xscom_offset' member.
> ---
>   hw/phb4.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
>   1 file changed, 64 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/phb4.c b/hw/phb4.c
> index 88b1a6fb..6b330793 100644
> --- a/hw/phb4.c
> +++ b/hw/phb4.c
> @@ -3218,7 +3218,67 @@ 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 */
> +	capp_xscom_write(capp, CAPP_ERR_STATUS_CTRL, PPC_BIT(3) | PPC_BIT(4));
> +
> +	/* Flush SUE uOP1 Register */
> +	if (p->rev != PHB4_REV_NIMBUS_DD10)
> +		capp_xscom_write(capp, FLUSH_SUE_UOP1, 0);
> +
> +	/* Release DMA/STQ engines */
> +	capp_xscom_write(capp, APC_FSM_READ_MASK, 0ull);
> +	capp_xscom_write(capp, XPT_FSM_RMM, 0ull);
> +
> +	/* Disable snoop */
> +	capp_xscom_write(capp, SNOOP_CAPI_CONFIG, 0);
> +
> +	/* Clear flush SUE state map register */
> +	capp_xscom_write(capp, FLUSH_SUE_STATE_MAP, 0);
> +
> +	/* Disable epoch timer */
> +	capp_xscom_write(capp, EPOCH_RECOVERY_TIMERS_CTRL, 0);
> +
> +	/* CAPP Transport Control Register */
> +	capp_xscom_write(capp, TRANSPORT_CONTROL, PPC_BIT(15));
> +
> +	/* Disable snooping */
> +	capp_xscom_write(capp, SNOOP_CONTROL, 0);
> +	capp_xscom_write(capp, SNOOP_CAPI_CONFIG, 0);
> +
> +	/* APC Master PB Control Register - disable examining cResps */
> +	capp_xscom_write(capp, 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 */
> +	capp_xscom_write(capp, CAPP_ERR_RPT_CLR, 0);
> +	capp_xscom_write(capp, CAPP_FIR, 0);
> +	capp_xscom_write(capp, CAPP_FIR_ACTION0, 0);
> +	capp_xscom_write(capp, CAPP_FIR_ACTION1, 0);
> +	capp_xscom_write(capp, 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)
> @@ -4621,8 +4681,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;
> @@ -4838,6 +4896,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 mbox series

Patch

diff --git a/hw/phb4.c b/hw/phb4.c
index 88b1a6fb..6b330793 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -3218,7 +3218,67 @@  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 */
+	capp_xscom_write(capp, CAPP_ERR_STATUS_CTRL, PPC_BIT(3) | PPC_BIT(4));
+
+	/* Flush SUE uOP1 Register */
+	if (p->rev != PHB4_REV_NIMBUS_DD10)
+		capp_xscom_write(capp, FLUSH_SUE_UOP1, 0);
+
+	/* Release DMA/STQ engines */
+	capp_xscom_write(capp, APC_FSM_READ_MASK, 0ull);
+	capp_xscom_write(capp, XPT_FSM_RMM, 0ull);
+
+	/* Disable snoop */
+	capp_xscom_write(capp, SNOOP_CAPI_CONFIG, 0);
+
+	/* Clear flush SUE state map register */
+	capp_xscom_write(capp, FLUSH_SUE_STATE_MAP, 0);
+
+	/* Disable epoch timer */
+	capp_xscom_write(capp, EPOCH_RECOVERY_TIMERS_CTRL, 0);
+
+	/* CAPP Transport Control Register */
+	capp_xscom_write(capp, TRANSPORT_CONTROL, PPC_BIT(15));
+
+	/* Disable snooping */
+	capp_xscom_write(capp, SNOOP_CONTROL, 0);
+	capp_xscom_write(capp, SNOOP_CAPI_CONFIG, 0);
+
+	/* APC Master PB Control Register - disable examining cResps */
+	capp_xscom_write(capp, 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 */
+	capp_xscom_write(capp, CAPP_ERR_RPT_CLR, 0);
+	capp_xscom_write(capp, CAPP_FIR, 0);
+	capp_xscom_write(capp, CAPP_FIR_ACTION0, 0);
+	capp_xscom_write(capp, CAPP_FIR_ACTION1, 0);
+	capp_xscom_write(capp, 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)
@@ -4621,8 +4681,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;
@@ -4838,6 +4896,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);