From patchwork Wed Nov 25 19:24:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Quinlan X-Patchwork-Id: 1345253 Return-Path: Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 02CDBC64E7C for ; Wed, 25 Nov 2020 19:24:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9808D206D9 for ; Wed, 25 Nov 2020 19:24:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="M2dxA/cH" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727550AbgKYTYh (ORCPT ); Wed, 25 Nov 2020 14:24:37 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57936 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725989AbgKYTYg (ORCPT ); Wed, 25 Nov 2020 14:24:36 -0500 Received: from mail-pg1-x542.google.com (mail-pg1-x542.google.com [IPv6:2607:f8b0:4864:20::542]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D313CC0613D4 for ; Wed, 25 Nov 2020 11:24:36 -0800 (PST) Received: by mail-pg1-x542.google.com with SMTP id 81so3309111pgf.0 for ; Wed, 25 Nov 2020 11:24:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=y7ndIeR1NUOUYYXQBcY9J5lvUU5rOgBYurIuVCh3u3U=; b=M2dxA/cH+RVXfOHRZxT8KpR/KWp2IExF/RUh+qhpd4R4H7s8+oTtCBdw4vnKF96iry K9HBuYyyTf7wkgLXvvK/HYWOIMgnjielI+HiMNAcXNuXBUYl6q/u8wuA4Gu0Hn8vrjIJ UVjYMzOhcRHWbdIXR6lHcit4ycQ4pNY61Usm4= 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=y7ndIeR1NUOUYYXQBcY9J5lvUU5rOgBYurIuVCh3u3U=; b=eAlCdX43vmScDJt3YTRkWOk4GYXOY1b0EsePo3w+6qeXHOslJQl1VbquRQIGF8pFux rFd9FOCJEfROH37Ez9t24/LPbirtD/zYMKXC+Ar+K3loxI5Aky5nBi7kMLMgdWQEF1t9 b5ez0XFQrfNATQV2gfN8/BbVm/SPpzn2fRB3VTwFE61zLAv6etbYQjl0UF4HcuG02EVl 7Ysu9VCvOfB23P36NlnWlITTyj+NX2oX9vaQ0P5T+Ntxg7/L6F07QKB3FZpPlcnng+GI ntkZt6nPpVt0tVCaoUB0ysrLYbZC8urUPAspdgdBmbeTv6RrOj0RC3OoivxQ712MyM20 /owQ== X-Gm-Message-State: AOAM532GkGz4uJ2e9M5NoBlQIy81uiLL7zX1iuxkpzmOc0IhgV7OFOdi JjkgnFMGaWcMh6jwmrjEluAsyA== X-Google-Smtp-Source: ABdhPJz6vVcoWrR8yqtqLYtufwlOsd1CczIE/cfJgEho7SPEEGDIbysVzY9piHcqK/7KbaAapHOebg== X-Received: by 2002:aa7:9e88:0:b029:18b:c1b7:a8cd with SMTP id p8-20020aa79e880000b029018bc1b7a8cdmr4480957pfq.21.1606332276224; Wed, 25 Nov 2020 11:24:36 -0800 (PST) Received: from stbsrv-and-01.and.broadcom.net ([192.19.231.250]) by smtp.gmail.com with ESMTPSA id j69sm2574885pfd.37.2020.11.25.11.24.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Nov 2020 11:24:35 -0800 (PST) From: Jim Quinlan To: linux-pci@vger.kernel.org, Nicolas Saenz Julienne , bcm-kernel-feedback-list@broadcom.com, james.quinlan@broadcom.com Cc: Lorenzo Pieralisi , Rob Herring , Bjorn Helgaas , Florian Fainelli , Liam Girdwood , Mark Brown , 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 v1 2/6] PCI: brcmstb: Add control of EP voltage regulator(s) Date: Wed, 25 Nov 2020 14:24:19 -0500 Message-Id: <20201125192424.14440-3-james.quinlan@broadcom.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201125192424.14440-1-james.quinlan@broadcom.com> References: <20201125192424.14440-1-james.quinlan@broadcom.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Control of EP regulators by the RC is needed because of the chicken-and-egg situation: although the regulator is "owned" by the EP and would be best handled on its driver, the EP cannot be discovered and probed unless its regulator is already turned on. Signed-off-by: Jim Quinlan --- drivers/pci/controller/pcie-brcmstb.c | 66 +++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c index bea86899bd5d..34d6bad07b66 100644 --- a/drivers/pci/controller/pcie-brcmstb.c +++ b/drivers/pci/controller/pcie-brcmstb.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -210,6 +211,18 @@ enum pcie_type { BCM2711, }; +enum pcie_regulators { + VPCIE12V, + VPCIE3V3, + VPCIE1V8, + VPCIE0V9, + PCIE_REGULATORS_MAX, +}; + +static const char *ep_regulator_names[PCIE_REGULATORS_MAX] = { + "vpcie12v", "vpcie3v3", "vpcie1v8", "vpcie0v9", +}; + struct pcie_cfg_data { const int *offsets; const enum pcie_type type; @@ -287,8 +300,53 @@ 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 *regulators[PCIE_REGULATORS_MAX]; + int num_regulators; }; +static int brcm_parse_regulators(struct brcm_pcie *pcie) +{ + struct device *dev = pcie->dev; + struct regulator *ep_reg; + int i; + + for (i = 0; i < PCIE_REGULATORS_MAX; i++) { + ep_reg = devm_regulator_get_optional(dev, ep_regulator_names[i]); + if (IS_ERR(ep_reg)) { + if (PTR_ERR(ep_reg) == -ENODEV) + continue; + dev_err(dev, "failed to get regulator %s\n", ep_regulator_names[i]); + return PTR_ERR(ep_reg); + } + pcie->regulators[i] = ep_reg; + pcie->num_regulators++; + } + return 0; +} + +static void brcm_set_regulators(struct brcm_pcie *pcie, bool on) +{ + struct device *dev = pcie->dev; + int ret, i; + + if (pcie->num_regulators == 0) + return; + + for (i = 0; i < PCIE_REGULATORS_MAX; i++) { + if (!pcie->regulators[i]) + continue; + if (on) { + ret = regulator_enable(pcie->regulators[i]); + dev_dbg(dev, "enable regulator %s (%s)\n", + ep_regulator_names[i], ret ? "fail" : "pass"); + } else { + ret = regulator_disable(pcie->regulators[i]); + dev_dbg(dev, "disable regulator %s (%s)\n", + ep_regulator_names[i], ret ? "fail" : "pass"); + } + } +} + /* * 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 @@ -1139,6 +1197,7 @@ static int brcm_pcie_suspend(struct device *dev) brcm_pcie_turn_off(pcie); ret = brcm_phy_stop(pcie); clk_disable_unprepare(pcie->clk); + brcm_set_regulators(pcie, false); return ret; } @@ -1151,6 +1210,7 @@ static int brcm_pcie_resume(struct device *dev) int ret; base = pcie->base; + brcm_set_regulators(pcie, true); clk_prepare_enable(pcie->clk); ret = brcm_phy_start(pcie); @@ -1189,6 +1249,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) @@ -1238,6 +1299,10 @@ static int brcm_pcie_probe(struct platform_device *pdev) pcie->perst_set = data->perst_set; pcie->bridge_sw_init_set = data->bridge_sw_init_set; + ret = brcm_parse_regulators(pcie); + if (ret) + return ret; + pcie->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pcie->base)) return PTR_ERR(pcie->base); @@ -1273,6 +1338,7 @@ static int brcm_pcie_probe(struct platform_device *pdev) return ret; } + brcm_set_regulators(pcie, true); ret = brcm_pcie_setup(pcie); if (ret) goto fail;