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

From: Hongxing Zhu
Date: Wed Aug 02 2023 - 22:43:18 EST


Hi Frank:
Thanks for your reply.

> -----Original Message-----
> From: Frank Li <frank.li@xxxxxxx>
> Sent: 2023年8月3日 5:54
> To: Hongxing Zhu <hongxing.zhu@xxxxxxx>
> Cc: l.stach@xxxxxxxxxxxxxx; shawnguo@xxxxxxxxxx; lpieralisi@xxxxxxxxxx;
> robh+dt@xxxxxxxxxx; krzysztof.kozlowski+dt@xxxxxxxxxx;
> linux-pci@xxxxxxxxxxxxxxx; devicetree@xxxxxxxxxxxxxxx;
> linux-arm-kernel@xxxxxxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx;
> kernel@xxxxxxxxxxxxxx; dl-linux-imx <linux-imx@xxxxxxx>
> 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@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.
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
> >