diff mbox series

[7/9] PCI: imx6: Add i.MX6Q and i.MX6QP PCIe EP supports

Message ID 1690956412-2439-8-git-send-email-hongxing.zhu@nxp.com
State New
Headers show
Series Add legacy i.MX PCIe EP mode supports | expand

Commit Message

Hongxing Zhu Aug. 2, 2023, 6:06 a.m. UTC
Add i.MX6Q and i.MX6QP PCIe EP supports.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
---
 drivers/pci/controller/dwc/pci-imx6.c | 61 ++++++++++++++++++++++++++-
 1 file changed, 60 insertions(+), 1 deletion(-)

Comments

Frank Li Aug. 2, 2023, 9:54 p.m. UTC | #1
On Wed, Aug 02, 2023 at 02:06:49PM +0800, Richard Zhu wrote:
> Add i.MX6Q and i.MX6QP PCIe EP supports.
> 
> Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> ---
>  drivers/pci/controller/dwc/pci-imx6.c | 61 ++++++++++++++++++++++++++-
>  1 file changed, 60 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index 27aaa2a6bf39..4da9553b49b4 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -46,8 +46,10 @@
>  
>  enum imx6_pcie_variants {
>  	IMX6Q,
> +	IMX6Q_EP,
>  	IMX6SX,
>  	IMX6QP,
> +	IMX6QP_EP,
>  	IMX7D,
>  	IMX8MQ,
>  	IMX8MM,
> @@ -567,7 +569,9 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
>  				   IMX6SX_GPR12_PCIE_TEST_POWERDOWN, 0);
>  		break;
>  	case IMX6QP:
> +	case IMX6QP_EP:
>  	case IMX6Q:
> +	case IMX6Q_EP:
>  		/* power up core phy and enable ref clock */
>  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
>  				   IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
> @@ -619,7 +623,9 @@ static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie)
>  		clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
>  		break;
>  	case IMX6QP:
> +	case IMX6QP_EP:
>  	case IMX6Q:
> +	case IMX6Q_EP:
>  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
>  				IMX6Q_GPR1_PCIE_REF_CLK_EN, 0);
>  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
> @@ -720,11 +726,13 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
>  				   IMX6SX_GPR5_PCIE_BTNRST_RESET);
>  		break;
>  	case IMX6QP:
> +	case IMX6QP_EP:
>  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
>  				   IMX6Q_GPR1_PCIE_SW_RST,
>  				   IMX6Q_GPR1_PCIE_SW_RST);
>  		break;
>  	case IMX6Q:
> +	case IMX6Q_EP:
>  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
>  				   IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18);
>  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
> @@ -777,12 +785,14 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
>  				   IMX6SX_GPR5_PCIE_BTNRST_RESET, 0);
>  		break;
>  	case IMX6QP:
> +	case IMX6QP_EP:
>  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
>  				   IMX6Q_GPR1_PCIE_SW_RST, 0);
>  
>  		usleep_range(200, 500);
>  		break;
>  	case IMX6Q:		/* Nothing to do */
> +	case IMX6Q_EP:
>  	case IMX8MM:
>  	case IMX8MM_EP:
>  	case IMX8MP:
> @@ -827,8 +837,10 @@ static void imx6_pcie_ltssm_enable(struct device *dev)
>  
>  	switch (imx6_pcie->drvdata->variant) {
>  	case IMX6Q:
> +	case IMX6Q_EP:
>  	case IMX6SX:
>  	case IMX6QP:
> +	case IMX6QP_EP:
>  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
>  				   IMX6Q_GPR12_PCIE_CTL_2,
>  				   IMX6Q_GPR12_PCIE_CTL_2);
> @@ -851,8 +863,10 @@ static void imx6_pcie_ltssm_disable(struct device *dev)
>  
>  	switch (imx6_pcie->drvdata->variant) {
>  	case IMX6Q:
> +	case IMX6Q_EP:
>  	case IMX6SX:
>  	case IMX6QP:
> +	case IMX6QP_EP:
>  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
>  				   IMX6Q_GPR12_PCIE_CTL_2, 0);
>  		break;
> @@ -1077,6 +1091,27 @@ static int imx6_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
>  	return 0;
>  }
>  
> +/*
> + * i.MX6Q and i.MX6QP PCIe EP BAR definitions.
> + * +-----------------------------------------------------------------+
> + * | BAR0     | BAR1     | BAR2     | BAR3     | BAR4     | BAR5     |
> + * +----------|----------|----------|----------|----------|----------+
> + * | 64-bit   | Disabled | 32-bit   | 32-bit   | Disabled | Disabled |
> + * |          |          |          | Fixed    |          |          |
> + * |          |          |          | 256Bytes |          |          |
> + * | Prefetch |          | Prefetch | None-    |          |          |
> + * | Memory   |          | Memory   | Prefetch |          |          |
> + * |          |          |          | IO       |          |          |
> + * +-----------------------------------------------------------------+
> + */
> +static const struct pci_epc_features imx6q_pcie_epc_features = {
> +	.linkup_notifier = false,
> +	.msi_capable = true,
> +	.msix_capable = false,
> +	.reserved_bar = 1 << BAR_4 | 1 << BAR_5,
> +	.align = SZ_64K,
> +};
> +
>  static const struct pci_epc_features imx8m_pcie_epc_features = {
>  	.linkup_notifier = false,
>  	.msi_capable = true,
> @@ -1088,7 +1123,16 @@ static const struct pci_epc_features imx8m_pcie_epc_features = {
>  static const struct pci_epc_features*
>  imx6_pcie_ep_get_features(struct dw_pcie_ep *ep)
>  {
> -	return &imx8m_pcie_epc_features;
> +	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> +	struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
> +
> +	switch (imx6_pcie->drvdata->variant) {
> +	case IMX6Q_EP:
> +	case IMX6QP_EP:
> +		return &imx6q_pcie_epc_features;
> +	default:
> +		return &imx8m_pcie_epc_features;

Could you add "const struct pci_epc_features" *epc_features in drvdata?

	if (imx6_pcie->drvdata->epc_features)
		return imx6_pcie->drvdata->epc_features;

	return &imx8m_pcie_epc_features;


Needn't change this code if new chip added in future.

Frank

> +	}
>  }
>  
>  static const struct dw_pcie_ep_ops pcie_ep_ops = {
> @@ -1157,6 +1201,7 @@ static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie)
>  	switch (imx6_pcie->drvdata->variant) {
>  	case IMX6SX:
>  	case IMX6QP:
> +	case IMX6QP_EP:
>  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
>  				IMX6SX_GPR12_PCIE_PM_TURN_OFF,
>  				IMX6SX_GPR12_PCIE_PM_TURN_OFF);
> @@ -1478,6 +1523,12 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  		.dbi_length = 0x200,
>  		.gpr = "fsl,imx6q-iomuxc-gpr",
>  	},
> +	[IMX6Q_EP] = {
> +		.variant = IMX6Q_EP,
> +		.mode = DW_PCIE_EP_TYPE,
> +		.flags = IMX6_PCIE_FLAG_IMX6_PHY,
> +		.gpr = "fsl,imx6q-iomuxc-gpr",

See above comments
		.epc_feature = &imx6q_pcie_epc_features;

Frank

> +	},
>  	[IMX6SX] = {
>  		.variant = IMX6SX,
>  		.flags = IMX6_PCIE_FLAG_IMX6_PHY |
> @@ -1493,6 +1544,12 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  		.dbi_length = 0x200,
>  		.gpr = "fsl,imx6q-iomuxc-gpr",
>  	},
> +	[IMX6QP_EP] = {
> +		.variant = IMX6QP_EP,
> +		.mode = DW_PCIE_EP_TYPE,
> +		.flags = IMX6_PCIE_FLAG_IMX6_PHY,
> +		.gpr = "fsl,imx6q-iomuxc-gpr",
> +	},
>  	[IMX7D] = {
>  		.variant = IMX7D,
>  		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
> @@ -1531,8 +1588,10 @@ static const struct imx6_pcie_drvdata drvdata[] = {
>  
>  static const struct of_device_id imx6_pcie_of_match[] = {
>  	{ .compatible = "fsl,imx6q-pcie",  .data = &drvdata[IMX6Q],  },
> +	{ .compatible = "fsl,imx6q-pcie-ep", .data = &drvdata[IMX6Q_EP], },
>  	{ .compatible = "fsl,imx6sx-pcie", .data = &drvdata[IMX6SX], },
>  	{ .compatible = "fsl,imx6qp-pcie", .data = &drvdata[IMX6QP], },
> +	{ .compatible = "fsl,imx6qp-pcie-ep", .data = &drvdata[IMX6QP_EP], },
>  	{ .compatible = "fsl,imx7d-pcie",  .data = &drvdata[IMX7D],  },
>  	{ .compatible = "fsl,imx8mq-pcie", .data = &drvdata[IMX8MQ], },
>  	{ .compatible = "fsl,imx8mm-pcie", .data = &drvdata[IMX8MM], },
> -- 
> 2.34.1
>
Hongxing Zhu Aug. 3, 2023, 2:42 a.m. UTC | #2
Hi Frank:
Thanks for your reply.

> -----Original Message-----
> From: Frank Li <frank.li@nxp.com>
> Sent: 2023年8月3日 5:54
> To: Hongxing Zhu <hongxing.zhu@nxp.com>
> Cc: l.stach@pengutronix.de; shawnguo@kernel.org; lpieralisi@kernel.org;
> robh+dt@kernel.org; krzysztof.kozlowski+dt@linaro.org;
> linux-pci@vger.kernel.org; devicetree@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; linux-kernel@vger.kernel.org;
> kernel@pengutronix.de; dl-linux-imx <linux-imx@nxp.com>
> Subject: Re: [PATCH 7/9] PCI: imx6: Add i.MX6Q and i.MX6QP PCIe EP supports
> 
> On Wed, Aug 02, 2023 at 02:06:49PM +0800, Richard Zhu wrote:
> > Add i.MX6Q and i.MX6QP PCIe EP supports.
> >
> > Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> > ---
> >  drivers/pci/controller/dwc/pci-imx6.c | 61
> > ++++++++++++++++++++++++++-
> >  1 file changed, 60 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pci-imx6.c
> > b/drivers/pci/controller/dwc/pci-imx6.c
> > index 27aaa2a6bf39..4da9553b49b4 100644
> > --- a/drivers/pci/controller/dwc/pci-imx6.c
> > +++ b/drivers/pci/controller/dwc/pci-imx6.c
> > @@ -46,8 +46,10 @@
> >
> >  enum imx6_pcie_variants {
> >  	IMX6Q,
> > +	IMX6Q_EP,
> >  	IMX6SX,
> >  	IMX6QP,
> > +	IMX6QP_EP,
> >  	IMX7D,
> >  	IMX8MQ,
> >  	IMX8MM,
> > @@ -567,7 +569,9 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie
> *imx6_pcie)
> >  				   IMX6SX_GPR12_PCIE_TEST_POWERDOWN, 0);
> >  		break;
> >  	case IMX6QP:
> > +	case IMX6QP_EP:
> >  	case IMX6Q:
> > +	case IMX6Q_EP:
> >  		/* power up core phy and enable ref clock */
> >  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
> >  				   IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18); @@ -619,7
> +623,9 @@ static
> > void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie)
> >  		clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
> >  		break;
> >  	case IMX6QP:
> > +	case IMX6QP_EP:
> >  	case IMX6Q:
> > +	case IMX6Q_EP:
> >  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
> >  				IMX6Q_GPR1_PCIE_REF_CLK_EN, 0);
> >  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, @@
> -720,11
> > +726,13 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie
> *imx6_pcie)
> >  				   IMX6SX_GPR5_PCIE_BTNRST_RESET);
> >  		break;
> >  	case IMX6QP:
> > +	case IMX6QP_EP:
> >  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
> >  				   IMX6Q_GPR1_PCIE_SW_RST,
> >  				   IMX6Q_GPR1_PCIE_SW_RST);
> >  		break;
> >  	case IMX6Q:
> > +	case IMX6Q_EP:
> >  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
> >  				   IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18);
> >  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, @@
> -777,12
> > +785,14 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie
> *imx6_pcie)
> >  				   IMX6SX_GPR5_PCIE_BTNRST_RESET, 0);
> >  		break;
> >  	case IMX6QP:
> > +	case IMX6QP_EP:
> >  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
> >  				   IMX6Q_GPR1_PCIE_SW_RST, 0);
> >
> >  		usleep_range(200, 500);
> >  		break;
> >  	case IMX6Q:		/* Nothing to do */
> > +	case IMX6Q_EP:
> >  	case IMX8MM:
> >  	case IMX8MM_EP:
> >  	case IMX8MP:
> > @@ -827,8 +837,10 @@ static void imx6_pcie_ltssm_enable(struct device
> > *dev)
> >
> >  	switch (imx6_pcie->drvdata->variant) {
> >  	case IMX6Q:
> > +	case IMX6Q_EP:
> >  	case IMX6SX:
> >  	case IMX6QP:
> > +	case IMX6QP_EP:
> >  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
> >  				   IMX6Q_GPR12_PCIE_CTL_2,
> >  				   IMX6Q_GPR12_PCIE_CTL_2);
> > @@ -851,8 +863,10 @@ static void imx6_pcie_ltssm_disable(struct device
> > *dev)
> >
> >  	switch (imx6_pcie->drvdata->variant) {
> >  	case IMX6Q:
> > +	case IMX6Q_EP:
> >  	case IMX6SX:
> >  	case IMX6QP:
> > +	case IMX6QP_EP:
> >  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
> >  				   IMX6Q_GPR12_PCIE_CTL_2, 0);
> >  		break;
> > @@ -1077,6 +1091,27 @@ static int imx6_pcie_ep_raise_irq(struct
> dw_pcie_ep *ep, u8 func_no,
> >  	return 0;
> >  }
> >
> > +/*
> > + * i.MX6Q and i.MX6QP PCIe EP BAR definitions.
> > + * +-----------------------------------------------------------------+
> > + * | BAR0     | BAR1     | BAR2     | BAR3     | BAR4     | BAR5
> |
> > + * +----------|----------|----------|----------|----------|----------+
> > + * | 64-bit   | Disabled | 32-bit   | 32-bit   | Disabled | Disabled |
> > + * |          |          |          | Fixed    |          |
> |
> > + * |          |          |          | 256Bytes |          |
> |
> > + * | Prefetch |          | Prefetch | None-    |          |          |
> > + * | Memory   |          | Memory   | Prefetch |          |
> |
> > + * |          |          |          | IO       |          |
> |
> > + *
> > ++-----------------------------------------------------------------+
> > + */
> > +static const struct pci_epc_features imx6q_pcie_epc_features = {
> > +	.linkup_notifier = false,
> > +	.msi_capable = true,
> > +	.msix_capable = false,
> > +	.reserved_bar = 1 << BAR_4 | 1 << BAR_5,
> > +	.align = SZ_64K,
> > +};
> > +
> >  static const struct pci_epc_features imx8m_pcie_epc_features = {
> >  	.linkup_notifier = false,
> >  	.msi_capable = true,
> > @@ -1088,7 +1123,16 @@ static const struct pci_epc_features
> > imx8m_pcie_epc_features = {  static const struct pci_epc_features*
> > imx6_pcie_ep_get_features(struct dw_pcie_ep *ep)  {
> > -	return &imx8m_pcie_epc_features;
> > +	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> > +	struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
> > +
> > +	switch (imx6_pcie->drvdata->variant) {
> > +	case IMX6Q_EP:
> > +	case IMX6QP_EP:
> > +		return &imx6q_pcie_epc_features;
> > +	default:
> > +		return &imx8m_pcie_epc_features;
> 
> Could you add "const struct pci_epc_features" *epc_features in drvdata?
> 
> 	if (imx6_pcie->drvdata->epc_features)
> 		return imx6_pcie->drvdata->epc_features;
> 
> 	return &imx8m_pcie_epc_features;
> 
> 
> Needn't change this code if new chip added in future.
Good suggestion, would follow this method to simple .get_features codes.
Thanks.
> 
> Frank
> 
> > +	}
> >  }
> >
> >  static const struct dw_pcie_ep_ops pcie_ep_ops = { @@ -1157,6 +1201,7
> > @@ static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie)
> >  	switch (imx6_pcie->drvdata->variant) {
> >  	case IMX6SX:
> >  	case IMX6QP:
> > +	case IMX6QP_EP:
> >  		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
> >  				IMX6SX_GPR12_PCIE_PM_TURN_OFF,
> >  				IMX6SX_GPR12_PCIE_PM_TURN_OFF);
> > @@ -1478,6 +1523,12 @@ static const struct imx6_pcie_drvdata drvdata[] = {
> >  		.dbi_length = 0x200,
> >  		.gpr = "fsl,imx6q-iomuxc-gpr",
> >  	},
> > +	[IMX6Q_EP] = {
> > +		.variant = IMX6Q_EP,
> > +		.mode = DW_PCIE_EP_TYPE,
> > +		.flags = IMX6_PCIE_FLAG_IMX6_PHY,
> > +		.gpr = "fsl,imx6q-iomuxc-gpr",
> 
> See above comments
> 		.epc_feature = &imx6q_pcie_epc_features;
Got that. Thanks.
> 
> Frank
> 
> > +	},
> >  	[IMX6SX] = {
> >  		.variant = IMX6SX,
> >  		.flags = IMX6_PCIE_FLAG_IMX6_PHY |
> > @@ -1493,6 +1544,12 @@ static const struct imx6_pcie_drvdata drvdata[] = {
> >  		.dbi_length = 0x200,
> >  		.gpr = "fsl,imx6q-iomuxc-gpr",
> >  	},
> > +	[IMX6QP_EP] = {
> > +		.variant = IMX6QP_EP,
> > +		.mode = DW_PCIE_EP_TYPE,
> > +		.flags = IMX6_PCIE_FLAG_IMX6_PHY,
> > +		.gpr = "fsl,imx6q-iomuxc-gpr",
> > +	},
> >  	[IMX7D] = {
> >  		.variant = IMX7D,
> >  		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND, @@ -1531,8
> +1588,10 @@
> > static const struct imx6_pcie_drvdata drvdata[] = {
> >
> >  static const struct of_device_id imx6_pcie_of_match[] = {
> >  	{ .compatible = "fsl,imx6q-pcie",  .data = &drvdata[IMX6Q],  },
> > +	{ .compatible = "fsl,imx6q-pcie-ep", .data = &drvdata[IMX6Q_EP], },
> >  	{ .compatible = "fsl,imx6sx-pcie", .data = &drvdata[IMX6SX], },
> >  	{ .compatible = "fsl,imx6qp-pcie", .data = &drvdata[IMX6QP], },
> > +	{ .compatible = "fsl,imx6qp-pcie-ep", .data = &drvdata[IMX6QP_EP],
> > +},
> >  	{ .compatible = "fsl,imx7d-pcie",  .data = &drvdata[IMX7D],  },
> >  	{ .compatible = "fsl,imx8mq-pcie", .data = &drvdata[IMX8MQ], },
> >  	{ .compatible = "fsl,imx8mm-pcie", .data = &drvdata[IMX8MM], },
> > --
> > 2.34.1
> >
diff mbox series

Patch

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 27aaa2a6bf39..4da9553b49b4 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -46,8 +46,10 @@ 
 
 enum imx6_pcie_variants {
 	IMX6Q,
+	IMX6Q_EP,
 	IMX6SX,
 	IMX6QP,
+	IMX6QP_EP,
 	IMX7D,
 	IMX8MQ,
 	IMX8MM,
@@ -567,7 +569,9 @@  static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
 				   IMX6SX_GPR12_PCIE_TEST_POWERDOWN, 0);
 		break;
 	case IMX6QP:
+	case IMX6QP_EP:
 	case IMX6Q:
+	case IMX6Q_EP:
 		/* power up core phy and enable ref clock */
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
 				   IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
@@ -619,7 +623,9 @@  static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie)
 		clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
 		break;
 	case IMX6QP:
+	case IMX6QP_EP:
 	case IMX6Q:
+	case IMX6Q_EP:
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
 				IMX6Q_GPR1_PCIE_REF_CLK_EN, 0);
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
@@ -720,11 +726,13 @@  static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
 				   IMX6SX_GPR5_PCIE_BTNRST_RESET);
 		break;
 	case IMX6QP:
+	case IMX6QP_EP:
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
 				   IMX6Q_GPR1_PCIE_SW_RST,
 				   IMX6Q_GPR1_PCIE_SW_RST);
 		break;
 	case IMX6Q:
+	case IMX6Q_EP:
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
 				   IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18);
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
@@ -777,12 +785,14 @@  static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
 				   IMX6SX_GPR5_PCIE_BTNRST_RESET, 0);
 		break;
 	case IMX6QP:
