xref: /linux/drivers/pci/controller/dwc/pcie-nxp-s32g.c (revision 24f171c7e145f43b9f187578e89b0982ce87e54c)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * PCIe host controller driver for NXP S32G SoCs
4  *
5  * Copyright 2019-2025 NXP
6  */
7 
8 #include <linux/interrupt.h>
9 #include <linux/io.h>
10 #include <linux/module.h>
11 #include <linux/of_device.h>
12 #include <linux/of_address.h>
13 #include <linux/pci.h>
14 #include <linux/phy/phy.h>
15 #include <linux/platform_device.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/sizes.h>
18 #include <linux/types.h>
19 
20 #include "pcie-designware.h"
21 
22 /* PCIe controller Sub-System */
23 
24 /* PCIe controller 0 General Control 1 */
25 #define PCIE_S32G_PE0_GEN_CTRL_1		0x50
26 #define DEVICE_TYPE_MASK			GENMASK(3, 0)
27 #define SRIS_MODE				BIT(8)
28 
29 /* PCIe controller 0 General Control 3 */
30 #define PCIE_S32G_PE0_GEN_CTRL_3		0x58
31 #define LTSSM_EN				BIT(0)
32 
33 /* PCIe Controller 0  Interrupt Status */
34 #define PCIE_S32G_PE0_INT_STS			0xE8
35 #define HP_INT_STS				BIT(6)
36 
37 /* Boundary between peripheral space and physical memory space */
38 #define S32G_MEMORY_BOUNDARY_ADDR		0x80000000
39 
40 struct s32g_pcie_port {
41 	struct list_head list;
42 	struct phy *phy;
43 };
44 
45 struct s32g_pcie {
46 	struct dw_pcie	pci;
47 	void __iomem *ctrl_base;
48 	struct list_head ports;
49 };
50 
51 #define to_s32g_from_dw_pcie(x) \
52 	container_of(x, struct s32g_pcie, pci)
53 
54 static void s32g_pcie_writel_ctrl(struct s32g_pcie *s32g_pp, u32 reg, u32 val)
55 {
56 	writel(val, s32g_pp->ctrl_base + reg);
57 }
58 
59 static u32 s32g_pcie_readl_ctrl(struct s32g_pcie *s32g_pp, u32 reg)
60 {
61 	return readl(s32g_pp->ctrl_base + reg);
62 }
63 
64 static void s32g_pcie_enable_ltssm(struct s32g_pcie *s32g_pp)
65 {
66 	u32 reg;
67 
68 	reg = s32g_pcie_readl_ctrl(s32g_pp, PCIE_S32G_PE0_GEN_CTRL_3);
69 	reg |= LTSSM_EN;
70 	s32g_pcie_writel_ctrl(s32g_pp, PCIE_S32G_PE0_GEN_CTRL_3, reg);
71 }
72 
73 static void s32g_pcie_disable_ltssm(struct s32g_pcie *s32g_pp)
74 {
75 	u32 reg;
76 
77 	reg = s32g_pcie_readl_ctrl(s32g_pp, PCIE_S32G_PE0_GEN_CTRL_3);
78 	reg &= ~LTSSM_EN;
79 	s32g_pcie_writel_ctrl(s32g_pp, PCIE_S32G_PE0_GEN_CTRL_3, reg);
80 }
81 
82 static int s32g_pcie_start_link(struct dw_pcie *pci)
83 {
84 	struct s32g_pcie *s32g_pp = to_s32g_from_dw_pcie(pci);
85 
86 	s32g_pcie_enable_ltssm(s32g_pp);
87 
88 	return 0;
89 }
90 
91 static void s32g_pcie_stop_link(struct dw_pcie *pci)
92 {
93 	struct s32g_pcie *s32g_pp = to_s32g_from_dw_pcie(pci);
94 
95 	s32g_pcie_disable_ltssm(s32g_pp);
96 }
97 
98 static struct dw_pcie_ops s32g_pcie_ops = {
99 	.start_link = s32g_pcie_start_link,
100 	.stop_link = s32g_pcie_stop_link,
101 };
102 
103 /* Configure the AMBA AXI Coherency Extensions (ACE) interface */
104 static void s32g_pcie_reset_mstr_ace(struct dw_pcie *pci)
105 {
106 	u32 ddr_base_low = lower_32_bits(S32G_MEMORY_BOUNDARY_ADDR);
107 	u32 ddr_base_high = upper_32_bits(S32G_MEMORY_BOUNDARY_ADDR);
108 
109 	dw_pcie_dbi_ro_wr_en(pci);
110 	dw_pcie_writel_dbi(pci, COHERENCY_CONTROL_3_OFF, 0x0);
111 
112 	/*
113 	 * Ncore is a cache-coherent interconnect module that enables the
114 	 * integration of heterogeneous coherent and non-coherent agents in
115 	 * the chip. Ncore transactions to peripheral should be non-coherent
116 	 * or it might drop them.
117 	 *
118 	 * One example where this is needed are PCIe MSIs, which use NoSnoop=0
119 	 * and might end up routed to Ncore. PCIe coherent traffic (e.g. MSIs)
120 	 * that targets peripheral space will be dropped by Ncore because
121 	 * peripherals on S32G are not coherent as slaves. We add a hard
122 	 * boundary in the PCIe controller coherency control registers to
123 	 * separate physical memory space from peripheral space.
124 	 *
125 	 * Define the start of DDR as seen by Linux as this boundary between
126 	 * "memory" and "peripherals", with peripherals being below.
127 	 */
128 	dw_pcie_writel_dbi(pci, COHERENCY_CONTROL_1_OFF,
129 			   (ddr_base_low & CFG_MEMTYPE_BOUNDARY_LOW_ADDR_MASK));
130 	dw_pcie_writel_dbi(pci, COHERENCY_CONTROL_2_OFF, ddr_base_high);
131 	dw_pcie_dbi_ro_wr_dis(pci);
132 }
133 
134 static int s32g_init_pcie_controller(struct dw_pcie_rp *pp)
135 {
136 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
137 	struct s32g_pcie *s32g_pp = to_s32g_from_dw_pcie(pci);
138 	u32 val;
139 
140 	/* Set RP mode */
141 	val = s32g_pcie_readl_ctrl(s32g_pp, PCIE_S32G_PE0_GEN_CTRL_1);
142 	val &= ~DEVICE_TYPE_MASK;
143 	val |= FIELD_PREP(DEVICE_TYPE_MASK, PCI_EXP_TYPE_ROOT_PORT);
144 
145 	/* Use default CRNS */
146 	val &= ~SRIS_MODE;
147 
148 	s32g_pcie_writel_ctrl(s32g_pp, PCIE_S32G_PE0_GEN_CTRL_1, val);
149 
150 	/*
151 	 * Make sure we use the coherency defaults (just in case the settings
152 	 * have been changed from their reset values)
153 	 */
154 	s32g_pcie_reset_mstr_ace(pci);
155 
156 	dw_pcie_dbi_ro_wr_en(pci);
157 
158 	val = dw_pcie_readl_dbi(pci, PCIE_PORT_FORCE);
159 	val |= PORT_FORCE_DO_DESKEW_FOR_SRIS;
160 	dw_pcie_writel_dbi(pci, PCIE_PORT_FORCE, val);
161 
162 	val = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
163 	val |= GEN3_RELATED_OFF_EQ_PHASE_2_3;
164 	dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, val);
165 
166 	dw_pcie_dbi_ro_wr_dis(pci);
167 
168 	return 0;
169 }
170 
171 static const struct dw_pcie_host_ops s32g_pcie_host_ops = {
172 	.init = s32g_init_pcie_controller,
173 };
174 
175 static int s32g_init_pcie_phy(struct s32g_pcie *s32g_pp)
176 {
177 	struct dw_pcie *pci = &s32g_pp->pci;
178 	struct device *dev = pci->dev;
179 	struct s32g_pcie_port *port, *tmp;
180 	int ret;
181 
182 	list_for_each_entry(port, &s32g_pp->ports, list) {
183 		ret = phy_init(port->phy);
184 		if (ret) {
185 			dev_err(dev, "Failed to init serdes PHY\n");
186 			goto err_phy_revert;
187 		}
188 
189 		ret = phy_set_mode_ext(port->phy, PHY_MODE_PCIE, 0);
190 		if (ret) {
191 			dev_err(dev, "Failed to set mode on serdes PHY\n");
192 			goto err_phy_exit;
193 		}
194 
195 		ret = phy_power_on(port->phy);
196 		if (ret) {
197 			dev_err(dev, "Failed to power on serdes PHY\n");
198 			goto err_phy_exit;
199 		}
200 	}
201 
202 	return 0;
203 
204 err_phy_exit:
205 	phy_exit(port->phy);
206 
207 err_phy_revert:
208 	list_for_each_entry_continue_reverse(port, &s32g_pp->ports, list) {
209 		phy_power_off(port->phy);
210 		phy_exit(port->phy);
211 	}
212 
213 	list_for_each_entry_safe(port, tmp, &s32g_pp->ports, list)
214 		list_del(&port->list);
215 
216 	return ret;
217 }
218 
219 static void s32g_deinit_pcie_phy(struct s32g_pcie *s32g_pp)
220 {
221 	struct s32g_pcie_port *port, *tmp;
222 
223 	list_for_each_entry_safe(port, tmp, &s32g_pp->ports, list) {
224 		phy_power_off(port->phy);
225 		phy_exit(port->phy);
226 		list_del(&port->list);
227 	}
228 }
229 
230 static int s32g_pcie_init(struct device *dev, struct s32g_pcie *s32g_pp)
231 {
232 	s32g_pcie_disable_ltssm(s32g_pp);
233 
234 	return s32g_init_pcie_phy(s32g_pp);
235 }
236 
237 static void s32g_pcie_deinit(struct s32g_pcie *s32g_pp)
238 {
239 	s32g_pcie_disable_ltssm(s32g_pp);
240 
241 	s32g_deinit_pcie_phy(s32g_pp);
242 }
243 
244 static int s32g_pcie_parse_port(struct s32g_pcie *s32g_pp, struct device_node *node)
245 {
246 	struct device *dev = s32g_pp->pci.dev;
247 	struct s32g_pcie_port *port;
248 	int num_lanes;
249 
250 	port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
251 	if (!port)
252 		return -ENOMEM;
253 
254 	port->phy = devm_of_phy_get(dev, node, NULL);
255 	if (IS_ERR(port->phy))
256 		return dev_err_probe(dev, PTR_ERR(port->phy),
257 				"Failed to get serdes PHY\n");
258 
259 	INIT_LIST_HEAD(&port->list);
260 	list_add_tail(&port->list, &s32g_pp->ports);
261 
262 	/*
263 	 * The DWC core initialization code cannot yet parse the num-lanes
264 	 * attribute in the Root Port node. The S32G only supports one Root
265 	 * Port for now so its driver can parse the node and set the num_lanes
266 	 * field of struct dwc_pcie before calling dw_pcie_host_init().
267 	 */
268 	if (!of_property_read_u32(node, "num-lanes", &num_lanes))
269 		s32g_pp->pci.num_lanes = num_lanes;
270 
271 	return 0;
272 }
273 
274 static int s32g_pcie_parse_ports(struct device *dev, struct s32g_pcie *s32g_pp)
275 {
276 	struct s32g_pcie_port *port, *tmp;
277 	int ret = -ENOENT;
278 
279 	for_each_available_child_of_node_scoped(dev->of_node, of_port) {
280 		if (!of_node_is_type(of_port, "pci"))
281 			continue;
282 
283 		ret = s32g_pcie_parse_port(s32g_pp, of_port);
284 		if (ret)
285 			goto err_port;
286 	}
287 
288 err_port:
289 	list_for_each_entry_safe(port, tmp, &s32g_pp->ports, list)
290 		list_del(&port->list);
291 
292 	return ret;
293 }
294 
295 static int s32g_pcie_get_resources(struct platform_device *pdev,
296 				   struct s32g_pcie *s32g_pp)
297 {
298 	struct dw_pcie *pci = &s32g_pp->pci;
299 	struct device *dev = &pdev->dev;
300 	int ret;
301 
302 	pci->dev = dev;
303 	pci->ops = &s32g_pcie_ops;
304 
305 	s32g_pp->ctrl_base = devm_platform_ioremap_resource_byname(pdev, "ctrl");
306 	if (IS_ERR(s32g_pp->ctrl_base))
307 		return PTR_ERR(s32g_pp->ctrl_base);
308 
309 	INIT_LIST_HEAD(&s32g_pp->ports);
310 
311 	ret = s32g_pcie_parse_ports(dev, s32g_pp);
312 	if (ret)
313 		return dev_err_probe(dev, ret,
314 				"Failed to parse Root Port: %d\n", ret);
315 
316 	platform_set_drvdata(pdev, s32g_pp);
317 
318 	return 0;
319 }
320 
321 static int s32g_pcie_probe(struct platform_device *pdev)
322 {
323 	struct device *dev = &pdev->dev;
324 	struct s32g_pcie *s32g_pp;
325 	struct dw_pcie_rp *pp;
326 	int ret;
327 
328 	s32g_pp = devm_kzalloc(dev, sizeof(*s32g_pp), GFP_KERNEL);
329 	if (!s32g_pp)
330 		return -ENOMEM;
331 
332 	ret = s32g_pcie_get_resources(pdev, s32g_pp);
333 	if (ret)
334 		return ret;
335 
336 	pm_runtime_no_callbacks(dev);
337 	devm_pm_runtime_enable(dev);
338 	ret = pm_runtime_get_sync(dev);
339 	if (ret < 0)
340 		goto err_pm_runtime_put;
341 
342 	ret = s32g_pcie_init(dev, s32g_pp);
343 	if (ret)
344 		goto err_pm_runtime_put;
345 
346 	pp = &s32g_pp->pci.pp;
347 	pp->ops = &s32g_pcie_host_ops;
348 	pp->use_atu_msg = true;
349 
350 	ret = dw_pcie_host_init(pp);
351 	if (ret)
352 		goto err_pcie_deinit;
353 
354 	return 0;
355 
356 err_pcie_deinit:
357 	s32g_pcie_deinit(s32g_pp);
358 err_pm_runtime_put:
359 	pm_runtime_put(dev);
360 
361 	return ret;
362 }
363 
364 static int s32g_pcie_suspend_noirq(struct device *dev)
365 {
366 	struct s32g_pcie *s32g_pp = dev_get_drvdata(dev);
367 	struct dw_pcie *pci = &s32g_pp->pci;
368 
369 	return dw_pcie_suspend_noirq(pci);
370 }
371 
372 static int s32g_pcie_resume_noirq(struct device *dev)
373 {
374 	struct s32g_pcie *s32g_pp = dev_get_drvdata(dev);
375 	struct dw_pcie *pci = &s32g_pp->pci;
376 
377 	return dw_pcie_resume_noirq(pci);
378 }
379 
380 static const struct dev_pm_ops s32g_pcie_pm_ops = {
381 	NOIRQ_SYSTEM_SLEEP_PM_OPS(s32g_pcie_suspend_noirq,
382 				  s32g_pcie_resume_noirq)
383 };
384 
385 static const struct of_device_id s32g_pcie_of_match[] = {
386 	{ .compatible = "nxp,s32g2-pcie" },
387 	{ /* sentinel */ },
388 };
389 MODULE_DEVICE_TABLE(of, s32g_pcie_of_match);
390 
391 static struct platform_driver s32g_pcie_driver = {
392 	.driver = {
393 		.name	= "s32g-pcie",
394 		.of_match_table = s32g_pcie_of_match,
395 		.suppress_bind_attrs = true,
396 		.pm = pm_sleep_ptr(&s32g_pcie_pm_ops),
397 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
398 	},
399 	.probe = s32g_pcie_probe,
400 };
401 
402 builtin_platform_driver(s32g_pcie_driver);
403 
404 MODULE_AUTHOR("Ionut Vicovan <Ionut.Vicovan@nxp.com>");
405 MODULE_DESCRIPTION("NXP S32G PCIe Host controller driver");
406 MODULE_LICENSE("GPL");
407