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