Commit 13725091 authored by Richard Zhu's avatar Richard Zhu Committed by Bjorn Helgaas
Browse files

PCI: imx6: Add Refclk for i.MX95 PCIe

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: default avatarRichard Zhu <hongxing.zhu@nxp.com>
Signed-off-by: default avatarKrzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: default avatarFrank Li <Frank.Li@nxp.com>
parent d4627402
Loading
Loading
Loading
Loading
+11 −5
Original line number Diff line number Diff line
@@ -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,