From patchwork Thu Apr 1 21:21:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Quinlan X-Patchwork-Id: 12179593 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 16411C433ED for ; Thu, 1 Apr 2021 21:30:19 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A9BDE61105 for ; Thu, 1 Apr 2021 21:30:18 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A9BDE61105 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:MIME-Version:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:Cc:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=N5CAbR/Ije/yf7QswIUw8BkEg7/W8KMrMN4BoGoZ79g=; b=BR0A9DZkmP2zgphCDhIYRkZOlI wzNGWsBD302aFRNDaBvntbQMyU8NcnH5cwqSlJo6JbBxMMk6mlaUinUtHNh1nWOeScaEWgDf5P9tk ktbLSVxyoQyjQI6hCBtZTrG0KhJVCJqg1qvZ7wp7sM2+z3IPf+YGnSJlxh/hymUCbBFIFDjF4BIOg JMGumf/wvy4X9hl5+KUWBCqTt0u5uqO3uuqzOXXvvhVaK4wgfX6tnjjln0bW3tMY6n3nLjVSdwOZS c1cVFNiDE8PmeYBruN9VtrTmlxbMRlEoOZP75pruzh3Q/Wj5J7qxBfbjxC/iw04suQoCeQNsyU5EG w2VCPgYQ==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lS4rn-00B3hx-AZ; Thu, 01 Apr 2021 21:28:39 +0000 Received: from mail-pf1-x435.google.com ([2607:f8b0:4864:20::435]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lS4lN-00B35Q-OP; Thu, 01 Apr 2021 21:22:53 +0000 Received: by mail-pf1-x435.google.com with SMTP id s11so2356723pfm.1; Thu, 01 Apr 2021 14:22:01 -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; bh=8VnZEjn3FMdva8ipBLV073OJdSwGTGi+Qmw1GQKtSJk=; b=rqKnVniAJqaznlfyFZnoH63rR6cVFwpgQ1QdlN2GJJEUGkszt41VRZqO4rpJeSuS5W ulfVwYfHvp8XURH5eqZdXRk3HjvyAmp8qq3bJ134fXnzYTTtscawCWC+iF+uCpSQq89a 7bW6bFpsWlfi63s1qgjE0H7ml3Y/BX9AFUA/0lQa0EGHhXKLZp8OCrL8X/Fvj+OpRhay d8f4T1l7t7sDxVP0p4nHlV1Vhc3gElYaA9PN8KVvin04fuQM3P6l9OTxU70AZWusuLfE 7/3vfT1uuQBVsMGt7v8BuPnU1bO9Rg9jgyDouparceLhXtuvpk6SUpfvnPtYgLP2LB0t MpVg== 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; bh=8VnZEjn3FMdva8ipBLV073OJdSwGTGi+Qmw1GQKtSJk=; b=nJ2AjuI9mBcRgMJLZl4PgdNgjdaSbaoRA2znlgibM2qUI5r+crmEWSgjL76xz0oXV4 nLGqaFO0plRpWPl15gLwQ5C3ZqSYfS/6mzZhM6uacg29dSx82II2qHqTZST2u13jHT1P ywFbgXYG+Bv/8320mYDUrPX1xnl5+0bg+ngmoUveM4TyBwClC9Z0GTf/QE9/UPUXo1I/ dnkOM53VoYCORslTqQCEV1XSxQnaXIvJAXmgcTz6tvNIJ9q6f/NZnTbZjPnUdVg7k9Iv XiRoL8TXXG3/R6Yz2tZNWF8UPgq+dGFerLeqfAhvYjAdq1pNImP4R4kbtslB05/tsKQo qIZg== X-Gm-Message-State: AOAM532MF3SJeRM71RbjPqlvbFvub3wLueGeWjTDhI9QtOo9XxHVuMAv pcY+BvMnPSTvukHJZwEi7y7fcMdnAvM= X-Google-Smtp-Source: ABdhPJwgmmrtZmxhTHaTcSUUdrBWSClYS0FE/GSnCuAlxz39mj1gVVrWBKV+9SHfDMvk4TEKO0KzZQ== X-Received: by 2002:a05:6a00:b86:b029:207:8ac9:85de with SMTP id g6-20020a056a000b86b02902078ac985demr9011916pfj.66.1617312120361; Thu, 01 Apr 2021 14:22:00 -0700 (PDT) Received: from stbsrv-and-01.and.broadcom.net ([192.19.231.250]) by smtp.gmail.com with ESMTPSA id q5sm5926707pfk.219.2021.04.01.14.21.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Apr 2021 14:22:00 -0700 (PDT) From: Jim Quinlan To: linux-pci@vger.kernel.org, Nicolas Saenz Julienne , Rob Herring , Mark Brown , bcm-kernel-feedback-list@broadcom.com, jim2101024@gmail.com, james.quinlan@broadcom.com Cc: Lorenzo Pieralisi , Bjorn Helgaas , Florian Fainelli , linux-rpi-kernel@lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE), linux-arm-kernel@lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE), linux-kernel@vger.kernel.org (open list) Subject: [PATCH v4 3/6] PCI: brcmstb: Add control of slot0 device voltage regulators Date: Thu, 1 Apr 2021 17:21:43 -0400 Message-Id: <20210401212148.47033-4-jim2101024@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210401212148.47033-1-jim2101024@gmail.com> References: <20210401212148.47033-1-jim2101024@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210401_222249_681783_8579615F X-CRM114-Status: GOOD ( 23.93 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org This Broadcom STB has one port and connects directly to one device, be it a switch or an endpoint. We want to be able to turn on/off any regulators for that device. Control of regulators is needed because of the chicken-and-egg situation: although the regulator is "owned" by the device and would be best handled by its driver, the device cannot be discovered and probed unless its regulator is already turned on. Signed-off-by: Jim Quinlan --- drivers/pci/controller/pcie-brcmstb.c | 83 +++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 5 deletions(-) diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c index 4ce1f3a60574..1b0de0c7da60 100644 --- a/drivers/pci/controller/pcie-brcmstb.c +++ b/drivers/pci/controller/pcie-brcmstb.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -169,6 +170,7 @@ #define SSC_STATUS_SSC_MASK 0x400 #define SSC_STATUS_PLL_LOCK_MASK 0x800 #define PCIE_BRCM_MAX_MEMC 3 +#define PCIE_BRCM_MAX_EP_REGULATORS 4 #define IDX_ADDR(pcie) (pcie->reg_offsets[EXT_CFG_INDEX]) #define DATA_ADDR(pcie) (pcie->reg_offsets[EXT_CFG_DATA]) @@ -192,6 +194,11 @@ static inline void brcm_pcie_perst_set_4908(struct brcm_pcie *pcie, u32 val); static inline void brcm_pcie_perst_set_7278(struct brcm_pcie *pcie, u32 val); static inline void brcm_pcie_perst_set_generic(struct brcm_pcie *pcie, u32 val); +static const char * const supplies[] = { + "vpcie12v-supply", + "vpcie3v3-supply", +}; + enum { RGR1_SW_INIT_1, EXT_CFG_INDEX, @@ -295,8 +302,27 @@ struct brcm_pcie { u32 hw_rev; void (*perst_set)(struct brcm_pcie *pcie, u32 val); void (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val); + struct regulator_bulk_data supplies[PCIE_BRCM_MAX_EP_REGULATORS]; + unsigned int num_supplies; }; +static int brcm_set_regulators(struct brcm_pcie *pcie, bool on) +{ + struct device *dev = pcie->dev; + int ret; + + if (!pcie->num_supplies) + return 0; + if (on) + ret = regulator_bulk_enable(pcie->num_supplies, pcie->supplies); + else + ret = regulator_bulk_disable(pcie->num_supplies, pcie->supplies); + if (ret) + dev_err(dev, "failed to %s EP regulators\n", + on ? "enable" : "disable"); + return ret; +} + /* * This is to convert the size of the inbound "BAR" region to the * non-linear values of PCIE_X_MISC_RC_BAR[123]_CONFIG_LO.SIZE @@ -1112,9 +1138,10 @@ static inline int brcm_phy_start(struct brcm_pcie *pcie) return pcie->rescal ? brcm_phy_cntl(pcie, 1) : 0; } -static inline int brcm_phy_stop(struct brcm_pcie *pcie) +static inline void brcm_phy_stop(struct brcm_pcie *pcie) { - return pcie->rescal ? brcm_phy_cntl(pcie, 0) : 0; + if (pcie->rescal) + brcm_phy_cntl(pcie, 0); } static void brcm_pcie_turn_off(struct brcm_pcie *pcie) @@ -1141,16 +1168,45 @@ static void brcm_pcie_turn_off(struct brcm_pcie *pcie) pcie->bridge_sw_init_set(pcie, 1); } +static int brcm_pcie_get_regulators(struct brcm_pcie *pcie) +{ + struct device_node *np = pcie->np; + struct property *pp; + const unsigned int ns = ARRAY_SIZE(supplies); + unsigned int i; + int ret = 0; + + /* Look for specific pcie regulators in the RC DT node. */ + for_each_property_of_node(np, pp) { + for (i = 0; i < ns; i++) + if (strcmp(supplies[i], pp->name) == 0) + break; + if (i >= ns) + continue; + + if (pcie->num_supplies < PCIE_BRCM_MAX_EP_REGULATORS) + pcie->supplies[pcie->num_supplies++].supply + = supplies[i]; + else + dev_warn(pcie->dev, "No room for supply %s\n", + supplies[i]); + } + + if (pcie->num_supplies) + ret = devm_regulator_bulk_get(pcie->dev, pcie->num_supplies, + pcie->supplies); + return ret; +} + static int brcm_pcie_suspend(struct device *dev) { struct brcm_pcie *pcie = dev_get_drvdata(dev); - int ret; brcm_pcie_turn_off(pcie); - ret = brcm_phy_stop(pcie); + brcm_phy_stop(pcie); clk_disable_unprepare(pcie->clk); - return ret; + return brcm_set_regulators(pcie, false); } static int brcm_pcie_resume(struct device *dev) @@ -1165,6 +1221,10 @@ static int brcm_pcie_resume(struct device *dev) if (ret) return ret; + ret = brcm_set_regulators(pcie, true); + if (ret) + return ret; + ret = brcm_phy_start(pcie); if (ret) goto err; @@ -1201,6 +1261,7 @@ static void __brcm_pcie_remove(struct brcm_pcie *pcie) brcm_phy_stop(pcie); reset_control_assert(pcie->rescal); clk_disable_unprepare(pcie->clk); + brcm_set_regulators(pcie, false); } static int brcm_pcie_remove(struct platform_device *pdev) @@ -1291,6 +1352,18 @@ static int brcm_pcie_probe(struct platform_device *pdev) return ret; } + ret = brcm_pcie_get_regulators(pcie); + if (ret) { + pcie->num_supplies = 0; + if (ret != -EPROBE_DEFER) + dev_err(pcie->dev, "failed to get regulators (err=%d)\n", ret); + goto fail; + } + + ret = brcm_set_regulators(pcie, true); + if (ret) + goto fail; + ret = brcm_pcie_setup(pcie); if (ret) goto fail;