diff --git a/hw/phb4.c b/hw/phb4.c
index 615cda66..16a4a62a 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -2777,6 +2777,38 @@ static bool phb4_host_sync_reset(void *data)
 	return rc <= OPAL_SUCCESS;
 }
 
+/*
+ * Notification from the pci-core that a pci slot state machine completed.
+ * We use this callback to mark the CAPP disabled if we were waiting for it.
+ */
+static void phb4_slot_sm_run_completed(struct pci_slot *slot, uint64_t err)
+{
+	struct phb4 *p = phb_to_phb4(slot->phb);
+	struct proc_chip *chip = get_chip(p->chip_id);
+
+	/* Check if we are disabling the capp */
+	if (p->flags & PHB4_CAPP_DISABLE) {
+		/* Make sure we done stomp on some else's req to enable capp */
+		lock(&capi_lock);
+
+		/* Unset the flags so that we dont fall into a creset loop */
+		p->flags &= ~(PHB4_CAPP_DISABLE);
+		chip->capp_phb4_attached_mask &= ~(1 << p->index);
+
+		/* Remove the host sync notifier is we are done.*/
+		opal_del_host_sync_notifier_with_data(phb4_host_sync_reset,
+							      p);
+		if (err) {
+			/* Force a CEC ipl reboot */
+			disable_fast_reboot("CAPP: reset failed");
+			PHBERR(p, "CAPP: Unable to reset. Error=%lld\n", err);
+		} else {
+			PHBINF(p, "CAPP: reset complete\n");
+		}
+		unlock(&capi_lock);
+	}
+}
+
 static int64_t phb4_poll_link(struct pci_slot *slot)
 {
 	struct phb4 *p = phb_to_phb4(slot->phb);
@@ -3116,6 +3148,44 @@ static int do_capp_recovery_scoms(struct phb4 *p)
 	return rc;
 }
 
+/*
+ * Disable CAPI mode on a PHB. Must be done while PHB is fenced and
+ * not in recovery.
+ */
+static void disable_capi_mode(struct phb4 *p)
+{
+	struct proc_chip *chip = get_chip(p->chip_id);
+	uint64_t reg;
+	uint32_t offset = PHB4_CAPP_REG_OFFSET(p);
+
+	PHBINF(p, "CAPP: Deactivating\n");
+
+	/* Check if CAPP attached to the PHB and active */
+	if (!(chip->capp_phb4_attached_mask & (1 << p->index))) {
+		PHBERR(p, "CAPP: Not attached to this PHB!\n");
+		return;
+	}
+
+	xscom_read(p->chip_id, p->pe_xscom + XPEC_NEST_CAPP_CNTL, &reg);
+	if (!(reg & PPC_BIT(0))) {
+		/* Not in CAPI mode, no action required */
+		PHBDBG(p, "CAPP: Not enabled!\n");
+		return;
+	}
+
+	/* CAPP should already be out of recovery in this function */
+	xscom_read(p->chip_id, CAPP_ERR_STATUS_CTRL + offset, &reg);
+	if (reg & PPC_BIT(0)) {
+		PHBERR(p, "CAPP: Cant disable while still in recovery!\n");
+		return;
+	}
+
+	PHBINF(p, "CAPP: Disabling CAPI mode\n");
+
+	/* Implement procedure to disable CAPP based on h/w sequence */
+}
+
+
 static int64_t phb4_creset(struct pci_slot *slot)
 {
 	struct phb4 *p = phb_to_phb4(slot->phb);
@@ -3176,6 +3246,9 @@ static int64_t phb4_creset(struct pci_slot *slot)
 			    (do_capp_recovery_scoms(p) != OPAL_SUCCESS))
 				goto error;
 
+			if (p->flags & PHB4_CAPP_DISABLE)
+				disable_capi_mode(p);
+
 			/* Clear errors in PFIR and NFIR */
 			xscom_write(p->chip_id, p->pci_stk_xscom + 0x1,
 				    ~p->pfir_cache);
@@ -3260,6 +3333,7 @@ static struct pci_slot *phb4_slot_create(struct phb *phb)
 	slot->ops.hreset		= phb4_hreset;
 	slot->ops.freset		= phb4_freset;
 	slot->ops.creset		= phb4_creset;
+	slot->ops.completed_sm_run      = phb4_slot_sm_run_completed;
 	slot->link_retries		= PHB4_LINK_LINK_RETRIES;
 
 	return slot;
@@ -4371,12 +4445,36 @@ static int64_t phb4_set_capi_mode(struct phb *phb, uint64_t mode,
 		break;
 
 	case OPAL_PHB_CAPI_MODE_SNOOP_OFF:
-	case OPAL_PHB_CAPI_MODE_PCIE: /* Not supported at the moment */
 		ret = !attached ? OPAL_SUCCESS : OPAL_UNSUPPORTED;
 		break;
 
+	case OPAL_PHB_CAPI_MODE_PCIE:
+		if (p->flags & PHB4_CAPP_DISABLE) {
+			/* We are in middle of a CAPP disable */
+			ret = OPAL_BUSY;
+
+		} else if (attached) {
+			p->flags |= PHB4_CAPP_DISABLE;
+			PHBINF(p, "CAPP: PCIE mode needs a cold-reset\n");
+			/* Kick off the pci state machine */
+			ret = phb4_creset(phb->slot);
+			ret = ret > 0 ? OPAL_BUSY : ret;
+
+		} else {
+			/* PHB already in PCI mode */
+			ret = OPAL_SUCCESS;
+		}
+		break;
+
 	case OPAL_PHB_CAPI_MODE_CAPI: /* Fall Through */
 	case OPAL_PHB_CAPI_MODE_DMA_TVT1:
+		/* Make sure that PHB is not disabling CAPP */
+		if (p->flags & PHB4_CAPP_DISABLE) {
+			PHBERR(p, "CAPP: Disable in progress\n");
+			ret = OPAL_BUSY;
+			break;
+		}
+
 		/* Check if ucode is available */
 		if (!capp_ucode_loaded(chip, p->index)) {
 			PHBERR(p, "CAPP: ucode not loaded\n");
@@ -4389,6 +4487,7 @@ static int64_t phb4_set_capi_mode(struct phb *phb, uint64_t mode,
 			PHBERR(p, "CAPP: recovery failed (%016llx)\n", reg);
 			ret = OPAL_HARDWARE;
 			break;
+
 		} else if ((reg & PPC_BIT(0)) && (!(reg & PPC_BIT(1)))) {
 			PHBDBG(p, "CAPP: recovery in progress\n");
 			ret = OPAL_BUSY;
diff --git a/include/phb4.h b/include/phb4.h
index d78bc317..050548be 100644
--- a/include/phb4.h
+++ b/include/phb4.h
@@ -164,6 +164,7 @@ struct phb4_err {
 #define PHB4_CFG_USE_ASB	0x00000002
 #define PHB4_CFG_BLOCKED	0x00000004
 #define PHB4_CAPP_RECOVERY	0x00000008
+#define PHB4_CAPP_DISABLE	0x00000010
 
 struct phb4 {
 	unsigned int		index;	    /* 0..5 index inside p9 */