+	case IMX6QP_EP:
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
 				   IMX6Q_GPR1_PCIE_SW_RST, 0);
 
 		usleep_range(200, 500);
 		break;
 	case IMX6Q:		/* Nothing to do */
+	case IMX6Q_EP:
 	case IMX8MM:
 	case IMX8MM_EP:
 	case IMX8MP:
@@ -827,8 +837,10 @@  static void imx6_pcie_ltssm_enable(struct device *dev)
 
 	switch (imx6_pcie->drvdata->variant) {
 	case IMX6Q:
+	case IMX6Q_EP:
 	case IMX6SX:
 	case IMX6QP:
+	case IMX6QP_EP:
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
 				   IMX6Q_GPR12_PCIE_CTL_2,
 				   IMX6Q_GPR12_PCIE_CTL_2);
@@ -851,8 +863,10 @@  static void imx6_pcie_ltssm_disable(struct device *dev)
 
 	switch (imx6_pcie->drvdata->variant) {
 	case IMX6Q:
+	case IMX6Q_EP:
 	case IMX6SX:
 	case IMX6QP:
+	case IMX6QP_EP:
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
 				   IMX6Q_GPR12_PCIE_CTL_2, 0);
 		break;
@@ -1077,6 +1091,27 @@  static int imx6_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
 	return 0;
 }
 
