linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 0/5] PCI: EPC: Add support to wake up host from D3 states
@ 2024-07-10 11:16 Krishna chaitanya chundru
  2024-07-10 11:16 ` [PATCH v6 1/5] PCI: endpoint: Add wakeup host API to EPC core Krishna chaitanya chundru
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Krishna chaitanya chundru @ 2024-07-10 11:16 UTC (permalink / raw)
  To: Manivannan Sadhasivam, Krzysztof Wilczyński,
	Kishon Vijay Abraham I, Bjorn Helgaas, Jonathan Corbet,
	Jingoo Han, Lorenzo Pieralisi, Rob Herring
  Cc: linux-pci, linux-doc, linux-kernel, linux-arm-msm, mhi,
	quic_vbadigan, quic_ramkri, quic_nitegupt, quic_skananth,
	quic_parass, Krishna chaitanya chundru

Here we propose this patch series to add support in PCI endpoint
driver to wake up host from D3 states.

As endpoint cannot send any data/MSI when the D-state is in
D3Cold or D3hot. Endpoint needs to bring the device back to D0
to send any kind of data.

For this endpoint needs to send inband PME the device is in D3hot
state or toggle wake when the device is D3 cold and vaux is not supplied.

Based on the D-state the EPF driver decides to wake host either by
toggling wake or by sending PME.

When the MHI state is in M3 MHI driver will wakeup the host using the
wakeup op.

This change is dependent on this series PCI: endpoint: add D-state change notifier
support
https://lore.kernel.org/all/20240710-dstate_notifier-v7-0-8d45d87b2b24@quicinc.com/T/#t

Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com>
---
Changes from v5:
	- rebased on linux next.
	- Link to v5: https://lore.kernel.org/linux-pci/1690952359-8625-4-git-send-email-quic_krichai@quicinc.com/T/#
Changes from v4:
	- removed the enum to select to send PME or toggle wake and use bool variable in 
	  the api itself as suggested by mani.
Changes from v3:
	- changed the bool return type to int for waking the host in mhi ep driver
	 as suggested by dan and bjorn.
	- Changed commit logs as suggested by bjorn.
Changes from v2:
        - Addressed review comments made by mani.
Changes from v1:
        - Moved from RFC patch to regular patch
        - Inclueded EPF patch and added a new op patch to notify D-state change.

---
Krishna chaitanya chundru (5):
      PCI: endpoint: Add wakeup host API to EPC core
      PCI: dwc: Add wakeup host op to pci_epc_ops
      PCI: qcom-ep: Add wake up host op to dw_pcie_ep_ops
      PCI: epf-mhi: Add wakeup host op
      bus: mhi: ep: wake up host if the MHI state is in M3

 Documentation/PCI/endpoint/pci-endpoint.rst     |  6 +++++
 drivers/bus/mhi/ep/main.c                       | 28 +++++++++++++++++++++++
 drivers/pci/controller/dwc/pcie-designware-ep.c | 12 ++++++++++
 drivers/pci/controller/dwc/pcie-designware.h    |  1 +
 drivers/pci/controller/dwc/pcie-qcom-ep.c       | 25 +++++++++++++++++++++
 drivers/pci/endpoint/functions/pci-epf-mhi.c    | 11 +++++++++
 drivers/pci/endpoint/pci-epc-core.c             | 30 +++++++++++++++++++++++++
 include/linux/mhi_ep.h                          |  1 +
 include/linux/pci-epc.h                         |  5 +++++
 9 files changed, 119 insertions(+)
---
base-commit: 4e0938fbb7efe1df1e57c0450a840d9605734c27
change-id: 20240710-wakeup_host-2b95824c0bcf

Best regards,
-- 
Krishna chaitanya chundru <quic_krichai@quicinc.com>


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v6 1/5] PCI: endpoint: Add wakeup host API to EPC core
  2024-07-10 11:16 [PATCH v6 0/5] PCI: EPC: Add support to wake up host from D3 states Krishna chaitanya chundru
@ 2024-07-10 11:16 ` Krishna chaitanya chundru
  2024-07-10 12:17   ` Bjorn Helgaas
  2024-07-10 11:16 ` [PATCH v6 2/5] PCI: dwc: Add wakeup host op to pci_epc_ops Krishna chaitanya chundru
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Krishna chaitanya chundru @ 2024-07-10 11:16 UTC (permalink / raw)
  To: Manivannan Sadhasivam, Krzysztof Wilczyński,
	Kishon Vijay Abraham I, Bjorn Helgaas, Jonathan Corbet,
	Jingoo Han, Lorenzo Pieralisi, Rob Herring
  Cc: linux-pci, linux-doc, linux-kernel, linux-arm-msm, mhi,
	quic_vbadigan, quic_ramkri, quic_nitegupt, quic_skananth,
	quic_parass, Krishna chaitanya chundru

