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:
parent
adfdef7381
commit
b7d67c6130
@ -69,6 +69,7 @@ enum imx6_pcie_variants {
|
|||||||
IMX8MQ_EP,
|
IMX8MQ_EP,
|
||||||
IMX8MM_EP,
|
IMX8MM_EP,
|
||||||
IMX8MP_EP,
|
IMX8MP_EP,
|
||||||
|
IMX95_EP,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IMX6_PCIE_FLAG_IMX6_PHY BIT(0)
|
#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_APP_RESET BIT(4)
|
||||||
#define IMX6_PCIE_FLAG_HAS_PHY_RESET BIT(5)
|
#define IMX6_PCIE_FLAG_HAS_PHY_RESET BIT(5)
|
||||||
#define IMX6_PCIE_FLAG_HAS_SERDES BIT(6)
|
#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)
|
#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;
|
break;
|
||||||
case IMX7D:
|
case IMX7D:
|
||||||
case IMX95:
|
case IMX95:
|
||||||
|
case IMX95_EP:
|
||||||
break;
|
break;
|
||||||
case IMX8MM:
|
case IMX8MM:
|
||||||
case IMX8MM_EP:
|
case IMX8MM_EP:
|
||||||
@ -1044,6 +1047,23 @@ static const struct pci_epc_features imx8m_pcie_epc_features = {
|
|||||||
.align = SZ_64K,
|
.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*
|
static const struct pci_epc_features*
|
||||||
imx6_pcie_ep_get_features(struct dw_pcie_ep *ep)
|
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;
|
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);
|
ret = dw_pcie_ep_init(ep);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "failed to initialize endpoint\n");
|
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,
|
.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
|
||||||
.epc_features = &imx8m_pcie_epc_features,
|
.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[] = {
|
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,imx8mq-pcie-ep", .data = &drvdata[IMX8MQ_EP], },
|
||||||
{ .compatible = "fsl,imx8mm-pcie-ep", .data = &drvdata[IMX8MM_EP], },
|
{ .compatible = "fsl,imx8mm-pcie-ep", .data = &drvdata[IMX8MM_EP], },
|
||||||
{ .compatible = "fsl,imx8mp-pcie-ep", .data = &drvdata[IMX8MP_EP], },
|
{ .compatible = "fsl,imx8mp-pcie-ep", .data = &drvdata[IMX8MP_EP], },
|
||||||
|
{ .compatible = "fsl,imx95-pcie-ep", .data = &drvdata[IMX95_EP], },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user