xref: /linux/drivers/net/ethernet/amd/xgbe/xgbe-platform.c (revision 0333b7399587ee0aaa863ed0d13a00a6c7c64068)
1 // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
2 /*
3  * Copyright (c) 2014-2025, Advanced Micro Devices, Inc.
4  * Copyright (c) 2014, Synopsys, Inc.
5  * All rights reserved
6  */
7 
8 #include <linux/module.h>
9 #include <linux/device.h>
10 #include <linux/platform_device.h>
11 #include <linux/spinlock.h>
12 #include <linux/netdevice.h>
13 #include <linux/etherdevice.h>
14 #include <linux/io.h>
15 #include <linux/of.h>
16 #include <linux/of_net.h>
17 #include <linux/of_platform.h>
18 #include <linux/clk.h>
19 #include <linux/property.h>
20 #include <linux/acpi.h>
21 #include <linux/mdio.h>
22 
23 #include "xgbe.h"
24 #include "xgbe-common.h"
25 
26 #ifdef CONFIG_ACPI
27 static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
28 {
29 	struct device *dev = pdata->dev;
30 	u32 property;
31 	int ret;
32 
33 	/* Obtain the system clock setting */
34 	ret = device_property_read_u32(dev, XGBE_ACPI_DMA_FREQ, &property);
35 	if (ret) {
36 		dev_err(dev, "unable to obtain %s property\n",
37 			XGBE_ACPI_DMA_FREQ);
38 		return ret;
39 	}
40 	pdata->sysclk_rate = property;
41 
42 	/* Obtain the PTP clock setting */
43 	ret = device_property_read_u32(dev, XGBE_ACPI_PTP_FREQ, &property);
44 	if (ret) {
45 		dev_err(dev, "unable to obtain %s property\n",
46 			XGBE_ACPI_PTP_FREQ);
47 		return ret;
48 	}
49 	pdata->ptpclk_rate = property;
50 
51 	return 0;
52 }
53 #else   /* CONFIG_ACPI */
54 static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
55 {
56 	return -EINVAL;
57 }
58 #endif  /* CONFIG_ACPI */
59 
60 #ifdef CONFIG_OF
61 static int xgbe_of_support(struct xgbe_prv_data *pdata)
62 {
63 	struct device *dev = pdata->dev;
64 
65 	/* Obtain the system clock setting */
66 	pdata->sysclk = devm_clk_get(dev, XGBE_DMA_CLOCK);
67 	if (IS_ERR(pdata->sysclk)) {
68 		dev_err(dev, "dma devm_clk_get failed\n");
69 		return PTR_ERR(pdata->sysclk);
70 	}
71 	pdata->sysclk_rate = clk_get_rate(pdata->sysclk);
72 
73 	/* Obtain the PTP clock setting */
74 	pdata->ptpclk = devm_clk_get(dev, XGBE_PTP_CLOCK);
75 	if (IS_ERR(pdata->ptpclk)) {
76 		dev_err(dev, "ptp devm_clk_get failed\n");
77 		return PTR_ERR(pdata->ptpclk);
78 	}
79 	pdata->ptpclk_rate = clk_get_rate(pdata->ptpclk);
80 
81 	return 0;
82 }
83 
84 static struct platform_device *xgbe_of_get_phy_pdev(struct xgbe_prv_data *pdata)
85 {
86 	struct device *dev = pdata->dev;
87 	struct device_node *phy_node;
88 	struct platform_device *phy_pdev;
89 
90 	phy_node = of_parse_phandle(dev->of_node, "phy-handle", 0);
91 	if (phy_node) {
92 		/* Old style device tree:
93 		 *   The XGBE and PHY resources are separate
94 		 */
95 		phy_pdev = of_find_device_by_node(phy_node);
96 		of_node_put(phy_node);
97 	} else {
98 		/* New style device tree:
99 		 *   The XGBE and PHY resources are grouped together with
100 		 *   the PHY resources listed last
101 		 */
102 		get_device(dev);
103 		phy_pdev = pdata->platdev;
104 	}
105 
106 	return phy_pdev;
107 }
108 #else   /* CONFIG_OF */
109 static int xgbe_of_support(struct xgbe_prv_data *pdata)
110 {
111 	return -EINVAL;
112 }
113 
114 static struct platform_device *xgbe_of_get_phy_pdev(struct xgbe_prv_data *pdata)
115 {
116 	return NULL;
117 }
118 #endif  /* CONFIG_OF */
119 
120 static unsigned int xgbe_resource_count(struct platform_device *pdev,
121 					unsigned int type)
122 {
123 	unsigned int count;
124 	int i;
125 
126 	for (i = 0, count = 0; i < pdev->num_resources; i++) {
127 		struct resource *res = &pdev->resource[i];
128 
129 		if (type == resource_type(res))
130 			count++;
131 	}
132 
133 	return count;
134 }
135 
136 static struct platform_device *xgbe_get_phy_pdev(struct xgbe_prv_data *pdata)
137 {
138 	struct platform_device *phy_pdev;
139 
140 	if (pdata->use_acpi) {
141 		get_device(pdata->dev);
142 		phy_pdev = pdata->platdev;
143 	} else {
144 		phy_pdev = xgbe_of_get_phy_pdev(pdata);
145 	}
146 
147 	return phy_pdev;
148 }
149 
150 static int xgbe_platform_probe(struct platform_device *pdev)
151 {
152 	struct xgbe_prv_data *pdata;
153 	struct device *dev = &pdev->dev;
154 	struct platform_device *phy_pdev;
155 	const char *phy_mode;
156 	unsigned int phy_memnum, phy_irqnum;
157 	unsigned int dma_irqnum, dma_irqend;
158 	enum dev_dma_attr attr;
159 	int ret;
160 
161 	pdata = xgbe_alloc_pdata(dev);
162 	if (IS_ERR(pdata)) {
163 		ret = PTR_ERR(pdata);
164 		goto err_alloc;
165 	}
166 
167 	pdata->platdev = pdev;
168 	pdata->adev = ACPI_COMPANION(dev);
169 	platform_set_drvdata(pdev, pdata);
170 
171 	/* Check if we should use ACPI or DT */
172 	pdata->use_acpi = dev->of_node ? 0 : 1;
173 
174 	/* Get the version data */
175 	pdata->vdata = (struct xgbe_version_data *)device_get_match_data(dev);
176 
177 	phy_pdev = xgbe_get_phy_pdev(pdata);
178 	if (!phy_pdev) {
179 		dev_err(dev, "unable to obtain phy device\n");
180 		ret = -EINVAL;
181 		goto err_phydev;
182 	}
183 	pdata->phy_platdev = phy_pdev;
184 	pdata->phy_dev = &phy_pdev->dev;
185 
186 	if (pdev == phy_pdev) {
187 		/* New style device tree or ACPI:
188 		 *   The XGBE and PHY resources are grouped together with
189 		 *   the PHY resources listed last
190 		 */
191 		phy_memnum = xgbe_resource_count(pdev, IORESOURCE_MEM) - 3;
192 		phy_irqnum = platform_irq_count(pdev) - 1;
193 		dma_irqnum = 1;
194 		dma_irqend = phy_irqnum;
195 	} else {
196 		/* Old style device tree:
197 		 *   The XGBE and PHY resources are separate
198 		 */
199 		phy_memnum = 0;
200 		phy_irqnum = 0;
201 		dma_irqnum = 1;
202 		dma_irqend = platform_irq_count(pdev);
203 	}
204 
205 	/* Obtain the mmio areas for the device */
206 	pdata->xgmac_regs = devm_platform_ioremap_resource(pdev, 0);
207 	if (IS_ERR(pdata->xgmac_regs)) {
208 		dev_err(dev, "xgmac ioremap failed\n");
209 		ret = PTR_ERR(pdata->xgmac_regs);
210 		goto err_io;
211 	}
212 	if (netif_msg_probe(pdata))
213 		dev_dbg(dev, "xgmac_regs = %p\n", pdata->xgmac_regs);
214 
215 	pdata->xpcs_regs = devm_platform_ioremap_resource(pdev, 1);
216 	if (IS_ERR(pdata->xpcs_regs)) {
217 		dev_err(dev, "xpcs ioremap failed\n");
218 		ret = PTR_ERR(pdata->xpcs_regs);
219 		goto err_io;
220 	}
221 	if (netif_msg_probe(pdata))
222 		dev_dbg(dev, "xpcs_regs  = %p\n", pdata->xpcs_regs);
223 
224 	pdata->rxtx_regs = devm_platform_ioremap_resource(phy_pdev,
225 							  phy_memnum++);
226 	if (IS_ERR(pdata->rxtx_regs)) {
227 		dev_err(dev, "rxtx ioremap failed\n");
228 		ret = PTR_ERR(pdata->rxtx_regs);
229 		goto err_io;
230 	}
231 	if (netif_msg_probe(pdata))
232 		dev_dbg(dev, "rxtx_regs  = %p\n", pdata->rxtx_regs);
233 
234 	pdata->sir0_regs = devm_platform_ioremap_resource(phy_pdev,
235 							  phy_memnum++);
236 	if (IS_ERR(pdata->sir0_regs)) {
237 		dev_err(dev, "sir0 ioremap failed\n");
238 		ret = PTR_ERR(pdata->sir0_regs);
239 		goto err_io;
240 	}
241 	if (netif_msg_probe(pdata))
242 		dev_dbg(dev, "sir0_regs  = %p\n", pdata->sir0_regs);
243 
244 	pdata->sir1_regs = devm_platform_ioremap_resource(phy_pdev,
245 							  phy_memnum++);
246 	if (IS_ERR(pdata->sir1_regs)) {
247 		dev_err(dev, "sir1 ioremap failed\n");
248 		ret = PTR_ERR(pdata->sir1_regs);
249 		goto err_io;
250 	}
251 	if (netif_msg_probe(pdata))
252 		dev_dbg(dev, "sir1_regs  = %p\n", pdata->sir1_regs);
253 
254 	/* Retrieve the MAC address */
255 	ret = device_get_mac_address(dev, pdata->mac_addr);
256 	if (ret) {
257 		dev_err(dev, "invalid MAC address property\n");
258 		goto err_io;
259 	}
260 
261 	/* Retrieve the PHY mode - it must be "xgmii" */
262 	ret = device_property_read_string(dev, XGBE_PHY_MODE_PROPERTY,
263 					  &phy_mode);
264 	if (ret || strcmp(phy_mode, phy_modes(PHY_INTERFACE_MODE_XGMII))) {
265 		dev_err(dev, "invalid %s property\n", XGBE_PHY_MODE_PROPERTY);
266 		if (!ret)
267 			ret = -EINVAL;
268 		goto err_io;
269 	}
270 	pdata->phy_mode = PHY_INTERFACE_MODE_XGMII;
271 
272 	/* Check for per channel interrupt support */
273 	if (device_property_present(dev, XGBE_DMA_IRQS_PROPERTY)) {
274 		pdata->per_channel_irq = 1;
275 		pdata->channel_irq_mode = XGBE_IRQ_MODE_EDGE;
276 	}
277 
278 	/* Obtain device settings unique to ACPI/OF */
279 	if (pdata->use_acpi)
280 		ret = xgbe_acpi_support(pdata);
281 	else
282 		ret = xgbe_of_support(pdata);
283 	if (ret)
284 		goto err_io;
285 
286 	/* Set the DMA coherency values */
287 	attr = device_get_dma_attr(dev);
288 	if (attr == DEV_DMA_NOT_SUPPORTED) {
289 		dev_err(dev, "DMA is not supported");
290 		ret = -ENODEV;
291 		goto err_io;
292 	}
293 	pdata->coherent = (attr == DEV_DMA_COHERENT);
294 	if (pdata->coherent) {
295 		pdata->arcr = XGBE_DMA_OS_ARCR;
296 		pdata->awcr = XGBE_DMA_OS_AWCR;
297 	} else {
298 		pdata->arcr = XGBE_DMA_SYS_ARCR;
299 		pdata->awcr = XGBE_DMA_SYS_AWCR;
300 	}
301 
302 	/* Set the maximum fifo amounts */
303 	pdata->tx_max_fifo_size = pdata->vdata->tx_max_fifo_size;
304 	pdata->rx_max_fifo_size = pdata->vdata->rx_max_fifo_size;
305 
306 	/* Set the hardware channel and queue counts */
307 	xgbe_set_counts(pdata);
308 
309 	/* Always have XGMAC and XPCS (auto-negotiation) interrupts */
310 	pdata->irq_count = 2;
311 
312 	/* Get the device interrupt */
313 	ret = platform_get_irq(pdev, 0);
314 	if (ret < 0)
315 		goto err_io;
316 	pdata->dev_irq = ret;
317 
318 	/* Get the per channel DMA interrupts */
319 	if (pdata->per_channel_irq) {
320 		unsigned int i, max = ARRAY_SIZE(pdata->channel_irq);
321 
322 		for (i = 0; (i < max) && (dma_irqnum < dma_irqend); i++) {
323 			ret = platform_get_irq(pdata->platdev, dma_irqnum++);
324 			if (ret < 0)
325 				goto err_io;
326 
327 			pdata->channel_irq[i] = ret;
328 		}
329 
330 		pdata->channel_irq_count = max;
331 
332 		pdata->irq_count += max;
333 	}
334 
335 	/* Get the auto-negotiation interrupt */
336 	ret = platform_get_irq(phy_pdev, phy_irqnum++);
337 	if (ret < 0)
338 		goto err_io;
339 	pdata->an_irq = ret;
340 
341 	/* Configure the netdev resource */
342 	ret = xgbe_config_netdev(pdata);
343 	if (ret)
344 		goto err_io;
345 
346 	netdev_notice(pdata->netdev, "net device enabled\n");
347 
348 	return 0;
349 
350 err_io:
351 	platform_device_put(phy_pdev);
352 
353 err_phydev:
354 	xgbe_free_pdata(pdata);
355 
356 err_alloc:
357 	dev_notice(dev, "net device not enabled\n");
358 
359 	return ret;
360 }
361 
362 static void xgbe_platform_remove(struct platform_device *pdev)
363 {
364 	struct xgbe_prv_data *pdata = platform_get_drvdata(pdev);
365 
366 	xgbe_deconfig_netdev(pdata);
367 
368 	platform_device_put(pdata->phy_platdev);
369 
370 	xgbe_free_pdata(pdata);
371 }
372 
373 #ifdef CONFIG_PM_SLEEP
374 static int xgbe_platform_suspend(struct device *dev)
375 {
376 	struct xgbe_prv_data *pdata = dev_get_drvdata(dev);
377 	struct net_device *netdev = pdata->netdev;
378 	int ret = 0;
379 
380 	DBGPR("-->xgbe_suspend\n");
381 
382 	if (netif_running(netdev))
383 		ret = xgbe_powerdown(netdev);
384 
385 	pdata->lpm_ctrl = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1);
386 	pdata->lpm_ctrl |= MDIO_CTRL1_LPOWER;
387 	XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, pdata->lpm_ctrl);
388 
389 	DBGPR("<--xgbe_suspend\n");
390 
391 	return ret;
392 }
393 
394 static int xgbe_platform_resume(struct device *dev)
395 {
396 	struct xgbe_prv_data *pdata = dev_get_drvdata(dev);
397 	struct net_device *netdev = pdata->netdev;
398 	int ret = 0;
399 
400 	DBGPR("-->xgbe_resume\n");
401 
402 	pdata->lpm_ctrl &= ~MDIO_CTRL1_LPOWER;
403 	XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, pdata->lpm_ctrl);
404 
405 	if (netif_running(netdev)) {
406 		ret = xgbe_powerup(netdev);
407 
408 		/* Schedule a restart in case the link or phy state changed
409 		 * while we were powered down.
410 		 */
411 		schedule_work(&pdata->restart_work);
412 	}
413 
414 	DBGPR("<--xgbe_resume\n");
415 
416 	return ret;
417 }
418 #endif /* CONFIG_PM_SLEEP */
419 
420 static const struct xgbe_version_data xgbe_v1 = {
421 	.init_function_ptrs_phy_impl	= xgbe_init_function_ptrs_phy_v1,
422 	.xpcs_access			= XGBE_XPCS_ACCESS_V1,
423 	.tx_max_fifo_size		= 81920,
424 	.rx_max_fifo_size		= 81920,
425 	.tx_tstamp_workaround		= 1,
426 };
427 
428 static const struct acpi_device_id xgbe_acpi_match[] = {
429 	{ .id = "AMDI8001",
430 	  .driver_data = (kernel_ulong_t)&xgbe_v1 },
431 	{},
432 };
433 
434 MODULE_DEVICE_TABLE(acpi, xgbe_acpi_match);
435 
436 static const struct of_device_id xgbe_of_match[] = {
437 	{ .compatible = "amd,xgbe-seattle-v1a",
438 	  .data = &xgbe_v1 },
439 	{},
440 };
441 
442 MODULE_DEVICE_TABLE(of, xgbe_of_match);
443 
444 static SIMPLE_DEV_PM_OPS(xgbe_platform_pm_ops,
445 			 xgbe_platform_suspend, xgbe_platform_resume);
446 
447 static struct platform_driver xgbe_driver = {
448 	.driver = {
449 		.name = XGBE_DRV_NAME,
450 		.acpi_match_table = xgbe_acpi_match,
451 		.of_match_table = xgbe_of_match,
452 		.pm = &xgbe_platform_pm_ops,
453 	},
454 	.probe = xgbe_platform_probe,
455 	.remove = xgbe_platform_remove,
456 };
457 
458 int xgbe_platform_init(void)
459 {
460 	return platform_driver_register(&xgbe_driver);
461 }
462 
463 void xgbe_platform_exit(void)
464 {
465 	platform_driver_unregister(&xgbe_driver);
466 }
467