* [RESEND] PCI: imx: Initial imx7d pm support
@ 2018-08-27 11:28 Leonard Crestez
2018-08-28 10:07 ` Lorenzo Pieralisi
2018-09-17 10:33 ` Lorenzo Pieralisi
0 siblings, 2 replies; 7+ messages in thread
From: Leonard Crestez @ 2018-08-27 11:28 UTC (permalink / raw)
To: Lorenzo Pieralisi
Cc: Dong Aisheng, Joao Pinto, Richard Zhu, kernel, Anson Huang,
Andrey Smirnov, Jingoo Han, linux-kernel, Fabio Estevam,
linux-imx, Philipp Zabel, linux-pci, Bjorn Helgaas,
linux-arm-kernel, Lucas Stach
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 <hongxing.zhu@nxp.com>, this
patch adjusts the code to the upstream imx7d implemention using reset
controls and power domains.
Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
---
drivers/pci/controller/dwc/pci-imx6.c | 97 +++++++++++++++++++++++++--
1 file changed, 92 insertions(+), 5 deletions(-)
Resending after RC1 as suggested here: https://lkml.org/lkml/2018/8/8/496
This was initially sent together with a dts fix, that was already
accepted by Shawn: https://lkml.org/lkml/2018/8/21/529
Some dependencies in this area are complicated but as far as I know
including this patch without others should not break anything that was
not already broken. Since this is a patch for something that has never
worked before it should be treated as a feature not a bugfix.
I have a few other patches for imx pci but it's better to deal with them
separately. This initial patch adding suspend support is useful by
itself.
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 4a9a673b4777..65b6d1015723 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -540,10 +540,28 @@ 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);
+ break;
+ }
+}
+
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 +576,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;
@@ -680,10 +694,82 @@ 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 IMX6SX:
+ case IMX6QP:
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ IMX6Q_GPR12_PCIE_CTL_2, 0);
+ break;
+ case IMX7D:
+ reset_control_assert(imx6_pcie->apps_reset);
+ break;
+ default:
+ dev_err(dev, "ltssm_disable not supported\n");
+ }
+}
+
+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;
+ 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)
+ dev_info(dev, "pcie link is down after resume.\n");
+
+ 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;
@@ -846,10 +932,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,
};
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [RESEND] PCI: imx: Initial imx7d pm support
2018-08-27 11:28 [RESEND] PCI: imx: Initial imx7d pm support Leonard Crestez
@ 2018-08-28 10:07 ` Lorenzo Pieralisi
2018-08-28 13:00 ` Leonard Crestez
2018-09-17 10:33 ` Lorenzo Pieralisi
1 sibling, 1 reply; 7+ messages in thread
From: Lorenzo Pieralisi @ 2018-08-28 10:07 UTC (permalink / raw)
To: Leonard Crestez
Cc: Dong Aisheng, Joao Pinto, Richard Zhu, kernel, Anson Huang,
Andrey Smirnov, Jingoo Han, linux-kernel, Fabio Estevam,
linux-imx, Philipp Zabel, linux-pci, Bjorn Helgaas,
linux-arm-kernel, Lucas Stach
On Mon, Aug 27, 2018 at 02:28:37PM +0300, Leonard Crestez wrote:
> 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 <hongxing.zhu@nxp.com>, this
> patch adjusts the code to the upstream imx7d implemention using reset
> controls and power domains.
I will add a Suggested-by: replacing this paragraph, it is always better
to add proper tags rather than credit hidden in commit logs messages.
> Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
> Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
> ---
> drivers/pci/controller/dwc/pci-imx6.c | 97 +++++++++++++++++++++++++--
> 1 file changed, 92 insertions(+), 5 deletions(-)
>
> Resending after RC1 as suggested here: https://lkml.org/lkml/2018/8/8/496
>
> This was initially sent together with a dts fix, that was already
> accepted by Shawn: https://lkml.org/lkml/2018/8/21/529
>
> Some dependencies in this area are complicated but as far as I know
> including this patch without others should not break anything that was
> not already broken. Since this is a patch for something that has never
> worked before it should be treated as a feature not a bugfix.
Ok, so I consider this v4.20 material, please shout if it has to be
sent as a fix, I do not think so given what we discussed above.
Lorenzo
> I have a few other patches for imx pci but it's better to deal with them
> separately. This initial patch adding suspend support is useful by
> itself.
>
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index 4a9a673b4777..65b6d1015723 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -540,10 +540,28 @@ 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);
> + break;
> + }
> +}
> +
> 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 +576,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;
>
> @@ -680,10 +694,82 @@ 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 IMX6SX:
> + case IMX6QP:
> + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
> + IMX6Q_GPR12_PCIE_CTL_2, 0);
> + break;
> + case IMX7D:
> + reset_control_assert(imx6_pcie->apps_reset);
> + break;
> + default:
> + dev_err(dev, "ltssm_disable not supported\n");
> + }
> +}
> +
> +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;
> + 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)
> + dev_info(dev, "pcie link is down after resume.\n");
> +
> + 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;
> @@ -846,10 +932,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,
> };
>
> --
> 2.17.1
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RESEND] PCI: imx: Initial imx7d pm support
2018-08-28 10:07 ` Lorenzo Pieralisi
@ 2018-08-28 13:00 ` Leonard Crestez
2018-08-28 14:55 ` Lorenzo Pieralisi
0 siblings, 1 reply; 7+ messages in thread
From: Leonard Crestez @ 2018-08-28 13:00 UTC (permalink / raw)
To: lorenzo.pieralisi
Cc: A.s. Dong, Joao.Pinto, Richard Zhu, kernel, Anson Huang,
andrew.smirnov, jingoohan1, linux-kernel, bhelgaas, dl-linux-imx,
p.zabel, linux-pci, Fabio Estevam, linux-arm-kernel, l.stach
On Tue, 2018-08-28 at 11:07 +0100, Lorenzo Pieralisi wrote:
> On Mon, Aug 27, 2018 at 02:28:37PM +0300, Leonard Crestez wrote:
> > 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 <hongxing.zhu@nxp.com>, this
> > patch adjusts the code to the upstream imx7d implemention using reset
> > controls and power domains.
>
> I will add a Suggested-by: replacing this paragraph, it is always better
> to add proper tags rather than credit hidden in commit logs messages.
Isn't "Originally-by:" a better tag for this?
> > Some dependencies in this area are complicated but as far as I know
> > including this patch without others should not break anything that was
> > not already broken. Since this is a patch for something that has never
> > worked before it should be treated as a feature not a bugfix.
>
> Ok, so I consider this v4.20 material, please shout if it has to be
> sent as a fix, I do not think so given what we discussed above.
Thanks!
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RESEND] PCI: imx: Initial imx7d pm support
2018-08-28 13:00 ` Leonard Crestez
@ 2018-08-28 14:55 ` Lorenzo Pieralisi
2018-09-03 13:52 ` Leonard Crestez
0 siblings, 1 reply; 7+ messages in thread
From: Lorenzo Pieralisi @ 2018-08-28 14:55 UTC (permalink / raw)
To: Leonard Crestez
Cc: Richard Zhu, A.s. Dong, linux-kernel, dl-linux-imx, jingoohan1,
linux-arm-kernel, Fabio Estevam, p.zabel, Joao.Pinto,
andrew.smirnov, Anson Huang, bhelgaas, l.stach, kernel,
linux-pci
On Tue, Aug 28, 2018 at 01:00:02PM +0000, Leonard Crestez wrote:
> On Tue, 2018-08-28 at 11:07 +0100, Lorenzo Pieralisi wrote:
> > On Mon, Aug 27, 2018 at 02:28:37PM +0300, Leonard Crestez wrote:
> > > 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 <hongxing.zhu@nxp.com>, this
> > > patch adjusts the code to the upstream imx7d implemention using reset
> > > controls and power domains.
> >
> > I will add a Suggested-by: replacing this paragraph, it is always better
> > to add proper tags rather than credit hidden in commit logs messages.
>
> Isn't "Originally-by:" a better tag for this?
We can add that, yes or add Richard as patch author, as you prefer to
give him credit.
Lorenzo
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RESEND] PCI: imx: Initial imx7d pm support
2018-08-28 14:55 ` Lorenzo Pieralisi
@ 2018-09-03 13:52 ` Leonard Crestez
0 siblings, 0 replies; 7+ messages in thread
From: Leonard Crestez @ 2018-09-03 13:52 UTC (permalink / raw)
To: lorenzo.pieralisi
Cc: A.s. Dong, Joao.Pinto, Richard Zhu, kernel, Anson Huang,
andrew.smirnov, jingoohan1, linux-kernel, bhelgaas, dl-linux-imx,
p.zabel, linux-pci, Fabio Estevam, linux-arm-kernel, l.stach
On Tue, 2018-08-28 at 15:55 +0100, Lorenzo Pieralisi wrote:
> On Tue, Aug 28, 2018 at 01:00:02PM +0000, Leonard Crestez wrote:
> > On Tue, 2018-08-28 at 11:07 +0100, Lorenzo Pieralisi wrote:
> > > On Mon, Aug 27, 2018 at 02:28:37PM +0300, Leonard Crestez wrote:
> > > > 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 <hongxing.zhu@nxp.com>, this
> > > > patch adjusts the code to the upstream imx7d implemention using reset
> > > > controls and power domains.
> > >
> > > I will add a Suggested-by: replacing this paragraph, it is always better
> > > to add proper tags rather than credit hidden in commit logs messages.
> >
> > Isn't "Originally-by:" a better tag for this?
>
> We can add that, yes or add Richard as patch author, as you prefer to
> give him credit.
I think "Originally-by:" is a better fit because there is no
clear correspondence with patches from the vendor tree.
--
Regards,
Leonard
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RESEND] PCI: imx: Initial imx7d pm support
2018-08-27 11:28 [RESEND] PCI: imx: Initial imx7d pm support Leonard Crestez
2018-08-28 10:07 ` Lorenzo Pieralisi
@ 2018-09-17 10:33 ` Lorenzo Pieralisi
2018-09-17 10:33 ` Lorenzo Pieralisi
1 sibling, 1 reply; 7+ messages in thread
From: Lorenzo Pieralisi @ 2018-09-17 10:33 UTC (permalink / raw)
To: Leonard Crestez
Cc: Dong Aisheng, Joao Pinto, Richard Zhu, kernel, Anson Huang,
Andrey Smirnov, Jingoo Han, linux-kernel, Fabio Estevam,
linux-imx, Philipp Zabel, linux-pci, Bjorn Helgaas,
linux-arm-kernel, Lucas Stach
On Mon, Aug 27, 2018 at 02:28:37PM +0300, Leonard Crestez wrote:
> 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 <hongxing.zhu@nxp.com>, this
> patch adjusts the code to the upstream imx7d implemention using reset
> controls and power domains.
>
> Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
> Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
> ---
> drivers/pci/controller/dwc/pci-imx6.c | 97 +++++++++++++++++++++++++--
> 1 file changed, 92 insertions(+), 5 deletions(-)
Applied to pci/dwc for v4.20, thanks.
Lorenzo
> Resending after RC1 as suggested here: https://lkml.org/lkml/2018/8/8/496
>
> This was initially sent together with a dts fix, that was already
> accepted by Shawn: https://lkml.org/lkml/2018/8/21/529
>
> Some dependencies in this area are complicated but as far as I know
> including this patch without others should not break anything that was
> not already broken. Since this is a patch for something that has never
> worked before it should be treated as a feature not a bugfix.
>
> I have a few other patches for imx pci but it's better to deal with them
> separately. This initial patch adding suspend support is useful by
> itself.
>
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index 4a9a673b4777..65b6d1015723 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -540,10 +540,28 @@ 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);
> + break;
> + }
> +}
> +
> 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 +576,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;
>
> @@ -680,10 +694,82 @@ 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 IMX6SX:
> + case IMX6QP:
> + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
> + IMX6Q_GPR12_PCIE_CTL_2, 0);
> + break;
> + case IMX7D:
> + reset_control_assert(imx6_pcie->apps_reset);
> + break;
> + default:
> + dev_err(dev, "ltssm_disable not supported\n");
> + }
> +}
> +
> +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;
> + 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)
> + dev_info(dev, "pcie link is down after resume.\n");
> +
> + 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;
> @@ -846,10 +932,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,
> };
>
> --
> 2.17.1
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RESEND] PCI: imx: Initial imx7d pm support
2018-09-17 10:33 ` Lorenzo Pieralisi
@ 2018-09-17 10:33 ` Lorenzo Pieralisi
0 siblings, 0 replies; 7+ messages in thread
From: Lorenzo Pieralisi @ 2018-09-17 10:33 UTC (permalink / raw)
To: Leonard Crestez
Cc: Lucas Stach, Andrey Smirnov, Richard Zhu, Anson Huang,
Philipp Zabel, Bjorn Helgaas, Jingoo Han, Joao Pinto,
Fabio Estevam, Dong Aisheng, linux-imx, kernel, linux-pci,
linux-arm-kernel, linux-kernel
On Mon, Aug 27, 2018 at 02:28:37PM +0300, Leonard Crestez wrote:
> 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 <hongxing.zhu@nxp.com>, this
> patch adjusts the code to the upstream imx7d implemention using reset
> controls and power domains.
>
> Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
> Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
> ---
> drivers/pci/controller/dwc/pci-imx6.c | 97 +++++++++++++++++++++++++--
> 1 file changed, 92 insertions(+), 5 deletions(-)
Applied to pci/dwc for v4.20, thanks.
Lorenzo
> Resending after RC1 as suggested here: https://lkml.org/lkml/2018/8/8/496
>
> This was initially sent together with a dts fix, that was already
> accepted by Shawn: https://lkml.org/lkml/2018/8/21/529
>
> Some dependencies in this area are complicated but as far as I know
> including this patch without others should not break anything that was
> not already broken. Since this is a patch for something that has never
> worked before it should be treated as a feature not a bugfix.
>
> I have a few other patches for imx pci but it's better to deal with them
> separately. This initial patch adding suspend support is useful by
> itself.
>
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index 4a9a673b4777..65b6d1015723 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -540,10 +540,28 @@ 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);
> + break;
> + }
> +}
> +
> 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 +576,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;
>
> @@ -680,10 +694,82 @@ 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 IMX6SX:
> + case IMX6QP:
> + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
> + IMX6Q_GPR12_PCIE_CTL_2, 0);
> + break;
> + case IMX7D:
> + reset_control_assert(imx6_pcie->apps_reset);
> + break;
> + default:
> + dev_err(dev, "ltssm_disable not supported\n");
> + }
> +}
> +
> +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;
> + 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)
> + dev_info(dev, "pcie link is down after resume.\n");
> +
> + 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;
> @@ -846,10 +932,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,
> };
>
> --
> 2.17.1
>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2018-09-17 10:33 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-27 11:28 [RESEND] PCI: imx: Initial imx7d pm support Leonard Crestez
2018-08-28 10:07 ` Lorenzo Pieralisi
2018-08-28 13:00 ` Leonard Crestez
2018-08-28 14:55 ` Lorenzo Pieralisi
2018-09-03 13:52 ` Leonard Crestez
2018-09-17 10:33 ` Lorenzo Pieralisi
2018-09-17 10:33 ` Lorenzo Pieralisi
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).