Re: [PATCH v2 6/8] PCI: qcom: ep: Add wake up host op to dw_pcie_ep_ops

From: Krishna Chaitanya Chundru
Date: Fri Jul 07 2023 - 06:59:19 EST



On 7/7/2023 11:40 AM, Manivannan Sadhasivam wrote:
On Fri, Jun 30, 2023 at 04:22:09PM +0530, Krishna chaitanya chundru wrote:

Subject prefix should be "PCI: qcom-ep:"

Add wakeup host op to dw_pcie_ep_ops to wake up host.
If the EPF asks to send PME trigger the inband PME by writing
into the parf registers otherwise toggle wake signal.

If the wakeup type is PME, then trigger inband PME by writing to the PARF
PARF_PM_CTRL register, otherwise toggle #WAKE.

Signed-off-by: Krishna chaitanya chundru <quic_krichai@xxxxxxxxxxx>
---
drivers/pci/controller/dwc/pcie-qcom-ep.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index e75aec4..e382b4b 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -89,6 +89,7 @@
/* PARF_PM_CTRL register fields */
#define PARF_PM_CTRL_REQ_EXIT_L1 BIT(1)
#define PARF_PM_CTRL_READY_ENTR_L23 BIT(2)
+#define PARF_PM_CTRL_XMT_PME BIT(4)
#define PARF_PM_CTRL_REQ_NOT_ENTR_L1 BIT(5)
/* PARF_MHI_CLOCK_RESET_CTRL fields */
@@ -729,10 +730,40 @@ static void qcom_pcie_ep_init(struct dw_pcie_ep *ep)
dw_pcie_ep_reset_bar(pci, bar);
}
+static int qcom_pcie_ep_wakeup_host(struct dw_pcie_ep *ep, u8 func_no,
+ enum pci_epc_wakeup_host_type type)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+ struct qcom_pcie_ep *pcie_ep = to_pcie_ep(pci);
+ struct device *dev = pci->dev;
+ u32 val;
+
+ if (type == PCI_WAKEUP_TOGGLE_WAKE) {
+ dev_dbg(dev, "Waking up the host by toggling WAKE#\n");
+ gpiod_set_value_cansleep(pcie_ep->wake, 1);
+ usleep_range(WAKE_DELAY_US, WAKE_DELAY_US + 500);
+ gpiod_set_value_cansleep(pcie_ep->wake, 0);
+ return 0;
+
+ } else if (type == PCI_WAKEUP_SEND_PME) {
+ dev_dbg(dev, "Waking up the host using PME\n");
+ val = readl_relaxed(pcie_ep->parf + PARF_PM_CTRL);
+ val |= PARF_PM_CTRL_XMT_PME;
+ writel_relaxed(val, pcie_ep->parf + PARF_PM_CTRL);
+
+ } else {
+ dev_err(dev, "Device is not in D3 state wakeup is not supported\n");
+ return -EOPNOTSUPP;
This is not needed if you use bool. And this debug message is wrong btw since
you are not checking whether the device is in D3 state or not.

- Mani

I will change it bool and will remove these.

- KC


+ }
+
+ return 0;
+}
+
static const struct dw_pcie_ep_ops pci_ep_ops = {
.ep_init = qcom_pcie_ep_init,
.raise_irq = qcom_pcie_ep_raise_irq,
.get_features = qcom_pcie_epc_get_features,
+ .wakeup_host = qcom_pcie_ep_wakeup_host,
};
static int qcom_pcie_ep_probe(struct platform_device *pdev)
--
2.7.4