From patchwork Fri Sep 11 17:52:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Quinlan X-Patchwork-Id: 11771283 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9714E59D for ; Fri, 11 Sep 2020 17:54:02 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 410D921D79 for ; Fri, 11 Sep 2020 17:54:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="FxJSdf8T"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="aQf6Egpf" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 410D921D79 Authentication-Results: mail.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=broadcom.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Type:MIME-Version: Cc:List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: References:In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=VzwZPJL3Wti9dSR8eWhRFAn00ZqBhZFgWZ3UfTXYP6U=; b=FxJSdf8TwncKSc7I5AigL6KdY N6RJnhbDgWQvHvmBKY2UScA4kTpUviWY4X0oKp2RgRRNm8sz4OptEbxG+Kvxj5DT3skv4WXksf/o9 Fs10sIm3fO3+GQb3QnWCWfwJ3DpM/FTzywsxq3K5nhtBQASWU0UdJr2zyY3dt1Xypqz+XOY6Ma/6j 7UErnDuTQQXYAZ738sjWHMRe4sCVRGIqh7lPaIytpGXutnGIL5tB91XwSc2Vwqq03CLR0aLsO5eqV xSDjs15VHQJQeDpBAy58frA5UlGWPMXpyEQrCP2ScFu5YJ9CLWin9R1XCbE2iVlXn6My59ZYGzohn i8RXJTbfw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kGnF4-0006al-9L; Fri, 11 Sep 2020 17:53:46 +0000 Received: from mail-pf1-x441.google.com ([2607:f8b0:4864:20::441]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kGnEH-0006Io-7i for linux-arm-kernel@lists.infradead.org; Fri, 11 Sep 2020 17:53:04 +0000 Received: by mail-pf1-x441.google.com with SMTP id o68so8073950pfg.2 for ; Fri, 11 Sep 2020 10:52:56 -0700 (PDT) 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=ygLiMDSXPgfTFvAw8rdehyTc8vg+K493tqn7kdt64AI=; b=aQf6Egpff/TeUf2SdCK/irEJ9cbYb+Z43bytRBwk7aDoh89k8eiHoH9ceXSDYpAXEH eHWDaDKT86/C59pzyV9X0pj6an6jJOACJtxk7ueb4KbMsZaqy87AeCuSqZ+z8ngRAyGM 4UVFTaafQPzpFh8y80WHJsucbbR8TXuqEs4lo= 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=ygLiMDSXPgfTFvAw8rdehyTc8vg+K493tqn7kdt64AI=; b=Y79MfA9bW3r3HfJarz3e6Sz3A4i9JSNQpjSa0CKXa0UqBnkAHQQPfPn3D1AwVHyTnY DDqmCwn4on6U/YfDyNMp5a2od/iyzyrPZtE6/KceCEwEhVkbXLTYkQOrNTVNHkuX8fNh LsSVFgM19siQshq1/OoIanAfvipkscjQ+Jsrfr6TRyRv8ebXonEaXsBwmJHzmUyfN5dM h0UAaaKOHWSwPwNaZzuns1YCSHtByiAl9V0xctAOznS2H5yRB2HxM1/A1mYEj5zGKWDx cjd4RGPpSXjn4x47JtTtFQ0MMdsWZkJm8Qcq4DNSpA8iat94l6rAMOjCATSimi6wJqJG P8Vw== X-Gm-Message-State: AOAM532vA8ZubLWynLcUu3BJwRw98UhrY/Tr/oL0jtcATIM5CFDFYT/x 9StHPca7nXR9T0DmjGxlggpsxA== X-Google-Smtp-Source: ABdhPJyhHECOF37B8cPeYszTu5V+UPeSgvuEGA8zmfHmlsioKPQtn0u3iL4UjDI7gz/BLeJyuRNeyA== X-Received: by 2002:a63:f752:: with SMTP id f18mr2345011pgk.94.1599846774810; Fri, 11 Sep 2020 10:52:54 -0700 (PDT) Received: from stbsrv-and-01.and.broadcom.net ([192.19.231.250]) by smtp.gmail.com with ESMTPSA id d77sm2871963pfd.121.2020.09.11.10.52.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Sep 2020 10:52:53 -0700 (PDT) From: Jim Quinlan To: linux-pci@vger.kernel.org, Nicolas Saenz Julienne , Christoph Hellwig , Robin Murphy , bcm-kernel-feedback-list@broadcom.com, james.quinlan@broadcom.com Subject: [PATCH v12 06/10] PCI: brcmstb: Add control of rescal reset Date: Fri, 11 Sep 2020 13:52:26 -0400 Message-Id: <20200911175232.19016-7-james.quinlan@broadcom.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200911175232.19016-1-james.quinlan@broadcom.com> References: <20200911175232.19016-1-james.quinlan@broadcom.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200911_135257_314450_7B199F6E X-CRM114-Status: GOOD ( 17.62 ) X-Spam-Score: -0.1 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.1 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:441 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 T_TVD_MIME_NO_HEADERS BODY: No description available. -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 MIME_HEADER_CTYPE_ONLY 'Content-Type' found without required MIME headers -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Rob Herring , Lorenzo Pieralisi , open list , Florian Fainelli , "moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE" , Philipp Zabel , Bjorn Helgaas , Jim Quinlan , "moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE" MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Jim Quinlan Some STB chips have a special purpose reset controller named RESCAL (reset calibration). The PCIe HW can now control RESCAL to start and stop its operation. On probe(), the RESCAL is deasserted and the driver goes through the sequence of setting registers and reading status in order to start the internal PHY that is required for the PCIe. Signed-off-by: Jim Quinlan Acked-by: Florian Fainelli Reviewed-by: Rob Herring --- drivers/pci/controller/pcie-brcmstb.c | 69 ++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c index 947cf3115eb0..8a84811972bd 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 @@ -994,6 +995,52 @@ static void brcm_pcie_enter_l23(struct brcm_pcie *pcie) dev_err(pcie->dev, "failed to enter low-power link state\n"); } +static int brcm_phy_cntl(struct brcm_pcie *pcie, const int start) +{ + static const u32 shifts[PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS] = { + PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_SHIFT, + PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_SHIFT, + PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_SHIFT,}; + static const u32 masks[PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS] = { + PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_MASK, + PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_MASK, + PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_MASK,}; + const int beg = start ? 0 : PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS - 1; + const int end = start ? PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS : -1; + u32 tmp, combined_mask = 0; + u32 val; + void __iomem *base = pcie->base; + int i, ret; + + for (i = beg; i != end; start ? i++ : i--) { + val = start ? BIT_MASK(shifts[i]) : 0; + tmp = readl(base + PCIE_DVT_PMU_PCIE_PHY_CTRL); + tmp = (tmp & ~masks[i]) | (val & masks[i]); + writel(tmp, base + PCIE_DVT_PMU_PCIE_PHY_CTRL); + usleep_range(50, 200); + combined_mask |= masks[i]; + } + + tmp = readl(base + PCIE_DVT_PMU_PCIE_PHY_CTRL); + val = start ? combined_mask : 0; + + ret = (tmp & combined_mask) == val ? 0 : -EIO; + if (ret) + dev_err(pcie->dev, "failed to %s phy\n", (start ? "start" : "stop")); + + return ret; +} + +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) +{ + return pcie->rescal ? brcm_phy_cntl(pcie, 0) : 0; +} + static void brcm_pcie_turn_off(struct brcm_pcie *pcie) { void __iomem *base = pcie->base; @@ -1021,11 +1068,13 @@ static void brcm_pcie_turn_off(struct brcm_pcie *pcie) 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); clk_disable_unprepare(pcie->clk); - return 0; + return ret; } static int brcm_pcie_resume(struct device *dev) @@ -1038,6 +1087,9 @@ static int brcm_pcie_resume(struct device *dev) base = pcie->base; clk_prepare_enable(pcie->clk); + ret = brcm_phy_start(pcie); + return ret; + /* Take bridge out of reset so we can access the SERDES reg */ pcie->bridge_sw_init_set(pcie, 0); @@ -1063,6 +1115,8 @@ static void __brcm_pcie_remove(struct brcm_pcie *pcie) { brcm_msi_remove(pcie); brcm_pcie_turn_off(pcie); + brcm_phy_stop(pcie); + reset_control_assert(pcie->rescal); clk_disable_unprepare(pcie->clk); } @@ -1142,6 +1196,19 @@ static int brcm_pcie_probe(struct platform_device *pdev) dev_err(&pdev->dev, "could not enable clock\n"); return ret; } + pcie->rescal = devm_reset_control_get_optional_shared(&pdev->dev, "rescal"); + if (IS_ERR(pcie->rescal)) + return PTR_ERR(pcie->rescal); + + ret = reset_control_deassert(pcie->rescal); + if (ret) + dev_err(&pdev->dev, "failed to deassert 'rescal'\n"); + + ret = brcm_phy_start(pcie); + if (ret) { + reset_control_assert(pcie->rescal); + return ret; + } ret = brcm_pcie_setup(pcie); if (ret)