Endpoint cannot send any data/MSI when the D-state is in
D3cold or D3hot. Endpoint needs to wake up the host to
bring the D-state to D0.

Endpoint can toggle wake signal when the D-state is in D3cold and vaux is
not supplied or can send inband PME.

To support this add wakeup_host() callback to the EPC core.

Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com>
---
 Documentation/PCI/endpoint/pci-endpoint.rst |  6 ++++++
 drivers/pci/endpoint/pci-epc-core.c         | 30 +++++++++++++++++++++++++++++
 include/linux/pci-epc.h                     |  5 +++++
 3 files changed, 41 insertions(+)

diff --git a/Documentation/PCI/endpoint/pci-endpoint.rst b/Documentation/PCI/endpoint/pci-endpoint.rst
index 3eb5648ca7ec..3744bc692b4b 100644
--- a/Documentation/PCI/endpoint/pci-endpoint.rst
+++ b/Documentation/PCI/endpoint/pci-endpoint.rst
@@ -53,6 +53,7 @@ by the PCI controller driver.
 	 * raise_irq: ops to raise a legacy, MSI or MSI-X interrupt
 	 * start: ops to start the PCI link
 	 * stop: ops to stop the PCI link
+	 * wakeup_host: ops to wakeup host
 
    The PCI controller driver can then create a new EPC device by invoking
    devm_pci_epc_create()/pci_epc_create().
@@ -120,6 +121,11 @@ by the PCI endpoint function driver.
    The PCI endpoint function driver should use pci_epc_mem_free_addr() to
    free the memory space allocated using pci_epc_mem_alloc_addr().
 
+* pci_epc_wakeup_host()
+
+   The PCI endpoint function driver should use pci_epc_wakeup_host() to wakeup
+   host.
+
 Other EPC APIs
 ~~~~~~~~~~~~~~
 
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index e2b9c458f2c4..7edc75de2ff3 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -162,6 +162,36 @@ const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
 }
 EXPORT_SYMBOL_GPL(pci_epc_get_features);
 
+/**
+ * pci_epc_wakeup_host() - Wakeup the host
+ * @epc: the EPC device which has to wakeup the host
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
+ * @send_pme: true if wakeup is by sending PME
+ *
+ * Invoke to wakeup host
+ */
+bool pci_epc_wakeup_host(struct pci_epc *epc, u8 func_no, u8 vfunc_no, bool send_pme)
+{
+	int ret;
+
+	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
+		return false;
+
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return false;
+
+	if (!epc->ops->wakeup_host)
+		return true;
+
+	mutex_lock(&epc->lock);
+	ret = epc->ops->wakeup_host(epc, func_no, vfunc_no, send_pme);
+	mutex_unlock(&epc->lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pci_epc_wakeup_host);
+
 /**
  * pci_epc_stop() - stop the PCI link
  * @epc: the link of the EPC device that has to be stopped
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index e473d1780928..fffde507da47 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -52,6 +52,7 @@ pci_epc_interface_string(enum pci_epc_interface_type type)
  * @start: ops to start the PCI link
  * @stop: ops to stop the PCI link
  * @get_features: ops to get the features supported by the EPC
+ * @wakeup_host: ops to wakeup the host
  * @owner: the module owner containing the ops
  */
 struct pci_epc_ops {
@@ -81,6 +82,8 @@ struct pci_epc_ops {
 	void	(*stop)(struct pci_epc *epc);
 	const struct pci_epc_features* (*get_features)(struct pci_epc *epc,
 						       u8 func_no, u8 vfunc_no);
+	bool	(*wakeup_host)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			       bool send_pme);
 	struct module *owner;
 };
 
@@ -258,6 +261,8 @@ int pci_epc_start(struct pci_epc *epc);
 void pci_epc_stop(struct pci_epc *epc);
 const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
 						    u8 func_no, u8 vfunc_no);
+bool pci_epc_wakeup_host(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			 bool send_pme);
 enum pci_barno
 pci_epc_get_first_free_bar(const struct pci_epc_features *epc_features);
 enum pci_barno pci_epc_get_next_free_bar(const struct pci_epc_features

-- 
2.42.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v6 2/5] PCI: dwc: Add wakeup host op to pci_epc_ops
  2024-07-10 11:16 [PATCH v6 0/5] PCI: EPC: Add support to wake up host from D3 states Krishna chaitanya chundru
  2024-07-10 11:16 ` [PATCH v6 1/5] PCI: endpoint: Add wakeup host API to EPC core Krishna chaitanya chundru
@ 2024-07-10 11:16 ` Krishna chaitanya chundru
  2024-07-10 11:16 ` [PATCH v6 3/5] PCI: qcom-ep: Add wake up host op to dw_pcie_ep_ops Krishna chaitanya chundru
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Krishna chaitanya chundru @ 2024-07-10 11:16 UTC (permalink / raw)
  To: Manivannan Sadhasivam, Krzysztof Wilczyński,
	Kishon Vijay Abraham I, Bjorn Helgaas, Jonathan Corbet,
	Jingoo Han, Lorenzo Pieralisi, Rob Herring
  Cc: linux-pci, linux-doc, linux-kernel, linux-arm-msm, mhi,
	quic_vbadigan, quic_ramkri, quic_nitegupt, quic_skananth,
	quic_parass, Krishna chaitanya chundru

Add wakeup host op to wake up host from D3cold or D3hot.

Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com>
---
 drivers/pci/controller/dwc/pcie-designware-ep.c | 12 ++++++++++++
 drivers/pci/controller/dwc/pcie-designware.h    |  1 +
 2 files changed, 13 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 43ba5c6738df..a20b6bec6078 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -440,6 +440,17 @@ dw_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 	return ep->ops->get_features(ep);
 }
 
+static bool dw_pcie_ep_wakeup_host(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+				   bool send_pme)
+{
+	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
+
+	if (!ep->ops->wakeup_host)
+		return false;
+
+	return ep->ops->wakeup_host(ep, func_no, send_pme);
+}
+
 static const struct pci_epc_ops epc_ops = {
 	.write_header		= dw_pcie_ep_write_header,
 	.set_bar		= dw_pcie_ep_set_bar,
@@ -454,6 +465,7 @@ static const struct pci_epc_ops epc_ops = {
 	.start			= dw_pcie_ep_start,
 	.stop			= dw_pcie_ep_stop,
 	.get_features		= dw_pcie_ep_get_features,
+	.wakeup_host		= dw_pcie_ep_wakeup_host,
 };
 
 /**
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 53c4c8f399c8..da15ccd7a3f5 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -365,6 +365,7 @@ struct dw_pcie_ep_ops {
 	 */
 	unsigned int (*get_dbi_offset)(struct dw_pcie_ep *ep, u8 func_no);
 	unsigned int (*get_dbi2_offset)(struct dw_pcie_ep *ep, u8 func_no);
+	bool	(*wakeup_host)(struct dw_pcie_ep *ep, u8 func_no, bool send_pme);
 };
 
 struct dw_pcie_ep_func {

-- 
2.42.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v6 3/5] PCI: qcom-ep: Add wake up host op to dw_pcie_ep_ops
  2024-07-10 11:16 [PATCH v6 0/5] PCI: EPC: Add support to wake up host from D3 states Krishna chaitanya chundru
  2024-07-10 11:16 ` [PATCH v6 1/5] PCI: endpoint: Add wakeup host API to EPC core Krishna chaitanya chundru
  2024-07-10 11:16 ` [PATCH v6 2/5] PCI: dwc: Add wakeup host op to pci_epc_ops Krishna chaitanya chundru
@ 2024-07-10 11:16 ` Krishna chaitanya chundru
  2024-07-11 17:04   ` Bjorn Helgaas
  2024-07-10 11:16 ` [PATCH v6 4/5] PCI: epf-mhi: Add wakeup host op Krishna chaitanya chundru
  2024-07-10 11:16 ` [PATCH v6 5/5] bus: mhi: ep: wake up host if the MHI state is in M3 Krishna chaitanya chundru
  4 siblings, 1 reply; 10+ messages in thread
From: Krishna chaitanya chundru @ 2024-07-10 11:16 UTC (permalink / raw)
  To: Manivannan Sadhasivam, Krzysztof Wilczyński,
	Kishon Vijay Abraham I, Bjorn Helgaas, Jonathan Corbet,
	Jingoo Han, Lorenzo Pieralisi, Rob Herring
  Cc: linux-pci, linux-doc, linux-kernel, linux-arm-msm, mhi,
	quic_vbadigan, quic_ramkri, quic_nitegupt, quic_skananth,
	quic_parass, Krishna chaitanya chundru

Add wakeup host op to dw_pcie_ep_ops to wake up host.
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@quicinc.com>
---
 drivers/pci/controller/dwc/pcie-qcom-ep.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index 627a33a1c5ca..d17e8542d07a 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -97,6 +97,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 */
@@ -817,10 +818,34 @@ static void qcom_pcie_ep_init(struct dw_pcie_ep *ep)
 		dw_pcie_ep_reset_bar(pci, bar);
 }
 
+static bool qcom_pcie_ep_wakeup_host(struct dw_pcie_ep *ep, u8 func_no, bool send_pme)
+{
+	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 (send_pme) {
+		dev_dbg(dev, "Waking up the host using PME\n");
+		val = readl_relaxed(pcie_ep->parf + PARF_PM_CTRL);
+		writel_relaxed(val | PARF_PM_CTRL_XMT_PME, pcie_ep->parf + PARF_PM_CTRL);
+		writel_relaxed(val, pcie_ep->parf + PARF_PM_CTRL);
+
+	} else {
+		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 true;
+}
+
 static const struct dw_pcie_ep_ops pci_ep_ops = {
 	.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.42.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v6 4/5] PCI: epf-mhi: Add wakeup host op
  2024-07-10 11:16 [PATCH v6 0/5] PCI: EPC: Add support to wake up host from D3 states Krishna chaitanya chundru
                   ` (2 preceding siblings ...)
  2024-07-10 11:16 ` [PATCH v6 3/5] PCI: qcom-ep: Add wake up host op to dw_pcie_ep_ops Krishna chaitanya chundru
@ 2024-07-10 11:16 ` Krishna chaitanya chundru
  2024-07-11 16:56   ` Bjorn Helgaas
  2024-07-10 11:16 ` [PATCH v6 5/5] bus: mhi: ep: wake up host if the MHI state is in M3 Krishna chaitanya chundru
  4 siblings, 1 reply; 10+ messages in thread
