xref: /linux/drivers/pci/controller/dwc/pcie-stm32.c (revision 43dfc13ca972988e620a6edb72956981b75ab6b0)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * STMicroelectronics STM32MP25 PCIe root complex driver.
4  *
5  * Copyright (C) 2025 STMicroelectronics
6  * Author: Christian Bruel <christian.bruel@foss.st.com>
7  */
8 
9 #include <linux/clk.h>
10 #include <linux/delay.h>
11 #include <linux/device.h>
12 #include <linux/err.h>
13 #include <linux/gpio/consumer.h>
14 #include <linux/irq.h>
15 #include <linux/mfd/syscon.h>
16 #include <linux/mod_devicetable.h>
17 #include <linux/module.h>
18 #include <linux/of.h>
19 #include <linux/of_platform.h>
20 #include <linux/phy/phy.h>
21 #include <linux/pinctrl/consumer.h>
22 #include <linux/platform_device.h>
23 #include <linux/pm.h>
24 #include <linux/pm_runtime.h>
25 #include <linux/pm_wakeirq.h>
26 #include <linux/regmap.h>
27 #include <linux/reset.h>
28 #include <linux/stddef.h>
29 
30 #include "../../pci.h"
31 
32 #include "pcie-designware.h"
33 #include "pcie-stm32.h"
34 
35 struct stm32_pcie {
36 	struct dw_pcie pci;
37 	struct regmap *regmap;
38 	struct reset_control *rst;
39 	struct phy *phy;
40 	struct clk *clk;
41 	struct gpio_desc *perst_gpio;
42 	struct gpio_desc *wake_gpio;
43 };
44 
45 static void stm32_pcie_deassert_perst(struct stm32_pcie *stm32_pcie)
46 {
47 	if (stm32_pcie->perst_gpio) {
48 		msleep(PCIE_T_PVPERL_MS);
49 		gpiod_set_value(stm32_pcie->perst_gpio, 0);
50 	}
51 
52 	msleep(PCIE_RESET_CONFIG_WAIT_MS);
53 }
54 
55 static void stm32_pcie_assert_perst(struct stm32_pcie *stm32_pcie)
56 {
57 	gpiod_set_value(stm32_pcie->perst_gpio, 1);
58 }
59 
60 static int stm32_pcie_start_link(struct dw_pcie *pci)
61 {
62 	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
63 
64 	return regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
65 				  STM32MP25_PCIECR_LTSSM_EN,
66 				  STM32MP25_PCIECR_LTSSM_EN);
67 }
68 
69 static void stm32_pcie_stop_link(struct dw_pcie *pci)
70 {
71 	struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
72 
73 	regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
74 			   STM32MP25_PCIECR_LTSSM_EN, 0);
75 }
76 
77 static int stm32_pcie_suspend_noirq(struct device *dev)
78 {
79 	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
80 	int ret;
81 
82 	ret = dw_pcie_suspend_noirq(&stm32_pcie->pci);
83 	if (ret)
84 		return ret;
85 
86 	stm32_pcie_assert_perst(stm32_pcie);
87 
88 	clk_disable_unprepare(stm32_pcie->clk);
89 
90 	if (!device_wakeup_path(dev))
91 		phy_exit(stm32_pcie->phy);
92 
93 	return pinctrl_pm_select_sleep_state(dev);
94 }
95 
96 static int stm32_pcie_resume_noirq(struct device *dev)
97 {
98 	struct stm32_pcie *stm32_pcie = dev_get_drvdata(dev);
99 	int ret;
100 
101 	/*
102 	 * The core clock is gated with CLKREQ# from the COMBOPHY REFCLK,
103 	 * thus if no device is present, must deassert it with a GPIO from
104 	 * pinctrl pinmux before accessing the DBI registers.
105 	 */
106 	ret = pinctrl_pm_select_init_state(dev);
107 	if (ret) {
108 		dev_err(dev, "Failed to activate pinctrl pm state: %d\n", ret);
109 		return ret;
110 	}
111 
112 	if (!device_wakeup_path(dev)) {
113 		ret = phy_init(stm32_pcie->phy);
114 		if (ret) {
115 			pinctrl_pm_select_default_state(dev);
116 			return ret;
117 		}
118 	}
119 
120 	ret = clk_prepare_enable(stm32_pcie->clk);
121 	if (ret)
122 		goto err_phy_exit;
123 
124 	stm32_pcie_deassert_perst(stm32_pcie);
125 
126 	ret = dw_pcie_resume_noirq(&stm32_pcie->pci);
127 	if (ret)
128 		goto err_disable_clk;
129 
130 	pinctrl_pm_select_default_state(dev);
131 
132 	return 0;
133 
134 err_disable_clk:
135 	stm32_pcie_assert_perst(stm32_pcie);
136 	clk_disable_unprepare(stm32_pcie->clk);
137 
138 err_phy_exit:
139 	phy_exit(stm32_pcie->phy);
140 	pinctrl_pm_select_default_state(dev);
141 
142 	return ret;
143 }
144 
145 static const struct dev_pm_ops stm32_pcie_pm_ops = {
146 	NOIRQ_SYSTEM_SLEEP_PM_OPS(stm32_pcie_suspend_noirq,
147 				  stm32_pcie_resume_noirq)
148 };
149 
150 static const struct dw_pcie_host_ops stm32_pcie_host_ops = {
151 };
152 
153 static const struct dw_pcie_ops dw_pcie_ops = {
154 	.start_link = stm32_pcie_start_link,
155 	.stop_link = stm32_pcie_stop_link
156 };
157 
158 static int stm32_add_pcie_port(struct stm32_pcie *stm32_pcie)
159 {
160 	struct device *dev = stm32_pcie->pci.dev;
161 	unsigned int wake_irq;
162 	int ret;
163 
164 	ret = phy_set_mode(stm32_pcie->phy, PHY_MODE_PCIE);
165 	if (ret)
166 		return ret;
167 
168 	ret = phy_init(stm32_pcie->phy);
169 	if (ret)
170 		return ret;
171 
172 	ret = regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR,
173 				 STM32MP25_PCIECR_TYPE_MASK,
174 				 STM32MP25_PCIECR_RC);
175 	if (ret)
176 		goto err_phy_exit;
177 
178 	stm32_pcie_deassert_perst(stm32_pcie);
179 
180 	if (stm32_pcie->wake_gpio) {
181 		wake_irq = gpiod_to_irq(stm32_pcie->wake_gpio);
182 		ret = dev_pm_set_dedicated_wake_irq(dev, wake_irq);
183 		if (ret) {
184 			dev_err(dev, "Failed to enable wakeup irq %d\n", ret);
185 			goto err_assert_perst;
186 		}
187 		irq_set_irq_type(wake_irq, IRQ_TYPE_EDGE_FALLING);
188 	}
189 
190 	return 0;
191 
192 err_assert_perst:
193 	stm32_pcie_assert_perst(stm32_pcie);
194 
195 err_phy_exit:
196 	phy_exit(stm32_pcie->phy);
197 
198 	return ret;
199 }
200 
201 static void stm32_remove_pcie_port(struct stm32_pcie *stm32_pcie)
202 {
203 	dev_pm_clear_wake_irq(stm32_pcie->pci.dev);
204 
205 	stm32_pcie_assert_perst(stm32_pcie);
206 
207 	phy_exit(stm32_pcie->phy);
208 }
209 
210 static int stm32_pcie_parse_port(struct stm32_pcie *stm32_pcie)
211 {
212 	struct device *dev = stm32_pcie->pci.dev;
213 	struct device_node *root_port;
214 
215 	root_port = of_get_next_available_child(dev->of_node, NULL);
216 
217 	stm32_pcie->phy = devm_of_phy_get(dev, root_port, NULL);
218 	if (IS_ERR(stm32_pcie->phy)) {
219 		of_node_put(root_port);
220 		return dev_err_probe(dev, PTR_ERR(stm32_pcie->phy),
221 				     "Failed to get pcie-phy\n");
222 	}
223 
224 	stm32_pcie->perst_gpio = devm_fwnode_gpiod_get(dev, of_fwnode_handle(root_port),
225 						       "reset", GPIOD_OUT_HIGH, NULL);
226 	if (IS_ERR(stm32_pcie->perst_gpio)) {
227 		if (PTR_ERR(stm32_pcie->perst_gpio) != -ENOENT) {
228 			of_node_put(root_port);
229 			return dev_err_probe(dev, PTR_ERR(stm32_pcie->perst_gpio),
230 					     "Failed to get reset GPIO\n");
231 		}
232 		stm32_pcie->perst_gpio = NULL;
233 	}
234 
235 	stm32_pcie->wake_gpio = devm_fwnode_gpiod_get(dev, of_fwnode_handle(root_port),
236 						      "wake", GPIOD_IN, NULL);
237 
238 	if (IS_ERR(stm32_pcie->wake_gpio)) {
239 		if (PTR_ERR(stm32_pcie->wake_gpio) != -ENOENT) {
240 			of_node_put(root_port);
241 			return dev_err_probe(dev, PTR_ERR(stm32_pcie->wake_gpio),
242 					     "Failed to get wake GPIO\n");
243 		}
244 		stm32_pcie->wake_gpio = NULL;
245 	}
246 
247 	of_node_put(root_port);
248 
249 	return 0;
250 }
251 
252 static int stm32_pcie_probe(struct platform_device *pdev)
253 {
254 	struct stm32_pcie *stm32_pcie;
255 	struct device *dev = &pdev->dev;
256 	int ret;
257 
258 	stm32_pcie = devm_kzalloc(dev, sizeof(*stm32_pcie), GFP_KERNEL);
259 	if (!stm32_pcie)
260 		return -ENOMEM;
261 
262 	stm32_pcie->pci.dev = dev;
263 	stm32_pcie->pci.ops = &dw_pcie_ops;
264 	stm32_pcie->pci.pp.ops = &stm32_pcie_host_ops;
265 
266 	stm32_pcie->regmap = syscon_regmap_lookup_by_compatible("st,stm32mp25-syscfg");
267 	if (IS_ERR(stm32_pcie->regmap))
268 		return dev_err_probe(dev, PTR_ERR(stm32_pcie->regmap),
269 				     "No syscfg specified\n");
270 
271 	stm32_pcie->clk = devm_clk_get(dev, NULL);
272 	if (IS_ERR(stm32_pcie->clk))
273 		return dev_err_probe(dev, PTR_ERR(stm32_pcie->clk),
274 				     "Failed to get PCIe clock source\n");
275 
276 	stm32_pcie->rst = devm_reset_control_get_exclusive(dev, NULL);
277 	if (IS_ERR(stm32_pcie->rst))
278 		return dev_err_probe(dev, PTR_ERR(stm32_pcie->rst),
279 				     "Failed to get PCIe reset\n");
280 
281 	ret = stm32_pcie_parse_port(stm32_pcie);
282 	if (ret)
283 		return ret;
284 
285 	platform_set_drvdata(pdev, stm32_pcie);
286 
287 	ret = stm32_add_pcie_port(stm32_pcie);
288 	if (ret)
289 		return ret;
290 
291 	reset_control_assert(stm32_pcie->rst);
292 	reset_control_deassert(stm32_pcie->rst);
293 
294 	ret = clk_prepare_enable(stm32_pcie->clk);
295 	if (ret) {
296 		dev_err(dev, "Core clock enable failed %d\n", ret);
297 		goto err_remove_port;
298 	}
299 
300 	ret = pm_runtime_set_active(dev);
301 	if (ret < 0) {
302 		dev_err_probe(dev, ret, "Failed to activate runtime PM\n");
303 		goto err_disable_clk;
304 	}
305 
306 	pm_runtime_no_callbacks(dev);
307 
308 	ret = devm_pm_runtime_enable(dev);
309 	if (ret < 0) {
310 		dev_err_probe(dev, ret, "Failed to enable runtime PM\n");
311 		goto err_disable_clk;
312 	}
313 
314 	ret = dw_pcie_host_init(&stm32_pcie->pci.pp);
315 	if (ret)
316 		goto err_disable_clk;
317 
318 	if (stm32_pcie->wake_gpio)
319 		device_init_wakeup(dev, true);
320 
321 	return 0;
322 
323 err_disable_clk:
324 	clk_disable_unprepare(stm32_pcie->clk);
325 
326 err_remove_port:
327 	stm32_remove_pcie_port(stm32_pcie);
328 
329 	return ret;
330 }
331 
332 static void stm32_pcie_remove(struct platform_device *pdev)
333 {
334 	struct stm32_pcie *stm32_pcie = platform_get_drvdata(pdev);
335 	struct dw_pcie_rp *pp = &stm32_pcie->pci.pp;
336 
337 	if (stm32_pcie->wake_gpio)
338 		device_init_wakeup(&pdev->dev, false);
339 
340 	dw_pcie_host_deinit(pp);
341 
342 	clk_disable_unprepare(stm32_pcie->clk);
343 
344 	stm32_remove_pcie_port(stm32_pcie);
345 
346 	pm_runtime_put_noidle(&pdev->dev);
347 }
348 
349 static const struct of_device_id stm32_pcie_of_match[] = {
350 	{ .compatible = "st,stm32mp25-pcie-rc" },
351 	{},
352 };
353 
354 static struct platform_driver stm32_pcie_driver = {
355 	.probe = stm32_pcie_probe,
356 	.remove = stm32_pcie_remove,
357 	.driver = {
358 		.name = "stm32-pcie",
359 		.of_match_table = stm32_pcie_of_match,
360 		.pm = &stm32_pcie_pm_ops,
361 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
362 	},
363 };
364 
365 module_platform_driver(stm32_pcie_driver);
366 
367 MODULE_AUTHOR("Christian Bruel <christian.bruel@foss.st.com>");
368 MODULE_DESCRIPTION("STM32MP25 PCIe Controller driver");
369 MODULE_LICENSE("GPL");
370 MODULE_DEVICE_TABLE(of, stm32_pcie_of_match);
371