PCI: imx6: Add iMX95 PCIe Root Complex support
Add iMX95 PCIe Root Complex support. Link: https://lore.kernel.org/r/20240220161924.3871774-11-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
671a89c451
commit
f5c04da3a1
@ -42,6 +42,19 @@
|
||||
#define IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE GENMASK(11, 8)
|
||||
#define IMX8MQ_PCIE2_BASE_ADDR 0x33c00000
|
||||
|
||||
#define IMX95_PCIE_PHY_GEN_CTRL 0x0
|
||||
#define IMX95_PCIE_REF_USE_PAD BIT(17)
|
||||
|
||||
#define IMX95_PCIE_SS_RW_REG_0 0xf0
|
||||
#define IMX95_PCIE_REF_CLKEN BIT(23)
|
||||
#define IMX95_PCIE_PHY_CR_PARA_SEL BIT(9)
|
||||
|
||||
#define IMX95_PE0_GEN_CTRL_1 0x1050
|
||||
#define IMX95_PCIE_DEVICE_TYPE GENMASK(3, 0)
|
||||
|
||||
#define IMX95_PE0_GEN_CTRL_3 0x1058
|
||||
#define IMX95_PCIE_LTSSM_EN BIT(0)
|
||||
|
||||
#define to_imx6_pcie(x) dev_get_drvdata((x)->dev)
|
||||
|
||||
enum imx6_pcie_variants {
|
||||
@ -52,6 +65,7 @@ enum imx6_pcie_variants {
|
||||
IMX8MQ,
|
||||
IMX8MM,
|
||||
IMX8MP,
|
||||
IMX95,
|
||||
IMX8MQ_EP,
|
||||
IMX8MM_EP,
|
||||
IMX8MP_EP,
|
||||
@ -63,6 +77,7 @@ enum imx6_pcie_variants {
|
||||
#define IMX6_PCIE_FLAG_HAS_PHYDRV BIT(3)
|
||||
#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_check_flag(pci, val) (pci->drvdata->flags & val)
|
||||
|
||||
@ -179,6 +194,24 @@ static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie)
|
||||
return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14;
|
||||
}
|
||||
|
||||
static int imx95_pcie_init_phy(struct imx6_pcie *imx6_pcie)
|
||||
{
|
||||
regmap_update_bits(imx6_pcie->iomuxc_gpr,
|
||||
IMX95_PCIE_SS_RW_REG_0,
|
||||
IMX95_PCIE_PHY_CR_PARA_SEL,
|
||||
IMX95_PCIE_PHY_CR_PARA_SEL);
|
||||
|
||||
regmap_update_bits(imx6_pcie->iomuxc_gpr,
|
||||
IMX95_PCIE_PHY_GEN_CTRL,
|
||||
IMX95_PCIE_REF_USE_PAD, 0);
|
||||
regmap_update_bits(imx6_pcie->iomuxc_gpr,
|
||||
IMX95_PCIE_SS_RW_REG_0,
|
||||
IMX95_PCIE_REF_CLKEN,
|
||||
IMX95_PCIE_REF_CLKEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie)
|
||||
{
|
||||
const struct imx6_pcie_drvdata *drvdata = imx6_pcie->drvdata;
|
||||
@ -575,6 +608,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
|
||||
IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
|
||||
break;
|
||||
case IMX7D:
|
||||
case IMX95:
|
||||
break;
|
||||
case IMX8MM:
|
||||
case IMX8MM_EP:
|
||||
@ -1279,12 +1313,32 @@ static int imx6_pcie_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(imx6_pcie->turnoff_reset);
|
||||
}
|
||||
|
||||
if (imx6_pcie->drvdata->gpr) {
|
||||
/* Grab GPR config register range */
|
||||
imx6_pcie->iomuxc_gpr =
|
||||
syscon_regmap_lookup_by_compatible(imx6_pcie->drvdata->gpr);
|
||||
if (IS_ERR(imx6_pcie->iomuxc_gpr)) {
|
||||
dev_err(dev, "unable to find iomuxc registers\n");
|
||||
return PTR_ERR(imx6_pcie->iomuxc_gpr);
|
||||
imx6_pcie->iomuxc_gpr =
|
||||
syscon_regmap_lookup_by_compatible(imx6_pcie->drvdata->gpr);
|
||||
if (IS_ERR(imx6_pcie->iomuxc_gpr))
|
||||
return dev_err_probe(dev, PTR_ERR(imx6_pcie->iomuxc_gpr),
|
||||
"unable to find iomuxc registers\n");
|
||||
}
|
||||
|
||||
if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_SERDES)) {
|
||||
void __iomem *off = devm_platform_ioremap_resource_byname(pdev, "app");
|
||||
|
||||
if (IS_ERR(off))
|
||||
return dev_err_probe(dev, PTR_ERR(off),
|
||||
"unable to find serdes registers\n");
|
||||
|
||||
static const struct regmap_config regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
};
|
||||
|
||||
imx6_pcie->iomuxc_gpr = devm_regmap_init_mmio(dev, off, ®map_config);
|
||||
if (IS_ERR(imx6_pcie->iomuxc_gpr))
|
||||
return dev_err_probe(dev, PTR_ERR(imx6_pcie->iomuxc_gpr),
|
||||
"unable to find iomuxc registers\n");
|
||||
}
|
||||
|
||||
/* Grab PCIe PHY Tx Settings */
|
||||
@ -1457,6 +1511,17 @@ static const struct imx6_pcie_drvdata drvdata[] = {
|
||||
.mode_off[0] = IOMUXC_GPR12,
|
||||
.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
|
||||
},
|
||||
[IMX95] = {
|
||||
.variant = IMX95,
|
||||
.flags = IMX6_PCIE_FLAG_HAS_SERDES,
|
||||
.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,
|
||||
},
|
||||
[IMX8MQ_EP] = {
|
||||
.variant = IMX8MQ_EP,
|
||||
.flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
|
||||
@ -1501,6 +1566,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,imx95-pcie", .data = &drvdata[IMX95], },
|
||||
{ .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], },
|
||||
|
Loading…
Reference in New Issue
Block a user