From: Krishna chaitanya chundru @ 2024-07-10 11:16 UTC (permalink / raw)
  To: Manivannan Sadhasivam, Krzysztof Wilczyński,
	Kishon Vijay Abraham I, Bjorn Helgaas, Jonathan Corbet,
	Jingoo Han, Lorenzo Pieralisi, Rob Herring
  Cc: linux-pci, linux-doc, linux-kernel, linux-arm-msm, mhi,
	quic_vbadigan, quic_ramkri, quic_nitegupt, quic_skananth,
	quic_parass, Krishna chaitanya chundru

Add wakeup host op for MHI EPF.
If the D-state is in D3cold toggle wake signal, otherwise send PME.

Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com>
---
 drivers/pci/endpoint/functions/pci-epf-mhi.c | 11 +++++++++++
 include/linux/mhi_ep.h                       |  1 +
 2 files changed, 12 insertions(+)

diff --git a/drivers/pci/endpoint/functions/pci-epf-mhi.c b/drivers/pci/endpoint/functions/pci-epf-mhi.c
index 6de9014e6e53..82fc52490324 100644
--- a/drivers/pci/endpoint/functions/pci-epf-mhi.c
+++ b/drivers/pci/endpoint/functions/pci-epf-mhi.c
@@ -708,6 +708,16 @@ static int pci_epf_mhi_dma_init(struct pci_epf_mhi *epf_mhi)
 	return ret;
 }
 
