1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) 2023 Sartura Ltd. 4 * 5 * Author: Robert Marko <robert.marko@sartura.hr> 6 * Christian Marangi <ansuelsmth@gmail.com> 7 * 8 * Qualcomm QCA8072 and QCA8075 PHY driver 9 */ 10 11 #include <linux/module.h> 12 #include <linux/of.h> 13 #include <linux/phy.h> 14 #include <linux/bitfield.h> 15 #include <linux/gpio/driver.h> 16 #include <linux/sfp.h> 17 18 #include "../phylib.h" 19 #include "qcom.h" 20 21 #define QCA807X_CHIP_CONFIGURATION 0x1f 22 #define QCA807X_BT_BX_REG_SEL BIT(15) 23 #define QCA807X_BT_BX_REG_SEL_FIBER 0 24 #define QCA807X_BT_BX_REG_SEL_COPPER 1 25 #define QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK GENMASK(3, 0) 26 #define QCA807X_CHIP_CONFIGURATION_MODE_QSGMII_SGMII 4 27 #define QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_FIBER 3 28 #define QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_ALL_COPPER 0 29 30 #define QCA807X_MEDIA_SELECT_STATUS 0x1a 31 #define QCA807X_MEDIA_DETECTED_COPPER BIT(5) 32 #define QCA807X_MEDIA_DETECTED_1000_BASE_X BIT(4) 33 #define QCA807X_MEDIA_DETECTED_100_BASE_FX BIT(3) 34 35 #define QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION 0x807e 36 #define QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION_EN BIT(0) 37 38 #define QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH 0x801a 39 #define QCA807X_CONTROL_DAC_MASK GENMASK(2, 0) 40 /* List of tweaks enabled by this bit: 41 * - With both FULL amplitude and FULL bias current: bias current 42 * is set to half. 43 * - With only DSP amplitude: bias current is set to half and 44 * is set to 1/4 with cable < 10m. 45 * - With DSP bias current (included both DSP amplitude and 46 * DSP bias current): bias current is half the detected current 47 * with cable < 10m. 48 */ 49 #define QCA807X_CONTROL_DAC_BIAS_CURRENT_TWEAK BIT(2) 50 #define QCA807X_CONTROL_DAC_DSP_BIAS_CURRENT BIT(1) 51 #define QCA807X_CONTROL_DAC_DSP_AMPLITUDE BIT(0) 52 53 #define QCA807X_MMD7_LED_100N_1 0x8074 54 #define QCA807X_MMD7_LED_100N_2 0x8075 55 #define QCA807X_MMD7_LED_1000N_1 0x8076 56 #define QCA807X_MMD7_LED_1000N_2 0x8077 57 58 #define QCA807X_MMD7_LED_CTRL(x) (0x8074 + ((x) * 2)) 59 #define QCA807X_MMD7_LED_FORCE_CTRL(x) (0x8075 + ((x) * 2)) 60 61 /* LED hw control pattern for fiber port */ 62 #define QCA807X_LED_FIBER_PATTERN_MASK GENMASK(11, 1) 63 #define QCA807X_LED_FIBER_TXACT_BLK_EN BIT(10) 64 #define QCA807X_LED_FIBER_RXACT_BLK_EN BIT(9) 65 #define QCA807X_LED_FIBER_FDX_ON_EN BIT(6) 66 #define QCA807X_LED_FIBER_HDX_ON_EN BIT(5) 67 #define QCA807X_LED_FIBER_1000BX_ON_EN BIT(2) 68 #define QCA807X_LED_FIBER_100FX_ON_EN BIT(1) 69 70 /* Some device repurpose the LED as GPIO out */ 71 #define QCA807X_GPIO_FORCE_EN QCA808X_LED_FORCE_EN 72 #define QCA807X_GPIO_FORCE_MODE_MASK QCA808X_LED_FORCE_MODE_MASK 73 74 #define QCA807X_FUNCTION_CONTROL 0x10 75 #define QCA807X_FC_MDI_CROSSOVER_MODE_MASK GENMASK(6, 5) 76 #define QCA807X_FC_MDI_CROSSOVER_AUTO 3 77 #define QCA807X_FC_MDI_CROSSOVER_MANUAL_MDIX 1 78 #define QCA807X_FC_MDI_CROSSOVER_MANUAL_MDI 0 79 80 /* PQSGMII Analog PHY specific */ 81 #define PQSGMII_CTRL_REG 0x0 82 #define PQSGMII_ANALOG_SW_RESET BIT(6) 83 #define PQSGMII_DRIVE_CONTROL_1 0xb 84 #define PQSGMII_TX_DRIVER_MASK GENMASK(7, 4) 85 #define PQSGMII_TX_DRIVER_140MV 0x0 86 #define PQSGMII_TX_DRIVER_160MV 0x1 87 #define PQSGMII_TX_DRIVER_180MV 0x2 88 #define PQSGMII_TX_DRIVER_200MV 0x3 89 #define PQSGMII_TX_DRIVER_220MV 0x4 90 #define PQSGMII_TX_DRIVER_240MV 0x5 91 #define PQSGMII_TX_DRIVER_260MV 0x6 92 #define PQSGMII_TX_DRIVER_280MV 0x7 93 #define PQSGMII_TX_DRIVER_300MV 0x8 94 #define PQSGMII_TX_DRIVER_320MV 0x9 95 #define PQSGMII_TX_DRIVER_400MV 0xa 96 #define PQSGMII_TX_DRIVER_500MV 0xb 97 #define PQSGMII_TX_DRIVER_600MV 0xc 98 #define PQSGMII_MODE_CTRL 0x6d 99 #define PQSGMII_MODE_CTRL_AZ_WORKAROUND_MASK BIT(0) 100 #define PQSGMII_MMD3_SERDES_CONTROL 0x805a 101 102 #define PHY_ID_QCA8072 0x004dd0b2 103 #define PHY_ID_QCA8075 0x004dd0b1 104 105 #define QCA807X_COMBO_ADDR_OFFSET 4 106 #define QCA807X_PQSGMII_ADDR_OFFSET 5 107 #define SERDES_RESET_SLEEP 100 108 109 enum qca807x_global_phy { 110 QCA807X_COMBO_ADDR = 4, 111 QCA807X_PQSGMII_ADDR = 5, 112 }; 113 114 struct qca807x_shared_priv { 115 unsigned int package_mode; 116 u32 tx_drive_strength; 117 }; 118 119 struct qca807x_gpio_priv { 120 struct phy_device *phy; 121 }; 122 123 struct qca807x_priv { 124 bool dac_full_amplitude; 125 bool dac_full_bias_current; 126 bool dac_disable_bias_current_tweak; 127 struct qcom_phy_hw_stats hw_stats; 128 }; 129 130 static int qca807x_cable_test_start(struct phy_device *phydev) 131 { 132 /* we do all the (time consuming) work later */ 133 return 0; 134 } 135 136 static int qca807x_led_parse_netdev(struct phy_device *phydev, unsigned long rules, 137 u16 *offload_trigger) 138 { 139 /* Parsing specific to netdev trigger */ 140 switch (phydev->port) { 141 case PORT_TP: 142 if (test_bit(TRIGGER_NETDEV_TX, &rules)) 143 *offload_trigger |= QCA808X_LED_TX_BLINK; 144 if (test_bit(TRIGGER_NETDEV_RX, &rules)) 145 *offload_trigger |= QCA808X_LED_RX_BLINK; 146 if (test_bit(TRIGGER_NETDEV_LINK_10, &rules)) 147 *offload_trigger |= QCA808X_LED_SPEED10_ON; 148 if (test_bit(TRIGGER_NETDEV_LINK_100, &rules)) 149 *offload_trigger |= QCA808X_LED_SPEED100_ON; 150 if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) 151 *offload_trigger |= QCA808X_LED_SPEED1000_ON; 152 if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules)) 153 *offload_trigger |= QCA808X_LED_HALF_DUPLEX_ON; 154 if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules)) 155 *offload_trigger |= QCA808X_LED_FULL_DUPLEX_ON; 156 break; 157 case PORT_FIBRE: 158 if (test_bit(TRIGGER_NETDEV_TX, &rules)) 159 *offload_trigger |= QCA807X_LED_FIBER_TXACT_BLK_EN; 160 if (test_bit(TRIGGER_NETDEV_RX, &rules)) 161 *offload_trigger |= QCA807X_LED_FIBER_RXACT_BLK_EN; 162 if (test_bit(TRIGGER_NETDEV_LINK_100, &rules)) 163 *offload_trigger |= QCA807X_LED_FIBER_100FX_ON_EN; 164 if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) 165 *offload_trigger |= QCA807X_LED_FIBER_1000BX_ON_EN; 166 if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules)) 167 *offload_trigger |= QCA807X_LED_FIBER_HDX_ON_EN; 168 if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules)) 169 *offload_trigger |= QCA807X_LED_FIBER_FDX_ON_EN; 170 break; 171 default: 172 return -EOPNOTSUPP; 173 } 174 175 if (rules && !*offload_trigger) 176 return -EOPNOTSUPP; 177 178 return 0; 179 } 180 181 static int qca807x_led_hw_control_enable(struct phy_device *phydev, u8 index) 182 { 183 u16 reg; 184 185 if (index > 1) 186 return -EINVAL; 187 188 reg = QCA807X_MMD7_LED_FORCE_CTRL(index); 189 return qca808x_led_reg_hw_control_enable(phydev, reg); 190 } 191 192 static int qca807x_led_hw_is_supported(struct phy_device *phydev, u8 index, 193 unsigned long rules) 194 { 195 u16 offload_trigger = 0; 196 197 if (index > 1) 198 return -EINVAL; 199 200 return qca807x_led_parse_netdev(phydev, rules, &offload_trigger); 201 } 202 203 static int qca807x_led_hw_control_set(struct phy_device *phydev, u8 index, 204 unsigned long rules) 205 { 206 u16 reg, mask, offload_trigger = 0; 207 int ret; 208 209 if (index > 1) 210 return -EINVAL; 211 212 ret = qca807x_led_parse_netdev(phydev, rules, &offload_trigger); 213 if (ret) 214 return ret; 215 216 ret = qca807x_led_hw_control_enable(phydev, index); 217 if (ret) 218 return ret; 219 220 switch (phydev->port) { 221 case PORT_TP: 222 reg = QCA807X_MMD7_LED_CTRL(index); 223 mask = QCA808X_LED_PATTERN_MASK; 224 break; 225 case PORT_FIBRE: 226 /* HW control pattern bits are in LED FORCE reg */ 227 reg = QCA807X_MMD7_LED_FORCE_CTRL(index); 228 mask = QCA807X_LED_FIBER_PATTERN_MASK; 229 break; 230 default: 231 return -EINVAL; 232 } 233 234 return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, mask, 235 offload_trigger); 236 } 237 238 static bool qca807x_led_hw_control_status(struct phy_device *phydev, u8 index) 239 { 240 u16 reg; 241 242 if (index > 1) 243 return false; 244 245 reg = QCA807X_MMD7_LED_FORCE_CTRL(index); 246 return qca808x_led_reg_hw_control_status(phydev, reg); 247 } 248 249 static int qca807x_led_hw_control_get(struct phy_device *phydev, u8 index, 250 unsigned long *rules) 251 { 252 u16 reg; 253 int val; 254 255 if (index > 1) 256 return -EINVAL; 257 258 /* Check if we have hw control enabled */ 259 if (qca807x_led_hw_control_status(phydev, index)) 260 return -EINVAL; 261 262 /* Parsing specific to netdev trigger */ 263 switch (phydev->port) { 264 case PORT_TP: 265 reg = QCA807X_MMD7_LED_CTRL(index); 266 val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); 267 if (val & QCA808X_LED_TX_BLINK) 268 set_bit(TRIGGER_NETDEV_TX, rules); 269 if (val & QCA808X_LED_RX_BLINK) 270 set_bit(TRIGGER_NETDEV_RX, rules); 271 if (val & QCA808X_LED_SPEED10_ON) 272 set_bit(TRIGGER_NETDEV_LINK_10, rules); 273 if (val & QCA808X_LED_SPEED100_ON) 274 set_bit(TRIGGER_NETDEV_LINK_100, rules); 275 if (val & QCA808X_LED_SPEED1000_ON) 276 set_bit(TRIGGER_NETDEV_LINK_1000, rules); 277 if (val & QCA808X_LED_HALF_DUPLEX_ON) 278 set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules); 279 if (val & QCA808X_LED_FULL_DUPLEX_ON) 280 set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules); 281 break; 282 case PORT_FIBRE: 283 /* HW control pattern bits are in LED FORCE reg */ 284 reg = QCA807X_MMD7_LED_FORCE_CTRL(index); 285 val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); 286 if (val & QCA807X_LED_FIBER_TXACT_BLK_EN) 287 set_bit(TRIGGER_NETDEV_TX, rules); 288 if (val & QCA807X_LED_FIBER_RXACT_BLK_EN) 289 set_bit(TRIGGER_NETDEV_RX, rules); 290 if (val & QCA807X_LED_FIBER_100FX_ON_EN) 291 set_bit(TRIGGER_NETDEV_LINK_100, rules); 292 if (val & QCA807X_LED_FIBER_1000BX_ON_EN) 293 set_bit(TRIGGER_NETDEV_LINK_1000, rules); 294 if (val & QCA807X_LED_FIBER_HDX_ON_EN) 295 set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules); 296 if (val & QCA807X_LED_FIBER_FDX_ON_EN) 297 set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules); 298 break; 299 default: 300 return -EINVAL; 301 } 302 303 return 0; 304 } 305 306 static int qca807x_led_hw_control_reset(struct phy_device *phydev, u8 index) 307 { 308 u16 reg, mask; 309 310 if (index > 1) 311 return -EINVAL; 312 313 switch (phydev->port) { 314 case PORT_TP: 315 reg = QCA807X_MMD7_LED_CTRL(index); 316 mask = QCA808X_LED_PATTERN_MASK; 317 break; 318 case PORT_FIBRE: 319 /* HW control pattern bits are in LED FORCE reg */ 320 reg = QCA807X_MMD7_LED_FORCE_CTRL(index); 321 mask = QCA807X_LED_FIBER_PATTERN_MASK; 322 break; 323 default: 324 return -EINVAL; 325 } 326 327 return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, mask); 328 } 329 330 static int qca807x_led_brightness_set(struct phy_device *phydev, 331 u8 index, enum led_brightness value) 332 { 333 u16 reg; 334 int ret; 335 336 if (index > 1) 337 return -EINVAL; 338 339 /* If we are setting off the LED reset any hw control rule */ 340 if (!value) { 341 ret = qca807x_led_hw_control_reset(phydev, index); 342 if (ret) 343 return ret; 344 } 345 346 reg = QCA807X_MMD7_LED_FORCE_CTRL(index); 347 return qca808x_led_reg_brightness_set(phydev, reg, value); 348 } 349 350 static int qca807x_led_blink_set(struct phy_device *phydev, u8 index, 351 unsigned long *delay_on, 352 unsigned long *delay_off) 353 { 354 u16 reg; 355 356 if (index > 1) 357 return -EINVAL; 358 359 reg = QCA807X_MMD7_LED_FORCE_CTRL(index); 360 return qca808x_led_reg_blink_set(phydev, reg, delay_on, delay_off); 361 } 362 363 #ifdef CONFIG_GPIOLIB 364 static int qca807x_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) 365 { 366 return GPIO_LINE_DIRECTION_OUT; 367 } 368 369 static int qca807x_gpio_get(struct gpio_chip *gc, unsigned int offset) 370 { 371 struct qca807x_gpio_priv *priv = gpiochip_get_data(gc); 372 u16 reg; 373 int val; 374 375 reg = QCA807X_MMD7_LED_FORCE_CTRL(offset); 376 val = phy_read_mmd(priv->phy, MDIO_MMD_AN, reg); 377 378 return FIELD_GET(QCA807X_GPIO_FORCE_MODE_MASK, val); 379 } 380 381 static int qca807x_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) 382 { 383 struct qca807x_gpio_priv *priv = gpiochip_get_data(gc); 384 u16 reg; 385 int val; 386 387 reg = QCA807X_MMD7_LED_FORCE_CTRL(offset); 388 389 val = phy_read_mmd(priv->phy, MDIO_MMD_AN, reg); 390 if (val < 0) 391 return val; 392 393 val &= ~QCA807X_GPIO_FORCE_MODE_MASK; 394 val |= QCA807X_GPIO_FORCE_EN; 395 val |= FIELD_PREP(QCA807X_GPIO_FORCE_MODE_MASK, value); 396 397 return phy_write_mmd(priv->phy, MDIO_MMD_AN, reg, val); 398 } 399 400 static int qca807x_gpio_dir_out(struct gpio_chip *gc, unsigned int offset, int value) 401 { 402 return qca807x_gpio_set(gc, offset, value); 403 } 404 405 static int qca807x_gpio(struct phy_device *phydev) 406 { 407 struct device *dev = &phydev->mdio.dev; 408 struct qca807x_gpio_priv *priv; 409 struct gpio_chip *gc; 410 411 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 412 if (!priv) 413 return -ENOMEM; 414 415 priv->phy = phydev; 416 417 gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL); 418 if (!gc) 419 return -ENOMEM; 420 421 gc->label = dev_name(dev); 422 gc->base = -1; 423 gc->ngpio = 2; 424 gc->parent = dev; 425 gc->owner = THIS_MODULE; 426 gc->can_sleep = true; 427 gc->get_direction = qca807x_gpio_get_direction; 428 gc->direction_output = qca807x_gpio_dir_out; 429 gc->get = qca807x_gpio_get; 430 gc->set = qca807x_gpio_set; 431 432 return devm_gpiochip_add_data(dev, gc, priv); 433 } 434 #endif 435 436 static int qca807x_read_fiber_status(struct phy_device *phydev) 437 { 438 bool changed; 439 int ss, err; 440 441 err = genphy_c37_read_status(phydev, &changed); 442 if (err || !changed) 443 return err; 444 445 /* Read the QCA807x PHY-Specific Status register fiber page, 446 * which indicates the speed and duplex that the PHY is actually 447 * using, irrespective of whether we are in autoneg mode or not. 448 */ 449 ss = phy_read(phydev, AT803X_SPECIFIC_STATUS); 450 if (ss < 0) 451 return ss; 452 453 phydev->speed = SPEED_UNKNOWN; 454 phydev->duplex = DUPLEX_UNKNOWN; 455 if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) { 456 switch (FIELD_GET(AT803X_SS_SPEED_MASK, ss)) { 457 case AT803X_SS_SPEED_100: 458 phydev->speed = SPEED_100; 459 break; 460 case AT803X_SS_SPEED_1000: 461 phydev->speed = SPEED_1000; 462 break; 463 } 464 465 if (ss & AT803X_SS_DUPLEX) 466 phydev->duplex = DUPLEX_FULL; 467 else 468 phydev->duplex = DUPLEX_HALF; 469 } 470 471 return 0; 472 } 473 474 static int qca807x_read_status(struct phy_device *phydev) 475 { 476 if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported)) { 477 switch (phydev->port) { 478 case PORT_FIBRE: 479 return qca807x_read_fiber_status(phydev); 480 case PORT_TP: 481 return at803x_read_status(phydev); 482 default: 483 return -EINVAL; 484 } 485 } 486 487 return at803x_read_status(phydev); 488 } 489 490 static int qca807x_phy_package_probe_once(struct phy_device *phydev) 491 { 492 struct qca807x_shared_priv *priv = phy_package_get_priv(phydev); 493 struct device_node *np = phy_package_get_node(phydev); 494 unsigned int tx_drive_strength; 495 const char *package_mode_name; 496 497 /* Default to 600mw if not defined */ 498 if (of_property_read_u32(np, "qcom,tx-drive-strength-milliwatt", 499 &tx_drive_strength)) 500 tx_drive_strength = 600; 501 502 switch (tx_drive_strength) { 503 case 140: 504 priv->tx_drive_strength = PQSGMII_TX_DRIVER_140MV; 505 break; 506 case 160: 507 priv->tx_drive_strength = PQSGMII_TX_DRIVER_160MV; 508 break; 509 case 180: 510 priv->tx_drive_strength = PQSGMII_TX_DRIVER_180MV; 511 break; 512 case 200: 513 priv->tx_drive_strength = PQSGMII_TX_DRIVER_200MV; 514 break; 515 case 220: 516 priv->tx_drive_strength = PQSGMII_TX_DRIVER_220MV; 517 break; 518 case 240: 519 priv->tx_drive_strength = PQSGMII_TX_DRIVER_240MV; 520 break; 521 case 260: 522 priv->tx_drive_strength = PQSGMII_TX_DRIVER_260MV; 523 break; 524 case 280: 525 priv->tx_drive_strength = PQSGMII_TX_DRIVER_280MV; 526 break; 527 case 300: 528 priv->tx_drive_strength = PQSGMII_TX_DRIVER_300MV; 529 break; 530 case 320: 531 priv->tx_drive_strength = PQSGMII_TX_DRIVER_320MV; 532 break; 533 case 400: 534 priv->tx_drive_strength = PQSGMII_TX_DRIVER_400MV; 535 break; 536 case 500: 537 priv->tx_drive_strength = PQSGMII_TX_DRIVER_500MV; 538 break; 539 case 600: 540 priv->tx_drive_strength = PQSGMII_TX_DRIVER_600MV; 541 break; 542 default: 543 return -EINVAL; 544 } 545 546 priv->package_mode = PHY_INTERFACE_MODE_NA; 547 if (!of_property_read_string(np, "qcom,package-mode", 548 &package_mode_name)) { 549 if (!strcasecmp(package_mode_name, 550 phy_modes(PHY_INTERFACE_MODE_PSGMII))) 551 priv->package_mode = PHY_INTERFACE_MODE_PSGMII; 552 else if (!strcasecmp(package_mode_name, 553 phy_modes(PHY_INTERFACE_MODE_QSGMII))) 554 priv->package_mode = PHY_INTERFACE_MODE_QSGMII; 555 else 556 return -EINVAL; 557 } 558 559 return 0; 560 } 561 562 static int qca807x_phy_package_config_init_once(struct phy_device *phydev) 563 { 564 struct qca807x_shared_priv *priv = phy_package_get_priv(phydev); 565 int val, ret; 566 567 /* Make sure PHY follow PHY package mode if enforced */ 568 if (priv->package_mode != PHY_INTERFACE_MODE_NA && 569 phydev->interface != priv->package_mode) 570 return -EINVAL; 571 572 phy_lock_mdio_bus(phydev); 573 574 /* Set correct PHY package mode */ 575 val = __phy_package_read(phydev, QCA807X_COMBO_ADDR, 576 QCA807X_CHIP_CONFIGURATION); 577 val &= ~QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK; 578 /* package_mode can be QSGMII or PSGMII and we validate 579 * this in probe_once. 580 * With package_mode to NA, we default to PSGMII. 581 */ 582 switch (priv->package_mode) { 583 case PHY_INTERFACE_MODE_QSGMII: 584 val |= QCA807X_CHIP_CONFIGURATION_MODE_QSGMII_SGMII; 585 break; 586 case PHY_INTERFACE_MODE_PSGMII: 587 default: 588 val |= QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_ALL_COPPER; 589 } 590 ret = __phy_package_write(phydev, QCA807X_COMBO_ADDR, 591 QCA807X_CHIP_CONFIGURATION, val); 592 if (ret) 593 goto exit; 594 595 /* After mode change Serdes reset is required */ 596 val = __phy_package_read(phydev, QCA807X_PQSGMII_ADDR, 597 PQSGMII_CTRL_REG); 598 val &= ~PQSGMII_ANALOG_SW_RESET; 599 ret = __phy_package_write(phydev, QCA807X_PQSGMII_ADDR, 600 PQSGMII_CTRL_REG, val); 601 if (ret) 602 goto exit; 603 604 msleep(SERDES_RESET_SLEEP); 605 606 val = __phy_package_read(phydev, QCA807X_PQSGMII_ADDR, 607 PQSGMII_CTRL_REG); 608 val |= PQSGMII_ANALOG_SW_RESET; 609 ret = __phy_package_write(phydev, QCA807X_PQSGMII_ADDR, 610 PQSGMII_CTRL_REG, val); 611 if (ret) 612 goto exit; 613 614 /* Workaround to enable AZ transmitting ability */ 615 val = __phy_package_read_mmd(phydev, QCA807X_PQSGMII_ADDR, 616 MDIO_MMD_PMAPMD, PQSGMII_MODE_CTRL); 617 val &= ~PQSGMII_MODE_CTRL_AZ_WORKAROUND_MASK; 618 ret = __phy_package_write_mmd(phydev, QCA807X_PQSGMII_ADDR, 619 MDIO_MMD_PMAPMD, PQSGMII_MODE_CTRL, val); 620 if (ret) 621 goto exit; 622 623 /* Set PQSGMII TX AMP strength */ 624 val = __phy_package_read(phydev, QCA807X_PQSGMII_ADDR, 625 PQSGMII_DRIVE_CONTROL_1); 626 val &= ~PQSGMII_TX_DRIVER_MASK; 627 val |= FIELD_PREP(PQSGMII_TX_DRIVER_MASK, priv->tx_drive_strength); 628 ret = __phy_package_write(phydev, QCA807X_PQSGMII_ADDR, 629 PQSGMII_DRIVE_CONTROL_1, val); 630 if (ret) 631 goto exit; 632 633 /* Prevent PSGMII going into hibernation via PSGMII self test */ 634 val = __phy_package_read_mmd(phydev, QCA807X_COMBO_ADDR, 635 MDIO_MMD_PCS, PQSGMII_MMD3_SERDES_CONTROL); 636 val &= ~BIT(1); 637 ret = __phy_package_write_mmd(phydev, QCA807X_COMBO_ADDR, 638 MDIO_MMD_PCS, PQSGMII_MMD3_SERDES_CONTROL, val); 639 640 exit: 641 phy_unlock_mdio_bus(phydev); 642 643 return ret; 644 } 645 646 static int qca807x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) 647 { 648 struct phy_device *phydev = upstream; 649 __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, }; 650 phy_interface_t iface; 651 int ret; 652 DECLARE_PHY_INTERFACE_MASK(interfaces); 653 654 sfp_parse_support(phydev->sfp_bus, id, support, interfaces); 655 iface = sfp_select_interface(phydev->sfp_bus, support); 656 657 dev_info(&phydev->mdio.dev, "%s SFP module inserted\n", phy_modes(iface)); 658 659 switch (iface) { 660 case PHY_INTERFACE_MODE_1000BASEX: 661 case PHY_INTERFACE_MODE_100BASEX: 662 /* Set PHY mode to PSGMII combo (1/4 copper + combo ports) mode */ 663 ret = phy_modify(phydev, 664 QCA807X_CHIP_CONFIGURATION, 665 QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK, 666 QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_FIBER); 667 /* Enable fiber mode autodection (1000Base-X or 100Base-FX) */ 668 ret = phy_set_bits_mmd(phydev, 669 MDIO_MMD_AN, 670 QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION, 671 QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION_EN); 672 /* Select fiber page */ 673 ret = phy_clear_bits(phydev, 674 QCA807X_CHIP_CONFIGURATION, 675 QCA807X_BT_BX_REG_SEL); 676 677 phydev->port = PORT_FIBRE; 678 break; 679 default: 680 dev_err(&phydev->mdio.dev, "Incompatible SFP module inserted\n"); 681 return -EINVAL; 682 } 683 684 return ret; 685 } 686 687 static void qca807x_sfp_remove(void *upstream) 688 { 689 struct phy_device *phydev = upstream; 690 691 /* Select copper page */ 692 phy_set_bits(phydev, 693 QCA807X_CHIP_CONFIGURATION, 694 QCA807X_BT_BX_REG_SEL); 695 696 phydev->port = PORT_TP; 697 } 698 699 static const struct sfp_upstream_ops qca807x_sfp_ops = { 700 .attach = phy_sfp_attach, 701 .detach = phy_sfp_detach, 702 .module_insert = qca807x_sfp_insert, 703 .module_remove = qca807x_sfp_remove, 704 .connect_phy = phy_sfp_connect_phy, 705 .disconnect_phy = phy_sfp_disconnect_phy, 706 }; 707 708 static int qca807x_probe(struct phy_device *phydev) 709 { 710 struct device_node *node = phydev->mdio.dev.of_node; 711 struct qca807x_shared_priv *shared_priv; 712 struct device *dev = &phydev->mdio.dev; 713 struct qca807x_priv *priv; 714 int ret; 715 716 ret = devm_of_phy_package_join(dev, phydev, sizeof(*shared_priv)); 717 if (ret) 718 return ret; 719 720 if (phy_package_probe_once(phydev)) { 721 ret = qca807x_phy_package_probe_once(phydev); 722 if (ret) 723 return ret; 724 } 725 726 shared_priv = phy_package_get_priv(phydev); 727 728 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 729 if (!priv) 730 return -ENOMEM; 731 732 priv->dac_full_amplitude = of_property_read_bool(node, "qcom,dac-full-amplitude"); 733 priv->dac_full_bias_current = of_property_read_bool(node, "qcom,dac-full-bias-current"); 734 priv->dac_disable_bias_current_tweak = of_property_read_bool(node, 735 "qcom,dac-disable-bias-current-tweak"); 736 737 #if IS_ENABLED(CONFIG_GPIOLIB) 738 /* Do not register a GPIO controller unless flagged for it */ 739 if (of_property_read_bool(node, "gpio-controller")) { 740 ret = qca807x_gpio(phydev); 741 if (ret) 742 return ret; 743 } 744 #endif 745 746 /* Attach SFP bus on combo port*/ 747 if (phy_read(phydev, QCA807X_CHIP_CONFIGURATION)) { 748 ret = phy_sfp_probe(phydev, &qca807x_sfp_ops); 749 if (ret) 750 return ret; 751 linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported); 752 linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->advertising); 753 } 754 755 phydev->priv = priv; 756 757 return 0; 758 } 759 760 static int qca807x_config_init(struct phy_device *phydev) 761 { 762 struct qca807x_priv *priv = phydev->priv; 763 u16 control_dac; 764 int ret; 765 766 if (phy_package_init_once(phydev)) { 767 ret = qca807x_phy_package_config_init_once(phydev); 768 if (ret) 769 return ret; 770 } 771 772 ret = qcom_phy_counter_config(phydev); 773 if (ret) 774 return ret; 775 776 control_dac = phy_read_mmd(phydev, MDIO_MMD_AN, 777 QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH); 778 control_dac &= ~QCA807X_CONTROL_DAC_MASK; 779 if (!priv->dac_full_amplitude) 780 control_dac |= QCA807X_CONTROL_DAC_DSP_AMPLITUDE; 781 if (!priv->dac_full_bias_current) 782 control_dac |= QCA807X_CONTROL_DAC_DSP_BIAS_CURRENT; 783 if (!priv->dac_disable_bias_current_tweak) 784 control_dac |= QCA807X_CONTROL_DAC_BIAS_CURRENT_TWEAK; 785 return phy_write_mmd(phydev, MDIO_MMD_AN, 786 QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH, 787 control_dac); 788 } 789 790 static int qca807x_update_stats(struct phy_device *phydev) 791 { 792 struct qca807x_priv *priv = phydev->priv; 793 794 return qcom_phy_update_stats(phydev, &priv->hw_stats); 795 } 796 797 static void qca807x_get_phy_stats(struct phy_device *phydev, 798 struct ethtool_eth_phy_stats *eth_stats, 799 struct ethtool_phy_stats *stats) 800 { 801 struct qca807x_priv *priv = phydev->priv; 802 803 qcom_phy_get_stats(stats, priv->hw_stats); 804 } 805 806 static struct phy_driver qca807x_drivers[] = { 807 { 808 PHY_ID_MATCH_EXACT(PHY_ID_QCA8072), 809 .name = "Qualcomm QCA8072", 810 .flags = PHY_POLL_CABLE_TEST, 811 /* PHY_GBIT_FEATURES */ 812 .probe = qca807x_probe, 813 .config_init = qca807x_config_init, 814 .read_status = qca807x_read_status, 815 .config_intr = at803x_config_intr, 816 .handle_interrupt = at803x_handle_interrupt, 817 .soft_reset = genphy_soft_reset, 818 .get_tunable = at803x_get_tunable, 819 .set_tunable = at803x_set_tunable, 820 .resume = genphy_resume, 821 .suspend = genphy_suspend, 822 .cable_test_start = qca807x_cable_test_start, 823 .cable_test_get_status = qca808x_cable_test_get_status, 824 .update_stats = qca807x_update_stats, 825 .get_phy_stats = qca807x_get_phy_stats, 826 .set_wol = at8031_set_wol, 827 .get_wol = at803x_get_wol, 828 }, 829 { 830 PHY_ID_MATCH_EXACT(PHY_ID_QCA8075), 831 .name = "Qualcomm QCA8075", 832 .flags = PHY_POLL_CABLE_TEST, 833 /* PHY_GBIT_FEATURES */ 834 .probe = qca807x_probe, 835 .config_init = qca807x_config_init, 836 .read_status = qca807x_read_status, 837 .config_intr = at803x_config_intr, 838 .handle_interrupt = at803x_handle_interrupt, 839 .soft_reset = genphy_soft_reset, 840 .get_tunable = at803x_get_tunable, 841 .set_tunable = at803x_set_tunable, 842 .resume = genphy_resume, 843 .suspend = genphy_suspend, 844 .cable_test_start = qca807x_cable_test_start, 845 .cable_test_get_status = qca808x_cable_test_get_status, 846 .led_brightness_set = qca807x_led_brightness_set, 847 .led_blink_set = qca807x_led_blink_set, 848 .led_hw_is_supported = qca807x_led_hw_is_supported, 849 .led_hw_control_set = qca807x_led_hw_control_set, 850 .led_hw_control_get = qca807x_led_hw_control_get, 851 .update_stats = qca807x_update_stats, 852 .get_phy_stats = qca807x_get_phy_stats, 853 .set_wol = at8031_set_wol, 854 .get_wol = at803x_get_wol, 855 }, 856 }; 857 module_phy_driver(qca807x_drivers); 858 859 static const struct mdio_device_id __maybe_unused qca807x_tbl[] = { 860 { PHY_ID_MATCH_EXACT(PHY_ID_QCA8072) }, 861 { PHY_ID_MATCH_EXACT(PHY_ID_QCA8075) }, 862 { } 863 }; 864 865 MODULE_AUTHOR("Robert Marko <robert.marko@sartura.hr>"); 866 MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>"); 867 MODULE_DESCRIPTION("Qualcomm QCA807x PHY driver"); 868 MODULE_DEVICE_TABLE(mdio, qca807x_tbl); 869 MODULE_LICENSE("GPL"); 870