Skip to content

Commit f5c04da

Browse files
nxpfrankliLorenzo Pieralisi
authored andcommitted
PCI: imx6: Add iMX95 PCIe Root Complex support
Add iMX95 PCIe Root Complex support. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Frank Li <[email protected]> Signed-off-by: Lorenzo Pieralisi <[email protected]> Reviewed-by: Manivannan Sadhasivam <[email protected]>
1 parent 671a89c commit f5c04da

File tree

1 file changed

+71
-5
lines changed

1 file changed

+71
-5
lines changed

drivers/pci/controller/dwc/pci-imx6.c

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,19 @@
4242
#define IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE GENMASK(11, 8)
4343
#define IMX8MQ_PCIE2_BASE_ADDR 0x33c00000
4444

45+
#define IMX95_PCIE_PHY_GEN_CTRL 0x0
46+
#define IMX95_PCIE_REF_USE_PAD BIT(17)
47+
48+
#define IMX95_PCIE_SS_RW_REG_0 0xf0
49+
#define IMX95_PCIE_REF_CLKEN BIT(23)
50+
#define IMX95_PCIE_PHY_CR_PARA_SEL BIT(9)
51+
52+
#define IMX95_PE0_GEN_CTRL_1 0x1050
53+
#define IMX95_PCIE_DEVICE_TYPE GENMASK(3, 0)
54+
55+
#define IMX95_PE0_GEN_CTRL_3 0x1058
56+
#define IMX95_PCIE_LTSSM_EN BIT(0)
57+
4558
#define to_imx6_pcie(x) dev_get_drvdata((x)->dev)
4659

4760
enum imx6_pcie_variants {
@@ -52,6 +65,7 @@ enum imx6_pcie_variants {
5265
IMX8MQ,
5366
IMX8MM,
5467
IMX8MP,
68+
IMX95,
5569
IMX8MQ_EP,
5670
IMX8MM_EP,
5771
IMX8MP_EP,
@@ -63,6 +77,7 @@ enum imx6_pcie_variants {
6377
#define IMX6_PCIE_FLAG_HAS_PHYDRV BIT(3)
6478
#define IMX6_PCIE_FLAG_HAS_APP_RESET BIT(4)
6579
#define IMX6_PCIE_FLAG_HAS_PHY_RESET BIT(5)
80+
#define IMX6_PCIE_FLAG_HAS_SERDES BIT(6)
6681

6782
#define imx6_check_flag(pci, val) (pci->drvdata->flags & val)
6883

@@ -179,6 +194,24 @@ static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie)
179194
return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14;
180195
}
181196

197+
static int imx95_pcie_init_phy(struct imx6_pcie *imx6_pcie)
198+
{
199+
regmap_update_bits(imx6_pcie->iomuxc_gpr,
200+
IMX95_PCIE_SS_RW_REG_0,
201+
IMX95_PCIE_PHY_CR_PARA_SEL,
202+
IMX95_PCIE_PHY_CR_PARA_SEL);
203+
204+
regmap_update_bits(imx6_pcie->iomuxc_gpr,
205+
IMX95_PCIE_PHY_GEN_CTRL,
206+
IMX95_PCIE_REF_USE_PAD, 0);
207+
regmap_update_bits(imx6_pcie->iomuxc_gpr,
208+
IMX95_PCIE_SS_RW_REG_0,
209+
IMX95_PCIE_REF_CLKEN,
210+
IMX95_PCIE_REF_CLKEN);
211+
212+
return 0;
213+
}
214+
182215
static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie)
183216
{
184217
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)
575608
IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
576609
break;
577610
case IMX7D:
611+
case IMX95:
578612
break;
579613
case IMX8MM:
580614
case IMX8MM_EP:
@@ -1279,12 +1313,32 @@ static int imx6_pcie_probe(struct platform_device *pdev)
12791313
return PTR_ERR(imx6_pcie->turnoff_reset);
12801314
}
12811315