+static int pci_epf_mhi_wakeup_host(struct mhi_ep_cntrl *mhi_cntrl)
+{
+	struct pci_epf_mhi *epf_mhi = to_epf_mhi(mhi_cntrl);
+	struct pci_epf *epf = epf_mhi->epf;
+	struct pci_epc *epc = epf->epc;
+
+	return pci_epc_wakeup_host(epc, epf->func_no, epf->vfunc_no,
+			(mhi_cntrl->dstate == PCI_D3cold) ? false : true);
+}
+
 static void pci_epf_mhi_dma_deinit(struct pci_epf_mhi *epf_mhi)
 {
 	destroy_workqueue(epf_mhi->dma_wq);
@@ -803,6 +813,7 @@ static int pci_epf_mhi_link_up(struct pci_epf *epf)
 	mhi_cntrl->unmap_free = pci_epf_mhi_unmap_free;
 	mhi_cntrl->read_sync = mhi_cntrl->read_async = pci_epf_mhi_iatu_read;
 	mhi_cntrl->write_sync = mhi_cntrl->write_async = pci_epf_mhi_iatu_write;
+	mhi_cntrl->wakeup_host = pci_epf_mhi_wakeup_host;
 	if (info->flags & MHI_EPF_USE_DMA) {
 		mhi_cntrl->read_sync = pci_epf_mhi_edma_read;
 		mhi_cntrl->write_sync = pci_epf_mhi_edma_write;
diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h
index 7c9e5895ea2c..04646cf7782b 100644
--- a/include/linux/mhi_ep.h
+++ b/include/linux/mhi_ep.h
@@ -165,6 +165,7 @@ struct mhi_ep_cntrl {
 	int (*write_sync)(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_buf_info *buf_info);
 	int (*read_async)(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_buf_info *buf_info);
 	int (*write_async)(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_buf_info *buf_info);
+	int (*wakeup_host)(struct mhi_ep_cntrl *mhi_cntrl);
 
 	enum mhi_state mhi_state;
 

-- 
2.42.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v6 5/5] bus: mhi: ep: wake up host if the MHI state is in M3
  2024-07-10 11:16 [PATCH v6 0/5] PCI: EPC: Add support to wake up host from D3 states Krishna chaitanya chundru
                   ` (3 preceding siblings ...)
  2024-07-10 11:16 ` [PATCH v6 4/5] PCI: epf-mhi: Add wakeup host op Krishna chaitanya chundru
@ 2024-07-10 11:16 ` Krishna chaitanya chundru
  2024-07-11 16:47   ` Bjorn Helgaas
  4 siblings, 1 reply; 10+ messages in thread
From: Krishna chaitanya chundru @ 2024-07-10 11:16 UTC (permalink / raw)
  To: Manivannan Sadhasivam, Krzysztof Wilczyński,
	Kishon Vijay Abraham I, Bjorn Helgaas, Jonathan Corbet,
	Jingoo Han, Lorenzo Pieralisi, Rob Herring
  Cc: linux-pci, linux-doc, linux-kernel, linux-arm-msm, mhi,
	quic_vbadigan, quic_ramkri, quic_nitegupt, quic_skananth,
	quic_parass, Krishna chaitanya chundru

If the MHI state is in M3 then most probably the host kept the
device in D3 hot or D3 cold, due to that endpoint transactions will not
reach the host, endpoint needs to wakes up the host to bring the host
to D0 which eventually bring back the MHI state to M0.

while queueing packets if the MHI state is in M3 wakeup host to bring
back link to M0.

Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com>
---
 drivers/bus/mhi/ep/main.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c
index b3eafcf2a2c5..b8713e5c1e1a 100644
--- a/drivers/bus/mhi/ep/main.c
+++ b/drivers/bus/mhi/ep/main.c
@@ -25,6 +25,26 @@ static DEFINE_IDA(mhi_ep_cntrl_ida);
 static int mhi_ep_create_device(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id);
 static int mhi_ep_destroy_device(struct device *dev, void *data);
 
+static int mhi_ep_wake_host(struct mhi_ep_cntrl *mhi_cntrl)
+{
+	enum mhi_state state;
+	bool mhi_reset;
+	u32 count = 0;
+
+	mhi_cntrl->wakeup_host(mhi_cntrl);
+
+	/* Wait for Host to set the M0 state */
+	while (count++ < M0_WAIT_COUNT) {
+		msleep(M0_WAIT_DELAY_MS);
+
+		mhi_ep_mmio_get_mhi_state(mhi_cntrl, &state, &mhi_reset);
+		if (state == MHI_STATE_M0)
+			return 0;
+	}
+
+	return -ENODEV;
+}
+
 static int mhi_ep_send_event(struct mhi_ep_cntrl *mhi_cntrl, u32 ring_idx,
 			     struct mhi_ring_element *el, bool bei)
 {
@@ -564,6 +584,14 @@ int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb)
 
 	mutex_lock(&mhi_chan->lock);
 
+	if (mhi_cntrl->mhi_state == MHI_STATE_M3) {
+		ret = mhi_ep_wake_host(mhi_cntrl);
+		if (ret) {
+			dev_err(dev, "Failed to wakeup host\n");
+			goto err_exit;
+		}
+	}
+
 	do {
 		/* Don't process the transfer ring if the channel is not in RUNNING state */
 		if (mhi_chan->state != MHI_CH_STATE_RUNNING) {

-- 
2.42.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v6 1/5] PCI: endpoint: Add wakeup host API to EPC core
  2024-07-10 11:16 ` [PATCH v6 1/5] PCI: endpoint: Add wakeup host API to EPC core Krishna chaitanya chundru
@ 2024-07-10 12:17   ` Bjorn Helgaas
  0 siblings, 0 replies; 10+ messages in thread
From: Bjorn Helgaas @ 2024-07-10 12:17 UTC (permalink / raw)
  To: Krishna chaitanya chundru
  Cc: Manivannan Sadhasivam, Krzysztof Wilczyński,
	Kishon Vijay Abraham I, Bjorn Helgaas, Jonathan Corbet,
	Jingoo Han, Lorenzo Pieralisi, Rob Herring, linux-pci, linux-doc,
	linux-kernel, linux-arm-msm, mhi, quic_vbadigan, quic_ramkri,
	quic_nitegupt, quic_skananth, quic_parass

On Wed, Jul 10, 2024 at 04:46:08PM +0530, Krishna chaitanya chundru wrote:
> Endpoint cannot send any data/MSI when the D-state is in
> D3cold or D3hot. Endpoint needs to wake up the host to
> bring the D-state to D0.
> 
> Endpoint can toggle wake signal when the D-state is in D3cold and vaux is
> not supplied or can send inband PME.
> 
> To support this add wakeup_host() callback to the EPC core.

Wrap to fill 75 columns consistently.  Also applies to other patches
in series.  In some cases you may intend separate paragraphs; add
blank lines between in those cases.

s/D-state is in D3cold/D-state is D3cold/ (a couple times here, also
applies to other patches and MHI state)

s/vaux/Vaux/ to match spec usage.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v6 5/5] bus: mhi: ep: wake up host if the MHI state is in M3
  2024-07-10 11:16 ` [PATCH v6 5/5] bus: mhi: ep: wake up host if the MHI state is in M3 Krishna chaitanya chundru
@ 2024-07-11 16:47   ` Bjorn Helgaas
  0 siblings, 0 replies; 10+ messages in thread
From: Bjorn Helgaas @ 2024-07-11 16:47 UTC (permalink / raw)
  To: Krishna chaitanya chundru
  Cc: Manivannan Sadhasivam, Krzysztof Wilczyński,
	Kishon Vijay Abraham I, Bjorn Helgaas, Jonathan Corbet,
	Jingoo Han, Lorenzo Pieralisi, Rob Herring, linux-pci, linux-doc,
	linux-kernel, linux-arm-msm, mhi, quic_vbadigan, quic_ramkri,
	quic_nitegupt, quic_skananth, quic_parass

On Wed, Jul 10, 2024 at 04:46:12PM +0530, Krishna chaitanya chundru wrote:
> If the MHI state is in M3 then most probably the host kept the
> device in D3 hot or D3 cold, due to that endpoint transactions will not
> reach the host, endpoint needs to wakes up the host to bring the host
> to D0 which eventually bring back the MHI state to M0.

s/needs to wakes up/needs to wake up/

s/D3 hot/D3hot/
s/D3 cold/D3cold/
to match other uses and make grep more effective.

> while queueing packets if the MHI state is in M3 wakeup host to bring
> back link to M0.

s/while/While/
s/MHI state is in M3/MHI is in M3/ (twice)

> Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com>
> ---
>  drivers/bus/mhi/ep/main.c | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c
> index b3eafcf2a2c5..b8713e5c1e1a 100644
> --- a/drivers/bus/mhi/ep/main.c
> +++ b/drivers/bus/mhi/ep/main.c
> @@ -25,6 +25,26 @@ static DEFINE_IDA(mhi_ep_cntrl_ida);
>  static int mhi_ep_create_device(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id);
>  static int mhi_ep_destroy_device(struct device *dev, void *data);
>  
> +static int mhi_ep_wake_host(struct mhi_ep_cntrl *mhi_cntrl)
> +{
> +	enum mhi_state state;
> +	bool mhi_reset;
> +	u32 count = 0;
> +
> +	mhi_cntrl->wakeup_host(mhi_cntrl);
> +
> +	/* Wait for Host to set the M0 state */
> +	while (count++ < M0_WAIT_COUNT) {
> +		msleep(M0_WAIT_DELAY_MS);

Tangent: the "M0_WAIT_DELAY_MS" name suggests that is the maximum
delay, but it seems the actual maximum delay is
M0_WAIT_DELAY_MS * M0_WAIT_COUNT.

Tangent 2: unless there's a reason to be different, it would be nice
to use the same loop structure as the similar delay in mhi_ep_enable().

> +		mhi_ep_mmio_get_mhi_state(mhi_cntrl, &state, &mhi_reset);
> +		if (state == MHI_STATE_M0)
> +			return 0;
> +	}
> +
> +	return -ENODEV;
> +}

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v6 4/5] PCI: epf-mhi: Add wakeup host op
  2024-07-10 11:16 ` [PATCH v6 4/5] PCI: epf-mhi: Add wakeup host op Krishna chaitanya chundru
@ 2024-07-11 16:56   ` Bjorn Helgaas
  0 siblings, 0 replies; 10+ messages in thread
From: Bjorn Helgaas @ 2024-07-11 16:56 UTC (permalink / raw)
  To: Krishna chaitanya chundru
  Cc: Manivannan Sadhasivam, Krzysztof Wilczyński,
	Kishon Vijay Abraham I, Bjorn Helgaas, Jonathan Corbet,
	Jingoo Han, Lorenzo Pieralisi, Rob Herring, linux-pci, linux-doc,
	linux-kernel, linux-arm-msm, mhi, quic_vbadigan, quic_ramkri,
	quic_nitegupt, quic_skananth, quic_parass

On Wed, Jul 10, 2024 at 04:46:11PM +0530, Krishna chaitanya chundru wrote:
> Add wakeup host op for MHI EPF.
> If the D-state is in D3cold toggle wake signal, otherwise send PME.

Feels racy.  Maybe it doesn't matter?  I guess it's unavoidable that
we could be in D3hot, commit to sending PME, and then main power goes
away so we're now in D3cold and the PME is not delivered?  Is there a
way to recover from that?

s/D-state is in D3cold/D-state is D3cold/
s/toggle wake/assert WAKE#/

Rewrap into single paragraph or add blank line between.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v6 3/5] PCI: qcom-ep: Add wake up host op to dw_pcie_ep_ops
  2024-07-10 11:16 ` [PATCH v6 3/5] PCI: qcom-ep: Add wake up host op to dw_pcie_ep_ops Krishna chaitanya chundru
@ 2024-07-11 17:04   ` Bjorn Helgaas
  0 siblings, 0 replies; 10+ messages in thread
