FILE
mxl-gsw1xx.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/dsa/lantiq/mxl-gsw1xx.c
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* DSA Driver for MaxLinear GSW1xx switch devices 3 * 4 * Copyright (C) 2025 Daniel Golle <daniel@makrotopia.org> 5 * Copyright (C) 2023 - 2024 MaxLinear Inc. 6 * Copyright (C) 2022 Snap One, LLC. All rights reserved. 7 * Copyright (C) 2017 - 2019 Hauke Mehrtens <hauke@hauke-m.de> 8 * Copyright (C) 2012 John Crispin <john@phrozen.org> 9 * Copyright (C) 2010 Lantiq Deutschland 10 */ 11 12#include <linux/bits.h> 13#include <linux/delay.h> 14#include <linux/jiffies.h> 15#include <linux/module.h> 16#include <linux/of_device.h> 17#include <linux/of_mdio.h> 18#include <linux/regmap.h> 19#include <linux/workqueue.h> 20#include <net/dsa.h> 21 22#include "lantiq_gswip.h" 23#include "mxl-gsw1xx.h" 24#include "mxl-gsw1xx_pce.h" 25 26struct gsw1xx_priv { 27 struct mdio_device *mdio_dev; 28 int smdio_badr; 29 struct regmap *sgmii; 30 struct regmap *gpio; 31 struct regmap *clk; 32 struct regmap *shell; 33 struct phylink_pcs pcs; 34 struct delayed_work clear_raneg; 35 phy_interface_t tbi_interface; 36 struct gswip_priv gswip; 37}; 38 39static int gsw1xx_config_smdio_badr(struct gsw1xx_priv *priv, 40 unsigned int reg) 41{ 42 struct mii_bus *bus = priv->mdio_dev->bus; 43 int sw_addr = priv->mdio_dev->addr; 44 int smdio_badr = priv->smdio_badr; 45 int res; 46 47 if (smdio_badr == GSW1XX_SMDIO_BADR_UNKNOWN || 48 reg - smdio_badr >= GSW1XX_SMDIO_BADR || 49 smdio_badr > reg) { 50 /* Configure the Switch Base Address */ 51 smdio_badr = reg & ~GENMASK(3, 0); 52 res = __mdiobus_write(bus, sw_addr, GSW1XX_SMDIO_BADR, smdio_badr); 53 if (res < 0) { 54 dev_err(&priv->mdio_dev->dev, 55 "%s: Error %d, configuring switch base\n", 56 __func__, res); 57 return res; 58 } 59 priv->smdio_badr = smdio_badr; 60 } 61 62 return smdio_badr; 63} 64 65static int gsw1xx_regmap_read(void *context, unsigned int reg, 66 unsigned int *val) 67{ 68 struct gsw1xx_priv *priv = context; 69 struct mii_bus *bus = priv->mdio_dev->bus; 70 int sw_addr = priv->mdio_dev->addr; 71 int smdio_badr; 72 int res; 73 74 smdio_badr = gsw1xx_config_smdio_badr(priv, reg); 75 if (smdio_badr < 0) 76 return smdio_badr; 77 78 res = __mdiobus_read(bus, sw_addr, reg - smdio_badr); 79 if (res < 0) { 80 dev_err(&priv->mdio_dev->dev, "%s: Error %d reading 0x%x\n", 81 __func__, res, reg); 82 return res; 83 } 84 85 *val = res; 86 87 return 0; 88} 89 90static int gsw1xx_regmap_write(void *context, unsigned int reg, 91 unsigned int val) 92{ 93 struct gsw1xx_priv *priv = context; 94 struct mii_bus *bus = priv->mdio_dev->bus; 95 int sw_addr = priv->mdio_dev->addr; 96 int smdio_badr; 97 int res; 98 99 smdio_badr = gsw1xx_config_smdio_badr(priv, reg); 100 if (smdio_badr < 0) 101 return smdio_badr; 102 103 res = __mdiobus_write(bus, sw_addr, reg - smdio_badr, val); 104 if (res < 0) 105 dev_err(&priv->mdio_dev->dev, 106 "%s: Error %d, writing 0x%x:0x%x\n", __func__, res, reg, 107 val); 108 109 return res; 110} 111 112static const struct regmap_bus gsw1xx_regmap_bus = { 113 .reg_write = gsw1xx_regmap_write, 114 .reg_read = gsw1xx_regmap_read, 115}; 116 117static void gsw1xx_mdio_regmap_lock(void *mdio_lock) 118{ 119 mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED); 120} 121 122static void gsw1xx_mdio_regmap_unlock(void *mdio_lock) 123{ 124 mutex_unlock(mdio_lock); 125} 126 127static unsigned int gsw1xx_pcs_inband_caps(struct phylink_pcs *pcs, 128 phy_interface_t interface) 129{ 130 return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE; 131} 132 133static struct gsw1xx_priv *pcs_to_gsw1xx(struct phylink_pcs *pcs) 134{ 135 return container_of(pcs, struct gsw1xx_priv, pcs); 136} 137 138static int gsw1xx_pcs_enable(struct phylink_pcs *pcs) 139{ 140 struct gsw1xx_priv *priv = pcs_to_gsw1xx(pcs); 141 142 /* Deassert SGMII shell reset */ 143 return regmap_clear_bits(priv->shell, GSW1XX_SHELL_RST_REQ, 144 GSW1XX_RST_REQ_SGMII_SHELL); 145} 146 147static void gsw1xx_pcs_disable(struct phylink_pcs *pcs) 148{ 149 struct gsw1xx_priv *priv = pcs_to_gsw1xx(pcs); 150 151 cancel_delayed_work_sync(&priv->clear_raneg); 152 153 /* Assert SGMII shell reset (will also clear RANEG bit) */ 154 regmap_set_bits(priv->shell, GSW1XX_SHELL_RST_REQ, 155 GSW1XX_RST_REQ_SGMII_SHELL); 156 157 priv->tbi_interface = PHY_INTERFACE_MODE_NA; 158} 159 160static void gsw1xx_pcs_get_state(struct phylink_pcs *pcs, 161 unsigned int neg_mode, 162 struct phylink_link_state *state) 163{ 164 struct gsw1xx_priv *priv = pcs_to_gsw1xx(pcs); 165 int ret; 166 u32 val; 167 168 ret = regmap_read(priv->sgmii, GSW1XX_SGMII_TBI_TBISTAT, &val); 169 if (ret < 0) 170 return; 171 172 state->link = !!(val & GSW1XX_SGMII_TBI_TBISTAT_LINK); 173 state->an_complete = !!(val & GSW1XX_SGMII_TBI_TBISTAT_AN_COMPLETE); 174 175 ret = regmap_read(priv->sgmii, GSW1XX_SGMII_TBI_LPSTAT, &val); 176 if (ret < 0) 177 return; 178 179 state->duplex = (val & GSW1XX_SGMII_TBI_LPSTAT_DUPLEX) ? 180 DUPLEX_FULL : DUPLEX_HALF; 181 if (val & GSW1XX_SGMII_TBI_LPSTAT_PAUSE_RX) 182 state->pause |= MLO_PAUSE_RX; 183 184 if (val & GSW1XX_SGMII_TBI_LPSTAT_PAUSE_TX) 185 state->pause |= MLO_PAUSE_TX; 186 187 switch (FIELD_GET(GSW1XX_SGMII_TBI_LPSTAT_SPEED, val)) { 188 case GSW1XX_SGMII_TBI_LPSTAT_SPEED_10: 189 state->speed = SPEED_10; 190 break; 191 case GSW1XX_SGMII_TBI_LPSTAT_SPEED_100: 192 state->speed = SPEED_100; 193 break; 194 case GSW1XX_SGMII_TBI_LPSTAT_SPEED_1000: 195 state->speed = SPEED_1000; 196 break; 197 case GSW1XX_SGMII_TBI_LPSTAT_SPEED_NOSGMII: 198 if (state->interface == PHY_INTERFACE_MODE_1000BASEX) 199 state->speed = SPEED_1000; 200 else if (state->interface == PHY_INTERFACE_MODE_2500BASEX) 201 state->speed = SPEED_2500; 202 else 203 state->speed = SPEED_UNKNOWN; 204 break; 205 } 206} 207 208static int gsw1xx_pcs_phy_xaui_write(struct gsw1xx_priv *priv, u16 addr, 209 u16 data) 210{ 211 int ret, val; 212 213 ret = regmap_write(priv->sgmii, GSW1XX_SGMII_PHY_D, data); 214 if (ret < 0) 215 return ret; 216 217 ret = regmap_write(priv->sgmii, GSW1XX_SGMII_PHY_A, addr); 218 if (ret < 0) 219 return ret; 220 221 ret = regmap_write(priv->sgmii, GSW1XX_SGMII_PHY_C, 222 GSW1XX_SGMII_PHY_WRITE | 223 GSW1XX_SGMII_PHY_RESET_N); 224 if (ret < 0) 225 return ret; 226 227 return regmap_read_poll_timeout(priv->sgmii, GSW1XX_SGMII_PHY_C, 228 val, val & GSW1XX_SGMII_PHY_STATUS, 229 1000, 100000); 230} 231 232static int gsw1xx_pcs_reset(struct gsw1xx_priv *priv) 233{ 234 int ret; 235 u16 val; 236 237 /* Assert and deassert SGMII shell reset */ 238 ret = regmap_set_bits(priv->shell, GSW1XX_SHELL_RST_REQ, 239 GSW1XX_RST_REQ_SGMII_SHELL); 240 if (ret < 0) 241 return ret; 242 243 ret = regmap_clear_bits(priv->shell, GSW1XX_SHELL_RST_REQ, 244 GSW1XX_RST_REQ_SGMII_SHELL); 245 if (ret < 0) 246 return ret; 247 248 /* Hardware Bringup FSM Enable */ 249 ret = regmap_write(priv->sgmii, GSW1XX_SGMII_PHY_HWBU_CTRL, 250 GSW1XX_SGMII_PHY_HWBU_CTRL_EN_HWBU_FSM | 251 GSW1XX_SGMII_PHY_HWBU_CTRL_HW_FSM_EN); 252 if (ret < 0) 253 return ret; 254 255 /* Configure SGMII PHY Receiver */ 256 val = FIELD_PREP(GSW1XX_SGMII_PHY_RX0_CFG2_EQ, 257 GSW1XX_SGMII_PHY_RX0_CFG2_EQ_DEF) | 258 GSW1XX_SGMII_PHY_RX0_CFG2_LOS_EN | 259 GSW1XX_SGMII_PHY_RX0_CFG2_TERM_EN | 260 FIELD_PREP(GSW1XX_SGMII_PHY_RX0_CFG2_FILT_CNT, 261 GSW1XX_SGMII_PHY_RX0_CFG2_FILT_CNT_DEF); 262 263 /* RX lane seems to be inverted internally, so bit 264 * GSW1XX_SGMII_PHY_RX0_CFG2_INVERT needs to be set for normal 265 * (ie. non-inverted) operation. 266 * 267 * TODO: Take care of inverted RX pair once generic property is 268 * available 269 */ 270 271 val |= GSW1XX_SGMII_PHY_RX0_CFG2_INVERT; 272 273 ret = regmap_write(priv->sgmii, GSW1XX_SGMII_PHY_RX0_CFG2, val); 274 if (ret < 0) 275 return ret; 276 277 val = FIELD_PREP(GSW1XX_SGMII_PHY_TX0_CFG3_VBOOST_LEVEL, 278 GSW1XX_SGMII_PHY_TX0_CFG3_VBOOST_LEVEL_DEF); 279 280 /* TODO: Take care of inverted TX pair once generic property is 281 * available 282 */ 283 284 ret = regmap_write(priv->sgmii, GSW1XX_SGMII_PHY_TX0_CFG3, val); 285 if (ret < 0) 286 return ret; 287 288 /* Reset and Release TBI */ 289 val = GSW1XX_SGMII_TBI_TBICTL_INITTBI | GSW1XX_SGMII_TBI_TBICTL_ENTBI | 290 GSW1XX_SGMII_TBI_TBICTL_CRSTRR | GSW1XX_SGMII_TBI_TBICTL_CRSOFF; 291 ret = regmap_write(priv->sgmii, GSW1XX_SGMII_TBI_TBICTL, val); 292 if (ret < 0) 293 return ret; 294 val &= ~GSW1XX_SGMII_TBI_TBICTL_INITTBI; 295 ret = regmap_write(priv->sgmii, GSW1XX_SGMII_TBI_TBICTL, val); 296 if (ret < 0) 297 return ret; 298 299 /* Release Tx Data Buffers */ 300 ret = regmap_set_bits(priv->sgmii, GSW1XX_SGMII_PCS_TXB_CTL, 301 GSW1XX_SGMII_PCS_TXB_CTL_INIT_TX_TXB); 302 if (ret < 0) 303 return ret; 304 ret = regmap_clear_bits(priv->sgmii, GSW1XX_SGMII_PCS_TXB_CTL, 305 GSW1XX_SGMII_PCS_TXB_CTL_INIT_TX_TXB); 306 if (ret < 0) 307 return ret; 308 309 /* Release Rx Data Buffers */ 310 ret = regmap_set_bits(priv->sgmii, GSW1XX_SGMII_PCS_RXB_CTL, 311 GSW1XX_SGMII_PCS_RXB_CTL_INIT_RX_RXB); 312 if (ret < 0) 313 return ret; 314 return regmap_clear_bits(priv->sgmii, GSW1XX_SGMII_PCS_RXB_CTL, 315 GSW1XX_SGMII_PCS_RXB_CTL_INIT_RX_RXB); 316} 317 318static int gsw1xx_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, 319 phy_interface_t interface, 320 const unsigned long *advertising, 321 bool permit_pause_to_mac) 322{ 323 struct gsw1xx_priv *priv = pcs_to_gsw1xx(pcs); 324 u16 txaneg, anegctl, nco_ctrl; 325 bool reconf = false; 326 int ret = 0; 327 328 /* do not unnecessarily disrupt link and skip resetting the hardware in 329 * case the PCS has previously been successfully configured for this 330 * interface mode 331 */ 332 if (priv->tbi_interface == interface) 333 reconf = true; 334 335 /* mark PCS configuration as incomplete */ 336 priv->tbi_interface = PHY_INTERFACE_MODE_NA; 337 338 if (!reconf) 339 ret = gsw1xx_pcs_reset(priv); 340 341 if (ret) 342 return ret; 343 344 /* override bootstrap pin settings 345 * OVRANEG sets ANEG Mode, Enable ANEG and restart ANEG to be 346 * taken from bits ANMODE, ANEGEN, RANEG of the ANEGCTL register. 347 * OVERABL sets ability bits in tx_config_reg to be taken from 348 * the TXANEGH and TXANEGL registers. 349 */ 350 anegctl = GSW1XX_SGMII_TBI_ANEGCTL_OVRANEG | 351 GSW1XX_SGMII_TBI_ANEGCTL_OVRABL; 352 353 switch (phylink_get_link_timer_ns(interface)) { 354 case 10000: 355 anegctl |= FIELD_PREP(GSW1XX_SGMII_TBI_ANEGCTL_LT, 356 GSW1XX_SGMII_TBI_ANEGCTL_LT_10US); 357 break; 358 case 1600000: 359 anegctl |= FIELD_PREP(GSW1XX_SGMII_TBI_ANEGCTL_LT, 360 GSW1XX_SGMII_TBI_ANEGCTL_LT_1_6MS); 361 break; 362 case 5000000: 363 anegctl |= FIELD_PREP(GSW1XX_SGMII_TBI_ANEGCTL_LT, 364 GSW1XX_SGMII_TBI_ANEGCTL_LT_5MS); 365 break; 366 case 10000000: 367 anegctl |= FIELD_PREP(GSW1XX_SGMII_TBI_ANEGCTL_LT, 368 GSW1XX_SGMII_TBI_ANEGCTL_LT_10MS); 369 break; 370 default: 371 return -EINVAL; 372 } 373 374 if (neg_mode & PHYLINK_PCS_NEG_INBAND) 375 anegctl |= GSW1XX_SGMII_TBI_ANEGCTL_ANEGEN; 376 377 txaneg = phylink_mii_c22_pcs_encode_advertisement(interface, advertising); 378 379 if (interface == PHY_INTERFACE_MODE_SGMII) { 380 /* lacking a defined reverse-SGMII interface mode this 381 * driver only supports SGMII (MAC side) for now 382 */ 383 anegctl |= FIELD_PREP(GSW1XX_SGMII_TBI_ANEGCTL_ANMODE, 384 GSW1XX_SGMII_TBI_ANEGCTL_ANMODE_SGMII_MAC); 385 txaneg |= ADVERTISE_LPACK; 386 } else if (interface == PHY_INTERFACE_MODE_1000BASEX || 387 interface == PHY_INTERFACE_MODE_2500BASEX) { 388 anegctl |= FIELD_PREP(GSW1XX_SGMII_TBI_ANEGCTL_ANMODE, 389 GSW1XX_SGMII_TBI_ANEGCTL_ANMODE_1000BASEX); 390 } else { 391 dev_err(priv->gswip.dev, "%s: wrong interface mode %s\n", 392 __func__, phy_modes(interface)); 393 return -EINVAL; 394 } 395 396 ret = regmap_write(priv->sgmii, GSW1XX_SGMII_TBI_TXANEGH, 397 FIELD_GET(GENMASK(15, 8), txaneg)); 398 if (ret < 0) 399 return ret; 400 ret = regmap_write(priv->sgmii, GSW1XX_SGMII_TBI_TXANEGL, 401 FIELD_GET(GENMASK(7, 0), txaneg)); 402 if (ret < 0) 403 return ret; 404 ret = regmap_write(priv->sgmii, GSW1XX_SGMII_TBI_ANEGCTL, anegctl); 405 if (ret < 0) 406 return ret; 407 408 if (!reconf) { 409 /* setup SerDes clock speed */ 410 if (interface == PHY_INTERFACE_MODE_2500BASEX) 411 nco_ctrl = GSW1XX_SGMII_2G5 | GSW1XX_SGMII_2G5_NCO2; 412 else 413 nco_ctrl = GSW1XX_SGMII_1G | GSW1XX_SGMII_1G_NCO1; 414 415 ret = regmap_update_bits(priv->clk, GSW1XX_CLK_NCO_CTRL, 416 GSW1XX_SGMII_HSP_MASK | 417 GSW1XX_SGMII_SEL, 418 nco_ctrl); 419 if (ret) 420 return ret; 421 422 ret = gsw1xx_pcs_phy_xaui_write(priv, 0x30, 0x80); 423 if (ret) 424 return ret; 425 } 426 427 /* PCS configuration has now been completed, store mode to prevent 428 * disrupting the link in case of future calls of this function for the 429 * same interface mode. 430 */ 431 priv->tbi_interface = interface; 432 433 return 0; 434} 435 436static void gsw1xx_pcs_clear_raneg(struct work_struct *work) 437{ 438 struct gsw1xx_priv *priv = 439 container_of(work, struct gsw1xx_priv, clear_raneg.work); 440 441 regmap_clear_bits(priv->sgmii, GSW1XX_SGMII_TBI_ANEGCTL, 442 GSW1XX_SGMII_TBI_ANEGCTL_RANEG); 443} 444 445static void gsw1xx_pcs_an_restart(struct phylink_pcs *pcs) 446{ 447 struct gsw1xx_priv *priv = pcs_to_gsw1xx(pcs); 448 449 cancel_delayed_work_sync(&priv->clear_raneg); 450 451 regmap_set_bits(priv->sgmii, GSW1XX_SGMII_TBI_ANEGCTL, 452 GSW1XX_SGMII_TBI_ANEGCTL_RANEG); 453 454 /* despite being documented as self-clearing, the RANEG bit 455 * sometimes remains set, preventing auto-negotiation from happening. 456 * MaxLinear advises to manually clear the bit after 10ms. 457 */ 458 schedule_delayed_work(&priv->clear_raneg, msecs_to_jiffies(10)); 459} 460 461static void gsw1xx_pcs_link_up(struct phylink_pcs *pcs, 462 unsigned int neg_mode, 463 phy_interface_t interface, int speed, 464 int duplex) 465{ 466 struct gsw1xx_priv *priv = pcs_to_gsw1xx(pcs); 467 u16 lpstat; 468 469 /* When in-band AN is enabled hardware will set lpstat */ 470 if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) 471 return; 472 473 /* Force speed and duplex settings */ 474 if (interface == PHY_INTERFACE_MODE_SGMII) { 475 if (speed == SPEED_10) 476 lpstat = FIELD_PREP(GSW1XX_SGMII_TBI_LPSTAT_SPEED, 477 GSW1XX_SGMII_TBI_LPSTAT_SPEED_10); 478 else if (speed == SPEED_100) 479 lpstat = FIELD_PREP(GSW1XX_SGMII_TBI_LPSTAT_SPEED, 480 GSW1XX_SGMII_TBI_LPSTAT_SPEED_100); 481 else 482 lpstat = FIELD_PREP(GSW1XX_SGMII_TBI_LPSTAT_SPEED, 483 GSW1XX_SGMII_TBI_LPSTAT_SPEED_1000); 484 } else { 485 lpstat = FIELD_PREP(GSW1XX_SGMII_TBI_LPSTAT_SPEED, 486 GSW1XX_SGMII_TBI_LPSTAT_SPEED_NOSGMII); 487 } 488 489 if (duplex == DUPLEX_FULL) 490 lpstat |= GSW1XX_SGMII_TBI_LPSTAT_DUPLEX; 491 492 regmap_write(priv->sgmii, GSW1XX_SGMII_TBI_LPSTAT, lpstat); 493} 494 495static const struct phylink_pcs_ops gsw1xx_pcs_ops = { 496 .pcs_inband_caps = gsw1xx_pcs_inband_caps, 497 .pcs_enable = gsw1xx_pcs_enable, 498 .pcs_disable = gsw1xx_pcs_disable, 499 .pcs_get_state = gsw1xx_pcs_get_state, 500 .pcs_config = gsw1xx_pcs_config, 501 .pcs_an_restart = gsw1xx_pcs_an_restart, 502 .pcs_link_up = gsw1xx_pcs_link_up, 503}; 504 505static void gsw1xx_phylink_get_caps(struct dsa_switch *ds, int port, 506 struct phylink_config *config) 507{ 508 struct gswip_priv *priv = ds->priv; 509 510 config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | 511 MAC_10 | MAC_100 | MAC_1000; 512 513 switch (port) { 514 case 0: 515 case 1: 516 case 2: 517 case 3: 518 __set_bit(PHY_INTERFACE_MODE_INTERNAL, 519 config->supported_interfaces); 520 break; 521 case 4: /* port 4: SGMII */ 522 __set_bit(PHY_INTERFACE_MODE_SGMII, 523 config->supported_interfaces); 524 __set_bit(PHY_INTERFACE_MODE_1000BASEX, 525 config->supported_interfaces); 526 if (priv->hw_info->supports_2500m) { 527 __set_bit(PHY_INTERFACE_MODE_2500BASEX, 528 config->supported_interfaces); 529 config->mac_capabilities |= MAC_2500FD; 530 } 531 return; /* no support for EEE on SGMII port */ 532 case 5: /* port 5: RGMII or RMII */ 533 __set_bit(PHY_INTERFACE_MODE_RMII, 534 config->supported_interfaces); 535 phy_interface_set_rgmii(config->supported_interfaces); 536 break; 537 } 538 539 config->lpi_capabilities = MAC_100FD | MAC_1000FD; 540 config->lpi_timer_default = 20; 541 memcpy(config->lpi_interfaces, config->supported_interfaces, 542 sizeof(config->lpi_interfaces)); 543} 544 545static struct phylink_pcs *gsw1xx_phylink_mac_select_pcs(struct phylink_config *config, 546 phy_interface_t interface) 547{ 548 struct dsa_port *dp = dsa_phylink_to_port(config); 549 struct gswip_priv *gswip_priv = dp->ds->priv; 550 struct gsw1xx_priv *gsw1xx_priv = container_of(gswip_priv, 551 struct gsw1xx_priv, 552 gswip); 553 554 switch (dp->index) { 555 case GSW1XX_SGMII_PORT: 556 return &gsw1xx_priv->pcs; 557 default: 558 return NULL; 559 } 560} 561 562static struct regmap *gsw1xx_regmap_init(struct gsw1xx_priv *priv, 563 const char *name, 564 unsigned int reg_base, 565 unsigned int max_register) 566{ 567 const struct regmap_config config = { 568 .name = name, 569 .reg_bits = 16, 570 .val_bits = 16, 571 .reg_base = reg_base, 572 .max_register = max_register, 573 .lock = gsw1xx_mdio_regmap_lock, 574 .unlock = gsw1xx_mdio_regmap_unlock, 575 .lock_arg = &priv->mdio_dev->bus->mdio_lock, 576 }; 577 578 return devm_regmap_init(&priv->mdio_dev->dev, &gsw1xx_regmap_bus, 579 priv, &config); 580} 581 582static int gsw1xx_probe(struct mdio_device *mdiodev) 583{ 584 struct device *dev = &mdiodev->dev; 585 struct gsw1xx_priv *priv; 586 u32 version; 587 int ret; 588 589 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 590 if (!priv) 591 return -ENOMEM; 592 593 priv->mdio_dev = mdiodev; 594 priv->smdio_badr = GSW1XX_SMDIO_BADR_UNKNOWN; 595 596 priv->gswip.dev = dev; 597 priv->gswip.hw_info = of_device_get_match_data(dev); 598 if (!priv->gswip.hw_info) 599 return -EINVAL; 600 601 priv->gswip.gswip = gsw1xx_regmap_init(priv, "switch", 602 GSW1XX_SWITCH_BASE, 0xfff); 603 if (IS_ERR(priv->gswip.gswip)) 604 return PTR_ERR(priv->gswip.gswip); 605 606 priv->gswip.mdio = gsw1xx_regmap_init(priv, "mdio", GSW1XX_MMDIO_BASE, 607 0xff); 608 if (IS_ERR(priv->gswip.mdio)) 609 return PTR_ERR(priv->gswip.mdio); 610 611 priv->gswip.mii = gsw1xx_regmap_init(priv, "mii", GSW1XX_RGMII_BASE, 612 0xff); 613 if (IS_ERR(priv->gswip.mii)) 614 return PTR_ERR(priv->gswip.mii); 615 616 priv->sgmii = gsw1xx_regmap_init(priv, "sgmii", GSW1XX_SGMII_BASE, 617 0xfff); 618 if (IS_ERR(priv->sgmii)) 619 return PTR_ERR(priv->sgmii); 620 621 priv->gpio = gsw1xx_regmap_init(priv, "gpio", GSW1XX_GPIO_BASE, 0xff); 622 if (IS_ERR(priv->gpio)) 623 return PTR_ERR(priv->gpio); 624 625 priv->clk = gsw1xx_regmap_init(priv, "clk", GSW1XX_CLK_BASE, 0xff); 626 if (IS_ERR(priv->clk)) 627 return PTR_ERR(priv->clk); 628 629 priv->shell = gsw1xx_regmap_init(priv, "shell", GSW1XX_SHELL_BASE, 630 0xff); 631 if (IS_ERR(priv->shell)) 632 return PTR_ERR(priv->shell); 633 634 priv->pcs.ops = &gsw1xx_pcs_ops; 635 priv->pcs.poll = true; 636 __set_bit(PHY_INTERFACE_MODE_SGMII, 637 priv->pcs.supported_interfaces); 638 __set_bit(PHY_INTERFACE_MODE_1000BASEX, 639 priv->pcs.supported_interfaces); 640 if (priv->gswip.hw_info->supports_2500m) 641 __set_bit(PHY_INTERFACE_MODE_2500BASEX, 642 priv->pcs.supported_interfaces); 643 priv->tbi_interface = PHY_INTERFACE_MODE_NA; 644 645 /* assert SGMII reset to power down SGMII unit */ 646 ret = regmap_set_bits(priv->shell, GSW1XX_SHELL_RST_REQ, 647 GSW1XX_RST_REQ_SGMII_SHELL); 648 if (ret < 0) 649 return ret; 650 651 /* configure GPIO pin-mux for MMDIO in case of external PHY connected to 652 * SGMII or RGMII as slave interface 653 */ 654 regmap_set_bits(priv->gpio, GPIO_ALTSEL0, 3); 655 regmap_set_bits(priv->gpio, GPIO_ALTSEL1, 3); 656 657 ret = regmap_read(priv->gswip.gswip, GSWIP_VERSION, &version); 658 if (ret) 659 return ret; 660 661 INIT_DELAYED_WORK(&priv->clear_raneg, gsw1xx_pcs_clear_raneg); 662 663 ret = gswip_probe_common(&priv->gswip, version); 664 if (ret) 665 return ret; 666 667 dev_set_drvdata(dev, &priv->gswip); 668 669 return 0; 670} 671 672static void gsw1xx_remove(struct mdio_device *mdiodev) 673{ 674 struct gswip_priv *priv = dev_get_drvdata(&mdiodev->dev); 675 struct gsw1xx_priv *gsw1xx_priv; 676 677 if (!priv) 678 return; 679 680 dsa_unregister_switch(priv->ds); 681 682 gsw1xx_priv = container_of(priv, struct gsw1xx_priv, gswip); 683 cancel_delayed_work_sync(&gsw1xx_priv->clear_raneg); 684} 685 686static void gsw1xx_shutdown(struct mdio_device *mdiodev) 687{ 688 struct gswip_priv *priv = dev_get_drvdata(&mdiodev->dev); 689 struct gsw1xx_priv *gsw1xx_priv; 690 691 if (!priv) 692 return; 693 694 dsa_switch_shutdown(priv->ds); 695 696 dev_set_drvdata(&mdiodev->dev, NULL); 697 698 gsw1xx_priv = container_of(priv, struct gsw1xx_priv, gswip); 699 cancel_delayed_work_sync(&gsw1xx_priv->clear_raneg); 700} 701 702static const struct gswip_hw_info gsw12x_data = { 703 .max_ports = GSW1XX_PORTS, 704 .allowed_cpu_ports = BIT(GSW1XX_MII_PORT) | BIT(GSW1XX_SGMII_PORT), 705 .mii_ports = BIT(GSW1XX_MII_PORT), 706 .mii_port_reg_offset = -GSW1XX_MII_PORT, 707 .mac_select_pcs = gsw1xx_phylink_mac_select_pcs, 708 .phylink_get_caps = &gsw1xx_phylink_get_caps, 709 .supports_2500m = true, 710 .pce_microcode = &gsw1xx_pce_microcode, 711 .pce_microcode_size = ARRAY_SIZE(gsw1xx_pce_microcode), 712 .tag_protocol = DSA_TAG_PROTO_MXL_GSW1XX, 713}; 714 715static const struct gswip_hw_info gsw140_data = { 716 .max_ports = GSW1XX_PORTS, 717 .allowed_cpu_ports = BIT(GSW1XX_MII_PORT) | BIT(GSW1XX_SGMII_PORT), 718 .mii_ports = BIT(GSW1XX_MII_PORT), 719 .mii_port_reg_offset = -GSW1XX_MII_PORT, 720 .mac_select_pcs = gsw1xx_phylink_mac_select_pcs, 721 .phylink_get_caps = &gsw1xx_phylink_get_caps, 722 .supports_2500m = true, 723 .pce_microcode = &gsw1xx_pce_microcode, 724 .pce_microcode_size = ARRAY_SIZE(gsw1xx_pce_microcode), 725 .tag_protocol = DSA_TAG_PROTO_MXL_GSW1XX, 726}; 727 728static const struct gswip_hw_info gsw141_data = { 729 .max_ports = GSW1XX_PORTS, 730 .allowed_cpu_ports = BIT(GSW1XX_MII_PORT) | BIT(GSW1XX_SGMII_PORT), 731 .mii_ports = BIT(GSW1XX_MII_PORT), 732 .mii_port_reg_offset = -GSW1XX_MII_PORT, 733 .mac_select_pcs = gsw1xx_phylink_mac_select_pcs, 734 .phylink_get_caps = gsw1xx_phylink_get_caps, 735 .pce_microcode = &gsw1xx_pce_microcode, 736 .pce_microcode_size = ARRAY_SIZE(gsw1xx_pce_microcode), 737 .tag_protocol = DSA_TAG_PROTO_MXL_GSW1XX, 738}; 739 740/* 741 * GSW125 is the industrial temperature version of GSW120. 742 * GSW145 is the industrial temperature version of GSW140. 743 */ 744static const struct of_device_id gsw1xx_of_match[] = { 745 { .compatible = "maxlinear,gsw120", .data = &gsw12x_data }, 746 { .compatible = "maxlinear,gsw125", .data = &gsw12x_data }, 747 { .compatible = "maxlinear,gsw140", .data = &gsw140_data }, 748 { .compatible = "maxlinear,gsw141", .data = &gsw141_data }, 749 { .compatible = "maxlinear,gsw145", .data = &gsw140_data }, 750 { /* sentinel */ }, 751}; 752 753MODULE_DEVICE_TABLE(of, gsw1xx_of_match); 754 755static struct mdio_driver gsw1xx_driver = { 756 .probe = gsw1xx_probe, 757 .remove = gsw1xx_remove, 758 .shutdown = gsw1xx_shutdown, 759 .mdiodrv.driver = { 760 .name = "mxl-gsw1xx", 761 .of_match_table = gsw1xx_of_match, 762 }, 763}; 764 765mdio_module_driver(gsw1xx_driver); 766 767MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>"); 768MODULE_DESCRIPTION("Driver for MaxLinear GSW1xx ethernet switch"); 769MODULE_LICENSE("GPL");
~/
Read-only file preview.