From patchwork Wed Apr 3 09:09:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver O'Halloran X-Patchwork-Id: 1075630 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44Z0h92yRJz9sSJ for ; Wed, 3 Apr 2019 20:11:53 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="meEUrLNs"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 44Z0h91LlYzDqH5 for ; Wed, 3 Apr 2019 20:11:53 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::529; helo=mail-pg1-x529.google.com; envelope-from=oohall@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="meEUrLNs"; dkim-atps=neutral Received: from mail-pg1-x529.google.com (mail-pg1-x529.google.com [IPv6:2607:f8b0:4864:20::529]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 44Z0dn4PndzDqCl for ; Wed, 3 Apr 2019 20:09:49 +1100 (AEDT) Received: by mail-pg1-x529.google.com with SMTP id p6so7983099pgh.9 for ; Wed, 03 Apr 2019 02:09:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=DaqnAAkBlqtH/ysZn5uCuiqAVauLe2awwI7B1IjOyTQ=; b=meEUrLNsTJsxuchG5haIxYAtZvlQrdt7qLaAmNSbidwvIDDve63a4V8eJG6qEg8u5W qqaMCJ+sRXlIQ0rVZjn5u5819cqV4axD6jxEFfi7VZpAcDgg4OBtJWkPF1K4QUbP0ZwZ 9H/QQgmkuGhzB8K3Y5IEpUMScRWdV96EMD3d2R004IhnguU8gTBkXnezyNvXJsAI+uUg VH/dkKz0Uo7RPj/Ab9WOqqXxhEnKJFtzWAgwwTEoL/Lx/mnfYpkgpTfZnmFqOO2JudVc G1r2TCwos5AW+9T6+oedFcu7Gu/dHUhMc5z7ZBWAnvCAKYFxx4HTZGIC+lo+6Ib/suOp RYDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=DaqnAAkBlqtH/ysZn5uCuiqAVauLe2awwI7B1IjOyTQ=; b=tC4nJHTZb92LVn1yN4wo5CkXSSk9ygZMzWi/E5IShzwbxwqruXRNiyIEnJ3hwmyExS M2ivIUCJsC7UqkmisbmdCrUkUnksTKcG65fOxNN1Vio4vMA9WxKgtPAVr5MH49J0sovs qidJ8l8XVa4RBPaXJwcEoQaIV0Nnl0vrKx9jPM8Vq5CNs2EGqzrAPK3cNNxnPsfswceD /8xdx4NVQD/1FyGwxWJxGO2sjk9aF879YYY1E1AU4Ms7StrE3gq5qAPKeNtg5fE7khVj T7ptUCwteHPpaC1jJdbgnS2aZWkt9dHd8ZJhHYkfsVPhY7H3bEL9vuR8bk3jKyEs77Hm kFEA== X-Gm-Message-State: APjAAAWSc0hHE0fGJyRU+U9yumBACm75XEL5NtxXmnMvMfAe+UcFhVqj M/2u8CbLr38A0fnii5hbvCaMkiDW X-Google-Smtp-Source: APXvYqx/fL+CEOr6hBiLUR5/W+xY3cvpfSD2AzjytZAAMNyN2nmOZEtpN98I0PMlK8+LVUGezR51Nw== X-Received: by 2002:a63:2c3:: with SMTP id 186mr71006690pgc.161.1554282586981; Wed, 03 Apr 2019 02:09:46 -0700 (PDT) Received: from wafer.ozlabs.ibm.com ([122.99.82.10]) by smtp.gmail.com with ESMTPSA id t64sm39165764pfa.86.2019.04.03.02.09.45 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 03 Apr 2019 02:09:46 -0700 (PDT) From: Oliver O'Halloran To: skiboot@lists.ozlabs.org Date: Wed, 3 Apr 2019 20:09:03 +1100 Message-Id: <20190403090920.362-7-oohall@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190403090920.362-1-oohall@gmail.com> References: <20190403090920.362-1-oohall@gmail.com> MIME-Version: 1.0 Subject: [Skiboot] [RFC PATCH 06/23] core/pci-slot: Add pci_slot_generic_freset() X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" Add a generic function that can use the assert_perst() and set_power_state() slot operations to do fundemental reset of the slot. Signed-off-by: Oliver O'Halloran --- core/pci-slot.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ hw/phb4.c | 5 ++-- include/pci-slot.h | 6 ++++ 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/core/pci-slot.c b/core/pci-slot.c index 497d0a47f426..14dd95ec0dd1 100644 --- a/core/pci-slot.c +++ b/core/pci-slot.c @@ -19,6 +19,7 @@ #include #include #include +#include /* Debugging options */ #define PCI_SLOT_PREFIX "PCI-SLOT-%016llx " @@ -114,6 +115,77 @@ static int64_t pci_slot_run_sm(struct pci_slot *slot) return ret; } +int64_t pci_slot_generic_freset(struct pci_slot *slot) +{ + uint16_t bdfn = slot->pd ? slot->pd->bdfn : 0; + struct phb *phb = slot->phb; + int64_t rc; + + /* We need atleast one of them to do an FRESET */ + assert(slot->ops.set_power_state || slot->ops.assert_perst); + // not strictly required... + assert(slot->ops.prepare_link_change); + + switch(slot->state) { + case PCI_SLOT_STATE_NORMAL: + case PCI_SLOT_FRESET_START: + PCIERR(phb, bdfn, "FRESET: Prepare for link down\n"); + + // FIXME: Handle errors + if (slot->ops.prepare_link_change) + slot->ops.prepare_link_change(slot, false); + if (slot->ops.assert_perst) + slot->ops.assert_perst(slot, true); + + /* + * If we don't have power control then skip those states + * and go straight to de-assert after 250ms. + */ + if (!slot->ops.set_power_state) { + pci_slot_set_state(slot, PCI_SLOT_FRESET_LIFT_PERST); + return pci_slot_set_sm_timeout(slot, msecs_to_tb(250)); + } + + pci_slot_set_state(slot, PCI_SLOT_FRESET_POWER_OFF); + + /* fallthrough */ + case PCI_SLOT_FRESET_POWER_OFF: + rc = slot->ops.set_power_state(slot, PCI_SLOT_POWER_OFF); + if (rc > 0) + return pci_slot_set_sm_timeout(slot, msecs_to_tb(rc)); + /* XXX: error handling */ + + /* leave power off for 250ms before turning the slot back on */ + PCIERR(phb, bdfn, "FRESET: Slot powered off\n"); + pci_slot_set_state(slot, PCI_SLOT_FRESET_POWER_ON); + return pci_slot_set_sm_timeout(slot, msecs_to_tb(250)); + + case PCI_SLOT_FRESET_POWER_ON: + rc = slot->ops.set_power_state(slot, PCI_SLOT_POWER_ON); + if (rc > 0) + return pci_slot_set_sm_timeout(slot, msecs_to_tb(rc)); + /* XXX: error handling */ + PCIERR(phb, bdfn, "FRESET: Slot powered on\n"); + + /* fallthrough */ + case PCI_SLOT_FRESET_LIFT_PERST: + PCIDBG(phb, bdfn, "FRESET: Deassert\n"); + if (slot->ops.assert_perst) + slot->ops.assert_perst(slot, false); + + pci_slot_set_state(slot, PCI_SLOT_STATE_LINK_START_POLL); + return slot->ops.poll_link(slot); + default: + PCIERR(phb, bdfn, "Unexpected slot state %08x\n", slot->state); + } + + PCIERR(phb, bdfn, "Uhh how did we get here???\n"); + backtrace(); + pci_slot_set_state(slot, PCI_SLOT_STATE_NORMAL); + + return OPAL_HARDWARE; +} + void pci_slot_add_dt_properties(struct pci_slot *slot, struct dt_node *np) { diff --git a/hw/phb4.c b/hw/phb4.c index bcd998d910af..591872c31c02 100644 --- a/hw/phb4.c +++ b/hw/phb4.c @@ -2939,6 +2939,9 @@ static void phb4_assert_perst(struct pci_slot *slot, bool assert) } else { linkctl &= ~PCICAP_EXP_LCTL_LINK_DIS; reg |= PHB_PCIE_CRESET_PERST_N; + + /* Clear link errors before we deassert PERST */ + phb4_err_clear_regb(p); } out_be64(p->regs + PHB_PCIE_CRESET, reg); @@ -3034,8 +3037,6 @@ static int64_t phb4_freset(struct pci_slot *slot) p->skip_perst = false; /* fall through */ case PHB4_SLOT_FRESET_ASSERT_DELAY: - /* Clear link errors before we deassert PERST */ - phb4_err_clear_regb(p); if (pci_tracing) { /* Enable tracing */ diff --git a/include/pci-slot.h b/include/pci-slot.h index cb36d7b6df5a..fec11ccf46c2 100644 --- a/include/pci-slot.h +++ b/include/pci-slot.h @@ -134,6 +134,10 @@ struct pci_slot_ops { #define PCI_SLOT_STATE_HRESET_HOLD (PCI_SLOT_STATE_HRESET + 2) #define PCI_SLOT_STATE_FRESET 0x00000300 #define PCI_SLOT_STATE_FRESET_POWER_OFF (PCI_SLOT_STATE_FRESET + 1) +#define PCI_SLOT_FRESET_START (PCI_SLOT_STATE_FRESET + 1) +#define PCI_SLOT_FRESET_POWER_OFF (PCI_SLOT_STATE_FRESET + 2) +#define PCI_SLOT_FRESET_POWER_ON (PCI_SLOT_STATE_FRESET + 3) +#define PCI_SLOT_FRESET_LIFT_PERST (PCI_SLOT_STATE_FRESET + 4) #define PCI_SLOT_STATE_CRESET 0x00000400 #define PCI_SLOT_STATE_CRESET_START (PCI_SLOT_STATE_CRESET + 1) #define PCI_SLOT_STATE_GPOWER 0x00000500 @@ -282,6 +286,8 @@ extern struct pci_slot *pci_slot_find(uint64_t id); extern void pci_slot_add_loc(struct pci_slot *slot, struct dt_node *np, const char *label); +int64_t pci_slot_generic_freset(struct pci_slot *slot); + /* DT based slot map */ extern struct dt_node *dt_slots;