1316+
if (imx6_pcie->drvdata->gpr) {
12821317
/* Grab GPR config register range */
1283-
imx6_pcie->iomuxc_gpr =
1284-
syscon_regmap_lookup_by_compatible(imx6_pcie->drvdata->gpr);
1285-
if (IS_ERR(imx6_pcie->iomuxc_gpr)) {
1286-
dev_err(dev, "unable to find iomuxc registers\n");
1287-
return PTR_ERR(imx6_pcie->iomuxc_gpr);
1318+
imx6_pcie->iomuxc_gpr =
1319+
syscon_regmap_lookup_by_compatible(imx6_pcie->drvdata->gpr);
1320+
if (IS_ERR(imx6_pcie->iomuxc_gpr))
1321+
return dev_err_probe(dev, PTR_ERR(imx6_pcie->iomuxc_gpr),
1322+
"unable to find iomuxc registers\n");
1323+
}
1324+
1325+
if (imx6_check_flag(imx6_pcie, IMX6_PCIE_FLAG_HAS_SERDES)) {
1326+
void __iomem *off = devm_platform_ioremap_resource_byname(pdev, "app");
1327+
1328+
if (IS_ERR(off))
1329+
return dev_err_probe(dev, PTR_ERR(off),
1330+
"unable to find serdes registers\n");
1331+
1332+
static const struct regmap_config regmap_config = {
1333+
.reg_bits = 32,
1334+
.val_bits = 32,
1335+
.reg_stride = 4,
1336+
};
1337+
1338+
imx6_pcie->iomuxc_gpr = devm_regmap_init_mmio(dev, off, &regmap_config);
1339+
if (IS_ERR(imx6_pcie->iomuxc_gpr))
1340+
return dev_err_probe(dev, PTR_ERR(imx6_pcie->iomuxc_gpr),
1341+
"unable to find iomuxc registers\n");
12881342
}
12891343

12901344
/* Grab PCIe PHY Tx Settings */
@@ -1457,6 +1511,17 @@ static const struct imx6_pcie_drvdata drvdata[] = {
14571511
.mode_off[0] = IOMUXC_GPR12,
14581512
.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
14591513
},
1514+
[IMX95] = {
1515+
.variant = IMX95,
1516+
.flags = IMX6_PCIE_FLAG_HAS_SERDES,
1517+
.clk_names = imx8mq_clks,
1518+
.clks_cnt = ARRAY_SIZE(imx8mq_clks),
1519+
.ltssm_off = IMX95_PE0_GEN_CTRL_3,
1520+
.ltssm_mask = IMX95_PCIE_LTSSM_EN,
1521+
.mode_off[0] = IMX95_PE0_GEN_CTRL_1,
1522+
.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
1523+
.init_phy = imx95_pcie_init_phy,
1524+
},
14601525
[IMX8MQ_EP] = {
14611526
.variant = IMX8MQ_EP,
14621527
.flags = IMX6_PCIE_FLAG_HAS_APP_RESET |
@@ -1501,6 +1566,7 @@ static const struct of_device_id imx6_pcie_of_match[] = {
15011566
{ .compatible = "fsl,imx8mq-pcie", .data = &drvdata[IMX8MQ], },
15021567
{ .compatible = "fsl,imx8mm-pcie", .data = &drvdata[IMX8MM], },
15031568
{ .compatible = "fsl,imx8mp-pcie", .data = &drvdata[IMX8MP], },
1569+
{ .compatible = "fsl,imx95-pcie", .data = &drvdata[IMX95], },
15041570
{ .compatible = "fsl,imx8mq-pcie-ep", .data = &drvdata[IMX8MQ_EP], },
15051571
{ .compatible = "fsl,imx8mm-pcie-ep", .data = &drvdata[IMX8MM_EP], },
15061572
{ .compatible = "fsl,imx8mp-pcie-ep", .data = &drvdata[IMX8MP_EP], },

0 commit comments

Comments
 (0)