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

Frank Li Frank.li at nxp.com
Wed Aug 2 14:54:01 PDT 2023


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 at 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
> 



More information about the linux-arm-kernel mailing list