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