Message ID | 1412069804-17162-3-git-send-email-r65037@freescale.com (mailing list archive) |
---|---|
State | New, archived |
Delegated to: | Bjorn Helgaas |
Headers | show |
Am Dienstag, den 30.09.2014, 17:36 +0800 schrieb Richard Zhu: > - imx6sx pcie has its own standalone pcie power supply. > In order to turn on the imx6sx pcie power during > initialization. Add the pcie regulator and the gpc regmap > into the imx6sx pcie structure. > - imx6sx pcie has the new added reset mechanism, add the > reset operations into the initialization. > - Register one PM call-back, enter/exit L2 state of the ASPM > during system suspend/resume. > - disp_axi clock is required by pcie inbound axi port actually. > Add one more clock named pcie_inbound_axi for imx6sx pcie. > > Signed-off-by: Richard Zhu <r65037@freescale.com> > --- > drivers/pci/host/pci-imx6.c | 163 ++++++++++++++++++++++++++++++++++++++------ > 1 file changed, 144 insertions(+), 19 deletions(-) > > diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c > index eac96fb..c74e87d 100644 > --- a/drivers/pci/host/pci-imx6.c > +++ b/drivers/pci/host/pci-imx6.c > @@ -22,8 +22,10 @@ > #include <linux/pci.h> > #include <linux/platform_device.h> > #include <linux/regmap.h> > +#include <linux/regulator/consumer.h> > #include <linux/resource.h> > #include <linux/signal.h> > +#include <linux/syscore_ops.h> > #include <linux/types.h> > #include <linux/interrupt.h> > > @@ -35,11 +37,15 @@ struct imx6_pcie { > int reset_gpio; > struct clk *pcie_bus; > struct clk *pcie_phy; > + struct clk *pcie_inbound_axi; > struct clk *pcie; > struct pcie_port pp; > struct regmap *iomuxc_gpr; > + struct regmap *gpc_ips_reg; > + struct regulator *pcie_regulator; I would expect this to be named pcie_phy_regulator. > void __iomem *mem_base; > }; > +static struct imx6_pcie *imx6_pcie; No. This is just bad style. You have the pointer available embedded in other structures at all relevant places. No global statics please. > > /* PCIe Root Complex registers (memory-mapped) */ > #define PCIE_RC_LCR 0x7c > @@ -77,6 +83,18 @@ struct imx6_pcie { > #define PHY_RX_OVRD_IN_LO_RX_DATA_EN (1 << 5) > #define PHY_RX_OVRD_IN_LO_RX_PLL_EN (1 << 3) > > +/* GPC PCIE PHY bit definitions */ > +#define GPC_CNTR 0 > +#define GPC_CNTR_PCIE_PHY_PUP_REQ BIT(7) > + > +static inline bool is_imx6sx_pcie(struct imx6_pcie *imx6_pcie) > +{ > + struct pcie_port *pp = &imx6_pcie->pp; > + struct device_node *np = pp->dev->of_node; > + > + return of_device_is_compatible(np, "fsl,imx6sx-pcie"); > +} > + > static int pcie_phy_poll_ack(void __iomem *dbi_base, int exp_val) > { > u32 val; > @@ -275,18 +293,29 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp) > goto err_pcie; > } > > - /* power up core phy and enable ref clock */ > - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, > - IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18); > - /* > - * the async reset input need ref clock to sync internally, > - * when the ref clock comes after reset, internal synced > - * reset time is too short , cannot meet the requirement. > - * add one ~10us delay here. > - */ > - udelay(10); > - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, > - IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16); > + if (is_imx6sx_pcie(imx6_pcie)) { > + ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi); > + if (ret) { > + dev_err(pp->dev, "unable to enable pcie clock\n"); > + goto err_inbound_axi; > + } > + > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, > + IMX6SX_GPR12_PCIE_TEST_PD, 0); > + } else { > + /* power up core phy and enable ref clock */ > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, > + IMX6Q_GPR1_PCIE_TEST_PD, 0); > + /* > + * the async reset input need ref clock to sync internally, > + * when the ref clock comes after reset, internal synced > + * reset time is too short , cannot meet the requirement. > + * add one ~10us delay here. > + */ > + udelay(10); > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, > + IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16); > + } > > /* allow the clocks to stabilize */ > usleep_range(200, 500); > @@ -297,8 +326,19 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp) > msleep(100); > gpio_set_value(imx6_pcie->reset_gpio, 1); > } > + > + /* > + * Release the PCIe PHY reset here, that we have set in > + * imx6_pcie_init_phy() now > + */ > + if (is_imx6sx_pcie(imx6_pcie)) > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5, > + IMX6SX_GPR5_PCIE_BTNRST, 0); > + > return 0; > > +err_inbound_axi: > + clk_disable_unprepare(imx6_pcie->pcie); > err_pcie: > clk_disable_unprepare(imx6_pcie->pcie_bus); > err_pcie_bus: > @@ -311,6 +351,26 @@ err_pcie_phy: > static void imx6_pcie_init_phy(struct pcie_port *pp) > { > struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp); > + int ret; > + > + /* Power up the separate domain available on i.MX6SX */ > + if (is_imx6sx_pcie(imx6_pcie)) { > + /* Force PCIe PHY reset */ > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5, > + IMX6SX_GPR5_PCIE_BTNRST, > + IMX6SX_GPR5_PCIE_BTNRST); > + > + regmap_update_bits(imx6_pcie->gpc_ips_reg, GPC_CNTR, > + GPC_CNTR_PCIE_PHY_PUP_REQ, > + GPC_CNTR_PCIE_PHY_PUP_REQ); > + regulator_set_voltage(imx6_pcie->pcie_regulator, > + 1100000, 1100000); > + ret = regulator_enable(imx6_pcie->pcie_regulator); > + if (ret) > + dev_info(pp->dev, "failed to enable pcie regulator.\n"); > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, > + IMX6SX_GPR12_RX_EQ_MASK, IMX6SX_GPR12_RX_EQ_2); > + } > > regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, > IMX6Q_GPR12_PCIE_CTL_2, 0 << 10); > @@ -319,7 +379,7 @@ static void imx6_pcie_init_phy(struct pcie_port *pp) > regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, > IMX6Q_GPR12_DEVICE_TYPE, PCI_EXP_TYPE_ROOT_PORT << 12); > regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, > - IMX6Q_GPR12_LOS_LEVEL, 9 << 4); > + IMX6Q_GPR12_LOS_LEVEL, IMX6Q_GPR12_LOS_LEVEL_9); > > regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, > IMX6Q_GPR8_TX_DEEMPH_GEN1, 0 << 0); > @@ -377,7 +437,8 @@ static int imx6_pcie_start_link(struct pcie_port *pp) > > /* Start LTSSM. */ > regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, > - IMX6Q_GPR12_PCIE_CTL_2, 1 << 10); > + IMX6Q_GPR12_PCIE_CTL_2, > + IMX6Q_GPR12_PCIE_CTL_2); > > ret = imx6_pcie_wait_for_link(pp); > if (ret) > @@ -553,9 +614,50 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp, > return 0; > } > > +#ifdef CONFIG_PM_SLEEP > +static int pci_imx_suspend(void) > +{ > + if (is_imx6sx_pcie(imx6_pcie)) { > + /* PM_TURN_OFF */ > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, > + IMX6SX_GPR12_PCIE_PM_TURN_OFF, > + IMX6SX_GPR12_PCIE_PM_TURN_OFF); > + udelay(10); > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, > + IMX6SX_GPR12_PCIE_PM_TURN_OFF, 0); > + } > + > + return 0; > +} > + > +static void pci_imx_resume(void) > +{ > + struct pcie_port *pp = &imx6_pcie->pp; > + > + if (is_imx6sx_pcie(imx6_pcie)) { > + /* Reset iMX6SX PCIe */ > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5, > + IMX6SX_GPR5_PCIE_PERST, IMX6SX_GPR5_PCIE_PERST); > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5, > + IMX6SX_GPR5_PCIE_PERST, 0); > + /* > + * controller maybe turn off, re-configure again > + */ > + dw_pcie_setup_rc(pp); > + > + if (IS_ENABLED(CONFIG_PCI_MSI)) > + dw_pcie_msi_cfg_restore(pp); > + } > +} > + > +static struct syscore_ops pci_imx_syscore_ops = { > + .suspend = pci_imx_suspend, > + .resume = pci_imx_resume, > +}; > +#endif > + > static int __init imx6_pcie_probe(struct platform_device *pdev) > { > - struct imx6_pcie *imx6_pcie; > struct pcie_port *pp; > struct device_node *np = pdev->dev.of_node; > struct resource *dbi_base; > @@ -572,7 +674,7 @@ static int __init imx6_pcie_probe(struct platform_device *pdev) > hook_fault_code(16 + 6, imx6q_pcie_abort_handler, SIGBUS, 0, > "imprecise external abort"); > > - dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbi"); You are breaking old devicetrees here. "rc_dbi" isn't a documented name and isn't available on old DTs. Besides the imx6q DT uses just "dbi" as the name. Don't touch this code, it does exactly the right thing by grabbing the first reg resource. > pp->dbi_base = devm_ioremap_resource(&pdev->dev, dbi_base); > if (IS_ERR(pp->dbi_base)) > return PTR_ERR(pp->dbi_base); > @@ -610,9 +712,28 @@ static int __init imx6_pcie_probe(struct platform_device *pdev) > return PTR_ERR(imx6_pcie->pcie); > } > > - /* Grab GPR config register range */ > - imx6_pcie->iomuxc_gpr = > - syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr"); > + if (is_imx6sx_pcie(imx6_pcie)) { > + imx6_pcie->pcie_inbound_axi = devm_clk_get(&pdev->dev, > + "pcie_inbound_axi"); > + if (IS_ERR(imx6_pcie->pcie_inbound_axi)) { > + dev_err(&pdev->dev, > + "pcie clock source missing or invalid\n"); > + return PTR_ERR(imx6_pcie->pcie_inbound_axi); > + } > + > + imx6_pcie->pcie_regulator = devm_regulator_get(pp->dev, > + "pcie-phy"); > + > + imx6_pcie->iomuxc_gpr = > + syscon_regmap_lookup_by_compatible > + ("fsl,imx6sx-iomuxc-gpr"); > + imx6_pcie->gpc_ips_reg = > + syscon_regmap_lookup_by_compatible("fsl,imx6sx-gpc"); > + } else { > + imx6_pcie->iomuxc_gpr = > + syscon_regmap_lookup_by_compatible > + ("fsl,imx6q-iomuxc-gpr"); > + } > if (IS_ERR(imx6_pcie->iomuxc_gpr)) { > dev_err(&pdev->dev, "unable to find iomuxc registers\n"); > return PTR_ERR(imx6_pcie->iomuxc_gpr); > @@ -623,6 +744,9 @@ static int __init imx6_pcie_probe(struct platform_device *pdev) > return ret; > > platform_set_drvdata(pdev, imx6_pcie); > +#ifdef CONFIG_PM_SLEEP > + register_syscore_ops(&pci_imx_syscore_ops); > +#endif > return 0; > } > > @@ -636,6 +760,7 @@ static void imx6_pcie_shutdown(struct platform_device *pdev) > > static const struct of_device_id imx6_pcie_of_match[] = { > { .compatible = "fsl,imx6q-pcie", }, > + { .compatible = "fsl,imx6sx-pcie", }, > {}, > }; > MODULE_DEVICE_TABLE(of, imx6_pcie_of_match);
> ? 2014?9?30????10:54?"Lucas Stach" <l.stach@pengutronix.de> ??? > > Am Dienstag, den 30.09.2014, 17:36 +0800 schrieb Richard Zhu: >> - imx6sx pcie has its own standalone pcie power supply. >> In order to turn on the imx6sx pcie power during >> initialization. Add the pcie regulator and the gpc regmap >> into the imx6sx pcie structure. >> - imx6sx pcie has the new added reset mechanism, add the >> reset operations into the initialization. >> - Register one PM call-back, enter/exit L2 state of the ASPM >> during system suspend/resume. >> - disp_axi clock is required by pcie inbound axi port actually. >> Add one more clock named pcie_inbound_axi for imx6sx pcie. >> >> Signed-off-by: Richard Zhu <r65037@freescale.com> >> --- >> drivers/pci/host/pci-imx6.c | 163 ++++++++++++++++++++++++++++++++++++++------ >> 1 file changed, 144 insertions(+), 19 deletions(-) >> >> diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c >> index eac96fb..c74e87d 100644 >> --- a/drivers/pci/host/pci-imx6.c >> +++ b/drivers/pci/host/pci-imx6.c >> @@ -22,8 +22,10 @@ >> #include <linux/pci.h> >> #include <linux/platform_device.h> >> #include <linux/regmap.h> >> +#include <linux/regulator/consumer.h> >> #include <linux/resource.h> >> #include <linux/signal.h> >> +#include <linux/syscore_ops.h> >> #include <linux/types.h> >> #include <linux/interrupt.h> >> >> @@ -35,11 +37,15 @@ struct imx6_pcie { >> int reset_gpio; >> struct clk *pcie_bus; >> struct clk *pcie_phy; >> + struct clk *pcie_inbound_axi; >> struct clk *pcie; >> struct pcie_port pp; >> struct regmap *iomuxc_gpr; >> + struct regmap *gpc_ips_reg; >> + struct regulator *pcie_regulator; > > I would expect this to be named pcie_phy_regulator. Ok. > >> void __iomem *mem_base; >> }; >> +static struct imx6_pcie *imx6_pcie; > > No. This is just bad style. You have the pointer available embedded in > other structures at all relevant places. No global statics please. Ok. > >> >> /* PCIe Root Complex registers (memory-mapped) */ >> #define PCIE_RC_LCR 0x7c >> @@ -77,6 +83,18 @@ struct imx6_pcie { >> #define PHY_RX_OVRD_IN_LO_RX_DATA_EN (1 << 5) >> #define PHY_RX_OVRD_IN_LO_RX_PLL_EN (1 << 3) >> >> +/* GPC PCIE PHY bit definitions */ >> +#define GPC_CNTR 0 >> +#define GPC_CNTR_PCIE_PHY_PUP_REQ BIT(7) >> + >> +static inline bool is_imx6sx_pcie(struct imx6_pcie *imx6_pcie) >> +{ >> + struct pcie_port *pp = &imx6_pcie->pp; >> + struct device_node *np = pp->dev->of_node; >> + >> + return of_device_is_compatible(np, "fsl,imx6sx-pcie"); >> +} >> + >> static int pcie_phy_poll_ack(void __iomem *dbi_base, int exp_val) >> { >> u32 val; >> @@ -275,18 +293,29 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp) >> goto err_pcie; >> } >> >> - /* power up core phy and enable ref clock */ >> - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, >> - IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18); >> - /* >> - * the async reset input need ref clock to sync internally, >> - * when the ref clock comes after reset, internal synced >> - * reset time is too short , cannot meet the requirement. >> - * add one ~10us delay here. >> - */ >> - udelay(10); >> - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, >> - IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16); >> + if (is_imx6sx_pcie(imx6_pcie)) { >> + ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi); >> + if (ret) { >> + dev_err(pp->dev, "unable to enable pcie clock\n"); >> + goto err_inbound_axi; >> + } >> + >> + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, >> + IMX6SX_GPR12_PCIE_TEST_PD, 0); >> + } else { >> + /* power up core phy and enable ref clock */ >> + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, >> + IMX6Q_GPR1_PCIE_TEST_PD, 0); >> + /* >> + * the async reset input need ref clock to sync internally, >> + * when the ref clock comes after reset, internal synced >> + * reset time is too short , cannot meet the requirement. >> + * add one ~10us delay here. >> + */ >> + udelay(10); >> + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, >> + IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16); >> + } >> >> /* allow the clocks to stabilize */ >> usleep_range(200, 500); >> @@ -297,8 +326,19 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp) >> msleep(100); >> gpio_set_value(imx6_pcie->reset_gpio, 1); >> } >> + >> + /* >> + * Release the PCIe PHY reset here, that we have set in >> + * imx6_pcie_init_phy() now >> + */ >> + if (is_imx6sx_pcie(imx6_pcie)) >> + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5, >> + IMX6SX_GPR5_PCIE_BTNRST, 0); >> + >> return 0; >> >> +err_inbound_axi: >> + clk_disable_unprepare(imx6_pcie->pcie); >> err_pcie: >> clk_disable_unprepare(imx6_pcie->pcie_bus); >> err_pcie_bus: >> @@ -311,6 +351,26 @@ err_pcie_phy: >> static void imx6_pcie_init_phy(struct pcie_port *pp) >> { >> struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp); >> + int ret; >> + >> + /* Power up the separate domain available on i.MX6SX */ >> + if (is_imx6sx_pcie(imx6_pcie)) { >> + /* Force PCIe PHY reset */ >> + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5, >> + IMX6SX_GPR5_PCIE_BTNRST, >> + IMX6SX_GPR5_PCIE_BTNRST); >> + >> + regmap_update_bits(imx6_pcie->gpc_ips_reg, GPC_CNTR, >> + GPC_CNTR_PCIE_PHY_PUP_REQ, >> + GPC_CNTR_PCIE_PHY_PUP_REQ); >> + regulator_set_voltage(imx6_pcie->pcie_regulator, >> + 1100000, 1100000); >> + ret = regulator_enable(imx6_pcie->pcie_regulator); >> + if (ret) >> + dev_info(pp->dev, "failed to enable pcie regulator.\n"); >> + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, >> + IMX6SX_GPR12_RX_EQ_MASK, IMX6SX_GPR12_RX_EQ_2); >> + } >> >> regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, >> IMX6Q_GPR12_PCIE_CTL_2, 0 << 10); >> @@ -319,7 +379,7 @@ static void imx6_pcie_init_phy(struct pcie_port *pp) >> regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, >> IMX6Q_GPR12_DEVICE_TYPE, PCI_EXP_TYPE_ROOT_PORT << 12); >> regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, >> - IMX6Q_GPR12_LOS_LEVEL, 9 << 4); >> + IMX6Q_GPR12_LOS_LEVEL, IMX6Q_GPR12_LOS_LEVEL_9); >> >> regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, >> IMX6Q_GPR8_TX_DEEMPH_GEN1, 0 << 0); >> @@ -377,7 +437,8 @@ static int imx6_pcie_start_link(struct pcie_port *pp) >> >> /* Start LTSSM. */ >> regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, >> - IMX6Q_GPR12_PCIE_CTL_2, 1 << 10); >> + IMX6Q_GPR12_PCIE_CTL_2, >> + IMX6Q_GPR12_PCIE_CTL_2); >> >> ret = imx6_pcie_wait_for_link(pp); >> if (ret) >> @@ -553,9 +614,50 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp, >> return 0; >> } >> >> +#ifdef CONFIG_PM_SLEEP >> +static int pci_imx_suspend(void) >> +{ >> + if (is_imx6sx_pcie(imx6_pcie)) { >> + /* PM_TURN_OFF */ >> + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, >> + IMX6SX_GPR12_PCIE_PM_TURN_OFF, >> + IMX6SX_GPR12_PCIE_PM_TURN_OFF); >> + udelay(10); >> + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, >> + IMX6SX_GPR12_PCIE_PM_TURN_OFF, 0); >> + } >> + >> + return 0; >> +} >> + >> +static void pci_imx_resume(void) >> +{ >> + struct pcie_port *pp = &imx6_pcie->pp; >> + >> + if (is_imx6sx_pcie(imx6_pcie)) { >> + /* Reset iMX6SX PCIe */ >> + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5, >> + IMX6SX_GPR5_PCIE_PERST, IMX6SX_GPR5_PCIE_PERST); >> + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5, >> + IMX6SX_GPR5_PCIE_PERST, 0); >> + /* >> + * controller maybe turn off, re-configure again >> + */ >> + dw_pcie_setup_rc(pp); >> + >> + if (IS_ENABLED(CONFIG_PCI_MSI)) >> + dw_pcie_msi_cfg_restore(pp); >> + } >> +} >> + >> +static struct syscore_ops pci_imx_syscore_ops = { >> + .suspend = pci_imx_suspend, >> + .resume = pci_imx_resume, >> +}; >> +#endif >> + >> static int __init imx6_pcie_probe(struct platform_device *pdev) >> { >> - struct imx6_pcie *imx6_pcie; >> struct pcie_port *pp; >> struct device_node *np = pdev->dev.of_node; >> struct resource *dbi_base; >> @@ -572,7 +674,7 @@ static int __init imx6_pcie_probe(struct platform_device *pdev) >> hook_fault_code(16 + 6, imx6q_pcie_abort_handler, SIGBUS, 0, >> "imprecise external abort"); >> >> - dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); >> + dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbi"); > > You are breaking old devicetrees here. "rc_dbi" isn't a documented name > and isn't available on old DTs. Besides the imx6q DT uses just "dbi" as > the name. Don't touch this code, it does exactly the right thing by > grabbing the first reg resource. Ok, changes would be removed. > >> pp->dbi_base = devm_ioremap_resource(&pdev->dev, dbi_base); >> if (IS_ERR(pp->dbi_base)) >> return PTR_ERR(pp->dbi_base); >> @@ -610,9 +712,28 @@ static int __init imx6_pcie_probe(struct platform_device *pdev) >> return PTR_ERR(imx6_pcie->pcie); >> } >> >> - /* Grab GPR config register range */ >> - imx6_pcie->iomuxc_gpr = >> - syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr"); >> + if (is_imx6sx_pcie(imx6_pcie)) { >> + imx6_pcie->pcie_inbound_axi = devm_clk_get(&pdev->dev, >> + "pcie_inbound_axi"); >> + if (IS_ERR(imx6_pcie->pcie_inbound_axi)) { >> + dev_err(&pdev->dev, >> + "pcie clock source missing or invalid\n"); >> + return PTR_ERR(imx6_pcie->pcie_inbound_axi); >> + } >> + >> + imx6_pcie->pcie_regulator = devm_regulator_get(pp->dev, >> + "pcie-phy"); >> + >> + imx6_pcie->iomuxc_gpr = >> + syscon_regmap_lookup_by_compatible >> + ("fsl,imx6sx-iomuxc-gpr"); >> + imx6_pcie->gpc_ips_reg = >> + syscon_regmap_lookup_by_compatible("fsl,imx6sx-gpc"); >> + } else { >> + imx6_pcie->iomuxc_gpr = >> + syscon_regmap_lookup_by_compatible >> + ("fsl,imx6q-iomuxc-gpr"); >> + } >> if (IS_ERR(imx6_pcie->iomuxc_gpr)) { >> dev_err(&pdev->dev, "unable to find iomuxc registers\n"); >> return PTR_ERR(imx6_pcie->iomuxc_gpr); >> @@ -623,6 +744,9 @@ static int __init imx6_pcie_probe(struct platform_device *pdev) >> return ret; >> >> platform_set_drvdata(pdev, imx6_pcie); >> +#ifdef CONFIG_PM_SLEEP >> + register_syscore_ops(&pci_imx_syscore_ops); >> +#endif >> return 0; >> } >> >> @@ -636,6 +760,7 @@ static void imx6_pcie_shutdown(struct platform_device *pdev) >> >> static const struct of_device_id imx6_pcie_of_match[] = { >> { .compatible = "fsl,imx6q-pcie", }, >> + { .compatible = "fsl,imx6sx-pcie", }, >> {}, >> }; >> MODULE_DEVICE_TABLE(of, imx6_pcie_of_match); > > -- > Pengutronix e.K. | Lucas Stach | > Industrial Linux Solutions | http://www.pengutronix.de/ | > > Best regards Richard
DQo+IC0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+IEZyb206IFpodSBSaWNoYXJkLVI2NTAz Nw0KPiBTZW50OiBUaHVyc2RheSwgT2N0b2JlciAwMiwgMjAxNCAxMDozOSBBTQ0KPiBUbzogTHVj YXMgU3RhY2gNCj4gQ2M6IFpodSBSaWNoYXJkLVI2NTAzNzsgbGludXgtcGNpLW93bmVyQHZnZXIu a2VybmVsLm9yZzsgbGludXgtDQo+IHBjaUB2Z2VyLmtlcm5lbC5vcmc7IEd1byBTaGF3bi1SNjUw NzM7IGZlc3RldmFtQGdtYWlsLmNvbTsNCj4gdGhhcnZleUBnYXRld29ya3MuY29tDQo+IFN1Ympl Y3Q6IFJlOiBbUEFUQ0ggdjQgMDIvMTBdIFBDSTogaW14NjogYWRkIGlteDZzeCBwY2llIHN1cHBv cnQNCj4gDQo+IA0KPiANCj4gDQo+ID4g1NogMjAxNMTqOdTCMzDI1aOsz8LO5zEwOjU0o6wiTHVj YXMgU3RhY2giIDxsLnN0YWNoQHBlbmd1dHJvbml4LmRlPiDQtLXAo7oNCj4gPg0KPiA+IEFtIERp ZW5zdGFnLCBkZW4gMzAuMDkuMjAxNCwgMTc6MzYgKzA4MDAgc2NocmllYiBSaWNoYXJkIFpodToN Cj4gPj4gLSBpbXg2c3ggcGNpZSBoYXMgaXRzIG93biBzdGFuZGFsb25lIHBjaWUgcG93ZXIgc3Vw cGx5Lg0KPiA+PiBJbiBvcmRlciB0byB0dXJuIG9uIHRoZSBpbXg2c3ggcGNpZSBwb3dlciBkdXJp bmcgaW5pdGlhbGl6YXRpb24uIEFkZA0KPiA+PiB0aGUgcGNpZSByZWd1bGF0b3IgYW5kIHRoZSBn cGMgcmVnbWFwIGludG8gdGhlIGlteDZzeCBwY2llIHN0cnVjdHVyZS4NCj4gPj4gLSBpbXg2c3gg cGNpZSBoYXMgdGhlIG5ldyBhZGRlZCByZXNldCBtZWNoYW5pc20sIGFkZCB0aGUgcmVzZXQNCj4g Pj4gb3BlcmF0aW9ucyBpbnRvIHRoZSBpbml0aWFsaXphdGlvbi4NCj4gPj4gLSBSZWdpc3RlciBv bmUgUE0gY2FsbC1iYWNrLCBlbnRlci9leGl0IEwyIHN0YXRlIG9mIHRoZSBBU1BNIGR1cmluZw0K PiA+PiBzeXN0ZW0gc3VzcGVuZC9yZXN1bWUuDQo+ID4+IC0gZGlzcF9heGkgY2xvY2sgaXMgcmVx dWlyZWQgYnkgcGNpZSBpbmJvdW5kIGF4aSBwb3J0IGFjdHVhbGx5Lg0KPiA+PiBBZGQgb25lIG1v cmUgY2xvY2sgbmFtZWQgcGNpZV9pbmJvdW5kX2F4aSBmb3IgaW14NnN4IHBjaWUuDQo+ID4+DQo+ ID4+IFNpZ25lZC1vZmYtYnk6IFJpY2hhcmQgWmh1IDxyNjUwMzdAZnJlZXNjYWxlLmNvbT4NCj4g Pj4gLS0tDQo+ID4+IGRyaXZlcnMvcGNpL2hvc3QvcGNpLWlteDYuYyB8IDE2Mw0KPiA+PiArKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKy0tLS0tLQ0KPiA+PiAxIGZpbGUgY2hh bmdlZCwgMTQ0IGluc2VydGlvbnMoKyksIDE5IGRlbGV0aW9ucygtKQ0KPiA+Pg0KPiA+PiBkaWZm IC0tZ2l0IGEvZHJpdmVycy9wY2kvaG9zdC9wY2ktaW14Ni5jDQo+ID4+IGIvZHJpdmVycy9wY2kv aG9zdC9wY2ktaW14Ni5jIGluZGV4IGVhYzk2ZmIuLmM3NGU4N2QgMTAwNjQ0DQo+ID4+IC0tLSBh L2RyaXZlcnMvcGNpL2hvc3QvcGNpLWlteDYuYw0KPiA+PiArKysgYi9kcml2ZXJzL3BjaS9ob3N0 L3BjaS1pbXg2LmMNCj4gPj4gQEAgLTIyLDggKzIyLDEwIEBADQo+ID4+ICNpbmNsdWRlIDxsaW51 eC9wY2kuaD4NCj4gPj4gI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPg0KPiA+PiAj aW5jbHVkZSA8bGludXgvcmVnbWFwLmg+DQo+ID4+ICsjaW5jbHVkZSA8bGludXgvcmVndWxhdG9y L2NvbnN1bWVyLmg+DQo+ID4+ICNpbmNsdWRlIDxsaW51eC9yZXNvdXJjZS5oPg0KPiA+PiAjaW5j bHVkZSA8bGludXgvc2lnbmFsLmg+DQo+ID4+ICsjaW5jbHVkZSA8bGludXgvc3lzY29yZV9vcHMu aD4NCj4gPj4gI2luY2x1ZGUgPGxpbnV4L3R5cGVzLmg+DQo+ID4+ICNpbmNsdWRlIDxsaW51eC9p bnRlcnJ1cHQuaD4NCj4gPj4NCj4gPj4gQEAgLTM1LDExICszNywxNSBAQCBzdHJ1Y3QgaW14Nl9w Y2llIHsNCj4gPj4gICAgaW50ICAgICAgICAgICAgcmVzZXRfZ3BpbzsNCj4gPj4gICAgc3RydWN0 IGNsayAgICAgICAgKnBjaWVfYnVzOw0KPiA+PiAgICBzdHJ1Y3QgY2xrICAgICAgICAqcGNpZV9w aHk7DQo+ID4+ICsgICAgc3RydWN0IGNsayAgICAgICAgKnBjaWVfaW5ib3VuZF9heGk7DQo+ID4+ ICAgIHN0cnVjdCBjbGsgICAgICAgICpwY2llOw0KPiA+PiAgICBzdHJ1Y3QgcGNpZV9wb3J0ICAg IHBwOw0KPiA+PiAgICBzdHJ1Y3QgcmVnbWFwICAgICAgICAqaW9tdXhjX2dwcjsNCj4gPj4gKyAg ICBzdHJ1Y3QgcmVnbWFwICAgICAgICAqZ3BjX2lwc19yZWc7DQo+ID4+ICsgICAgc3RydWN0IHJl Z3VsYXRvciAgICAqcGNpZV9yZWd1bGF0b3I7DQo+ID4NCj4gPiBJIHdvdWxkIGV4cGVjdCB0aGlz IHRvIGJlIG5hbWVkIHBjaWVfcGh5X3JlZ3VsYXRvci4NCj4gT2suDQo+ID4NCj4gPj4gICAgdm9p ZCBfX2lvbWVtICAgICAgICAqbWVtX2Jhc2U7DQo+ID4+IH07DQo+ID4+ICtzdGF0aWMgc3RydWN0 IGlteDZfcGNpZSAqaW14Nl9wY2llOw0KPiA+DQo+ID4gTm8uIFRoaXMgaXMganVzdCBiYWQgc3R5 bGUuIFlvdSBoYXZlIHRoZSBwb2ludGVyIGF2YWlsYWJsZSBlbWJlZGRlZCBpbg0KPiA+IG90aGVy IHN0cnVjdHVyZXMgYXQgYWxsIHJlbGV2YW50IHBsYWNlcy4gTm8gZ2xvYmFsIHN0YXRpY3MgcGxl YXNlLg0KPiBPay4NCkhpIEx1Y2FzOg0KUmVnYXJkaW5nIHRvIHRoZSBkZWZpbml0aW9ucyhwYXN0 ZWQgYmVsb3cpIG9mIHRoZSBzdHJ1Y3Qgc3lzY29yZV9vcHMsIGJvdGggc3VzcGVuZCBhbmQgcmVz dW1lDQpvZiB0aGUgc3lzY29yZV9vcHMgaXMgdm9pZCB0eXBlIGZ1bmN0aW9ucy4NCklmIHRoZXJl IGlzIG5vIHRoZSBzdGF0aWMgZ2xvYmFsIHN0cnVjdCBpbXg2X3BjaWUsIEkgZG9uJ3Qga25vdyBo b3cgaXQgY2FuIGJlIHVzZWQgaW4gc3VzcGVuZC9yZXN1bWUgb2YgcGNpX2lteF9zeXNjb3JlX29w cy4NCnN0cnVjdCBzeXNjb3JlX29wcyB7DQogICAgICAgIHN0cnVjdCBsaXN0X2hlYWQgbm9kZTsN CiAgICAgICAgaW50ICgqc3VzcGVuZCkodm9pZCk7DQogICAgICAgIHZvaWQgKCpyZXN1bWUpKHZv aWQpOw0KICAgICAgICB2b2lkICgqc2h1dGRvd24pKHZvaWQpOw0KfTsNCg0KQmVzdCBSZWdhcmRz DQpSaWNoYXJkIFpodQ0KDQo+ID4NCj4gPj4NCj4gPj4gLyogUENJZSBSb290IENvbXBsZXggcmVn aXN0ZXJzIChtZW1vcnktbWFwcGVkKSAqLw0KPiA+PiAjZGVmaW5lIFBDSUVfUkNfTENSICAgICAg ICAgICAgICAgIDB4N2MNCj4gPj4gQEAgLTc3LDYgKzgzLDE4IEBAIHN0cnVjdCBpbXg2X3BjaWUg eyAjZGVmaW5lDQo+ID4+IFBIWV9SWF9PVlJEX0lOX0xPX1JYX0RBVEFfRU4gKDEgPDwgNSkgI2Rl ZmluZQ0KPiA+PiBQSFlfUlhfT1ZSRF9JTl9MT19SWF9QTExfRU4gKDEgPDwgMykNCj4gPj4NCj4g Pj4gKy8qIEdQQyBQQ0lFIFBIWSBiaXQgZGVmaW5pdGlvbnMgKi8NCj4gPj4gKyNkZWZpbmUgR1BD X0NOVFIgICAgICAgICAgICAwDQo+ID4+ICsjZGVmaW5lIEdQQ19DTlRSX1BDSUVfUEhZX1BVUF9S RVEgICAgQklUKDcpDQo+ID4+ICsNCj4gPj4gK3N0YXRpYyBpbmxpbmUgYm9vbCBpc19pbXg2c3hf cGNpZShzdHJ1Y3QgaW14Nl9wY2llICppbXg2X3BjaWUpIHsNCj4gPj4gKyAgICBzdHJ1Y3QgcGNp ZV9wb3J0ICpwcCA9ICZpbXg2X3BjaWUtPnBwOw0KPiA+PiArICAgIHN0cnVjdCBkZXZpY2Vfbm9k ZSAqbnAgPSBwcC0+ZGV2LT5vZl9ub2RlOw0KPiA+PiArDQo+ID4+ICsgICAgcmV0dXJuIG9mX2Rl dmljZV9pc19jb21wYXRpYmxlKG5wLCAiZnNsLGlteDZzeC1wY2llIik7IH0NCj4gPj4gKw0KPiA+ PiBzdGF0aWMgaW50IHBjaWVfcGh5X3BvbGxfYWNrKHZvaWQgX19pb21lbSAqZGJpX2Jhc2UsIGlu dCBleHBfdmFsKSB7DQo+ID4+ICAgIHUzMiB2YWw7DQo+ID4+IEBAIC0yNzUsMTggKzI5MywyOSBA QCBzdGF0aWMgaW50IGlteDZfcGNpZV9kZWFzc2VydF9jb3JlX3Jlc2V0KHN0cnVjdA0KPiBwY2ll X3BvcnQgKnBwKQ0KPiA+PiAgICAgICAgZ290byBlcnJfcGNpZTsNCj4gPj4gICAgfQ0KPiA+Pg0K PiA+PiAtICAgIC8qIHBvd2VyIHVwIGNvcmUgcGh5IGFuZCBlbmFibGUgcmVmIGNsb2NrICovDQo+ ID4+IC0gICAgcmVnbWFwX3VwZGF0ZV9iaXRzKGlteDZfcGNpZS0+aW9tdXhjX2dwciwgSU9NVVhD X0dQUjEsDQo+ID4+IC0gICAgICAgICAgICBJTVg2UV9HUFIxX1BDSUVfVEVTVF9QRCwgMCA8PCAx OCk7DQo+ID4+IC0gICAgLyoNCj4gPj4gLSAgICAgKiB0aGUgYXN5bmMgcmVzZXQgaW5wdXQgbmVl ZCByZWYgY2xvY2sgdG8gc3luYyBpbnRlcm5hbGx5LA0KPiA+PiAtICAgICAqIHdoZW4gdGhlIHJl ZiBjbG9jayBjb21lcyBhZnRlciByZXNldCwgaW50ZXJuYWwgc3luY2VkDQo+ID4+IC0gICAgICog cmVzZXQgdGltZSBpcyB0b28gc2hvcnQgLCBjYW5ub3QgbWVldCB0aGUgcmVxdWlyZW1lbnQuDQo+ ID4+IC0gICAgICogYWRkIG9uZSB+MTB1cyBkZWxheSBoZXJlLg0KPiA+PiAtICAgICAqLw0KPiA+ PiAtICAgIHVkZWxheSgxMCk7DQo+ID4+IC0gICAgcmVnbWFwX3VwZGF0ZV9iaXRzKGlteDZfcGNp ZS0+aW9tdXhjX2dwciwgSU9NVVhDX0dQUjEsDQo+ID4+IC0gICAgICAgICAgICBJTVg2UV9HUFIx X1BDSUVfUkVGX0NMS19FTiwgMSA8PCAxNik7DQo+ID4+ICsgICAgaWYgKGlzX2lteDZzeF9wY2ll KGlteDZfcGNpZSkpIHsNCj4gPj4gKyAgICAgICAgcmV0ID0gY2xrX3ByZXBhcmVfZW5hYmxlKGlt eDZfcGNpZS0+cGNpZV9pbmJvdW5kX2F4aSk7DQo+ID4+ICsgICAgICAgIGlmIChyZXQpIHsNCj4g Pj4gKyAgICAgICAgICAgIGRldl9lcnIocHAtPmRldiwgInVuYWJsZSB0byBlbmFibGUgcGNpZSBj bG9ja1xuIik7DQo+ID4+ICsgICAgICAgICAgICBnb3RvIGVycl9pbmJvdW5kX2F4aTsNCj4gPj4g KyAgICAgICAgfQ0KPiA+PiArDQo+ID4+ICsgICAgICAgIHJlZ21hcF91cGRhdGVfYml0cyhpbXg2 X3BjaWUtPmlvbXV4Y19ncHIsIElPTVVYQ19HUFIxMiwNCj4gPj4gKyAgICAgICAgICAgICAgICBJ TVg2U1hfR1BSMTJfUENJRV9URVNUX1BELCAwKTsNCj4gPj4gKyAgICB9IGVsc2Ugew0KPiA+PiAr ICAgICAgICAvKiBwb3dlciB1cCBjb3JlIHBoeSBhbmQgZW5hYmxlIHJlZiBjbG9jayAqLw0KPiA+ PiArICAgICAgICByZWdtYXBfdXBkYXRlX2JpdHMoaW14Nl9wY2llLT5pb211eGNfZ3ByLCBJT01V WENfR1BSMSwNCj4gPj4gKyAgICAgICAgICAgICAgICBJTVg2UV9HUFIxX1BDSUVfVEVTVF9QRCwg MCk7DQo+ID4+ICsgICAgICAgIC8qDQo+ID4+ICsgICAgICAgICAqIHRoZSBhc3luYyByZXNldCBp bnB1dCBuZWVkIHJlZiBjbG9jayB0byBzeW5jIGludGVybmFsbHksDQo+ID4+ICsgICAgICAgICAq IHdoZW4gdGhlIHJlZiBjbG9jayBjb21lcyBhZnRlciByZXNldCwgaW50ZXJuYWwgc3luY2VkDQo+ ID4+ICsgICAgICAgICAqIHJlc2V0IHRpbWUgaXMgdG9vIHNob3J0ICwgY2Fubm90IG1lZXQgdGhl IHJlcXVpcmVtZW50Lg0KPiA+PiArICAgICAgICAgKiBhZGQgb25lIH4xMHVzIGRlbGF5IGhlcmUu DQo+ID4+ICsgICAgICAgICAqLw0KPiA+PiArICAgICAgICB1ZGVsYXkoMTApOw0KPiA+PiArICAg ICAgICByZWdtYXBfdXBkYXRlX2JpdHMoaW14Nl9wY2llLT5pb211eGNfZ3ByLCBJT01VWENfR1BS MSwNCj4gPj4gKyAgICAgICAgICAgICAgICBJTVg2UV9HUFIxX1BDSUVfUkVGX0NMS19FTiwgMSA8 PCAxNik7DQo+ID4+ICsgICAgfQ0KPiA+Pg0KPiA+PiAgICAvKiBhbGxvdyB0aGUgY2xvY2tzIHRv IHN0YWJpbGl6ZSAqLw0KPiA+PiAgICB1c2xlZXBfcmFuZ2UoMjAwLCA1MDApOw0KPiA+PiBAQCAt Mjk3LDggKzMyNiwxOSBAQCBzdGF0aWMgaW50IGlteDZfcGNpZV9kZWFzc2VydF9jb3JlX3Jlc2V0 KHN0cnVjdA0KPiBwY2llX3BvcnQgKnBwKQ0KPiA+PiAgICAgICAgbXNsZWVwKDEwMCk7DQo+ID4+ ICAgICAgICBncGlvX3NldF92YWx1ZShpbXg2X3BjaWUtPnJlc2V0X2dwaW8sIDEpOw0KPiA+PiAg ICB9DQo+ID4+ICsNCj4gPj4gKyAgICAvKg0KPiA+PiArICAgICAqIFJlbGVhc2UgdGhlIFBDSWUg UEhZIHJlc2V0IGhlcmUsIHRoYXQgd2UgaGF2ZSBzZXQgaW4NCj4gPj4gKyAgICAgKiBpbXg2X3Bj aWVfaW5pdF9waHkoKSBub3cNCj4gPj4gKyAgICAgKi8NCj4gPj4gKyAgICBpZiAoaXNfaW14NnN4 X3BjaWUoaW14Nl9wY2llKSkNCj4gPj4gKyAgICAgICAgcmVnbWFwX3VwZGF0ZV9iaXRzKGlteDZf cGNpZS0+aW9tdXhjX2dwciwgSU9NVVhDX0dQUjUsDQo+ID4+ICsgICAgICAgICAgICAgICAgSU1Y NlNYX0dQUjVfUENJRV9CVE5SU1QsIDApOw0KPiA+PiArDQo+ID4+ICAgIHJldHVybiAwOw0KPiA+ Pg0KPiA+PiArZXJyX2luYm91bmRfYXhpOg0KPiA+PiArICAgIGNsa19kaXNhYmxlX3VucHJlcGFy ZShpbXg2X3BjaWUtPnBjaWUpOw0KPiA+PiBlcnJfcGNpZToNCj4gPj4gICAgY2xrX2Rpc2FibGVf dW5wcmVwYXJlKGlteDZfcGNpZS0+cGNpZV9idXMpOw0KPiA+PiBlcnJfcGNpZV9idXM6DQo+ID4+ IEBAIC0zMTEsNiArMzUxLDI2IEBAIGVycl9wY2llX3BoeToNCj4gPj4gc3RhdGljIHZvaWQgaW14 Nl9wY2llX2luaXRfcGh5KHN0cnVjdCBwY2llX3BvcnQgKnBwKSB7DQo+ID4+ICAgIHN0cnVjdCBp bXg2X3BjaWUgKmlteDZfcGNpZSA9IHRvX2lteDZfcGNpZShwcCk7DQo+ID4+ICsgICAgaW50IHJl dDsNCj4gPj4gKw0KPiA+PiArICAgIC8qIFBvd2VyIHVwIHRoZSBzZXBhcmF0ZSBkb21haW4gYXZh aWxhYmxlIG9uIGkuTVg2U1ggKi8NCj4gPj4gKyAgICBpZiAoaXNfaW14NnN4X3BjaWUoaW14Nl9w Y2llKSkgew0KPiA+PiArICAgICAgICAvKiBGb3JjZSBQQ0llIFBIWSByZXNldCAqLw0KPiA+PiAr ICAgICAgICByZWdtYXBfdXBkYXRlX2JpdHMoaW14Nl9wY2llLT5pb211eGNfZ3ByLCBJT01VWENf R1BSNSwNCj4gPj4gKyAgICAgICAgICAgICAgICBJTVg2U1hfR1BSNV9QQ0lFX0JUTlJTVCwNCj4g Pj4gKyAgICAgICAgICAgICAgICBJTVg2U1hfR1BSNV9QQ0lFX0JUTlJTVCk7DQo+ID4+ICsNCj4g Pj4gKyAgICAgICAgcmVnbWFwX3VwZGF0ZV9iaXRzKGlteDZfcGNpZS0+Z3BjX2lwc19yZWcsIEdQ Q19DTlRSLA0KPiA+PiArICAgICAgICAgICAgICAgIEdQQ19DTlRSX1BDSUVfUEhZX1BVUF9SRVEs DQo+ID4+ICsgICAgICAgICAgICAgICAgR1BDX0NOVFJfUENJRV9QSFlfUFVQX1JFUSk7DQo+ID4+ ICsgICAgICAgIHJlZ3VsYXRvcl9zZXRfdm9sdGFnZShpbXg2X3BjaWUtPnBjaWVfcmVndWxhdG9y LA0KPiA+PiArICAgICAgICAgICAgICAgIDExMDAwMDAsIDExMDAwMDApOw0KPiA+PiArICAgICAg ICByZXQgPSByZWd1bGF0b3JfZW5hYmxlKGlteDZfcGNpZS0+cGNpZV9yZWd1bGF0b3IpOw0KPiA+ PiArICAgICAgICBpZiAocmV0KQ0KPiA+PiArICAgICAgICAgICAgZGV2X2luZm8ocHAtPmRldiwg ImZhaWxlZCB0byBlbmFibGUgcGNpZSByZWd1bGF0b3IuXG4iKTsNCj4gPj4gKyAgICAgICAgcmVn bWFwX3VwZGF0ZV9iaXRzKGlteDZfcGNpZS0+aW9tdXhjX2dwciwgSU9NVVhDX0dQUjEyLA0KPiA+ PiArICAgICAgICAgICAgICAgIElNWDZTWF9HUFIxMl9SWF9FUV9NQVNLLCBJTVg2U1hfR1BSMTJf UlhfRVFfMik7DQo+ID4+ICsgICAgfQ0KPiA+Pg0KPiA+PiAgICByZWdtYXBfdXBkYXRlX2JpdHMo aW14Nl9wY2llLT5pb211eGNfZ3ByLCBJT01VWENfR1BSMTIsDQo+ID4+ICAgICAgICAgICAgSU1Y NlFfR1BSMTJfUENJRV9DVExfMiwgMCA8PCAxMCk7IEBAIC0zMTksNyArMzc5LDcgQEANCj4gPj4g c3RhdGljIHZvaWQgaW14Nl9wY2llX2luaXRfcGh5KHN0cnVjdCBwY2llX3BvcnQgKnBwKQ0KPiA+ PiAgICByZWdtYXBfdXBkYXRlX2JpdHMoaW14Nl9wY2llLT5pb211eGNfZ3ByLCBJT01VWENfR1BS MTIsDQo+ID4+ICAgICAgICAgICAgSU1YNlFfR1BSMTJfREVWSUNFX1RZUEUsIFBDSV9FWFBfVFlQ RV9ST09UX1BPUlQgPDwgMTIpOw0KPiA+PiAgICByZWdtYXBfdXBkYXRlX2JpdHMoaW14Nl9wY2ll LT5pb211eGNfZ3ByLCBJT01VWENfR1BSMTIsDQo+ID4+IC0gICAgICAgICAgICBJTVg2UV9HUFIx Ml9MT1NfTEVWRUwsIDkgPDwgNCk7DQo+ID4+ICsgICAgICAgICAgICBJTVg2UV9HUFIxMl9MT1Nf TEVWRUwsIElNWDZRX0dQUjEyX0xPU19MRVZFTF85KTsNCj4gPj4NCj4gPj4gICAgcmVnbWFwX3Vw ZGF0ZV9iaXRzKGlteDZfcGNpZS0+aW9tdXhjX2dwciwgSU9NVVhDX0dQUjgsDQo+ID4+ICAgICAg ICAgICAgSU1YNlFfR1BSOF9UWF9ERUVNUEhfR0VOMSwgMCA8PCAwKTsgQEAgLTM3Nyw3ICs0Mzcs OCBAQA0KPiA+PiBzdGF0aWMgaW50IGlteDZfcGNpZV9zdGFydF9saW5rKHN0cnVjdCBwY2llX3Bv cnQgKnBwKQ0KPiA+Pg0KPiA+PiAgICAvKiBTdGFydCBMVFNTTS4gKi8NCj4gPj4gICAgcmVnbWFw X3VwZGF0ZV9iaXRzKGlteDZfcGNpZS0+aW9tdXhjX2dwciwgSU9NVVhDX0dQUjEyLA0KPiA+PiAt ICAgICAgICAgICAgSU1YNlFfR1BSMTJfUENJRV9DVExfMiwgMSA8PCAxMCk7DQo+ID4+ICsgICAg ICAgICAgICBJTVg2UV9HUFIxMl9QQ0lFX0NUTF8yLA0KPiA+PiArICAgICAgICAgICAgSU1YNlFf R1BSMTJfUENJRV9DVExfMik7DQo+ID4+DQo+ID4+ICAgIHJldCA9IGlteDZfcGNpZV93YWl0X2Zv cl9saW5rKHBwKTsNCj4gPj4gICAgaWYgKHJldCkNCj4gPj4gQEAgLTU1Myw5ICs2MTQsNTAgQEAg c3RhdGljIGludCBfX2luaXQgaW14Nl9hZGRfcGNpZV9wb3J0KHN0cnVjdCBwY2llX3BvcnQNCj4g KnBwLA0KPiA+PiAgICByZXR1cm4gMDsNCj4gPj4gfQ0KPiA+Pg0KPiA+PiArI2lmZGVmIENPTkZJ R19QTV9TTEVFUA0KPiA+PiArc3RhdGljIGludCBwY2lfaW14X3N1c3BlbmQodm9pZCkNCj4gPj4g K3sNCj4gPj4gKyAgICBpZiAoaXNfaW14NnN4X3BjaWUoaW14Nl9wY2llKSkgew0KPiA+PiArICAg ICAgICAvKiBQTV9UVVJOX09GRiAqLw0KPiA+PiArICAgICAgICByZWdtYXBfdXBkYXRlX2JpdHMo aW14Nl9wY2llLT5pb211eGNfZ3ByLCBJT01VWENfR1BSMTIsDQo+ID4+ICsgICAgICAgICAgICAg ICAgSU1YNlNYX0dQUjEyX1BDSUVfUE1fVFVSTl9PRkYsDQo+ID4+ICsgICAgICAgICAgICAgICAg SU1YNlNYX0dQUjEyX1BDSUVfUE1fVFVSTl9PRkYpOw0KPiA+PiArICAgICAgICB1ZGVsYXkoMTAp Ow0KPiA+PiArICAgICAgICByZWdtYXBfdXBkYXRlX2JpdHMoaW14Nl9wY2llLT5pb211eGNfZ3By LCBJT01VWENfR1BSMTIsDQo+ID4+ICsgICAgICAgICAgICAgICAgSU1YNlNYX0dQUjEyX1BDSUVf UE1fVFVSTl9PRkYsIDApOw0KPiA+PiArICAgIH0NCj4gPj4gKw0KPiA+PiArICAgIHJldHVybiAw Ow0KPiA+PiArfQ0KPiA+PiArDQo+ID4+ICtzdGF0aWMgdm9pZCBwY2lfaW14X3Jlc3VtZSh2b2lk KQ0KPiA+PiArew0KPiA+PiArICAgIHN0cnVjdCBwY2llX3BvcnQgKnBwID0gJmlteDZfcGNpZS0+ cHA7DQo+ID4+ICsNCj4gPj4gKyAgICBpZiAoaXNfaW14NnN4X3BjaWUoaW14Nl9wY2llKSkgew0K PiA+PiArICAgICAgICAvKiBSZXNldCBpTVg2U1ggUENJZSAqLw0KPiA+PiArICAgICAgICByZWdt YXBfdXBkYXRlX2JpdHMoaW14Nl9wY2llLT5pb211eGNfZ3ByLCBJT01VWENfR1BSNSwNCj4gPj4g KyAgICAgICAgICAgICAgICBJTVg2U1hfR1BSNV9QQ0lFX1BFUlNULCBJTVg2U1hfR1BSNV9QQ0lF X1BFUlNUKTsNCj4gPj4gKyAgICAgICAgcmVnbWFwX3VwZGF0ZV9iaXRzKGlteDZfcGNpZS0+aW9t dXhjX2dwciwgSU9NVVhDX0dQUjUsDQo+ID4+ICsgICAgICAgICAgICAgICAgSU1YNlNYX0dQUjVf UENJRV9QRVJTVCwgMCk7DQo+ID4+ICsgICAgICAgIC8qDQo+ID4+ICsgICAgICAgICAqIGNvbnRy b2xsZXIgbWF5YmUgdHVybiBvZmYsIHJlLWNvbmZpZ3VyZSBhZ2Fpbg0KPiA+PiArICAgICAgICAg Ki8NCj4gPj4gKyAgICAgICAgZHdfcGNpZV9zZXR1cF9yYyhwcCk7DQo+ID4+ICsNCj4gPj4gKyAg ICAgICAgaWYgKElTX0VOQUJMRUQoQ09ORklHX1BDSV9NU0kpKQ0KPiA+PiArICAgICAgICAgICAg ZHdfcGNpZV9tc2lfY2ZnX3Jlc3RvcmUocHApOw0KPiA+PiArICAgIH0NCj4gPj4gK30NCj4gPj4g Kw0KPiA+PiArc3RhdGljIHN0cnVjdCBzeXNjb3JlX29wcyBwY2lfaW14X3N5c2NvcmVfb3BzID0g ew0KPiA+PiArICAgIC5zdXNwZW5kID0gcGNpX2lteF9zdXNwZW5kLA0KPiA+PiArICAgIC5yZXN1 bWUgPSBwY2lfaW14X3Jlc3VtZSwNCj4gPj4gK307DQo+ID4+ICsjZW5kaWYNCj4gPj4gKw0KPiA+ PiBzdGF0aWMgaW50IF9faW5pdCBpbXg2X3BjaWVfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2Rldmlj ZSAqcGRldikgew0KPiA+PiAtICAgIHN0cnVjdCBpbXg2X3BjaWUgKmlteDZfcGNpZTsNCj4gPj4g ICAgc3RydWN0IHBjaWVfcG9ydCAqcHA7DQo+ID4+ICAgIHN0cnVjdCBkZXZpY2Vfbm9kZSAqbnAg PSBwZGV2LT5kZXYub2Zfbm9kZTsNCj4gPj4gICAgc3RydWN0IHJlc291cmNlICpkYmlfYmFzZTsN Cj4gPj4gQEAgLTU3Miw3ICs2NzQsNyBAQCBzdGF0aWMgaW50IF9faW5pdCBpbXg2X3BjaWVfcHJv YmUoc3RydWN0DQo+IHBsYXRmb3JtX2RldmljZSAqcGRldikNCj4gPj4gICAgaG9va19mYXVsdF9j b2RlKDE2ICsgNiwgaW14NnFfcGNpZV9hYm9ydF9oYW5kbGVyLCBTSUdCVVMsIDAsDQo+ID4+ICAg ICAgICAiaW1wcmVjaXNlIGV4dGVybmFsIGFib3J0Iik7DQo+ID4+DQo+ID4+IC0gICAgZGJpX2Jh c2UgPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDApOw0KPiA+ PiArICAgIGRiaV9iYXNlID0gcGxhdGZvcm1fZ2V0X3Jlc291cmNlX2J5bmFtZShwZGV2LCBJT1JF U09VUkNFX01FTSwNCj4gPj4gKyAicmNfZGJpIik7DQo+ID4NCj4gPiBZb3UgYXJlIGJyZWFraW5n IG9sZCBkZXZpY2V0cmVlcyBoZXJlLiAicmNfZGJpIiBpc24ndCBhIGRvY3VtZW50ZWQNCj4gPiBu YW1lIGFuZCBpc24ndCBhdmFpbGFibGUgb24gb2xkIERUcy4gQmVzaWRlcyB0aGUgaW14NnEgRFQg dXNlcyBqdXN0DQo+ID4gImRiaSIgYXMgdGhlIG5hbWUuIERvbid0IHRvdWNoIHRoaXMgY29kZSwg aXQgZG9lcyBleGFjdGx5IHRoZSByaWdodA0KPiA+IHRoaW5nIGJ5IGdyYWJiaW5nIHRoZSBmaXJz dCByZWcgcmVzb3VyY2UuDQo+IA0KPiBPaywgY2hhbmdlcyB3b3VsZCBiZSByZW1vdmVkLg0KPiAN Cj4gPg0KPiA+PiAgICBwcC0+ZGJpX2Jhc2UgPSBkZXZtX2lvcmVtYXBfcmVzb3VyY2UoJnBkZXYt PmRldiwgZGJpX2Jhc2UpOw0KPiA+PiAgICBpZiAoSVNfRVJSKHBwLT5kYmlfYmFzZSkpDQo+ID4+ ICAgICAgICByZXR1cm4gUFRSX0VSUihwcC0+ZGJpX2Jhc2UpOw0KPiA+PiBAQCAtNjEwLDkgKzcx MiwyOCBAQCBzdGF0aWMgaW50IF9faW5pdCBpbXg2X3BjaWVfcHJvYmUoc3RydWN0DQo+IHBsYXRm b3JtX2RldmljZSAqcGRldikNCj4gPj4gICAgICAgIHJldHVybiBQVFJfRVJSKGlteDZfcGNpZS0+ cGNpZSk7DQo+ID4+ICAgIH0NCj4gPj4NCj4gPj4gLSAgICAvKiBHcmFiIEdQUiBjb25maWcgcmVn aXN0ZXIgcmFuZ2UgKi8NCj4gPj4gLSAgICBpbXg2X3BjaWUtPmlvbXV4Y19ncHIgPQ0KPiA+PiAt ICAgICAgICAgc3lzY29uX3JlZ21hcF9sb29rdXBfYnlfY29tcGF0aWJsZSgiZnNsLGlteDZxLWlv bXV4Yy1ncHIiKTsNCj4gPj4gKyAgICBpZiAoaXNfaW14NnN4X3BjaWUoaW14Nl9wY2llKSkgew0K PiA+PiArICAgICAgICBpbXg2X3BjaWUtPnBjaWVfaW5ib3VuZF9heGkgPSBkZXZtX2Nsa19nZXQo JnBkZXYtPmRldiwNCj4gPj4gKyAgICAgICAgICAgICAgICAicGNpZV9pbmJvdW5kX2F4aSIpOw0K PiA+PiArICAgICAgICBpZiAoSVNfRVJSKGlteDZfcGNpZS0+cGNpZV9pbmJvdW5kX2F4aSkpIHsN Cj4gPj4gKyAgICAgICAgICAgIGRldl9lcnIoJnBkZXYtPmRldiwNCj4gPj4gKyAgICAgICAgICAg ICAgICAicGNpZSBjbG9jayBzb3VyY2UgbWlzc2luZyBvciBpbnZhbGlkXG4iKTsNCj4gPj4gKyAg ICAgICAgICAgIHJldHVybiBQVFJfRVJSKGlteDZfcGNpZS0+cGNpZV9pbmJvdW5kX2F4aSk7DQo+ ID4+ICsgICAgICAgIH0NCj4gPj4gKw0KPiA+PiArICAgICAgICBpbXg2X3BjaWUtPnBjaWVfcmVn dWxhdG9yID0gZGV2bV9yZWd1bGF0b3JfZ2V0KHBwLT5kZXYsDQo+ID4+ICsgICAgICAgICAgICAg ICAgInBjaWUtcGh5Iik7DQo+ID4+ICsNCj4gPj4gKyAgICAgICAgaW14Nl9wY2llLT5pb211eGNf Z3ByID0NCj4gPj4gKyAgICAgICAgICAgICBzeXNjb25fcmVnbWFwX2xvb2t1cF9ieV9jb21wYXRp YmxlDQo+ID4+ICsgICAgICAgICAgICAgKCJmc2wsaW14NnN4LWlvbXV4Yy1ncHIiKTsNCj4gPj4g KyAgICAgICAgaW14Nl9wY2llLT5ncGNfaXBzX3JlZyA9DQo+ID4+ICsgICAgICAgICAgICAgc3lz Y29uX3JlZ21hcF9sb29rdXBfYnlfY29tcGF0aWJsZSgiZnNsLGlteDZzeC1ncGMiKTsNCj4gPj4g KyAgICB9IGVsc2Ugew0KPiA+PiArICAgICAgICBpbXg2X3BjaWUtPmlvbXV4Y19ncHIgPQ0KPiA+ PiArICAgICAgICAgICAgc3lzY29uX3JlZ21hcF9sb29rdXBfYnlfY29tcGF0aWJsZQ0KPiA+PiAr ICAgICAgICAgICAgKCJmc2wsaW14NnEtaW9tdXhjLWdwciIpOw0KPiA+PiArICAgIH0NCj4gPj4g ICAgaWYgKElTX0VSUihpbXg2X3BjaWUtPmlvbXV4Y19ncHIpKSB7DQo+ID4+ICAgICAgICBkZXZf ZXJyKCZwZGV2LT5kZXYsICJ1bmFibGUgdG8gZmluZCBpb211eGMgcmVnaXN0ZXJzXG4iKTsNCj4g Pj4gICAgICAgIHJldHVybiBQVFJfRVJSKGlteDZfcGNpZS0+aW9tdXhjX2dwcik7IEBAIC02MjMs NiArNzQ0LDkgQEANCj4gPj4gc3RhdGljIGludCBfX2luaXQgaW14Nl9wY2llX3Byb2JlKHN0cnVj dCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpDQo+ID4+ICAgICAgICByZXR1cm4gcmV0Ow0KPiA+Pg0K PiA+PiAgICBwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShwZGV2LCBpbXg2X3BjaWUpOw0KPiA+PiArI2lm ZGVmIENPTkZJR19QTV9TTEVFUA0KPiA+PiArICAgIHJlZ2lzdGVyX3N5c2NvcmVfb3BzKCZwY2lf aW14X3N5c2NvcmVfb3BzKTsNCj4gPj4gKyNlbmRpZg0KPiA+PiAgICByZXR1cm4gMDsNCj4gPj4g fQ0KPiA+Pg0KPiA+PiBAQCAtNjM2LDYgKzc2MCw3IEBAIHN0YXRpYyB2b2lkIGlteDZfcGNpZV9z aHV0ZG93bihzdHJ1Y3QNCj4gPj4gcGxhdGZvcm1fZGV2aWNlICpwZGV2KQ0KPiA+Pg0KPiA+PiBz dGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBpbXg2X3BjaWVfb2ZfbWF0Y2hbXSA9IHsN Cj4gPj4gICAgeyAuY29tcGF0aWJsZSA9ICJmc2wsaW14NnEtcGNpZSIsIH0sDQo+ID4+ICsgICAg eyAuY29tcGF0aWJsZSA9ICJmc2wsaW14NnN4LXBjaWUiLCB9LA0KPiA+PiAgICB7fSwNCj4gPj4g fTsNCj4gPj4gTU9EVUxFX0RFVklDRV9UQUJMRShvZiwgaW14Nl9wY2llX29mX21hdGNoKTsNCj4g Pg0KPiA+IC0tDQo+ID4gUGVuZ3V0cm9uaXggZS5LLiAgICAgICAgICAgICB8IEx1Y2FzIFN0YWNo ICAgICAgICAgICAgICAgICB8DQo+ID4gSW5kdXN0cmlhbCBMaW51eCBTb2x1dGlvbnMgICB8IGh0 dHA6Ly93d3cucGVuZ3V0cm9uaXguZGUvICB8DQo+ID4NCj4gPg0KPiBCZXN0IHJlZ2FyZHMNCj4g UmljaGFyZA0K -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index eac96fb..c74e87d 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c @@ -22,8 +22,10 @@ #include <linux/pci.h> #include <linux/platform_device.h> #include <linux/regmap.h> +#include <linux/regulator/consumer.h> #include <linux/resource.h> #include <linux/signal.h> +#include <linux/syscore_ops.h> #include <linux/types.h> #include <linux/interrupt.h> @@ -35,11 +37,15 @@ struct imx6_pcie { int reset_gpio; struct clk *pcie_bus; struct clk *pcie_phy; + struct clk *pcie_inbound_axi; struct clk *pcie; struct pcie_port pp; struct regmap *iomuxc_gpr; + struct regmap *gpc_ips_reg; + struct regulator *pcie_regulator; void __iomem *mem_base; }; +static struct imx6_pcie *imx6_pcie; /* PCIe Root Complex registers (memory-mapped) */ #define PCIE_RC_LCR 0x7c @@ -77,6 +83,18 @@ struct imx6_pcie { #define PHY_RX_OVRD_IN_LO_RX_DATA_EN (1 << 5) #define PHY_RX_OVRD_IN_LO_RX_PLL_EN (1 << 3) +/* GPC PCIE PHY bit definitions */ +#define GPC_CNTR 0 +#define GPC_CNTR_PCIE_PHY_PUP_REQ BIT(7) + +static inline bool is_imx6sx_pcie(struct imx6_pcie *imx6_pcie) +{ + struct pcie_port *pp = &imx6_pcie->pp; + struct device_node *np = pp->dev->of_node; + + return of_device_is_compatible(np, "fsl,imx6sx-pcie"); +} + static int pcie_phy_poll_ack(void __iomem *dbi_base, int exp_val) { u32 val; @@ -275,18 +293,29 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp) goto err_pcie; } - /* power up core phy and enable ref clock */ - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, - IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18); - /* - * the async reset input need ref clock to sync internally, - * when the ref clock comes after reset, internal synced - * reset time is too short , cannot meet the requirement. - * add one ~10us delay here. - */ - udelay(10); - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, - IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16); + if (is_imx6sx_pcie(imx6_pcie)) { + ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi); + if (ret) { + dev_err(pp->dev, "unable to enable pcie clock\n"); + goto err_inbound_axi; + } + + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, + IMX6SX_GPR12_PCIE_TEST_PD, 0); + } else { + /* power up core phy and enable ref clock */ + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_TEST_PD, 0); + /* + * the async reset input need ref clock to sync internally, + * when the ref clock comes after reset, internal synced + * reset time is too short , cannot meet the requirement. + * add one ~10us delay here. + */ + udelay(10); + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16); + } /* allow the clocks to stabilize */ usleep_range(200, 500); @@ -297,8 +326,19 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp) msleep(100); gpio_set_value(imx6_pcie->reset_gpio, 1); } + + /* + * Release the PCIe PHY reset here, that we have set in + * imx6_pcie_init_phy() now + */ + if (is_imx6sx_pcie(imx6_pcie)) + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5, + IMX6SX_GPR5_PCIE_BTNRST, 0); + return 0; +err_inbound_axi: + clk_disable_unprepare(imx6_pcie->pcie); err_pcie: clk_disable_unprepare(imx6_pcie->pcie_bus); err_pcie_bus: @@ -311,6 +351,26 @@ err_pcie_phy: static void imx6_pcie_init_phy(struct pcie_port *pp) { struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp); + int ret; + + /* Power up the separate domain available on i.MX6SX */ + if (is_imx6sx_pcie(imx6_pcie)) { + /* Force PCIe PHY reset */ + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5, + IMX6SX_GPR5_PCIE_BTNRST, + IMX6SX_GPR5_PCIE_BTNRST); + + regmap_update_bits(imx6_pcie->gpc_ips_reg, GPC_CNTR, + GPC_CNTR_PCIE_PHY_PUP_REQ, + GPC_CNTR_PCIE_PHY_PUP_REQ); + regulator_set_voltage(imx6_pcie->pcie_regulator, + 1100000, 1100000); + ret = regulator_enable(imx6_pcie->pcie_regulator); + if (ret) + dev_info(pp->dev, "failed to enable pcie regulator.\n"); + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, + IMX6SX_GPR12_RX_EQ_MASK, IMX6SX_GPR12_RX_EQ_2); + } regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, IMX6Q_GPR12_PCIE_CTL_2, 0 << 10); @@ -319,7 +379,7 @@ static void imx6_pcie_init_phy(struct pcie_port *pp) regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, IMX6Q_GPR12_DEVICE_TYPE, PCI_EXP_TYPE_ROOT_PORT << 12); regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, - IMX6Q_GPR12_LOS_LEVEL, 9 << 4); + IMX6Q_GPR12_LOS_LEVEL, IMX6Q_GPR12_LOS_LEVEL_9); regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, IMX6Q_GPR8_TX_DEEMPH_GEN1, 0 << 0); @@ -377,7 +437,8 @@ static int imx6_pcie_start_link(struct pcie_port *pp) /* Start LTSSM. */ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, - IMX6Q_GPR12_PCIE_CTL_2, 1 << 10); + IMX6Q_GPR12_PCIE_CTL_2, + IMX6Q_GPR12_PCIE_CTL_2); ret = imx6_pcie_wait_for_link(pp); if (ret) @@ -553,9 +614,50 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp, return 0; } +#ifdef CONFIG_PM_SLEEP +static int pci_imx_suspend(void) +{ + if (is_imx6sx_pcie(imx6_pcie)) { + /* PM_TURN_OFF */ + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, + IMX6SX_GPR12_PCIE_PM_TURN_OFF, + IMX6SX_GPR12_PCIE_PM_TURN_OFF); + udelay(10); + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, + IMX6SX_GPR12_PCIE_PM_TURN_OFF, 0); + } + + return 0; +} + +static void pci_imx_resume(void) +{ + struct pcie_port *pp = &imx6_pcie->pp; + + if (is_imx6sx_pcie(imx6_pcie)) { + /* Reset iMX6SX PCIe */ + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5, + IMX6SX_GPR5_PCIE_PERST, IMX6SX_GPR5_PCIE_PERST); + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5, + IMX6SX_GPR5_PCIE_PERST, 0); + /* + * controller maybe turn off, re-configure again + */ + dw_pcie_setup_rc(pp); + + if (IS_ENABLED(CONFIG_PCI_MSI)) + dw_pcie_msi_cfg_restore(pp); + } +} + +static struct syscore_ops pci_imx_syscore_ops = { + .suspend = pci_imx_suspend, + .resume = pci_imx_resume, +}; +#endif + static int __init imx6_pcie_probe(struct platform_device *pdev) { - struct imx6_pcie *imx6_pcie; struct pcie_port *pp; struct device_node *np = pdev->dev.of_node; struct resource *dbi_base; @@ -572,7 +674,7 @@ static int __init imx6_pcie_probe(struct platform_device *pdev) hook_fault_code(16 + 6, imx6q_pcie_abort_handler, SIGBUS, 0, "imprecise external abort"); - dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); + dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbi"); pp->dbi_base = devm_ioremap_resource(&pdev->dev, dbi_base); if (IS_ERR(pp->dbi_base)) return PTR_ERR(pp->dbi_base); @@ -610,9 +712,28 @@ static int __init imx6_pcie_probe(struct platform_device *pdev) return PTR_ERR(imx6_pcie->pcie); } - /* Grab GPR config register range */ - imx6_pcie->iomuxc_gpr = - syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr"); + if (is_imx6sx_pcie(imx6_pcie)) { + imx6_pcie->pcie_inbound_axi = devm_clk_get(&pdev->dev, + "pcie_inbound_axi"); + if (IS_ERR(imx6_pcie->pcie_inbound_axi)) { + dev_err(&pdev->dev, + "pcie clock source missing or invalid\n"); + return PTR_ERR(imx6_pcie->pcie_inbound_axi); + } + + imx6_pcie->pcie_regulator = devm_regulator_get(pp->dev, + "pcie-phy"); + + imx6_pcie->iomuxc_gpr = + syscon_regmap_lookup_by_compatible + ("fsl,imx6sx-iomuxc-gpr"); + imx6_pcie->gpc_ips_reg = + syscon_regmap_lookup_by_compatible("fsl,imx6sx-gpc"); + } else { + imx6_pcie->iomuxc_gpr = + syscon_regmap_lookup_by_compatible + ("fsl,imx6q-iomuxc-gpr"); + } if (IS_ERR(imx6_pcie->iomuxc_gpr)) { dev_err(&pdev->dev, "unable to find iomuxc registers\n"); return PTR_ERR(imx6_pcie->iomuxc_gpr); @@ -623,6 +744,9 @@ static int __init imx6_pcie_probe(struct platform_device *pdev) return ret; platform_set_drvdata(pdev, imx6_pcie); +#ifdef CONFIG_PM_SLEEP + register_syscore_ops(&pci_imx_syscore_ops); +#endif return 0; } @@ -636,6 +760,7 @@ static void imx6_pcie_shutdown(struct platform_device *pdev) static const struct of_device_id imx6_pcie_of_match[] = { { .compatible = "fsl,imx6q-pcie", }, + { .compatible = "fsl,imx6sx-pcie", }, {}, }; MODULE_DEVICE_TABLE(of, imx6_pcie_of_match);
- imx6sx pcie has its own standalone pcie power supply. In order to turn on the imx6sx pcie power during initialization. Add the pcie regulator and the gpc regmap into the imx6sx pcie structure. - imx6sx pcie has the new added reset mechanism, add the reset operations into the initialization. - Register one PM call-back, enter/exit L2 state of the ASPM during system suspend/resume. - disp_axi clock is required by pcie inbound axi port actually. Add one more clock named pcie_inbound_axi for imx6sx pcie. Signed-off-by: Richard Zhu <r65037@freescale.com> --- drivers/pci/host/pci-imx6.c | 163 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 144 insertions(+), 19 deletions(-)