PCI: imx6: Add iMX95 Endpoint (EP) support

Add iMX95 EP support and add 64bit address support.
The internal bus bridge for PCI support 64bit DMA address in iMX95 hence
call dma_set_mask_and_coherent() to set 64 bit DMA mask.

Link: https://lore.kernel.org/r/20240220161924.3871774-15-Frank.Li@nxp.com
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
This commit is contained in:
Frank Li 2024-02-20 11:19:24 -05:00 committed by Lorenzo Pieralisi
parent adfdef7381
commit b7d67c6130

View File

@ -69,6 +69,7 @@ enum imx6_pcie_variants {
IMX8MQ_EP,
IMX8MM_EP,
IMX8MP_EP,
IMX95_EP,
};
#define IMX6_PCIE_FLAG_IMX6_PHY BIT(0)
@ -78,6 +79,7 @@ enum imx6_pcie_variants {
#define IMX6_PCIE_FLAG_HAS_APP_RESET BIT(4)
#define IMX6_PCIE_FLAG_HAS_PHY_RESET BIT(5)
#define IMX6_PCIE_FLAG_HAS_SERDES BIT(6)
#define IMX6_PCIE_FLAG_SUPPORT_64BIT BIT(7)
#define imx6_check_flag(pci, val) (pci->drvdata->flags & val)
@ -610,6 +612,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
break;
case IMX7D:
case IMX95:
case IMX95_EP:
break;
case IMX8MM:
case IMX8MM_EP:
@ -1044,6 +1047,23 @@ static const struct pci_epc_features imx8m_pcie_epc_features = {
.align = SZ_64K,
};
/*
* BAR# | Default BAR enable | Default BAR Type | Default BAR Size | BAR Sizing Scheme
* ================================================================================================
* BAR0 | Enable | 64-bit | 1 MB | Programmable Size
* BAR1 | Disable | 32-bit | 64 KB | Fixed Size
* BAR1 should be disabled if BAR0 is 64bit.
* BAR2 | Enable | 32-bit | 1 MB | Programmable Size
* BAR3 | Enable | 32-bit | 64 KB | Programmable Size
* BAR4 | Enable | 32-bit | 1M | Programmable Size
* BAR5 | Enable | 32-bit | 64 KB | Programmable Size
*/
static const struct pci_epc_features imx95_pcie_epc_features = {
.msi_capable = true,
.bar[BAR_1] = { .type = BAR_FIXED, .fixed_size = SZ_64K, },
.align = SZ_4K,
};
static const struct pci_epc_features*
imx6_pcie_ep_get_features(struct dw_pcie_ep *ep)
{
@ -1086,6 +1106,18 @@ static int imx6_add_pcie_ep(struct imx6_pcie *imx6_pcie,
pci->dbi_base2 = pci->dbi_base + pcie_dbi2_offset;
/*
* FIXME: Ideally, dbi2 base address should come from DT. But since only IMX95 is defining
* "dbi2" in DT, "dbi_base2" is set to NULL here for that platform alone so that the DWC
* core code can fetch that from DT. But once all platform DTs were fixed, this and the
* above "dbi_base2" setting should be removed.
*/
if (device_property_match_string(dev, "reg-names", "dbi2") >= 0)
pci->dbi_base2 = NULL;
if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_SUPPORT_64BIT))
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
ret = dw_pcie_ep_init(ep);
if (ret) {
dev_err(dev, "failed to initialize endpoint\n");
@ -1556,6 +1588,20 @@ static const struct imx6_pcie_drvdata drvdata[] = {
.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
.epc_features = &imx8m_pcie_epc_features,
},
[IMX95_EP] = {
.variant = IMX95_EP,
.flags = IMX6_PCIE_FLAG_HAS_SERDES |
IMX6_PCIE_FLAG_SUPPORT_64BIT,
.clk_names = imx8mq_clks,
.clks_cnt = ARRAY_SIZE(imx8mq_clks),
.ltssm_off = IMX95_PE0_GEN_CTRL_3,
.ltssm_mask = IMX95_PCIE_LTSSM_EN,
.mode_off[0] = IMX95_PE0_GEN_CTRL_1,
.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
.init_phy = imx95_pcie_init_phy,
.epc_features = &imx95_pcie_epc_features,
.mode = DW_PCIE_EP_TYPE,
},
};
static const struct of_device_id imx6_pcie_of_match[] = {
@ -1570,6 +1616,7 @@ static const struct of_device_id imx6_pcie_of_match[] = {
{ .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], },
{ .compatible = "fsl,imx95-pcie-ep", .data = &drvdata[IMX95_EP], },
{},
};