Add wakeup host op to dw_pcie_ep_ops to wake up host from D3cold or D3hot. Signed-off-by: Krishna chaitanya chundru <quic_krichai@xxxxxxxxxxx> --- drivers/pci/controller/dwc/pcie-qcom-ep.c | 34 +++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index 5d146ec..916a138 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -91,6 +91,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 */ @@ -794,10 +795,43 @@ 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) +{ + 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 perst, dstate, val; + + perst = gpiod_get_value(pcie_ep->reset); + /* Toggle wake GPIO when device is in D3 cold */ + if (perst) { + dev_info(dev, "Device is in D3 cold 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; + } + + dstate = dw_pcie_readl_dbi(pci, DBI_CON_STATUS) & + DBI_CON_STATUS_POWER_STATE_MASK; + if (dstate == 3) { + dev_info(dev, "Device is in D3 hot sending inband 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 -EPERM; + } + + 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