From: Jim Quinlan <james.quinlan@broadcom.com>
To: james.quinlan@broadcom.com,
Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
Cc: Jim Quinlan <james.quinlan@broadcom.com>,
Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>,
Rob Herring <robh@kernel.org>,
Bjorn Helgaas <bhelgaas@google.com>,
Florian Fainelli <f.fainelli@gmail.com>,
bcm-kernel-feedback-list@broadcom.com (maintainer:BROADCOM
BCM7XXX ARM ARCHITECTURE), Philipp Zabel <p.zabel@pengutronix.de>,
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-pci@vger.kernel.org (open list:PCI NATIVE HOST BRIDGE AND
ENDPOINT DRIVERS), linux-kernel@vger.kernel.org (open list)
Subject: [PATCH 07/15] PCI: brcmstb: Add control of rescal reset
Date: Tue, 19 May 2020 16:34:05 -0400 [thread overview]
Message-ID: <20200519203419.12369-8-james.quinlan@broadcom.com> (raw)
In-Reply-To: <20200519203419.12369-1-james.quinlan@broadcom.com>
From: Jim Quinlan <jquinlan@broadcom.com>
Some STB chips have a special purpose reset controller named
RESCAL (reset calibration). This commit adds the control
of RESCAL as well as the ability to start and stop its
operation for PCIe HW.
Signed-off-by: Jim Quinlan <jquinlan@broadcom.com>
---
drivers/pci/controller/pcie-brcmstb.c | 81 ++++++++++++++++++++++++++-
1 file changed, 80 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 2c470104ba38..0787e8f6f7e5 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -23,6 +23,7 @@
#include <linux/of_platform.h>
#include <linux/pci.h>
#include <linux/printk.h>
+#include <linux/reset.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/string.h>
@@ -152,7 +153,17 @@
#define SSC_STATUS_SSC_MASK 0x400
#define SSC_STATUS_PLL_LOCK_MASK 0x800
-#define IDX_ADDR(pcie) \
+/* Rescal registers */
+#define PCIE_DVT_PMU_PCIE_PHY_CTRL 0xc700
+#define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS 0x3
+#define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_MASK 0x4
+#define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_SHIFT 0x2
+#define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_MASK 0x2
+#define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_SHIFT 0x1
+#define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_MASK 0x1
+#define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_SHIFT 0x0
+
+#define IDX_ADDR(pcie) \
(pcie->reg_offsets[EXT_CFG_INDEX])
#define DATA_ADDR(pcie) \
(pcie->reg_offsets[EXT_CFG_DATA])
@@ -242,6 +253,7 @@ struct brcm_pcie {
const int *reg_offsets;
const int *reg_field_info;
enum pcie_type type;
+ struct reset_control *rescal;
};
/*
@@ -957,6 +969,47 @@ 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 = !!start;
+ void __iomem *base = pcie->base;
+ int i;
+
+ for (i = beg; i != end; start ? i++ : i--) {
+ tmp = readl(base + PCIE_DVT_PMU_PCIE_PHY_CTRL);
+ tmp = (tmp & ~masks[i]) | ((val << shifts[i]) & 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;
+
+ return (tmp & combined_mask) == val ? 0 : -EIO;
+}
+
+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;
@@ -987,6 +1040,9 @@ static int brcm_pcie_suspend(struct device *dev)
int ret = 0;
brcm_pcie_turn_off(pcie);
+ ret = brcm_phy_stop(pcie);
+ if (ret)
+ dev_err(pcie->dev, "failed to stop phy\n");
clk_disable_unprepare(pcie->clk);
return ret;
@@ -1002,6 +1058,12 @@ static int brcm_pcie_resume(struct device *dev)
base = pcie->base;
clk_prepare_enable(pcie->clk);
+ ret = brcm_phy_start(pcie);
+ if (ret) {
+ dev_err(pcie->dev, "failed to start phy\n");
+ return ret;
+ }
+
/* Take bridge out of reset so we can access the SERDES reg */
brcm_pcie_bridge_sw_init_set(pcie, 0);
@@ -1028,6 +1090,8 @@ static void __brcm_pcie_remove(struct brcm_pcie *pcie)
{
brcm_msi_remove(pcie);
brcm_pcie_turn_off(pcie);
+ if (brcm_phy_stop(pcie))
+ dev_err(pcie->dev, "failed to stop phy\n");
clk_disable_unprepare(pcie->clk);
}
@@ -1100,6 +1164,21 @@ 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_shared(&pdev->dev, "rescal");
+ if (IS_ERR(pcie->rescal)) {
+ if (PTR_ERR(pcie->rescal) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ pcie->rescal = NULL;
+ } else {
+ ret = reset_control_deassert(pcie->rescal);
+ if (ret)
+ dev_err(&pdev->dev, "failed to deassert 'rescal'\n");
+ }
+ ret = brcm_phy_start(pcie);
+ if (ret) {
+ dev_err(pcie->dev, "failed to start phy\n");
+ return ret;
+ }
ret = brcm_pcie_setup(pcie);
if (ret)
--
2.17.1
next prev parent reply other threads:[~2020-05-19 20:35 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-19 20:33 [PATCH 00/15] PCI: brcmstb: enable PCIe for STB chips Jim Quinlan
2020-05-19 20:33 ` [PATCH 01/15] PCI: brcmstb: PCIE_BRCMSTB depends on ARCH_BRCMSTB Jim Quinlan
2020-05-19 20:48 ` Florian Fainelli
2020-05-19 20:34 ` [PATCH 02/15] ahci_brcm: fix use of BCM7216 reset controller Jim Quinlan
2020-05-20 7:14 ` Philipp Zabel
2020-05-19 20:34 ` [PATCH 03/15] dt-bindings: PCI: Add bindings for more Brcmstb chips Jim Quinlan
2020-05-19 20:34 ` [PATCH 04/15] PCI: brcmstb: Add compatibily of other chips Jim Quinlan
2020-05-20 11:51 ` Nicolas Saenz Julienne
2020-05-20 14:30 ` Jim Quinlan
2020-05-20 14:41 ` Nicolas Saenz Julienne
2020-05-21 19:35 ` Jim Quinlan
2020-05-22 9:17 ` Nicolas Saenz Julienne
2020-05-19 20:34 ` [PATCH 05/15] PCI: brcmstb: Add suspend and resume pm_ops Jim Quinlan
2020-05-19 20:34 ` [PATCH 06/15] PCI: brcmstb: Asserting PERST is different for 7278 Jim Quinlan
2020-05-19 20:34 ` Jim Quinlan [this message]
2020-05-20 7:27 ` [PATCH 07/15] PCI: brcmstb: Add control of rescal reset Philipp Zabel
2020-05-21 21:48 ` Jim Quinlan
2020-05-25 16:58 ` Florian Fainelli
2020-05-19 20:34 ` [PATCH 08/15] of: Include a dev param in of_dma_get_range() Jim Quinlan
2020-05-19 20:34 ` [PATCH 09/15] device core: Add ability to handle multiple dma offsets Jim Quinlan
2020-05-20 5:43 ` Greg Kroah-Hartman
2020-05-20 13:50 ` Jim Quinlan
2020-05-20 14:03 ` Greg Kroah-Hartman
2020-05-20 11:28 ` Nicolas Saenz Julienne
2020-05-22 14:31 ` Jim Quinlan
2020-05-20 17:42 ` Christoph Hellwig
2020-05-20 18:26 ` Jim Quinlan
2020-05-20 22:36 ` Dan Williams
2020-05-21 8:19 ` Christoph Hellwig
2020-05-19 20:34 ` [PATCH 10/15] dma-direct: Invoke dma offset func if needed Jim Quinlan
2020-05-19 20:34 ` [PATCH 11/15] arm: dma-mapping: " Jim Quinlan
2020-05-19 20:34 ` [PATCH 12/15] PCI: brcmstb: Set internal memory viewport sizes Jim Quinlan
2020-05-19 20:34 ` [PATCH 13/15] PCI: brcmstb: Accommodate MSI for older chips Jim Quinlan
2020-05-19 20:34 ` [PATCH 14/15] PCI: brcmstb: Set bus max burst side by chip type Jim Quinlan
2020-05-20 13:44 ` Nicolas Saenz Julienne
2020-05-20 14:27 ` Jim Quinlan
2020-05-19 20:34 ` [PATCH 15/15] PCI: brcmstb: add compatilbe chips to match list Jim Quinlan
2020-05-20 16:15 ` [PATCH 00/15] PCI: brcmstb: enable PCIe for STB chips Bjorn Helgaas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200519203419.12369-8-james.quinlan@broadcom.com \
--to=james.quinlan@broadcom.com \
--cc=bcm-kernel-feedback-list@broadcom.com \
--cc=bhelgaas@google.com \
--cc=f.fainelli@gmail.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux-rpi-kernel@lists.infradead.org \
--cc=lorenzo.pieralisi@arm.com \
--cc=nsaenzjulienne@suse.de \
--cc=p.zabel@pengutronix.de \
--cc=robh@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox