From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 83E4AECDE5F for ; Mon, 23 Jul 2018 09:38:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 31CF720846 for ; Mon, 23 Jul 2018 09:38:18 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 31CF720846 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388204AbeGWKie (ORCPT ); Mon, 23 Jul 2018 06:38:34 -0400 Received: from metis.ext.pengutronix.de ([85.220.165.71]:59953 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388043AbeGWKie (ORCPT ); Mon, 23 Jul 2018 06:38:34 -0400 Received: from kresse.hi.pengutronix.de ([2001:67c:670:100:1d::2a]) by metis.ext.pengutronix.de with esmtp (Exim 4.89) (envelope-from ) id 1fhXI7-0002F7-Bt; Mon, 23 Jul 2018 11:38:07 +0200 Message-ID: <1532338685.3163.93.camel@pengutronix.de> Subject: Re: [PATCH v2 3/3] PCI: imx: Initial imx7d pm support From: Lucas Stach To: Leonard Crestez , Richard Zhu , Andrey Smirnov Cc: Shawn Guo , Joao Pinto , Jingoo Han , Bjorn Helgaas , Lorenzo Pieralisi , linux-pci@vger.kernel.org, linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Fabio Estevam , Dong Aisheng , kernel@pengutronix.de, linux-imx@nxp.com Date: Mon, 23 Jul 2018 11:38:05 +0200 In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.22.6-1+deb9u1 Mime-Version: 1.0 Content-Transfer-Encoding: 8bit X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::2a X-SA-Exim-Mail-From: l.stach@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Leonard, Am Freitag, den 20.07.2018, 15:47 +0300 schrieb Leonard Crestez: > On imx7d the pcie-phy power domain is turned off in suspend and this can > make the system hang after resume when attempting any read from PCI. > > Fix this by adding minimal suspend/resume code from the nxp internal > tree. This will prepare for powering down on suspend and reset the block > on resume. > > Code is only for imx7d but a very similar sequence can be used for > other socs. > > > The original author is mostly Richard Zhu , this > patch adjusts the code to the upstream imx7d implemention using reset > controls and power domains. > > > Signed-off-by: Leonard Crestez > --- >  drivers/pci/controller/dwc/pci-imx6.c | 95 +++++++++++++++++++++++++-- >  1 file changed, 90 insertions(+), 5 deletions(-) > > diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c > index 80f604602783..daebee905108 100644 > --- a/drivers/pci/controller/dwc/pci-imx6.c > +++ b/drivers/pci/controller/dwc/pci-imx6.c > @@ -540,10 +540,27 @@ static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie) >   > >   dev_err(dev, "Speed change timeout\n"); > >   return -EINVAL; >  } >   > +static void imx6_pcie_ltssm_enable(struct device *dev) > +{ > > + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); > + > > + switch (imx6_pcie->variant) { > > + case IMX6Q: > > + case IMX6SX: > > + case IMX6QP: > > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, > > +    IMX6Q_GPR12_PCIE_CTL_2, > > +    IMX6Q_GPR12_PCIE_CTL_2); > > + break; > > + case IMX7D: > > + reset_control_deassert(imx6_pcie->apps_reset); > > + } > +} > + >  static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie) >  { > >   struct dw_pcie *pci = imx6_pcie->pci; > >   struct device *dev = pci->dev; > >   u32 tmp; > @@ -558,15 +575,11 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie) > >   tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK; > >   tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1; > >   dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp); >   > >   /* Start LTSSM. */ > > - if (imx6_pcie->variant == IMX7D) > > - reset_control_deassert(imx6_pcie->apps_reset); > > - else > > - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, > > -    IMX6Q_GPR12_PCIE_CTL_2, 1 << 10); > > + imx6_pcie_ltssm_enable(dev); >   > >   ret = imx6_pcie_wait_for_link(imx6_pcie); > >   if (ret) > >   goto err_reset_phy; >   > @@ -681,10 +694,81 @@ static int imx6_add_pcie_port(struct imx6_pcie *imx6_pcie, >   >  static const struct dw_pcie_ops dw_pcie_ops = { > >   .link_up = imx6_pcie_link_up, >  }; >   > +#ifdef CONFIG_PM_SLEEP > +static void imx6_pcie_ltssm_disable(struct device *dev) > +{ > > + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); > + > > + switch (imx6_pcie->variant) { > > + case IMX6Q: > > + case IMX6SX: > > + case IMX6QP: > > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, > +    IMX6Q_GPR12_PCIE_CTL_2, 0); Has this been tested on i.MX6? LTSSM disable requires a more complex sequence on this SoC to avoid hanging the system. See commit 3e3e406e3807 "PCI: imx6: Put LTSSM in "Detect" state before disabling it". Note that implementing the correct sequence requires the core clocks to still be on when disabling LTSSM, so would need to switch ordering of the function calls in imx6_pcie_suspend_noirq. > + break; > > + case IMX7D: > > + reset_control_assert(imx6_pcie->apps_reset); > > + break; > > + } > +} > + > +static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie) > +{ > > + clk_disable_unprepare(imx6_pcie->pcie); > > + clk_disable_unprepare(imx6_pcie->pcie_phy); > > + clk_disable_unprepare(imx6_pcie->pcie_bus); > + > > + if (imx6_pcie->variant == IMX7D) { > > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, > > +    IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, > > +    IMX7D_GPR12_PCIE_PHY_REFCLK_SEL); > > + } > +} > + > +static int imx6_pcie_suspend_noirq(struct device *dev) > +{ > > + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); > + > > + if (imx6_pcie->variant != IMX7D) > > + return 0; > + > > + imx6_pcie_clk_disable(imx6_pcie); > > + imx6_pcie_ltssm_disable(dev); > + > > + return 0; > +} > + > +static int imx6_pcie_resume_noirq(struct device *dev) > +{ > > + int ret = 0; > > + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); > > + struct pcie_port *pp = &imx6_pcie->pci->pp; > + > > + if (imx6_pcie->variant != IMX7D) > > + return 0; > + > > + imx6_pcie_assert_core_reset(imx6_pcie); > > + imx6_pcie_init_phy(imx6_pcie); > > + imx6_pcie_deassert_core_reset(imx6_pcie); > > + dw_pcie_setup_rc(pp); > + > > + ret = imx6_pcie_establish_link(imx6_pcie); > > + if (ret < 0) > + pr_err("pcie link is down after resume.\n"); dev_err(), please. Regards, Lucas > + > > + return 0; > +} > +#endif > + > +static const struct dev_pm_ops imx6_pcie_pm_ops = { > > + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx6_pcie_suspend_noirq, > > +       imx6_pcie_resume_noirq) > +}; > + >  static int imx6_pcie_probe(struct platform_device *pdev) >  { > >   struct device *dev = &pdev->dev; > >   struct dw_pcie *pci; > >   struct imx6_pcie *imx6_pcie; > @@ -847,10 +931,11 @@ static const struct of_device_id imx6_pcie_of_match[] = { >  static struct platform_driver imx6_pcie_driver = { > >   .driver = { > > >   .name = "imx6q-pcie", > >   .of_match_table = imx6_pcie_of_match, > >   .suppress_bind_attrs = true, > > + .pm = &imx6_pcie_pm_ops, > >   }, > >   .probe    = imx6_pcie_probe, > >   .shutdown = imx6_pcie_shutdown, >  }; >   From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Return-Path: Message-ID: <1532338685.3163.93.camel@pengutronix.de> Subject: Re: [PATCH v2 3/3] PCI: imx: Initial imx7d pm support From: Lucas Stach To: Leonard Crestez , Richard Zhu , Andrey Smirnov Date: Mon, 23 Jul 2018 11:38:05 +0200 In-Reply-To: References: Mime-Version: 1.0 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Dong Aisheng , Joao Pinto , linux-pm@vger.kernel.org, Jingoo Han , linux-kernel@vger.kernel.org, Fabio Estevam , Lorenzo Pieralisi , linux-imx@nxp.com, kernel@pengutronix.de, linux-pci@vger.kernel.org, Bjorn Helgaas , Shawn Guo , linux-arm-kernel@lists.infradead.org Content-Type: text/plain; charset="utf-8" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+bjorn=helgaas.com@lists.infradead.org List-ID: SGkgTGVvbmFyZCwKCkFtIEZyZWl0YWcsIGRlbiAyMC4wNy4yMDE4LCAxNTo0NyArMDMwMCBzY2hy aWViIExlb25hcmQgQ3Jlc3RlejoKPiBPbiBpbXg3ZCB0aGUgcGNpZS1waHkgcG93ZXIgZG9tYWlu IGlzIHR1cm5lZCBvZmYgaW4gc3VzcGVuZCBhbmQgdGhpcyBjYW4KPiBtYWtlIHRoZSBzeXN0ZW0g aGFuZyBhZnRlciByZXN1bWUgd2hlbiBhdHRlbXB0aW5nIGFueSByZWFkIGZyb20gUENJLgo+IAo+ IEZpeCB0aGlzIGJ5IGFkZGluZyBtaW5pbWFsIHN1c3BlbmQvcmVzdW1lIGNvZGUgZnJvbSB0aGUg bnhwIGludGVybmFsCj4gdHJlZS4gVGhpcyB3aWxsIHByZXBhcmUgZm9yIHBvd2VyaW5nIGRvd24g b24gc3VzcGVuZCBhbmQgcmVzZXQgdGhlIGJsb2NrCj4gb24gcmVzdW1lLgo+IAo+IENvZGUgaXMg b25seSBmb3IgaW14N2QgYnV0IGEgdmVyeSBzaW1pbGFyIHNlcXVlbmNlIGNhbiBiZSB1c2VkIGZv cgo+IG90aGVyIHNvY3MuCj4gCj4gPiBUaGUgb3JpZ2luYWwgYXV0aG9yIGlzIG1vc3RseSBSaWNo YXJkIFpodSA8aG9uZ3hpbmcuemh1QG54cC5jb20+LCB0aGlzCj4gcGF0Y2ggYWRqdXN0cyB0aGUg Y29kZSB0byB0aGUgdXBzdHJlYW0gaW14N2QgaW1wbGVtZW50aW9uIHVzaW5nIHJlc2V0Cj4gY29u dHJvbHMgYW5kIHBvd2VyIGRvbWFpbnMuCj4gCj4gPiBTaWduZWQtb2ZmLWJ5OiBMZW9uYXJkIENy ZXN0ZXogPGxlb25hcmQuY3Jlc3RlekBueHAuY29tPgo+IC0tLQo+IMKgZHJpdmVycy9wY2kvY29u dHJvbGxlci9kd2MvcGNpLWlteDYuYyB8IDk1ICsrKysrKysrKysrKysrKysrKysrKysrKystLQo+ IMKgMSBmaWxlIGNoYW5nZWQsIDkwIGluc2VydGlvbnMoKyksIDUgZGVsZXRpb25zKC0pCj4gCj4g ZGlmZiAtLWdpdCBhL2RyaXZlcnMvcGNpL2NvbnRyb2xsZXIvZHdjL3BjaS1pbXg2LmMgYi9kcml2 ZXJzL3BjaS9jb250cm9sbGVyL2R3Yy9wY2ktaW14Ni5jCj4gaW5kZXggODBmNjA0NjAyNzgzLi5k YWViZWU5MDUxMDggMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9wY2kvY29udHJvbGxlci9kd2MvcGNp LWlteDYuYwo+ICsrKyBiL2RyaXZlcnMvcGNpL2NvbnRyb2xsZXIvZHdjL3BjaS1pbXg2LmMKPiBA QCAtNTQwLDEwICs1NDAsMjcgQEAgc3RhdGljIGludCBpbXg2X3BjaWVfd2FpdF9mb3Jfc3BlZWRf Y2hhbmdlKHN0cnVjdCBpbXg2X3BjaWUgKmlteDZfcGNpZSkKPiDCoAo+ID4gwqAJZGV2X2Vycihk ZXYsICJTcGVlZCBjaGFuZ2UgdGltZW91dFxuIik7Cj4gPiDCoAlyZXR1cm4gLUVJTlZBTDsKPiDC oH0KPiDCoAo+ICtzdGF0aWMgdm9pZCBpbXg2X3BjaWVfbHRzc21fZW5hYmxlKHN0cnVjdCBkZXZp Y2UgKmRldikKPiArewo+ID4gKwlzdHJ1Y3QgaW14Nl9wY2llICppbXg2X3BjaWUgPSBkZXZfZ2V0 X2RydmRhdGEoZGV2KTsKPiArCj4gPiArCXN3aXRjaCAoaW14Nl9wY2llLT52YXJpYW50KSB7Cj4g PiArCWNhc2UgSU1YNlE6Cj4gPiArCWNhc2UgSU1YNlNYOgo+ID4gKwljYXNlIElNWDZRUDoKPiA+ ICsJCXJlZ21hcF91cGRhdGVfYml0cyhpbXg2X3BjaWUtPmlvbXV4Y19ncHIsIElPTVVYQ19HUFIx MiwKPiA+ICsJCQkJwqDCoMKgSU1YNlFfR1BSMTJfUENJRV9DVExfMiwKPiA+ICsJCQkJwqDCoMKg SU1YNlFfR1BSMTJfUENJRV9DVExfMik7Cj4gPiArCQlicmVhazsKPiA+ICsJY2FzZSBJTVg3RDoK PiA+ICsJCXJlc2V0X2NvbnRyb2xfZGVhc3NlcnQoaW14Nl9wY2llLT5hcHBzX3Jlc2V0KTsKPiA+ ICsJfQo+ICt9Cj4gKwo+IMKgc3RhdGljIGludCBpbXg2X3BjaWVfZXN0YWJsaXNoX2xpbmsoc3Ry dWN0IGlteDZfcGNpZSAqaW14Nl9wY2llKQo+IMKgewo+ID4gwqAJc3RydWN0IGR3X3BjaWUgKnBj aSA9IGlteDZfcGNpZS0+cGNpOwo+ID4gwqAJc3RydWN0IGRldmljZSAqZGV2ID0gcGNpLT5kZXY7 Cj4gPiDCoAl1MzIgdG1wOwo+IEBAIC01NTgsMTUgKzU3NSwxMSBAQCBzdGF0aWMgaW50IGlteDZf cGNpZV9lc3RhYmxpc2hfbGluayhzdHJ1Y3QgaW14Nl9wY2llICppbXg2X3BjaWUpCj4gPiDCoAl0 bXAgJj0gflBDSUVfUkNfTENSX01BWF9MSU5LX1NQRUVEU19NQVNLOwo+ID4gwqAJdG1wIHw9IFBD SUVfUkNfTENSX01BWF9MSU5LX1NQRUVEU19HRU4xOwo+ID4gwqAJZHdfcGNpZV93cml0ZWxfZGJp KHBjaSwgUENJRV9SQ19MQ1IsIHRtcCk7Cj4gwqAKPiA+IMKgCS8qIFN0YXJ0IExUU1NNLiAqLwo+ ID4gLQlpZiAoaW14Nl9wY2llLT52YXJpYW50ID09IElNWDdEKQo+ID4gLQkJcmVzZXRfY29udHJv bF9kZWFzc2VydChpbXg2X3BjaWUtPmFwcHNfcmVzZXQpOwo+ID4gLQllbHNlCj4gPiAtCQlyZWdt YXBfdXBkYXRlX2JpdHMoaW14Nl9wY2llLT5pb211eGNfZ3ByLCBJT01VWENfR1BSMTIsCj4gPiAt CQkJCcKgwqDCoElNWDZRX0dQUjEyX1BDSUVfQ1RMXzIsIDEgPDwgMTApOwo+ID4gKwlpbXg2X3Bj aWVfbHRzc21fZW5hYmxlKGRldik7Cj4gwqAKPiA+IMKgCXJldCA9IGlteDZfcGNpZV93YWl0X2Zv cl9saW5rKGlteDZfcGNpZSk7Cj4gPiDCoAlpZiAocmV0KQo+ID4gwqAJCWdvdG8gZXJyX3Jlc2V0 X3BoeTsKPiDCoAo+IEBAIC02ODEsMTAgKzY5NCw4MSBAQCBzdGF0aWMgaW50IGlteDZfYWRkX3Bj aWVfcG9ydChzdHJ1Y3QgaW14Nl9wY2llICppbXg2X3BjaWUsCj4gwqAKPiDCoHN0YXRpYyBjb25z dCBzdHJ1Y3QgZHdfcGNpZV9vcHMgZHdfcGNpZV9vcHMgPSB7Cj4gPiDCoAkubGlua191cCA9IGlt eDZfcGNpZV9saW5rX3VwLAo+IMKgfTsKPiDCoAo+ICsjaWZkZWYgQ09ORklHX1BNX1NMRUVQCj4g K3N0YXRpYyB2b2lkIGlteDZfcGNpZV9sdHNzbV9kaXNhYmxlKHN0cnVjdCBkZXZpY2UgKmRldikK PiArewo+ID4gKwlzdHJ1Y3QgaW14Nl9wY2llICppbXg2X3BjaWUgPSBkZXZfZ2V0X2RydmRhdGEo ZGV2KTsKPiArCj4gPiArCXN3aXRjaCAoaW14Nl9wY2llLT52YXJpYW50KSB7Cj4gPiArCWNhc2Ug SU1YNlE6Cj4gPiArCWNhc2UgSU1YNlNYOgo+ID4gKwljYXNlIElNWDZRUDoKPiA+ICsJCXJlZ21h cF91cGRhdGVfYml0cyhpbXg2X3BjaWUtPmlvbXV4Y19ncHIsIElPTVVYQ19HUFIxMiwKPiArCQkJ CcKgwqDCoElNWDZRX0dQUjEyX1BDSUVfQ1RMXzIsIDApOwoKSGFzIHRoaXMgYmVlbiB0ZXN0ZWQg b24gaS5NWDY/IExUU1NNIGRpc2FibGUgcmVxdWlyZXMgYSBtb3JlIGNvbXBsZXgKc2VxdWVuY2Ug b24gdGhpcyBTb0MgdG8gYXZvaWQgaGFuZ2luZyB0aGUgc3lzdGVtLiBTZWUgY29tbWl0CjNlM2U0 MDZlMzgwNyAiUENJOiBpbXg2OiBQdXQgTFRTU00gaW4gIkRldGVjdCIgc3RhdGUgYmVmb3JlIGRp c2FibGluZwppdCIuCgpOb3RlIHRoYXQgaW1wbGVtZW50aW5nIHRoZSBjb3JyZWN0IHNlcXVlbmNl IHJlcXVpcmVzIHRoZSBjb3JlIGNsb2NrcyB0bwogIHN0aWxsIGJlIG9uIHdoZW4gZGlzYWJsaW5n IExUU1NNLCBzbyB3b3VsZCBuZWVkIHRvIHN3aXRjaCBvcmRlcmluZyBvZgp0aGUgZnVuY3Rpb24g Y2FsbHMgaW7CoGlteDZfcGNpZV9zdXNwZW5kX25vaXJxLgoKPiArCQlicmVhazsKPiA+ICsJY2Fz ZSBJTVg3RDoKPiA+ICsJCXJlc2V0X2NvbnRyb2xfYXNzZXJ0KGlteDZfcGNpZS0+YXBwc19yZXNl dCk7Cj4gPiArCQlicmVhazsKPiA+ICsJfQo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBpbXg2X3Bj aWVfY2xrX2Rpc2FibGUoc3RydWN0IGlteDZfcGNpZSAqaW14Nl9wY2llKQo+ICt7Cj4gPiArCWNs a19kaXNhYmxlX3VucHJlcGFyZShpbXg2X3BjaWUtPnBjaWUpOwo+ID4gKwljbGtfZGlzYWJsZV91 bnByZXBhcmUoaW14Nl9wY2llLT5wY2llX3BoeSk7Cj4gPiArCWNsa19kaXNhYmxlX3VucHJlcGFy ZShpbXg2X3BjaWUtPnBjaWVfYnVzKTsKPiArCj4gPiArCWlmIChpbXg2X3BjaWUtPnZhcmlhbnQg PT0gSU1YN0QpIHsKPiA+ICsJCXJlZ21hcF91cGRhdGVfYml0cyhpbXg2X3BjaWUtPmlvbXV4Y19n cHIsIElPTVVYQ19HUFIxMiwKPiA+ICsJCQkJwqDCoMKgSU1YN0RfR1BSMTJfUENJRV9QSFlfUkVG Q0xLX1NFTCwKPiA+ICsJCQkJwqDCoMKgSU1YN0RfR1BSMTJfUENJRV9QSFlfUkVGQ0xLX1NFTCk7 Cj4gPiArCX0KPiArfQo+ICsKPiArc3RhdGljIGludCBpbXg2X3BjaWVfc3VzcGVuZF9ub2lycShz dHJ1Y3QgZGV2aWNlICpkZXYpCj4gK3sKPiA+ICsJc3RydWN0IGlteDZfcGNpZSAqaW14Nl9wY2ll ID0gZGV2X2dldF9kcnZkYXRhKGRldik7Cj4gKwo+ID4gKwlpZiAoaW14Nl9wY2llLT52YXJpYW50 ICE9IElNWDdEKQo+ID4gKwkJcmV0dXJuIDA7Cj4gKwo+ID4gKwlpbXg2X3BjaWVfY2xrX2Rpc2Fi bGUoaW14Nl9wY2llKTsKPiA+ICsJaW14Nl9wY2llX2x0c3NtX2Rpc2FibGUoZGV2KTsKPiArCj4g PiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGlteDZfcGNpZV9yZXN1bWVfbm9p cnEoc3RydWN0IGRldmljZSAqZGV2KQo+ICt7Cj4gPiArCWludCByZXQgPSAwOwo+ID4gKwlzdHJ1 Y3QgaW14Nl9wY2llICppbXg2X3BjaWUgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKPiA+ICsJc3Ry dWN0IHBjaWVfcG9ydCAqcHAgPSAmaW14Nl9wY2llLT5wY2ktPnBwOwo+ICsKPiA+ICsJaWYgKGlt eDZfcGNpZS0+dmFyaWFudCAhPSBJTVg3RCkKPiA+ICsJCXJldHVybiAwOwo+ICsKPiA+ICsJaW14 Nl9wY2llX2Fzc2VydF9jb3JlX3Jlc2V0KGlteDZfcGNpZSk7Cj4gPiArCWlteDZfcGNpZV9pbml0 X3BoeShpbXg2X3BjaWUpOwo+ID4gKwlpbXg2X3BjaWVfZGVhc3NlcnRfY29yZV9yZXNldChpbXg2 X3BjaWUpOwo+ID4gKwlkd19wY2llX3NldHVwX3JjKHBwKTsKPiArCj4gPiArCXJldCA9IGlteDZf cGNpZV9lc3RhYmxpc2hfbGluayhpbXg2X3BjaWUpOwo+ID4gKwlpZiAocmV0IDwgMCkKPiArCQlw cl9lcnIoInBjaWUgbGluayBpcyBkb3duIGFmdGVyIHJlc3VtZS5cbiIpOwoKZGV2X2VycigpLCBw bGVhc2UuCgpSZWdhcmRzLApMdWNhcwoKPiArCj4gPiArCXJldHVybiAwOwo+ICt9Cj4gKyNlbmRp Zgo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBkZXZfcG1fb3BzIGlteDZfcGNpZV9wbV9vcHMg PSB7Cj4gPiArCVNFVF9OT0lSUV9TWVNURU1fU0xFRVBfUE1fT1BTKGlteDZfcGNpZV9zdXNwZW5k X25vaXJxLAo+ID4gKwkJCQnCoMKgwqDCoMKgwqBpbXg2X3BjaWVfcmVzdW1lX25vaXJxKQo+ICt9 Owo+ICsKPiDCoHN0YXRpYyBpbnQgaW14Nl9wY2llX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZp Y2UgKnBkZXYpCj4gwqB7Cj4gPiDCoAlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmcGRldi0+ZGV2Owo+ ID4gwqAJc3RydWN0IGR3X3BjaWUgKnBjaTsKPiA+IMKgCXN0cnVjdCBpbXg2X3BjaWUgKmlteDZf cGNpZTsKPiBAQCAtODQ3LDEwICs5MzEsMTEgQEAgc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZp Y2VfaWQgaW14Nl9wY2llX29mX21hdGNoW10gPSB7Cj4gwqBzdGF0aWMgc3RydWN0IHBsYXRmb3Jt X2RyaXZlciBpbXg2X3BjaWVfZHJpdmVyID0gewo+ID4gwqAJLmRyaXZlciA9IHsKPiA+ID4gwqAJ CS5uYW1lCT0gImlteDZxLXBjaWUiLAo+ID4gwqAJCS5vZl9tYXRjaF90YWJsZSA9IGlteDZfcGNp ZV9vZl9tYXRjaCwKPiA+IMKgCQkuc3VwcHJlc3NfYmluZF9hdHRycyA9IHRydWUsCj4gPiArCQku cG0gPSAmaW14Nl9wY2llX3BtX29wcywKPiA+IMKgCX0sCj4gPiDCoAkucHJvYmXCoMKgwqDCoD0g aW14Nl9wY2llX3Byb2JlLAo+ID4gwqAJLnNodXRkb3duID0gaW14Nl9wY2llX3NodXRkb3duLAo+ IMKgfTsKPiDCoAoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X18KbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QKbGludXgtYXJtLWtlcm5lbEBsaXN0cy5p bmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8v bGludXgtYXJtLWtlcm5lbAo= From mboxrd@z Thu Jan 1 00:00:00 1970 From: l.stach@pengutronix.de (Lucas Stach) Date: Mon, 23 Jul 2018 11:38:05 +0200 Subject: [PATCH v2 3/3] PCI: imx: Initial imx7d pm support In-Reply-To: References: Message-ID: <1532338685.3163.93.camel@pengutronix.de> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Hi Leonard, Am Freitag, den 20.07.2018, 15:47 +0300 schrieb Leonard Crestez: > On imx7d the pcie-phy power domain is turned off in suspend and this can > make the system hang after resume when attempting any read from PCI. > > Fix this by adding minimal suspend/resume code from the nxp internal > tree. This will prepare for powering down on suspend and reset the block > on resume. > > Code is only for imx7d but a very similar sequence can be used for > other socs. > > > The original author is mostly Richard Zhu , this > patch adjusts the code to the upstream imx7d implemention using reset > controls and power domains. > > > Signed-off-by: Leonard Crestez > --- > ?drivers/pci/controller/dwc/pci-imx6.c | 95 +++++++++++++++++++++++++-- > ?1 file changed, 90 insertions(+), 5 deletions(-) > > diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c > index 80f604602783..daebee905108 100644 > --- a/drivers/pci/controller/dwc/pci-imx6.c > +++ b/drivers/pci/controller/dwc/pci-imx6.c > @@ -540,10 +540,27 @@ static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie) > ? > > ? dev_err(dev, "Speed change timeout\n"); > > ? return -EINVAL; > ?} > ? > +static void imx6_pcie_ltssm_enable(struct device *dev) > +{ > > + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); > + > > + switch (imx6_pcie->variant) { > > + case IMX6Q: > > + case IMX6SX: > > + case IMX6QP: > > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, > > + ???IMX6Q_GPR12_PCIE_CTL_2, > > + ???IMX6Q_GPR12_PCIE_CTL_2); > > + break; > > + case IMX7D: > > + reset_control_deassert(imx6_pcie->apps_reset); > > + } > +} > + > ?static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie) > ?{ > > ? struct dw_pcie *pci = imx6_pcie->pci; > > ? struct device *dev = pci->dev; > > ? u32 tmp; > @@ -558,15 +575,11 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie) > > ? tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK; > > ? tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1; > > ? dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp); > ? > > ? /* Start LTSSM. */ > > - if (imx6_pcie->variant == IMX7D) > > - reset_control_deassert(imx6_pcie->apps_reset); > > - else > > - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, > > - ???IMX6Q_GPR12_PCIE_CTL_2, 1 << 10); > > + imx6_pcie_ltssm_enable(dev); > ? > > ? ret = imx6_pcie_wait_for_link(imx6_pcie); > > ? if (ret) > > ? goto err_reset_phy; > ? > @@ -681,10 +694,81 @@ static int imx6_add_pcie_port(struct imx6_pcie *imx6_pcie, > ? > ?static const struct dw_pcie_ops dw_pcie_ops = { > > ? .link_up = imx6_pcie_link_up, > ?}; > ? > +#ifdef CONFIG_PM_SLEEP > +static void imx6_pcie_ltssm_disable(struct device *dev) > +{ > > + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); > + > > + switch (imx6_pcie->variant) { > > + case IMX6Q: > > + case IMX6SX: > > + case IMX6QP: > > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, > + ???IMX6Q_GPR12_PCIE_CTL_2, 0); Has this been tested on i.MX6? LTSSM disable requires a more complex sequence on this SoC to avoid hanging the system. See commit 3e3e406e3807 "PCI: imx6: Put LTSSM in "Detect" state before disabling it". Note that implementing the correct sequence requires the core clocks to still be on when disabling LTSSM, so would need to switch ordering of the function calls in?imx6_pcie_suspend_noirq. > + break; > > + case IMX7D: > > + reset_control_assert(imx6_pcie->apps_reset); > > + break; > > + } > +} > + > +static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie) > +{ > > + clk_disable_unprepare(imx6_pcie->pcie); > > + clk_disable_unprepare(imx6_pcie->pcie_phy); > > + clk_disable_unprepare(imx6_pcie->pcie_bus); > + > > + if (imx6_pcie->variant == IMX7D) { > > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, > > + ???IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, > > + ???IMX7D_GPR12_PCIE_PHY_REFCLK_SEL); > > + } > +} > + > +static int imx6_pcie_suspend_noirq(struct device *dev) > +{ > > + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); > + > > + if (imx6_pcie->variant != IMX7D) > > + return 0; > + > > + imx6_pcie_clk_disable(imx6_pcie); > > + imx6_pcie_ltssm_disable(dev); > + > > + return 0; > +} > + > +static int imx6_pcie_resume_noirq(struct device *dev) > +{ > > + int ret = 0; > > + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); > > + struct pcie_port *pp = &imx6_pcie->pci->pp; > + > > + if (imx6_pcie->variant != IMX7D) > > + return 0; > + > > + imx6_pcie_assert_core_reset(imx6_pcie); > > + imx6_pcie_init_phy(imx6_pcie); > > + imx6_pcie_deassert_core_reset(imx6_pcie); > > + dw_pcie_setup_rc(pp); > + > > + ret = imx6_pcie_establish_link(imx6_pcie); > > + if (ret < 0) > + pr_err("pcie link is down after resume.\n"); dev_err(), please. Regards, Lucas > + > > + return 0; > +} > +#endif > + > +static const struct dev_pm_ops imx6_pcie_pm_ops = { > > + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx6_pcie_suspend_noirq, > > + ??????imx6_pcie_resume_noirq) > +}; > + > ?static int imx6_pcie_probe(struct platform_device *pdev) > ?{ > > ? struct device *dev = &pdev->dev; > > ? struct dw_pcie *pci; > > ? struct imx6_pcie *imx6_pcie; > @@ -847,10 +931,11 @@ static const struct of_device_id imx6_pcie_of_match[] = { > ?static struct platform_driver imx6_pcie_driver = { > > ? .driver = { > > > ? .name = "imx6q-pcie", > > ? .of_match_table = imx6_pcie_of_match, > > ? .suppress_bind_attrs = true, > > + .pm = &imx6_pcie_pm_ops, > > ? }, > > ? .probe????= imx6_pcie_probe, > > ? .shutdown = imx6_pcie_shutdown, > ?}; > ?