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

From: Frank Li
Date: Wed Aug 02 2023 - 17:54:28 EST


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@xxxxxxx>
> ---
> 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
>