From 1af5ea1dc2df627ac11361ee9795cf4f240f66f1 Mon Sep 17 00:00:00 2001 From: Richard Zhu Date: Mon, 16 Jan 2023 13:41:11 +0800 Subject: [PATCH 1/8] dt-bindings: imx6q-pcie: Add i.MX8MM PCIe EP mode compatible string Add i.MX8MM PCIe endpoint mode compatible string. Link: https://lore.kernel.org/r/1673847684-31893-2-git-send-email-hongxing.zhu@nxp.com Signed-off-by: Richard Zhu Signed-off-by: Lorenzo Pieralisi Acked-by: Rob Herring --- Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml index bad980902f66..6a547aabe729 100644 --- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml +++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml @@ -24,6 +24,7 @@ properties: - fsl,imx8mq-pcie - fsl,imx8mm-pcie - fsl,imx8mp-pcie + - fsl,imx8mm-pcie-ep reg: items: From dea44b629ae186410d822e2bf576143bebd932f1 Mon Sep 17 00:00:00 2001 From: Richard Zhu Date: Mon, 16 Jan 2023 13:41:12 +0800 Subject: [PATCH 2/8] dt-bindings: imx6q-pcie: Add i.MX8MQ PCIe EP mode compatible string Add i.MX8MQ PCIe endpoint mode compatible string. Link: https://lore.kernel.org/r/1673847684-31893-3-git-send-email-hongxing.zhu@nxp.com Signed-off-by: Richard Zhu Signed-off-by: Lorenzo Pieralisi Acked-by: Rob Herring --- Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml index 6a547aabe729..b57f748acafa 100644 --- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml +++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml @@ -25,6 +25,7 @@ properties: - fsl,imx8mm-pcie - fsl,imx8mp-pcie - fsl,imx8mm-pcie-ep + - fsl,imx8mq-pcie-ep reg: items: From 2dd6dc57d2da459983ded133767d0389194f15b8 Mon Sep 17 00:00:00 2001 From: Richard Zhu Date: Mon, 16 Jan 2023 13:41:13 +0800 Subject: [PATCH 3/8] dt-bindings: imx6q-pcie: Add i.MX8MP PCIe EP mode compatible string Add i.MX8MP PCIe endpoint mode compatible string. Link: https://lore.kernel.org/r/1673847684-31893-4-git-send-email-hongxing.zhu@nxp.com Signed-off-by: Richard Zhu Signed-off-by: Lorenzo Pieralisi Acked-by: Rob Herring --- Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml index b57f748acafa..f13f87fddb3d 100644 --- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml +++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml @@ -26,6 +26,7 @@ properties: - fsl,imx8mp-pcie - fsl,imx8mm-pcie-ep - fsl,imx8mq-pcie-ep + - fsl,imx8mp-pcie-ep reg: items: From 01ea5ede419733fdc39e75875f0861d16a829fe6 Mon Sep 17 00:00:00 2001 From: Richard Zhu Date: Mon, 16 Jan 2023 13:41:20 +0800 Subject: [PATCH 4/8] misc: pci_endpoint_test: Add i.MX8 PCIe EP device support Set the DEVICE_ID of i.MX8 PCIe and add i.MX8 PCIE EP device support in pci_endpoint_test driver. Link: https://lore.kernel.org/r/1673847684-31893-11-git-send-email-hongxing.zhu@nxp.com Signed-off-by: Richard Zhu Signed-off-by: Lorenzo Pieralisi --- drivers/misc/pci_endpoint_test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c index 11530b4ec389..e2687229955d 100644 --- a/drivers/misc/pci_endpoint_test.c +++ b/drivers/misc/pci_endpoint_test.c @@ -72,6 +72,7 @@ #define PCI_DEVICE_ID_TI_J7200 0xb00f #define PCI_DEVICE_ID_TI_AM64 0xb010 #define PCI_DEVICE_ID_LS1088A 0x80c0 +#define PCI_DEVICE_ID_IMX8 0x0808 #define is_am654_pci_dev(pdev) \ ((pdev)->device == PCI_DEVICE_ID_TI_AM654) @@ -980,6 +981,7 @@ static const struct pci_device_id pci_endpoint_test_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0x81c0), .driver_data = (kernel_ulong_t)&default_data, }, + { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, PCI_DEVICE_ID_IMX8),}, { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, PCI_DEVICE_ID_LS1088A), .driver_data = (kernel_ulong_t)&default_data, }, From 75c2f26da03f93e988cd7678722ea893a8c63796 Mon Sep 17 00:00:00 2001 From: Richard Zhu Date: Mon, 16 Jan 2023 13:41:21 +0800 Subject: [PATCH 5/8] PCI: imx6: Add i.MX PCIe EP mode support i.MX PCIe is one dual mode PCIe controller. Add i.MX PCIe EP mode support here, and split the PCIe modes to the Root Complex mode and Endpoint mode. Link: https://lore.kernel.org/r/1673847684-31893-12-git-send-email-hongxing.zhu@nxp.com Signed-off-by: Richard Zhu Signed-off-by: Lorenzo Pieralisi --- drivers/pci/controller/dwc/Kconfig | 23 ++++- drivers/pci/controller/dwc/pci-imx6.c | 128 +++++++++++++++++++++++--- 2 files changed, 137 insertions(+), 14 deletions(-) diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig index a0d2713f0e88..dffd7fbdfb98 100644 --- a/drivers/pci/controller/dwc/Kconfig +++ b/drivers/pci/controller/dwc/Kconfig @@ -92,10 +92,31 @@ config PCI_EXYNOS functions to implement the driver. config PCI_IMX6 - bool "Freescale i.MX6/7/8 PCIe controller" + bool + +config PCI_IMX6_HOST + bool "Freescale i.MX6/7/8 PCIe controller host mode" depends on ARCH_MXC || COMPILE_TEST depends on PCI_MSI select PCIE_DW_HOST + select PCI_IMX6 + help + Enables support for the PCIe controller in the i.MX SoCs to + work in Root Complex mode. The PCI controller on i.MX is based + on DesignWare hardware and therefore the driver re-uses the + DesignWare core functions to implement the driver. + +config PCI_IMX6_EP + bool "Freescale i.MX6/7/8 PCIe controller endpoint mode" + depends on ARCH_MXC || COMPILE_TEST + depends on PCI_ENDPOINT + select PCIE_DW_EP + select PCI_IMX6 + help + Enables support for the PCIe controller in the i.MX SoCs to + work in endpoint mode. The PCI controller on i.MX is based + on DesignWare hardware and therefore the driver re-uses the + DesignWare core functions to implement the driver. config PCIE_SPEAR13XX bool "STMicroelectronics SPEAr PCIe controller" diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 1dde5c579edc..572faa91eea7 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -60,6 +60,7 @@ enum imx6_pcie_variants { struct imx6_pcie_drvdata { enum imx6_pcie_variants variant; + enum dw_pcie_device_mode mode; u32 flags; int dbi_length; const char *gpr; @@ -159,17 +160,20 @@ static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie) static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie) { - unsigned int mask, val; + unsigned int mask, val, mode; + + if (imx6_pcie->drvdata->mode == DW_PCIE_EP_TYPE) + mode = PCI_EXP_TYPE_ENDPOINT; + else + mode = PCI_EXP_TYPE_ROOT_PORT; if (imx6_pcie->drvdata->variant == IMX8MQ && imx6_pcie->controller_id == 1) { mask = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE; - val = FIELD_PREP(IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE, - PCI_EXP_TYPE_ROOT_PORT); + val = FIELD_PREP(IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE, mode); } else { mask = IMX6Q_GPR12_DEVICE_TYPE; - val = FIELD_PREP(IMX6Q_GPR12_DEVICE_TYPE, - PCI_EXP_TYPE_ROOT_PORT); + val = FIELD_PREP(IMX6Q_GPR12_DEVICE_TYPE, mode); } regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, mask, val); @@ -1003,8 +1007,99 @@ static const struct dw_pcie_host_ops imx6_pcie_host_ops = { static const struct dw_pcie_ops dw_pcie_ops = { .start_link = imx6_pcie_start_link, + .stop_link = imx6_pcie_stop_link, }; +static void imx6_pcie_ep_init(struct dw_pcie_ep *ep) +{ + enum pci_barno bar; + struct dw_pcie *pci = to_dw_pcie_from_ep(ep); + + for (bar = BAR_0; bar <= BAR_5; bar++) + dw_pcie_ep_reset_bar(pci, bar); +} + +static int imx6_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, + enum pci_epc_irq_type type, + u16 interrupt_num) +{ + struct dw_pcie *pci = to_dw_pcie_from_ep(ep); + + switch (type) { + case PCI_EPC_IRQ_LEGACY: + return dw_pcie_ep_raise_legacy_irq(ep, func_no); + case PCI_EPC_IRQ_MSI: + return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num); + case PCI_EPC_IRQ_MSIX: + return dw_pcie_ep_raise_msix_irq(ep, func_no, interrupt_num); + default: + dev_err(pci->dev, "UNKNOWN IRQ type\n"); + return -EINVAL; + } + + return 0; +} + +static const struct pci_epc_features imx8m_pcie_epc_features = { + .linkup_notifier = false, + .msi_capable = true, + .msix_capable = false, + .reserved_bar = 1 << BAR_1 | 1 << BAR_3, + .align = SZ_64K, +}; + +static const struct pci_epc_features* +imx6_pcie_ep_get_features(struct dw_pcie_ep *ep) +{ + return &imx8m_pcie_epc_features; +} + +static const struct dw_pcie_ep_ops pcie_ep_ops = { + .ep_init = imx6_pcie_ep_init, + .raise_irq = imx6_pcie_ep_raise_irq, + .get_features = imx6_pcie_ep_get_features, +}; + +static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie, + struct platform_device *pdev) +{ + int ret; + unsigned int pcie_dbi2_offset; + struct dw_pcie_ep *ep; + struct resource *res; + struct dw_pcie *pci = imx6_pcie->pci; + struct dw_pcie_rp *pp = &pci->pp; + struct device *dev = pci->dev; + + imx6_pcie_host_init(pp); + ep = &pci->ep; + ep->ops = &pcie_ep_ops; + + switch (imx6_pcie->drvdata->variant) { + default: + pcie_dbi2_offset = SZ_4K; + break; + } + pci->dbi_base2 = pci->dbi_base + pcie_dbi2_offset; + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space"); + if (!res) + return -EINVAL; + + ep->phys_base = res->start; + ep->addr_size = resource_size(res); + ep->page_size = SZ_64K; + + ret = dw_pcie_ep_init(ep); + if (ret) { + dev_err(dev, "failed to initialize endpoint\n"); + return ret; + } + /* Start LTSSM. */ + imx6_pcie_ltssm_enable(dev); + + return 0; +} + static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie) { struct device *dev = imx6_pcie->pci->dev; @@ -1279,15 +1374,22 @@ static int imx6_pcie_probe(struct platform_device *pdev) if (ret) return ret; - ret = dw_pcie_host_init(&pci->pp); - if (ret < 0) - return ret; + if (imx6_pcie->drvdata->mode == DW_PCIE_EP_TYPE) { + ret = imx6_add_pcie_ep(imx6_pcie, pdev); + if (ret < 0) + return ret; + } else { + ret = dw_pcie_host_init(&pci->pp); + if (ret < 0) + return ret; - if (pci_msi_enabled()) { - u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_MSI); - val = dw_pcie_readw_dbi(pci, offset + PCI_MSI_FLAGS); - val |= PCI_MSI_FLAGS_ENABLE; - dw_pcie_writew_dbi(pci, offset + PCI_MSI_FLAGS, val); + if (pci_msi_enabled()) { + u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_MSI); + + val = dw_pcie_readw_dbi(pci, offset + PCI_MSI_FLAGS); + val |= PCI_MSI_FLAGS_ENABLE; + dw_pcie_writew_dbi(pci, offset + PCI_MSI_FLAGS, val); + } } return 0; From 530ba41250b69db4b5beb9fc03bd7183881c5e7f Mon Sep 17 00:00:00 2001 From: Richard Zhu Date: Mon, 16 Jan 2023 13:41:22 +0800 Subject: [PATCH 6/8] PCI: imx6: Add i.MX8MQ PCIe EP support Add i.MX8MQ PCIe EP support. Link: https://lore.kernel.org/r/1673847684-31893-13-git-send-email-hongxing.zhu@nxp.com Signed-off-by: Richard Zhu Signed-off-by: Lorenzo Pieralisi --- drivers/pci/controller/dwc/pci-imx6.c | 38 +++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 572faa91eea7..8190b1de67f9 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -52,6 +52,7 @@ enum imx6_pcie_variants { IMX8MQ, IMX8MM, IMX8MP, + IMX8MQ_EP, }; #define IMX6_PCIE_FLAG_IMX6_PHY BIT(0) @@ -153,6 +154,7 @@ struct imx6_pcie { static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie) { WARN_ON(imx6_pcie->drvdata->variant != IMX8MQ && + imx6_pcie->drvdata->variant != IMX8MQ_EP && imx6_pcie->drvdata->variant != IMX8MM && imx6_pcie->drvdata->variant != IMX8MP); return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14; @@ -167,13 +169,22 @@ static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie) else mode = PCI_EXP_TYPE_ROOT_PORT; - if (imx6_pcie->drvdata->variant == IMX8MQ && - imx6_pcie->controller_id == 1) { - mask = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE; - val = FIELD_PREP(IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE, mode); - } else { + switch (imx6_pcie->drvdata->variant) { + case IMX8MQ: + case IMX8MQ_EP: + if (imx6_pcie->controller_id == 1) { + mask = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE; + val = FIELD_PREP(IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE, + mode); + } else { + mask = IMX6Q_GPR12_DEVICE_TYPE; + val = FIELD_PREP(IMX6Q_GPR12_DEVICE_TYPE, mode); + } + break; + default: mask = IMX6Q_GPR12_DEVICE_TYPE; val = FIELD_PREP(IMX6Q_GPR12_DEVICE_TYPE, mode); + break; } regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, mask, val); @@ -315,6 +326,7 @@ static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie) */ break; case IMX8MQ: + case IMX8MQ_EP: /* * TODO: Currently this code assumes external * oscillator is being used @@ -566,6 +578,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie) break; case IMX8MM: case IMX8MQ: + case IMX8MQ_EP: case IMX8MP: ret = clk_prepare_enable(imx6_pcie->pcie_aux); if (ret) { @@ -611,6 +624,7 @@ static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie) break; case IMX8MM: case IMX8MQ: + case IMX8MQ_EP: case IMX8MP: clk_disable_unprepare(imx6_pcie->pcie_aux); break; @@ -676,6 +690,7 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie) switch (imx6_pcie->drvdata->variant) { case IMX7D: case IMX8MQ: + case IMX8MQ_EP: reset_control_assert(imx6_pcie->pciephy_reset); fallthrough; case IMX8MM: @@ -717,6 +732,7 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) switch (imx6_pcie->drvdata->variant) { case IMX8MQ: + case IMX8MQ_EP: reset_control_deassert(imx6_pcie->pciephy_reset); break; case IMX7D: @@ -804,6 +820,7 @@ static void imx6_pcie_ltssm_enable(struct device *dev) break; case IMX7D: case IMX8MQ: + case IMX8MQ_EP: case IMX8MM: case IMX8MP: reset_control_deassert(imx6_pcie->apps_reset); @@ -824,6 +841,7 @@ static void imx6_pcie_ltssm_disable(struct device *dev) break; case IMX7D: case IMX8MQ: + case IMX8MQ_EP: case IMX8MM: case IMX8MP: reset_control_assert(imx6_pcie->apps_reset); @@ -1076,6 +1094,9 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie, ep->ops = &pcie_ep_ops; switch (imx6_pcie->drvdata->variant) { + case IMX8MQ_EP: + pcie_dbi2_offset = SZ_1M; + break; default: pcie_dbi2_offset = SZ_4K; break; @@ -1261,6 +1282,7 @@ static int imx6_pcie_probe(struct platform_device *pdev) "pcie_inbound_axi clock missing or invalid\n"); break; case IMX8MQ: + case IMX8MQ_EP: imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux"); if (IS_ERR(imx6_pcie->pcie_aux)) return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_aux), @@ -1445,6 +1467,11 @@ static const struct imx6_pcie_drvdata drvdata[] = { .flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND, .gpr = "fsl,imx8mp-iomuxc-gpr", }, + [IMX8MQ_EP] = { + .variant = IMX8MQ_EP, + .mode = DW_PCIE_EP_TYPE, + .gpr = "fsl,imx8mq-iomuxc-gpr", + }, }; static const struct of_device_id imx6_pcie_of_match[] = { @@ -1455,6 +1482,7 @@ static const struct of_device_id imx6_pcie_of_match[] = { { .compatible = "fsl,imx8mq-pcie", .data = &drvdata[IMX8MQ], }, { .compatible = "fsl,imx8mm-pcie", .data = &drvdata[IMX8MM], }, { .compatible = "fsl,imx8mp-pcie", .data = &drvdata[IMX8MP], }, + { .compatible = "fsl,imx8mq-pcie-ep", .data = &drvdata[IMX8MQ_EP], }, {}, }; From fb3217e2cfc6a577481b6accc3e17032f242e0ac Mon Sep 17 00:00:00 2001 From: Richard Zhu Date: Mon, 16 Jan 2023 13:41:23 +0800 Subject: [PATCH 7/8] PCI: imx6: Add i.MX8MM PCIe EP support Add i.MX8MM PCIe EP support. Link: https://lore.kernel.org/r/1673847684-31893-14-git-send-email-hongxing.zhu@nxp.com Signed-off-by: Richard Zhu Signed-off-by: Lorenzo Pieralisi --- drivers/pci/controller/dwc/pci-imx6.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 8190b1de67f9..eab332eb4c36 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -53,6 +53,7 @@ enum imx6_pcie_variants { IMX8MM, IMX8MP, IMX8MQ_EP, + IMX8MM_EP, }; #define IMX6_PCIE_FLAG_IMX6_PHY BIT(0) @@ -156,6 +157,7 @@ static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie) WARN_ON(imx6_pcie->drvdata->variant != IMX8MQ && imx6_pcie->drvdata->variant != IMX8MQ_EP && imx6_pcie->drvdata->variant != IMX8MM && + imx6_pcie->drvdata->variant != IMX8MM_EP && imx6_pcie->drvdata->variant != IMX8MP); return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14; } @@ -319,6 +321,7 @@ static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie) { switch (imx6_pcie->drvdata->variant) { case IMX8MM: + case IMX8MM_EP: case IMX8MP: /* * The PHY initialization had been done in the PHY @@ -577,6 +580,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie) case IMX7D: break; case IMX8MM: + case IMX8MM_EP: case IMX8MQ: case IMX8MQ_EP: case IMX8MP: @@ -623,6 +627,7 @@ static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie) IMX7D_GPR12_PCIE_PHY_REFCLK_SEL); break; case IMX8MM: + case IMX8MM_EP: case IMX8MQ: case IMX8MQ_EP: case IMX8MP: @@ -694,6 +699,7 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie) reset_control_assert(imx6_pcie->pciephy_reset); fallthrough; case IMX8MM: + case IMX8MM_EP: case IMX8MP: reset_control_assert(imx6_pcie->apps_reset); break; @@ -771,6 +777,7 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) break; case IMX6Q: /* Nothing to do */ case IMX8MM: + case IMX8MM_EP: case IMX8MP: break; } @@ -822,6 +829,7 @@ static void imx6_pcie_ltssm_enable(struct device *dev) case IMX8MQ: case IMX8MQ_EP: case IMX8MM: + case IMX8MM_EP: case IMX8MP: reset_control_deassert(imx6_pcie->apps_reset); break; @@ -843,6 +851,7 @@ static void imx6_pcie_ltssm_disable(struct device *dev) case IMX8MQ: case IMX8MQ_EP: case IMX8MM: + case IMX8MM_EP: case IMX8MP: reset_control_assert(imx6_pcie->apps_reset); break; @@ -1095,6 +1104,7 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie, switch (imx6_pcie->drvdata->variant) { case IMX8MQ_EP: + case IMX8MM_EP: pcie_dbi2_offset = SZ_1M; break; default: @@ -1307,6 +1317,7 @@ static int imx6_pcie_probe(struct platform_device *pdev) } break; case IMX8MM: + case IMX8MM_EP: case IMX8MP: imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux"); if (IS_ERR(imx6_pcie->pcie_aux)) @@ -1472,6 +1483,11 @@ static const struct imx6_pcie_drvdata drvdata[] = { .mode = DW_PCIE_EP_TYPE, .gpr = "fsl,imx8mq-iomuxc-gpr", }, + [IMX8MM_EP] = { + .variant = IMX8MM_EP, + .mode = DW_PCIE_EP_TYPE, + .gpr = "fsl,imx8mm-iomuxc-gpr", + }, }; static const struct of_device_id imx6_pcie_of_match[] = { @@ -1483,6 +1499,7 @@ static const struct of_device_id imx6_pcie_of_match[] = { { .compatible = "fsl,imx8mm-pcie", .data = &drvdata[IMX8MM], }, { .compatible = "fsl,imx8mp-pcie", .data = &drvdata[IMX8MP], }, { .compatible = "fsl,imx8mq-pcie-ep", .data = &drvdata[IMX8MQ_EP], }, + { .compatible = "fsl,imx8mm-pcie-ep", .data = &drvdata[IMX8MM_EP], }, {}, }; From c435669a41dd4ee063572e17b48c14806ad31f72 Mon Sep 17 00:00:00 2001 From: Richard Zhu Date: Mon, 16 Jan 2023 13:41:24 +0800 Subject: [PATCH 8/8] PCI: imx6: Add i.MX8MP PCIe EP support Add the i.MX8MP PCIe EP support. Link: https://lore.kernel.org/r/1673847684-31893-15-git-send-email-hongxing.zhu@nxp.com Signed-off-by: Richard Zhu Signed-off-by: Lorenzo Pieralisi --- drivers/pci/controller/dwc/pci-imx6.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index eab332eb4c36..55a0405b921d 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -54,6 +54,7 @@ enum imx6_pcie_variants { IMX8MP, IMX8MQ_EP, IMX8MM_EP, + IMX8MP_EP, }; #define IMX6_PCIE_FLAG_IMX6_PHY BIT(0) @@ -158,7 +159,8 @@ static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie) imx6_pcie->drvdata->variant != IMX8MQ_EP && imx6_pcie->drvdata->variant != IMX8MM && imx6_pcie->drvdata->variant != IMX8MM_EP && - imx6_pcie->drvdata->variant != IMX8MP); + imx6_pcie->drvdata->variant != IMX8MP && + imx6_pcie->drvdata->variant != IMX8MP_EP); return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14; } @@ -323,6 +325,7 @@ static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie) case IMX8MM: case IMX8MM_EP: case IMX8MP: + case IMX8MP_EP: /* * The PHY initialization had been done in the PHY * driver, break here directly. @@ -584,6 +587,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie) case IMX8MQ: case IMX8MQ_EP: case IMX8MP: + case IMX8MP_EP: ret = clk_prepare_enable(imx6_pcie->pcie_aux); if (ret) { dev_err(dev, "unable to enable pcie_aux clock\n"); @@ -631,6 +635,7 @@ static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie) case IMX8MQ: case IMX8MQ_EP: case IMX8MP: + case IMX8MP_EP: clk_disable_unprepare(imx6_pcie->pcie_aux); break; default: @@ -701,6 +706,7 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie) case IMX8MM: case IMX8MM_EP: case IMX8MP: + case IMX8MP_EP: reset_control_assert(imx6_pcie->apps_reset); break; case IMX6SX: @@ -779,6 +785,7 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) case IMX8MM: case IMX8MM_EP: case IMX8MP: + case IMX8MP_EP: break; } @@ -831,6 +838,7 @@ static void imx6_pcie_ltssm_enable(struct device *dev) case IMX8MM: case IMX8MM_EP: case IMX8MP: + case IMX8MP_EP: reset_control_deassert(imx6_pcie->apps_reset); break; } @@ -853,6 +861,7 @@ static void imx6_pcie_ltssm_disable(struct device *dev) case IMX8MM: case IMX8MM_EP: case IMX8MP: + case IMX8MP_EP: reset_control_assert(imx6_pcie->apps_reset); break; } @@ -1105,6 +1114,7 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie, switch (imx6_pcie->drvdata->variant) { case IMX8MQ_EP: case IMX8MM_EP: + case IMX8MP_EP: pcie_dbi2_offset = SZ_1M; break; default: @@ -1319,6 +1329,7 @@ static int imx6_pcie_probe(struct platform_device *pdev) case IMX8MM: case IMX8MM_EP: case IMX8MP: + case IMX8MP_EP: imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux"); if (IS_ERR(imx6_pcie->pcie_aux)) return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_aux), @@ -1488,6 +1499,11 @@ static const struct imx6_pcie_drvdata drvdata[] = { .mode = DW_PCIE_EP_TYPE, .gpr = "fsl,imx8mm-iomuxc-gpr", }, + [IMX8MP_EP] = { + .variant = IMX8MP_EP, + .mode = DW_PCIE_EP_TYPE, + .gpr = "fsl,imx8mp-iomuxc-gpr", + }, }; static const struct of_device_id imx6_pcie_of_match[] = { @@ -1500,6 +1516,7 @@ static const struct of_device_id imx6_pcie_of_match[] = { { .compatible = "fsl,imx8mp-pcie", .data = &drvdata[IMX8MP], }, { .compatible = "fsl,imx8mq-pcie-ep", .data = &drvdata[IMX8MQ_EP], }, { .compatible = "fsl,imx8mm-pcie-ep", .data = &drvdata[IMX8MM_EP], }, + { .compatible = "fsl,imx8mp-pcie-ep", .data = &drvdata[IMX8MP_EP], }, {}, };