From: Siddharth Vadapalli s-vadapalli@ti.com
[ Upstream commit 82c4be4168e26a5593aaa1002b5678128a638824 ]
The ACSPCIE module is capable of driving the reference clock required by the PCIe Endpoint device. It is an alternative to on-board and external reference clock generators. Enabling the output from the ACSPCIE module's PAD IO Buffers requires clearing the "PAD IO disable" bits of the ACSPCIE_PROXY_CTRL register in the CTRL_MMR register space.
Add support to enable the ACSPCIE reference clock output using the optional device-tree property "ti,syscon-acspcie-proxy-ctrl".
Link: https://lore.kernel.org/linux-pci/20240829105316.1483684-3-s-vadapalli@ti.co... Signed-off-by: Siddharth Vadapalli s-vadapalli@ti.com Signed-off-by: Krzysztof WilczyĆski kwilczynski@kernel.org Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Stable-dep-of: f842d3313ba1 ("PCI: j721e: Fix programming sequence of "strap" settings") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/cadence/pci-j721e.c | 39 +++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c index f76a358e2b5b6..28da514bfa128 100644 --- a/drivers/pci/controller/cadence/pci-j721e.c +++ b/drivers/pci/controller/cadence/pci-j721e.c @@ -48,6 +48,7 @@ enum link_status { #define J721E_MODE_RC BIT(7) #define LANE_COUNT(n) ((n) << 8)
+#define ACSPCIE_PAD_DISABLE_MASK GENMASK(1, 0) #define GENERATION_SEL_MASK GENMASK(1, 0)
struct j721e_pcie { @@ -225,6 +226,36 @@ static int j721e_pcie_set_lane_count(struct j721e_pcie *pcie, return ret; }
+static int j721e_enable_acspcie_refclk(struct j721e_pcie *pcie, + struct regmap *syscon) +{ + struct device *dev = pcie->cdns_pcie->dev; + struct device_node *node = dev->of_node; + u32 mask = ACSPCIE_PAD_DISABLE_MASK; + struct of_phandle_args args; + u32 val; + int ret; + + ret = of_parse_phandle_with_fixed_args(node, + "ti,syscon-acspcie-proxy-ctrl", + 1, 0, &args); + if (ret) { + dev_err(dev, + "ti,syscon-acspcie-proxy-ctrl has invalid arguments\n"); + return ret; + } + + /* Clear PAD IO disable bits to enable refclk output */ + val = ~(args.args[0]); + ret = regmap_update_bits(syscon, 0, mask, val); + if (ret) { + dev_err(dev, "failed to enable ACSPCIE refclk: %d\n", ret); + return ret; + } + + return 0; +} + static int j721e_pcie_ctrl_init(struct j721e_pcie *pcie) { struct device *dev = pcie->cdns_pcie->dev; @@ -264,7 +295,13 @@ static int j721e_pcie_ctrl_init(struct j721e_pcie *pcie) return ret; }
- return 0; + /* Enable ACSPCIE refclk output if the optional property exists */ + syscon = syscon_regmap_lookup_by_phandle_optional(node, + "ti,syscon-acspcie-proxy-ctrl"); + if (!syscon) + return 0; + + return j721e_enable_acspcie_refclk(pcie, syscon); }
static int cdns_ti_pcie_config_read(struct pci_bus *bus, unsigned int devfn,