From: Bjorn Helgaas @ 2024-07-11 17:04 UTC (permalink / raw)
  To: Krishna chaitanya chundru
  Cc: Manivannan Sadhasivam, Krzysztof Wilczyński,
	Kishon Vijay Abraham I, Bjorn Helgaas, Jonathan Corbet,
	Jingoo Han, Lorenzo Pieralisi, Rob Herring, linux-pci, linux-doc,
	linux-kernel, linux-arm-msm, mhi, quic_vbadigan, quic_ramkri,
	quic_nitegupt, quic_skananth, quic_parass

On Wed, Jul 10, 2024 at 04:46:10PM +0530, Krishna chaitanya chundru wrote:
> Add wakeup host op to dw_pcie_ep_ops to wake up host.
> If the wakeup type is PME, then trigger inband PME by writing to the PARF
> PARF_PM_CTRL register, otherwise toggle #WAKE.

Wrap into single paragraph or add blank line between.

> Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com>
> ---
>  drivers/pci/controller/dwc/pcie-qcom-ep.c | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c
> index 627a33a1c5ca..d17e8542d07a 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
> @@ -97,6 +97,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 */
> @@ -817,10 +818,34 @@ static void qcom_pcie_ep_init(struct dw_pcie_ep *ep)
>  		dw_pcie_ep_reset_bar(pci, bar);
>  }
>  
> +static bool qcom_pcie_ep_wakeup_host(struct dw_pcie_ep *ep, u8 func_no, bool send_pme)
> +{
> +	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 (send_pme) {
> +		dev_dbg(dev, "Waking up the host using PME\n");
> +		val = readl_relaxed(pcie_ep->parf + PARF_PM_CTRL);
> +		writel_relaxed(val | PARF_PM_CTRL_XMT_PME, pcie_ep->parf + PARF_PM_CTRL);
> +		writel_relaxed(val, pcie_ep->parf + PARF_PM_CTRL);
> +
> +	} else {
> +		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);

PCIe r6.0, sec 5.3.3.2, says

  When WAKE# is used as a wakeup mechanism, once WAKE# has been
  asserted, the asserting Function must continue to drive the signal
  low until main power has been restored to the component as indicated
  by Fundamental Reset going inactive.

That doesn't seem compatible with a simple delay as you have here.

> +		gpiod_set_value_cansleep(pcie_ep->wake, 0);
> +	}
> +
> +	return true;
> +}
> +
>  static const struct dw_pcie_ep_ops pci_ep_ops = {
>  	.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.42.0
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2024-07-11 17:04 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-10 11:16 [PATCH v6 0/5] PCI: EPC: Add support to wake up host from D3 states Krishna chaitanya chundru
2024-07-10 11:16 ` [PATCH v6 1/5] PCI: endpoint: Add wakeup host API to EPC core Krishna chaitanya chundru
2024-07-10 12:17   ` Bjorn Helgaas
2024-07-10 11:16 ` [PATCH v6 2/5] PCI: dwc: Add wakeup host op to pci_epc_ops Krishna chaitanya chundru
2024-07-10 11:16 ` [PATCH v6 3/5] PCI: qcom-ep: Add wake up host op to dw_pcie_ep_ops Krishna chaitanya chundru
2024-07-11 17:04   ` Bjorn Helgaas
2024-07-10 11:16 ` [PATCH v6 4/5] PCI: epf-mhi: Add wakeup host op Krishna chaitanya chundru
2024-07-11 16:56   ` Bjorn Helgaas
2024-07-10 11:16 ` [PATCH v6 5/5] bus: mhi: ep: wake up host if the MHI state is in M3 Krishna chaitanya chundru
2024-07-11 16:47   ` Bjorn Helgaas

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).