+/*
+ * i.MX6Q and i.MX6QP PCIe EP BAR definitions.
+ * +-----------------------------------------------------------------+
+ * | BAR0     | BAR1     | BAR2     | BAR3     | BAR4     | BAR5     |
+ * +----------|----------|----------|----------|----------|----------+
+ * | 64-bit   | Disabled | 32-bit   | 32-bit   | Disabled | Disabled |
+ * |          |          |          | Fixed    |          |          |
+ * |          |          |          | 256Bytes |          |          |
+ * | Prefetch |          | Prefetch | None-    |          |          |
+ * | Memory   |          | Memory   | Prefetch |          |          |
+ * |          |          |          | IO       |          |          |
+ * +-----------------------------------------------------------------+
+ */
+static const struct pci_epc_features imx6q_pcie_epc_features = {
+	.linkup_notifier = false,
+	.msi_capable = true,
+	.msix_capable = false,
+	.reserved_bar = 1 << BAR_4 | 1 << BAR_5,
+	.align = SZ_64K,
+};
+
 static const struct pci_epc_features imx8m_pcie_epc_features = {
 	.linkup_notifier = false,
 	.msi_capable = true,
@@ -1088,7 +1123,16 @@  static const struct pci_epc_features imx8m_pcie_epc_features = {
 static const struct pci_epc_features*
 imx6_pcie_ep_get_features(struct dw_pcie_ep *ep)
 {
-	return &imx8m_pcie_epc_features;
+	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+	struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
+
+	switch (imx6_pcie->drvdata->variant) {
+	case IMX6Q_EP:
+	case IMX6QP_EP:
+		return &imx6q_pcie_epc_features;
+	default:
+		return &imx8m_pcie_epc_features;
+	}
 }
 
 static const struct dw_pcie_ep_ops pcie_ep_ops = {
@@ -1157,6 +1201,7 @@  static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie)
 	switch (imx6_pcie->drvdata->variant) {
 	case IMX6SX:
 	case IMX6QP:
+	case IMX6QP_EP:
 		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
 				IMX6SX_GPR12_PCIE_PM_TURN_OFF,
 				IMX6SX_GPR12_PCIE_PM_TURN_OFF);
@@ -1478,6 +1523,12 @@  static const struct imx6_pcie_drvdata drvdata[] = {
 		.dbi_length = 0x200,
 		.gpr = "fsl,imx6q-iomuxc-gpr",
 	},
+	[IMX6Q_EP] = {
+		.variant = IMX6Q_EP,
+		.mode = DW_PCIE_EP_TYPE,
+		.flags = IMX6_PCIE_FLAG_IMX6_PHY,
+		.gpr = "fsl,imx6q-iomuxc-gpr",
+	},
 	[IMX6SX] = {
 		.variant = IMX6SX,
 		.flags = IMX6_PCIE_FLAG_IMX6_PHY |
@@ -1493,6 +1544,12 @@  static const struct imx6_pcie_drvdata drvdata[] = {
 		.dbi_length = 0x200,
 		.gpr = "fsl,imx6q-iomuxc-gpr",
 	},
+	[IMX6QP_EP] = {
+		.variant = IMX6QP_EP,
+		.mode = DW_PCIE_EP_TYPE,
+		.flags = IMX6_PCIE_FLAG_IMX6_PHY,
+		.gpr = "fsl,imx6q-iomuxc-gpr",
+	},
 	[IMX7D] = {
 		.variant = IMX7D,
 		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
@@ -1531,8 +1588,10 @@  static const struct imx6_pcie_drvdata drvdata[] = {
 
 static const struct of_device_id imx6_pcie_of_match[] = {
 	{ .compatible = "fsl,imx6q-pcie",  .data = &drvdata[IMX6Q],  },
+	{ .compatible = "fsl,imx6q-pcie-ep", .data = &drvdata[IMX6Q_EP], },
 	{ .compatible = "fsl,imx6sx-pcie", .data = &drvdata[IMX6SX], },
 	{ .compatible = "fsl,imx6qp-pcie", .data = &drvdata[IMX6QP], },
+	{ .compatible = "fsl,imx6qp-pcie-ep", .data = &drvdata[IMX6QP_EP], },
 	{ .compatible = "fsl,imx7d-pcie",  .data = &drvdata[IMX7D],  },
 	{ .compatible = "fsl,imx8mq-pcie", .data = &drvdata[IMX8MQ], },
 	{ .compatible = "fsl,imx8mm-pcie", .data = &drvdata[IMX8MM], },