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