From patchwork Thu Apr 5 06:53:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver O'Halloran X-Patchwork-Id: 895286 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40Gtpb4lZzz9s0y for ; Thu, 5 Apr 2018 16:53:59 +1000 (AEST) 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="MLvQ8aRJ"; 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 40Gtpb2xBbzF1l6 for ; Thu, 5 Apr 2018 16:53:59 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="MLvQ8aRJ"; dkim-atps=neutral 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:400e:c01::241; helo=mail-pl0-x241.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="MLvQ8aRJ"; dkim-atps=neutral Received: from mail-pl0-x241.google.com (mail-pl0-x241.google.com [IPv6:2607:f8b0:400e:c01::241]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 40GtpB72sxzDrnp for ; Thu, 5 Apr 2018 16:53:38 +1000 (AEST) Received: by mail-pl0-x241.google.com with SMTP id 59-v6so15157381plc.13 for ; Wed, 04 Apr 2018 23:53:37 -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; bh=8N/+84WJAC+KG0PJYlQQIfE6UVLLagiNKHuRXnPT3kI=; b=MLvQ8aRJqPTxkD74VMviNfvEbDgOSfZQqRtP3NmxHj6unq9iGd9Y2pOAcuyC6jx3Rj Tt0N17Lpj1T7kXofCcLh967OU7ipNsmzielKLlxDIZVTPt1OZ54nnT9HeTBd1/0fhAWb 9qiWKL17TuycEmlMzKoQymD5oHHF/88xWyak1fvpnFwo2CAfcjHYzZW7Ur6fJoqTU2Ph XEUhxWrIXEyTltg7DR4K1EdvI+TdJAxtu3BqnIUIIjyKa+I9H0X9eEMTS0P5SYMklHQv 1hvFIr2SPfh3QpJ6DOV419kHu9BCWFp6FI72SgLrlQ9Z7gpC1eXfu0CYCo6m8aMw17Yp +3eg== 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; bh=8N/+84WJAC+KG0PJYlQQIfE6UVLLagiNKHuRXnPT3kI=; b=fWtndSxh8L7ai+zYognitZgTIjMFOwy5USW7VqtMqFPVtLbmQOQsD4IGt/L/xabEhr hsOeDPYZxiPHIQh6jrBk1Z92YpljvA1Bz6oXhGy3z72InETRPCT48Y92V3lDe90aWg7J UL83WSmun1T66I5h+Q8BppdbmpU8UbDyOpd2spMI5KgvJQ4C9dM4SvXmpgwKcnppucV+ oTjPU+iQi0tvhTUufOO5q08OzRtObZEnCd0aItjo4VHxjT9Sgf/okMQZ0KJfqRzj1TyP Ea0yzjYK9D0I3zcqgnX7RKYfDgsRAA5bVeF0SSOyyP41bWWVkRTTtdUUSOeIuugE0aqX mOXQ== X-Gm-Message-State: AElRT7Fil6xUBxJwG2Q4ORvguhP6qxw2KfqQa5lNZg8waec6YtNdBEVm vFMLPTY5lMKsIljksrreFlDDgQ== X-Google-Smtp-Source: AIpwx4/uYc8y07dxgS8AQfqKk52rHqop+XFXsnIWiHivWQMR8NVqvZPTN8L40CJJWytPuJmwa5bCHg== X-Received: by 10.99.120.3 with SMTP id t3mr13832381pgc.56.1522911215623; Wed, 04 Apr 2018 23:53:35 -0700 (PDT) Received: from flat-canetoad.ozlabs.ibm.com ([122.99.82.10]) by smtp.gmail.com with ESMTPSA id j11sm12608871pgs.13.2018.04.04.23.53.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 04 Apr 2018 23:53:34 -0700 (PDT) From: Oliver O'Halloran To: skiboot@lists.ozlabs.org Date: Thu, 5 Apr 2018 16:53:20 +1000 Message-Id: <20180405065322.3647-1-oohall@gmail.com> X-Mailer: git-send-email 2.9.5 Subject: [Skiboot] [PATCH 1/3] core/pci: Set slot power limit when supported X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" The PCIe slot capability can be implemented in a root or switch downstream port to set the maximum power a card is allowed to draw from the system. This patch adds support for setting the power limit when the platform has defined one. Signed-off-by: Oliver O'Halloran --- core/pci-slot.c | 1 + core/pci.c | 40 ++++++++++++++++++++++++++++++++++++++++ include/pci-slot.h | 1 + 3 files changed, 42 insertions(+) diff --git a/core/pci-slot.c b/core/pci-slot.c index 8bddc147e9d2..71d2769e710b 100644 --- a/core/pci-slot.c +++ b/core/pci-slot.c @@ -133,6 +133,7 @@ void pci_slot_add_dt_properties(struct pci_slot *slot, dt_add_property_cells(np, "ibm,slot-card-desc", slot->card_desc); dt_add_property_cells(np, "ibm,slot-card-mech", slot->card_mech); dt_add_property_cells(np, "ibm,slot-wired-lanes", slot->wired_lanes); + dt_add_property_cells(np, "ibm,power-limit", slot->power_limit); if (slot->ops.add_properties) slot->ops.add_properties(slot, np); diff --git a/core/pci.c b/core/pci.c index 3fc4854a3ed8..6d627a1e4db0 100644 --- a/core/pci.c +++ b/core/pci.c @@ -713,6 +713,43 @@ void pci_remove_bus(struct phb *phb, struct list_head *list) } } +static void pci_set_power_limit(struct pci_device *pd) +{ + uint32_t offset, val; + uint16_t caps; + + offset = pci_cap(pd, PCI_CFG_CAP_ID_EXP, false); + if (!offset) { + PCIERR(pd->phb, pd->bdfn, "Legacy dev?\n"); + return; /* legacy dev */ + } + + pci_cfg_read16(pd->phb, pd->bdfn, + offset + PCICAP_EXP_CAPABILITY_REG, &caps); + if (!(caps & PCICAP_EXP_CAP_SLOT)) { + PCIERR(pd->phb, pd->bdfn, "slot cap missing?\n"); + return; /* bridge has no slot capabilities */ + } + + if (!pd->slot || !pd->slot->power_limit) { + PCIERR(pd->phb, pd->bdfn, "slot information missing!!!\n"); + return; + } + + pci_cfg_read32(pd->phb, pd->bdfn, offset + PCICAP_EXP_SLOTCAP, &val); + + val = SETFIELD(PCICAP_EXP_SLOTCAP_SPLSC, val, 0); /* 1W scale */ + val = SETFIELD(PCICAP_EXP_SLOTCAP_SPLVA, val, pd->slot->power_limit); + + pci_cfg_write32(pd->phb, pd->bdfn, offset + PCICAP_EXP_SLOTCAP, val); + + /* update the cached copy in the slot */ + pd->slot->slot_cap = val; + + PCIERR(pd->phb, pd->bdfn, "Slot power limit set to %dW\n", + pd->slot->power_limit); +} + /* Perform a recursive scan of the bus at bus_number populating * the list passed as an argument. This also performs the bus * numbering, so it returns the largest bus number that was @@ -847,6 +884,9 @@ uint8_t pci_scan_bus(struct phb *phb, uint8_t bus, uint8_t max_bus, /* Clear up bridge resources */ pci_cleanup_bridge(phb, pd); + /* set a slot power limit (if we have one) */ + pci_set_power_limit(pd); + /* Configure the bridge. This will enable power to the slot * if it's currently disabled, lift reset, etc... * diff --git a/include/pci-slot.h b/include/pci-slot.h index bb66d7c7f888..cd757535a470 100644 --- a/include/pci-slot.h +++ b/include/pci-slot.h @@ -169,6 +169,7 @@ struct pci_slot { uint8_t card_desc; uint8_t card_mech; uint8_t wired_lanes; + uint8_t power_limit; /* * PCI slot is driven by state machine with polling function.