]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
PCI: imx6: Add Refclk for i.MX95 PCIe
authorRichard Zhu <hongxing.zhu@nxp.com>
Tue, 26 Nov 2024 07:56:54 +0000 (15:56 +0800)
committerBjorn Helgaas <bhelgaas@google.com>
Thu, 16 Jan 2025 20:20:37 +0000 (14:20 -0600)
Add "ref" clock to enable Refclk. To avoid breaking DT backwards
compatibility, the i.MX95 "ref" clock is optional. Use
devm_clk_get_optional() to fetch i.MX95 PCIe optional clocks in driver.

If using external clock, "ref" clock should point to external reference.

If using internal clock, CREF_EN in LAST_TO_REG controls reference output,
implemented in drivers/clk/imx/clk-imx95-blk-ctl.c.

Link: https://lore.kernel.org/r/20241126075702.4099164-3-hongxing.zhu@nxp.com
Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Signed-off-by: Krzysztof WilczyƄski <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
drivers/pci/controller/dwc/pci-imx6.c

index 2366648793b35d487213b75819119278cc9db843..4beb12b6e6eae341d8279d44174279fe0d5fcfd1 100644 (file)
@@ -104,6 +104,7 @@ struct imx_pcie_drvdata {
        const char *gpr;
        const char * const *clk_names;
        const u32 clks_cnt;
+       const u32 clks_optional_cnt;
        const u32 ltssm_off;
        const u32 ltssm_mask;
        const u32 mode_off[IMX_PCIE_MAX_INSTANCES];
@@ -1322,9 +1323,8 @@ static int imx_pcie_probe(struct platform_device *pdev)
        struct device_node *np;
        struct resource *dbi_base;
        struct device_node *node = dev->of_node;
-       int ret;
+       int i, ret, req_cnt;
        u16 val;
-       int i;
 
        imx_pcie = devm_kzalloc(dev, sizeof(*imx_pcie), GFP_KERNEL);
        if (!imx_pcie)
@@ -1374,9 +1374,13 @@ static int imx_pcie_probe(struct platform_device *pdev)
                imx_pcie->clks[i].id = imx_pcie->drvdata->clk_names[i];
 
        /* Fetch clocks */
-       ret = devm_clk_bulk_get(dev, imx_pcie->drvdata->clks_cnt, imx_pcie->clks);
+       req_cnt = imx_pcie->drvdata->clks_cnt - imx_pcie->drvdata->clks_optional_cnt;
+       ret = devm_clk_bulk_get(dev, req_cnt, imx_pcie->clks);
        if (ret)
                return ret;
+       imx_pcie->clks[req_cnt].clk = devm_clk_get_optional(dev, "ref");
+       if (IS_ERR(imx_pcie->clks[req_cnt].clk))
+               return PTR_ERR(imx_pcie->clks[req_cnt].clk);
 
        if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_PHYDRV)) {
                imx_pcie->phy = devm_phy_get(dev, "pcie-phy");
@@ -1524,6 +1528,7 @@ static const char * const imx8mm_clks[] = {"pcie_bus", "pcie", "pcie_aux"};
 static const char * const imx8mq_clks[] = {"pcie_bus", "pcie", "pcie_phy", "pcie_aux"};
 static const char * const imx6sx_clks[] = {"pcie_bus", "pcie", "pcie_phy", "pcie_inbound_axi"};
 static const char * const imx8q_clks[] = {"mstr", "slv", "dbi"};
+static const char * const imx95_clks[] = {"pcie_bus", "pcie", "pcie_phy", "pcie_aux", "ref"};
 
 static const struct imx_pcie_drvdata drvdata[] = {
        [IMX6Q] = {
@@ -1639,8 +1644,9 @@ static const struct imx_pcie_drvdata drvdata[] = {
        [IMX95] = {
                .variant = IMX95,
                .flags = IMX_PCIE_FLAG_HAS_SERDES,
-               .clk_names = imx8mq_clks,
-               .clks_cnt = ARRAY_SIZE(imx8mq_clks),
+               .clk_names = imx95_clks,
+               .clks_cnt = ARRAY_SIZE(imx95_clks),
+               .clks_optional_cnt = 1,
                .ltssm_off = IMX95_PE0_GEN_CTRL_3,
                .ltssm_mask = IMX95_PCIE_LTSSM_EN,
                .mode_off[0]  = IMX95_PE0_GEN_CTRL_1,