FILE
lantiq_gswip.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/dsa/lantiq/lantiq_gswip.c
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Lantiq / Intel GSWIP switch driver for VRX200, xRX300 and xRX330 SoCs 4 * 5 * Copyright (C) 2025 Daniel Golle <daniel@makrotopia.org> 6 * Copyright (C) 2017 - 2019 Hauke Mehrtens <hauke@hauke-m.de> 7 * Copyright (C) 2012 John Crispin <john@phrozen.org> 8 * Copyright (C) 2010 Lantiq Deutschland 9 */ 10 11#include "lantiq_gswip.h" 12#include "lantiq_pce.h" 13 14#include <linux/clk.h> 15#include <linux/delay.h> 16#include <linux/firmware.h> 17#include <linux/mfd/syscon.h> 18#include <linux/module.h> 19#include <linux/of_platform.h> 20#include <linux/platform_device.h> 21#include <linux/regmap.h> 22#include <linux/reset.h> 23#include <dt-bindings/mips/lantiq_rcu_gphy.h> 24 25#include <net/dsa.h> 26 27struct xway_gphy_match_data { 28 char *fe_firmware_name; 29 char *ge_firmware_name; 30}; 31 32static void gswip_xrx200_phylink_get_caps(struct dsa_switch *ds, int port, 33 struct phylink_config *config) 34{ 35 switch (port) { 36 case 0: 37 case 1: 38 phy_interface_set_rgmii(config->supported_interfaces); 39 __set_bit(PHY_INTERFACE_MODE_MII, 40 config->supported_interfaces); 41 __set_bit(PHY_INTERFACE_MODE_REVMII, 42 config->supported_interfaces); 43 __set_bit(PHY_INTERFACE_MODE_RMII, 44 config->supported_interfaces); 45 break; 46 47 case 2: 48 case 3: 49 case 4: 50 case 6: 51 __set_bit(PHY_INTERFACE_MODE_INTERNAL, 52 config->supported_interfaces); 53 break; 54 55 case 5: 56 phy_interface_set_rgmii(config->supported_interfaces); 57 __set_bit(PHY_INTERFACE_MODE_INTERNAL, 58 config->supported_interfaces); 59 break; 60 } 61 62 config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | 63 MAC_10 | MAC_100 | MAC_1000; 64} 65 66static void gswip_xrx300_phylink_get_caps(struct dsa_switch *ds, int port, 67 struct phylink_config *config) 68{ 69 switch (port) { 70 case 0: 71 phy_interface_set_rgmii(config->supported_interfaces); 72 __set_bit(PHY_INTERFACE_MODE_GMII, 73 config->supported_interfaces); 74 __set_bit(PHY_INTERFACE_MODE_RMII, 75 config->supported_interfaces); 76 break; 77 78 case 1: 79 case 2: 80 case 3: 81 case 4: 82 case 6: 83 __set_bit(PHY_INTERFACE_MODE_INTERNAL, 84 config->supported_interfaces); 85 break; 86 87 case 5: 88 phy_interface_set_rgmii(config->supported_interfaces); 89 __set_bit(PHY_INTERFACE_MODE_INTERNAL, 90 config->supported_interfaces); 91 __set_bit(PHY_INTERFACE_MODE_RMII, 92 config->supported_interfaces); 93 break; 94 } 95 96 config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | 97 MAC_10 | MAC_100 | MAC_1000; 98} 99 100static const struct xway_gphy_match_data xrx200a1x_gphy_data = { 101 .fe_firmware_name = "lantiq/xrx200_phy22f_a14.bin", 102 .ge_firmware_name = "lantiq/xrx200_phy11g_a14.bin", 103}; 104 105static const struct xway_gphy_match_data xrx200a2x_gphy_data = { 106 .fe_firmware_name = "lantiq/xrx200_phy22f_a22.bin", 107 .ge_firmware_name = "lantiq/xrx200_phy11g_a22.bin", 108}; 109 110static const struct xway_gphy_match_data xrx300_gphy_data = { 111 .fe_firmware_name = "lantiq/xrx300_phy22f_a21.bin", 112 .ge_firmware_name = "lantiq/xrx300_phy11g_a21.bin", 113}; 114 115static const struct of_device_id xway_gphy_match[] __maybe_unused = { 116 { .compatible = "lantiq,xrx200-gphy-fw", .data = NULL }, 117 { .compatible = "lantiq,xrx200a1x-gphy-fw", .data = &xrx200a1x_gphy_data }, 118 { .compatible = "lantiq,xrx200a2x-gphy-fw", .data = &xrx200a2x_gphy_data }, 119 { .compatible = "lantiq,xrx300-gphy-fw", .data = &xrx300_gphy_data }, 120 { .compatible = "lantiq,xrx330-gphy-fw", .data = &xrx300_gphy_data }, 121 {}, 122}; 123 124static int gswip_gphy_fw_load(struct gswip_priv *priv, struct gswip_gphy_fw *gphy_fw) 125{ 126 struct device *dev = priv->dev; 127 const struct firmware *fw; 128 void *fw_addr; 129 dma_addr_t dma_addr; 130 dma_addr_t dev_addr; 131 size_t size; 132 int ret; 133 134 ret = clk_prepare_enable(gphy_fw->clk_gate); 135 if (ret) 136 return ret; 137 138 reset_control_assert(gphy_fw->reset); 139 140 /* The vendor BSP uses a 200ms delay after asserting the reset line. 141 * Without this some users are observing that the PHY is not coming up 142 * on the MDIO bus. 143 */ 144 msleep(200); 145 146 ret = request_firmware(&fw, gphy_fw->fw_name, dev); 147 if (ret) 148 return dev_err_probe(dev, ret, "failed to load firmware: %s\n", 149 gphy_fw->fw_name); 150 151 /* GPHY cores need the firmware code in a persistent and contiguous 152 * memory area with a 16 kB boundary aligned start address. 153 */ 154 size = fw->size + XRX200_GPHY_FW_ALIGN; 155 156 fw_addr = dmam_alloc_coherent(dev, size, &dma_addr, GFP_KERNEL); 157 if (fw_addr) { 158 fw_addr = PTR_ALIGN(fw_addr, XRX200_GPHY_FW_ALIGN); 159 dev_addr = ALIGN(dma_addr, XRX200_GPHY_FW_ALIGN); 160 memcpy(fw_addr, fw->data, fw->size); 161 } else { 162 release_firmware(fw); 163 return -ENOMEM; 164 } 165 166 release_firmware(fw); 167 168 ret = regmap_write(priv->rcu_regmap, gphy_fw->fw_addr_offset, dev_addr); 169 if (ret) 170 return ret; 171 172 reset_control_deassert(gphy_fw->reset); 173 174 return ret; 175} 176 177static int gswip_gphy_fw_probe(struct gswip_priv *priv, 178 struct gswip_gphy_fw *gphy_fw, 179 struct device_node *gphy_fw_np, int i) 180{ 181 struct device *dev = priv->dev; 182 u32 gphy_mode; 183 int ret; 184 char gphyname[10]; 185 186 snprintf(gphyname, sizeof(gphyname), "gphy%d", i); 187 188 gphy_fw->clk_gate = devm_clk_get(dev, gphyname); 189 if (IS_ERR(gphy_fw->clk_gate)) { 190 return dev_err_probe(dev, PTR_ERR(gphy_fw->clk_gate), 191 "Failed to lookup gate clock\n"); 192 } 193 194 ret = of_property_read_u32(gphy_fw_np, "reg", &gphy_fw->fw_addr_offset); 195 if (ret) 196 return ret; 197 198 ret = of_property_read_u32(gphy_fw_np, "lantiq,gphy-mode", &gphy_mode); 199 /* Default to GE mode */ 200 if (ret) 201 gphy_mode = GPHY_MODE_GE; 202 203 switch (gphy_mode) { 204 case GPHY_MODE_FE: 205 gphy_fw->fw_name = priv->gphy_fw_name_cfg->fe_firmware_name; 206 break; 207 case GPHY_MODE_GE: 208 gphy_fw->fw_name = priv->gphy_fw_name_cfg->ge_firmware_name; 209 break; 210 default: 211 return dev_err_probe(dev, -EINVAL, "Unknown GPHY mode %d\n", 212 gphy_mode); 213 } 214 215 gphy_fw->reset = of_reset_control_array_get_exclusive(gphy_fw_np); 216 if (IS_ERR(gphy_fw->reset)) 217 return dev_err_probe(dev, PTR_ERR(gphy_fw->reset), 218 "Failed to lookup gphy reset\n"); 219 220 return gswip_gphy_fw_load(priv, gphy_fw); 221} 222 223static void gswip_gphy_fw_remove(struct gswip_priv *priv, 224 struct gswip_gphy_fw *gphy_fw) 225{ 226 int ret; 227 228 /* check if the device was fully probed */ 229 if (!gphy_fw->fw_name) 230 return; 231 232 ret = regmap_write(priv->rcu_regmap, gphy_fw->fw_addr_offset, 0); 233 if (ret) 234 dev_err(priv->dev, "can not reset GPHY FW pointer\n"); 235 236 clk_disable_unprepare(gphy_fw->clk_gate); 237 238 reset_control_put(gphy_fw->reset); 239} 240 241static int gswip_gphy_fw_list(struct gswip_priv *priv, 242 struct device_node *gphy_fw_list_np, u32 version) 243{ 244 struct device *dev = priv->dev; 245 struct device_node *gphy_fw_np; 246 const struct of_device_id *match; 247 int err; 248 int i = 0; 249 250 /* The VRX200 rev 1.1 uses the GSWIP 2.0 and needs the older 251 * GPHY firmware. The VRX200 rev 1.2 uses the GSWIP 2.1 and also 252 * needs a different GPHY firmware. 253 */ 254 if (of_device_is_compatible(gphy_fw_list_np, "lantiq,xrx200-gphy-fw")) { 255 switch (version) { 256 case GSWIP_VERSION_2_0: 257 priv->gphy_fw_name_cfg = &xrx200a1x_gphy_data; 258 break; 259 case GSWIP_VERSION_2_1: 260 priv->gphy_fw_name_cfg = &xrx200a2x_gphy_data; 261 break; 262 default: 263 return dev_err_probe(dev, -ENOENT, 264 "unknown GSWIP version: 0x%x\n", 265 version); 266 } 267 } 268 269 match = of_match_node(xway_gphy_match, gphy_fw_list_np); 270 if (match && match->data) 271 priv->gphy_fw_name_cfg = match->data; 272 273 if (!priv->gphy_fw_name_cfg) 274 return dev_err_probe(dev, -ENOENT, 275 "GPHY compatible type not supported\n"); 276 277 priv->num_gphy_fw = of_get_available_child_count(gphy_fw_list_np); 278 if (!priv->num_gphy_fw) 279 return -ENOENT; 280 281 priv->rcu_regmap = syscon_regmap_lookup_by_phandle(gphy_fw_list_np, 282 "lantiq,rcu"); 283 if (IS_ERR(priv->rcu_regmap)) 284 return PTR_ERR(priv->rcu_regmap); 285 286 priv->gphy_fw = devm_kmalloc_array(dev, priv->num_gphy_fw, 287 sizeof(*priv->gphy_fw), 288 GFP_KERNEL | __GFP_ZERO); 289 if (!priv->gphy_fw) 290 return -ENOMEM; 291 292 for_each_available_child_of_node(gphy_fw_list_np, gphy_fw_np) { 293 err = gswip_gphy_fw_probe(priv, &priv->gphy_fw[i], 294 gphy_fw_np, i); 295 if (err) { 296 of_node_put(gphy_fw_np); 297 goto remove_gphy; 298 } 299 i++; 300 } 301 302 /* The standalone PHY11G requires 300ms to be fully 303 * initialized and ready for any MDIO communication after being 304 * taken out of reset. For the SoC-internal GPHY variant there 305 * is no (known) documentation for the minimum time after a 306 * reset. Use the same value as for the standalone variant as 307 * some users have reported internal PHYs not being detected 308 * without any delay. 309 */ 310 msleep(300); 311 312 return 0; 313 314remove_gphy: 315 for (i = 0; i < priv->num_gphy_fw; i++) 316 gswip_gphy_fw_remove(priv, &priv->gphy_fw[i]); 317 return err; 318} 319 320static const struct regmap_config sw_regmap_config = { 321 .name = "switch", 322 .reg_bits = 32, 323 .val_bits = 32, 324 .reg_shift = REGMAP_UPSHIFT(2), 325 .val_format_endian = REGMAP_ENDIAN_NATIVE, 326 .max_register = GSWIP_SDMA_PCTRLp(6), 327}; 328 329static const struct regmap_config mdio_regmap_config = { 330 .name = "mdio", 331 .reg_bits = 32, 332 .val_bits = 32, 333 .reg_shift = REGMAP_UPSHIFT(2), 334 .val_format_endian = REGMAP_ENDIAN_NATIVE, 335 .max_register = GSWIP_MDIO_PHYp(0), 336}; 337 338static const struct regmap_config mii_regmap_config = { 339 .name = "mii", 340 .reg_bits = 32, 341 .val_bits = 32, 342 .reg_shift = REGMAP_UPSHIFT(2), 343 .val_format_endian = REGMAP_ENDIAN_NATIVE, 344 .max_register = GSWIP_MII_CFGp(6), 345}; 346 347static int gswip_probe(struct platform_device *pdev) 348{ 349 struct device_node *np, *gphy_fw_np; 350 __iomem void *gswip, *mdio, *mii; 351 struct device *dev = &pdev->dev; 352 struct gswip_priv *priv; 353 int err; 354 int i; 355 u32 version; 356 357 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 358 if (!priv) 359 return -ENOMEM; 360 361 gswip = devm_platform_ioremap_resource(pdev, 0); 362 if (IS_ERR(gswip)) 363 return PTR_ERR(gswip); 364 365 mdio = devm_platform_ioremap_resource(pdev, 1); 366 if (IS_ERR(mdio)) 367 return PTR_ERR(mdio); 368 369 mii = devm_platform_ioremap_resource(pdev, 2); 370 if (IS_ERR(mii)) 371 return PTR_ERR(mii); 372 373 priv->gswip = devm_regmap_init_mmio(dev, gswip, &sw_regmap_config); 374 if (IS_ERR(priv->gswip)) 375 return PTR_ERR(priv->gswip); 376 377 priv->mdio = devm_regmap_init_mmio(dev, mdio, &mdio_regmap_config); 378 if (IS_ERR(priv->mdio)) 379 return PTR_ERR(priv->mdio); 380 381 priv->mii = devm_regmap_init_mmio(dev, mii, &mii_regmap_config); 382 if (IS_ERR(priv->mii)) 383 return PTR_ERR(priv->mii); 384 385 priv->hw_info = of_device_get_match_data(dev); 386 if (!priv->hw_info) 387 return -EINVAL; 388 389 priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL); 390 if (!priv->ds) 391 return -ENOMEM; 392 393 priv->dev = dev; 394 395 regmap_read(priv->gswip, GSWIP_VERSION, &version); 396 397 np = dev->of_node; 398 switch (version) { 399 case GSWIP_VERSION_2_0: 400 case GSWIP_VERSION_2_1: 401 if (!of_device_is_compatible(np, "lantiq,xrx200-gswip")) 402 return -EINVAL; 403 break; 404 case GSWIP_VERSION_2_2: 405 case GSWIP_VERSION_2_2_ETC: 406 if (!of_device_is_compatible(np, "lantiq,xrx300-gswip") && 407 !of_device_is_compatible(np, "lantiq,xrx330-gswip")) 408 return -EINVAL; 409 break; 410 default: 411 return dev_err_probe(dev, -ENOENT, 412 "unknown GSWIP version: 0x%x\n", version); 413 } 414 415 /* bring up the mdio bus */ 416 gphy_fw_np = of_get_compatible_child(dev->of_node, "lantiq,gphy-fw"); 417 if (gphy_fw_np) { 418 err = gswip_gphy_fw_list(priv, gphy_fw_np, version); 419 of_node_put(gphy_fw_np); 420 if (err) 421 return dev_err_probe(dev, err, 422 "gphy fw probe failed\n"); 423 } 424 425 err = gswip_probe_common(priv, version); 426 if (err) 427 goto gphy_fw_remove; 428 429 platform_set_drvdata(pdev, priv); 430 431 return 0; 432 433gphy_fw_remove: 434 for (i = 0; i < priv->num_gphy_fw; i++) 435 gswip_gphy_fw_remove(priv, &priv->gphy_fw[i]); 436 return err; 437} 438 439static void gswip_remove(struct platform_device *pdev) 440{ 441 struct gswip_priv *priv = platform_get_drvdata(pdev); 442 int i; 443 444 if (!priv) 445 return; 446 447 dsa_unregister_switch(priv->ds); 448 449 for (i = 0; i < priv->num_gphy_fw; i++) 450 gswip_gphy_fw_remove(priv, &priv->gphy_fw[i]); 451} 452 453static void gswip_shutdown(struct platform_device *pdev) 454{ 455 struct gswip_priv *priv = platform_get_drvdata(pdev); 456 457 if (!priv) 458 return; 459 460 dsa_switch_shutdown(priv->ds); 461 462 platform_set_drvdata(pdev, NULL); 463} 464 465static const struct gswip_hw_info gswip_xrx200 = { 466 .max_ports = 7, 467 .allowed_cpu_ports = BIT(6), 468 .mii_ports = BIT(0) | BIT(1) | BIT(5), 469 .mii_port_reg_offset = 0, 470 .phylink_get_caps = gswip_xrx200_phylink_get_caps, 471 .pce_microcode = &gswip_pce_microcode, 472 .pce_microcode_size = ARRAY_SIZE(gswip_pce_microcode), 473 .tag_protocol = DSA_TAG_PROTO_GSWIP, 474}; 475 476static const struct gswip_hw_info gswip_xrx300 = { 477 .max_ports = 7, 478 .allowed_cpu_ports = BIT(6), 479 .mii_ports = BIT(0) | BIT(5), 480 .mii_port_reg_offset = 0, 481 .phylink_get_caps = gswip_xrx300_phylink_get_caps, 482 .pce_microcode = &gswip_pce_microcode, 483 .pce_microcode_size = ARRAY_SIZE(gswip_pce_microcode), 484 .tag_protocol = DSA_TAG_PROTO_GSWIP, 485}; 486 487static const struct of_device_id gswip_of_match[] = { 488 { .compatible = "lantiq,xrx200-gswip", .data = &gswip_xrx200 }, 489 { .compatible = "lantiq,xrx300-gswip", .data = &gswip_xrx300 }, 490 { .compatible = "lantiq,xrx330-gswip", .data = &gswip_xrx300 }, 491 {}, 492}; 493MODULE_DEVICE_TABLE(of, gswip_of_match); 494 495static struct platform_driver gswip_driver = { 496 .probe = gswip_probe, 497 .remove = gswip_remove, 498 .shutdown = gswip_shutdown, 499 .driver = { 500 .name = "gswip", 501 .of_match_table = gswip_of_match, 502 }, 503}; 504 505module_platform_driver(gswip_driver); 506 507MODULE_FIRMWARE("lantiq/xrx300_phy11g_a21.bin"); 508MODULE_FIRMWARE("lantiq/xrx300_phy22f_a21.bin"); 509MODULE_FIRMWARE("lantiq/xrx200_phy11g_a14.bin"); 510MODULE_FIRMWARE("lantiq/xrx200_phy11g_a22.bin"); 511MODULE_FIRMWARE("lantiq/xrx200_phy22f_a14.bin"); 512MODULE_FIRMWARE("lantiq/xrx200_phy22f_a22.bin"); 513MODULE_AUTHOR("Hauke Mehrtens <hauke@hauke-m.de>"); 514MODULE_DESCRIPTION("Lantiq / Intel GSWIP driver"); 515MODULE_LICENSE("GPL v2");
~/
Read-only file preview.