From: Krishna chaitanya chundru <quic_krichai@quicinc.com>
To: "Bartosz Golaszewski" <brgl@bgdev.pl>,
"Manivannan Sadhasivam" <manivannan.sadhasivam@linaro.org>,
"Lorenzo Pieralisi" <lpieralisi@kernel.org>,
"Krzysztof Wilczyński" <kw@linux.com>,
"Rob Herring" <robh@kernel.org>,
"Bjorn Helgaas" <bhelgaas@google.com>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
"Bjorn Andersson" <andersson@kernel.org>,
"Konrad Dybcio" <konrad.dybcio@linaro.org>,
"Jingoo Han" <jingoohan1@gmail.com>
Cc: <quic_vbadigan@quicinc.com>, <quic_skananth@quicinc.com>,
<quic_nitegupt@quicinc.com>, <linux-arm-msm@vger.kernel.org>,
<linux-pci@vger.kernel.org>, <devicetree@vger.kernel.org>,
<linux-kernel@vger.kernel.org>,
Krishna chaitanya chundru <quic_krichai@quicinc.com>
Subject: [PATCH RFC 6/7] pci: qcom: Add support for start_link() & stop_link()
Date: Wed, 26 Jun 2024 18:07:54 +0530 [thread overview]
Message-ID: <20240626-qps615-v1-6-2ade7bd91e02@quicinc.com> (raw)
In-Reply-To: <20240626-qps615-v1-0-2ade7bd91e02@quicinc.com>
In the stop_link() if the PCIe link is not up, disable LTSSM enable
bit to stop link training otherwise keep the link in D3cold.
And in the start_link() the enable LTSSM bit if the resources are
turned on other wise do the all the initialization and then start
the link.
Introduce ltssm_disable function op to stop the link training.
Use a flag 'pci_pwrctl_turned_off" to indicate the resources are
turned off by the pci pwrctl framework.
If the link is stopped using the stop_link() then just return with
doing anything in suspend and resume.
Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com>
---
drivers/pci/controller/dwc/pcie-qcom.c | 108 +++++++++++++++++++++++++++++----
1 file changed, 97 insertions(+), 11 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index 14772edcf0d3..1ab3ffdb3914 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -37,6 +37,7 @@
/* PARF registers */
#define PARF_SYS_CTRL 0x00
#define PARF_PM_CTRL 0x20
+#define PARF_PM_STTS 0x24
#define PARF_PCS_DEEMPH 0x34
#define PARF_PCS_SWING 0x38
#define PARF_PHY_CTRL 0x40
@@ -83,6 +84,9 @@
/* PARF_PM_CTRL register fields */
#define REQ_NOT_ENTR_L1 BIT(5)
+/* PARF_PM_STTS register fields */
+#define PM_ENTER_L23 BIT(5)
+
/* PARF_PCS_DEEMPH register fields */
#define PCS_DEEMPH_TX_DEEMPH_GEN1(x) FIELD_PREP(GENMASK(21, 16), x)
#define PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(x) FIELD_PREP(GENMASK(13, 8), x)
@@ -126,6 +130,7 @@
/* ELBI_SYS_CTRL register fields */
#define ELBI_SYS_CTRL_LT_ENABLE BIT(0)
+#define ELBI_SYS_CTRL_PME_TURNOFF_MSG BIT(4)
/* AXI_MSTR_RESP_COMP_CTRL0 register fields */
#define CFG_REMOTE_RD_REQ_BRIDGE_SIZE_2K 0x4
@@ -228,6 +233,7 @@ struct qcom_pcie_ops {
void (*host_post_init)(struct qcom_pcie *pcie);
void (*deinit)(struct qcom_pcie *pcie);
void (*ltssm_enable)(struct qcom_pcie *pcie);
+ void (*ltssm_disable)(struct qcom_pcie *pcie);
int (*config_sid)(struct qcom_pcie *pcie);
};
@@ -248,10 +254,13 @@ struct qcom_pcie {
const struct qcom_pcie_cfg *cfg;
struct dentry *debugfs;
bool suspended;
+ bool pci_pwrctl_turned_off;
};
#define to_qcom_pcie(x) dev_get_drvdata((x)->dev)
+static void qcom_pcie_icc_update(struct qcom_pcie *pcie);
+
static void qcom_ep_reset_assert(struct qcom_pcie *pcie)
{
gpiod_set_value_cansleep(pcie->reset, 1);
@@ -266,17 +275,6 @@ static void qcom_ep_reset_deassert(struct qcom_pcie *pcie)
usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500);
}
-static int qcom_pcie_start_link(struct dw_pcie *pci)
-{
- struct qcom_pcie *pcie = to_qcom_pcie(pci);
-
- /* Enable Link Training state machine */
- if (pcie->cfg->ops->ltssm_enable)
- pcie->cfg->ops->ltssm_enable(pcie);
-
- return 0;
-}
-
static void qcom_pcie_clear_aspm_l0s(struct dw_pcie *pci)
{
struct qcom_pcie *pcie = to_qcom_pcie(pci);
@@ -556,6 +554,15 @@ static int qcom_pcie_post_init_1_0_0(struct qcom_pcie *pcie)
return 0;
}
+static void qcom_pcie_2_3_2_ltssm_disable(struct qcom_pcie *pcie)
+{
+ u32 val;
+
+ val = readl(pcie->parf + PARF_LTSSM);
+ val &= ~LTSSM_EN;
+ writel(val, pcie->parf + PARF_LTSSM);
+}
+
static void qcom_pcie_2_3_2_ltssm_enable(struct qcom_pcie *pcie)
{
u32 val;
@@ -1336,6 +1343,7 @@ static const struct qcom_pcie_ops ops_2_7_0 = {
.post_init = qcom_pcie_post_init_2_7_0,
.deinit = qcom_pcie_deinit_2_7_0,
.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
+ .ltssm_disable = qcom_pcie_2_3_2_ltssm_disable,
};
/* Qcom IP rev.: 1.9.0 */
@@ -1346,6 +1354,7 @@ static const struct qcom_pcie_ops ops_1_9_0 = {
.host_post_init = qcom_pcie_host_post_init_2_7_0,
.deinit = qcom_pcie_deinit_2_7_0,
.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
+ .ltssm_disable = qcom_pcie_2_3_2_ltssm_disable,
.config_sid = qcom_pcie_config_sid_1_9_0,
};
@@ -1395,9 +1404,81 @@ static const struct qcom_pcie_cfg cfg_sc8280xp = {
.no_l0s = true,
};
+static int qcom_pcie_turnoff_link(struct dw_pcie *pci)
+{
+ struct qcom_pcie *pcie = to_qcom_pcie(pci);
+ u32 ret_l23, val, ret;
+
+ if (!dw_pcie_link_up(pcie->pci)) {
+ if (pcie->cfg->ops->ltssm_disable)
+ pcie->cfg->ops->ltssm_disable(pcie);
+ } else {
+ writel(ELBI_SYS_CTRL_PME_TURNOFF_MSG, pcie->elbi + ELBI_SYS_CTRL);
+
+ ret_l23 = readl_poll_timeout(pcie->parf + PARF_PM_STTS, val,
+ val & PM_ENTER_L23, 10000, 100000);
+ if (ret_l23) {
+ dev_err(pci->dev, "Failed to enter L2/L3\n");
+ return -ETIMEDOUT;
+ }
+
+ qcom_pcie_host_deinit(&pcie->pci->pp);
+
+ ret = icc_disable(pcie->icc_mem);
+ if (ret)
+ dev_err(pci->dev, "Failed to disable PCIe-MEM interconnect path: %d\n",
+ ret);
+
+ pcie->pci_pwrctl_turned_off = true;
+ }
+
+ return 0;
+}
+
+static int qcom_pcie_turnon_link(struct dw_pcie *pci)
+{
+ struct qcom_pcie *pcie = to_qcom_pcie(pci);
+
+ if (pcie->pci_pwrctl_turned_off) {
+ qcom_pcie_host_init(&pcie->pci->pp);
+
+ dw_pcie_setup_rc(&pcie->pci->pp);
+ }
+
+ if (pcie->cfg->ops->ltssm_enable)
+ pcie->cfg->ops->ltssm_enable(pcie);
+
+ /* Ignore the retval, the devices may come up later. */
+ dw_pcie_wait_for_link(pcie->pci);
+
+ qcom_pcie_icc_update(pcie);
+
+ pcie->pci_pwrctl_turned_off = false;
+
+ return 0;
+}
+
+static int qcom_pcie_start_link(struct dw_pcie *pci)
+{
+ return qcom_pcie_turnon_link(pci);
+}
+
+static void qcom_pcie_stop_link(struct dw_pcie *pci)
+{
+ struct qcom_pcie *pcie = to_qcom_pcie(pci);
+
+ if (!dw_pcie_link_up(pcie->pci)) {
+ if (pcie->cfg->ops->ltssm_disable)
+ pcie->cfg->ops->ltssm_disable(pcie);
+ } else {
+ qcom_pcie_turnoff_link(pci);
+ }
+}
+
static const struct dw_pcie_ops dw_pcie_ops = {
.link_up = qcom_pcie_link_up,
.start_link = qcom_pcie_start_link,
+ .stop_link = qcom_pcie_stop_link,
};
static int qcom_pcie_icc_init(struct qcom_pcie *pcie)
@@ -1604,6 +1685,8 @@ static int qcom_pcie_suspend_noirq(struct device *dev)
struct qcom_pcie *pcie = dev_get_drvdata(dev);
int ret;
+ if (pcie->pci_pwrctl_turned_off)
+ return 0;
/*
* Set minimum bandwidth required to keep data path functional during
* suspend.
@@ -1642,6 +1725,9 @@ static int qcom_pcie_resume_noirq(struct device *dev)
struct qcom_pcie *pcie = dev_get_drvdata(dev);
int ret;
+ if (pcie->pci_pwrctl_turned_off)
+ return 0;
+
if (pcie->suspended) {
ret = qcom_pcie_host_init(&pcie->pci->pp);
if (ret)
--
2.42.0
next prev parent reply other threads:[~2024-06-26 12:38 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-26 12:37 [PATCH RFC 0/7] PCI: enable Power and configure the QPS615 PCIe switch Krishna chaitanya chundru
2024-06-26 12:37 ` [PATCH RFC 1/7] dt: bindings: add qcom,qps615.yaml Krishna chaitanya chundru
2024-06-26 13:34 ` Rob Herring (Arm)
2024-06-26 15:01 ` Bjorn Andersson
2024-06-27 15:31 ` Rob Herring
2024-07-01 13:26 ` Krzysztof Kozlowski
2024-06-26 12:37 ` [PATCH RFC 2/7] arm64: dts: qcom: qcs6490-rb3gen2: Add qps615 node Krishna chaitanya chundru
2024-06-26 17:11 ` Bjorn Andersson
2024-06-26 17:51 ` Dmitry Baryshkov
2024-06-26 12:37 ` [PATCH RFC 3/7] pci: Change the parent of the platform devices for child OF nodes Krishna chaitanya chundru
2024-06-26 15:12 ` Bartosz Golaszewski
2024-07-01 17:54 ` Bjorn Helgaas
2024-06-26 12:37 ` [PATCH RFC 4/7] pci: Add new start_link() & stop_link function ops Krishna chaitanya chundru
2024-06-26 15:07 ` Bartosz Golaszewski
2024-06-26 12:37 ` [PATCH RFC 5/7] pci: dwc: Add support for new pci function op Krishna chaitanya chundru
2024-06-26 12:37 ` Krishna chaitanya chundru [this message]
2024-06-26 14:31 ` [PATCH RFC 6/7] pci: qcom: Add support for start_link() & stop_link() Bjorn Andersson
2024-07-01 20:14 ` Bjorn Helgaas
2024-06-26 12:37 ` [PATCH RFC 7/7] pci: pwrctl: Add power control driver for qps615 Krishna chaitanya chundru
2024-06-26 15:25 ` Bartosz Golaszewski
2024-06-26 15:37 ` Konrad Dybcio
2024-08-03 3:18 ` Krishna Chaitanya Chundru
2024-06-26 17:00 ` Bjorn Andersson
2024-06-26 18:09 ` Dmitry Baryshkov
2024-07-01 19:54 ` Bjorn Helgaas
2024-06-26 13:31 ` [PATCH RFC 0/7] PCI: enable Power and configure the QPS615 PCIe switch Rob Herring (Arm)
2024-06-26 15:29 ` Bjorn Helgaas
2024-07-01 17:51 ` 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=20240626-qps615-v1-6-2ade7bd91e02@quicinc.com \
--to=quic_krichai@quicinc.com \
--cc=andersson@kernel.org \
--cc=bhelgaas@google.com \
--cc=brgl@bgdev.pl \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=jingoohan1@gmail.com \
--cc=konrad.dybcio@linaro.org \
--cc=krzk+dt@kernel.org \
--cc=kw@linux.com \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lpieralisi@kernel.org \
--cc=manivannan.sadhasivam@linaro.org \
--cc=quic_nitegupt@quicinc.com \
--cc=quic_skananth@quicinc.com \
--cc=quic_vbadigan@quicinc.com \
--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;
as well as URLs for NNTP newsgroup(s).