Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-stmmac-dwmac-qcom-ethqos-add-support-for-emac4'

Bartosz Golaszewski says:

====================
net: stmmac: dwmac-qcom-ethqos: add support for EMAC4

Extend the dwmac-qcom-ethqos driver to support EMAC4. While at it: rework the
code somewhat. The bindings have been reviewed by DT maintainers.

This is a sub-series of [1] with only the patches targetting the net subsystem
as they can go in independently.

[1] https://lore.kernel.org/lkml/20230617001644.4e093326@kernel.org/T/
====================

Link: https://lore.kernel.org/r/20230619092402.195578-1-brgl@bgdev.pl
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+226 -76
+11 -1
Documentation/devicetree/bindings/net/qcom,ethqos.yaml
··· 20 20 compatible: 21 21 enum: 22 22 - qcom,qcs404-ethqos 23 + - qcom,sa8775p-ethqos 23 24 - qcom,sc8280xp-ethqos 24 25 - qcom,sm8150-ethqos 25 26 ··· 33 32 - const: rgmii 34 33 35 34 interrupts: 35 + minItems: 1 36 36 items: 37 37 - description: Combined signal for various interrupt events 38 38 - description: The interrupt that occurs when Rx exits the LPI state 39 39 40 40 interrupt-names: 41 + minItems: 1 41 42 items: 42 43 - const: macirq 43 44 - const: eth_lpi ··· 52 49 - const: stmmaceth 53 50 - const: pclk 54 51 - const: ptp_ref 55 - - const: rgmii 52 + - enum: 53 + - rgmii 54 + - phyaux 56 55 57 56 iommus: 58 57 maxItems: 1 58 + 59 + phys: true 60 + 61 + phy-names: 62 + const: serdes 59 63 60 64 required: 61 65 - compatible
+3
Documentation/devicetree/bindings/net/snps,dwmac.yaml
··· 67 67 - loongson,ls2k-dwmac 68 68 - loongson,ls7a-dwmac 69 69 - qcom,qcs404-ethqos 70 + - qcom,sa8775p-ethqos 70 71 - qcom,sc8280xp-ethqos 71 72 - qcom,sm8150-ethqos 72 73 - renesas,r9a06g032-gmac ··· 583 582 - ingenic,x1600-mac 584 583 - ingenic,x1830-mac 585 584 - ingenic,x2000-mac 585 + - qcom,sa8775p-ethqos 586 586 - qcom,sc8280xp-ethqos 587 587 - snps,dwmac-3.50a 588 588 - snps,dwmac-4.10a ··· 640 638 - ingenic,x1830-mac 641 639 - ingenic,x2000-mac 642 640 - qcom,qcs404-ethqos 641 + - qcom,sa8775p-ethqos 643 642 - qcom,sc8280xp-ethqos 644 643 - qcom,sm8150-ethqos 645 644 - snps,dwmac-4.00
+210 -74
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
··· 6 6 #include <linux/of_device.h> 7 7 #include <linux/platform_device.h> 8 8 #include <linux/phy.h> 9 + #include <linux/phy/phy.h> 10 + #include <linux/property.h> 11 + 9 12 #include "stmmac.h" 10 13 #include "stmmac_platform.h" 11 14 ··· 75 72 #define RGMII_CONFIG2_DATA_DIVIDE_CLK_SEL BIT(6) 76 73 #define RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN BIT(5) 77 74 75 + /* MAC_CTRL_REG bits */ 76 + #define ETHQOS_MAC_CTRL_SPEED_MODE BIT(14) 77 + #define ETHQOS_MAC_CTRL_PORT_SEL BIT(15) 78 + 78 79 struct ethqos_emac_por { 79 80 unsigned int offset; 80 81 unsigned int value; ··· 88 81 const struct ethqos_emac_por *por; 89 82 unsigned int num_por; 90 83 bool rgmii_config_loopback_en; 91 - bool has_emac3; 84 + bool has_emac_ge_3; 85 + const char *link_clk_name; 86 + bool has_integrated_pcs; 92 87 struct dwmac4_addrs dwmac4_addrs; 93 88 }; 94 89 95 90 struct qcom_ethqos { 96 91 struct platform_device *pdev; 97 92 void __iomem *rgmii_base; 93 + void __iomem *mac_base; 94 + int (*configure_func)(struct qcom_ethqos *ethqos); 98 95 99 - unsigned int rgmii_clk_rate; 100 - struct clk *rgmii_clk; 96 + unsigned int link_clk_rate; 97 + struct clk *link_clk; 98 + struct phy *serdes_phy; 101 99 unsigned int speed; 100 + int phy_mode; 102 101 103 102 const struct ethqos_emac_por *por; 104 103 unsigned int num_por; 105 104 bool rgmii_config_loopback_en; 106 - bool has_emac3; 105 + bool has_emac_ge_3; 107 106 }; 108 107 109 108 static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset) ··· 128 115 { 129 116 unsigned int temp; 130 117 131 - temp = rgmii_readl(ethqos, offset); 118 + temp = rgmii_readl(ethqos, offset); 132 119 temp = (temp & ~(mask)) | val; 133 120 rgmii_writel(ethqos, temp, offset); 134 121 } ··· 136 123 static void rgmii_dump(void *priv) 137 124 { 138 125 struct qcom_ethqos *ethqos = priv; 126 + struct device *dev = &ethqos->pdev->dev; 139 127 140 - dev_dbg(&ethqos->pdev->dev, "Rgmii register dump\n"); 141 - dev_dbg(&ethqos->pdev->dev, "RGMII_IO_MACRO_CONFIG: %x\n", 128 + dev_dbg(dev, "Rgmii register dump\n"); 129 + dev_dbg(dev, "RGMII_IO_MACRO_CONFIG: %x\n", 142 130 rgmii_readl(ethqos, RGMII_IO_MACRO_CONFIG)); 143 - dev_dbg(&ethqos->pdev->dev, "SDCC_HC_REG_DLL_CONFIG: %x\n", 131 + dev_dbg(dev, "SDCC_HC_REG_DLL_CONFIG: %x\n", 144 132 rgmii_readl(ethqos, SDCC_HC_REG_DLL_CONFIG)); 145 - dev_dbg(&ethqos->pdev->dev, "SDCC_HC_REG_DDR_CONFIG: %x\n", 133 + dev_dbg(dev, "SDCC_HC_REG_DDR_CONFIG: %x\n", 146 134 rgmii_readl(ethqos, SDCC_HC_REG_DDR_CONFIG)); 147 - dev_dbg(&ethqos->pdev->dev, "SDCC_HC_REG_DLL_CONFIG2: %x\n", 135 + dev_dbg(dev, "SDCC_HC_REG_DLL_CONFIG2: %x\n", 148 136 rgmii_readl(ethqos, SDCC_HC_REG_DLL_CONFIG2)); 149 - dev_dbg(&ethqos->pdev->dev, "SDC4_STATUS: %x\n", 137 + dev_dbg(dev, "SDC4_STATUS: %x\n", 150 138 rgmii_readl(ethqos, SDC4_STATUS)); 151 - dev_dbg(&ethqos->pdev->dev, "SDCC_USR_CTL: %x\n", 139 + dev_dbg(dev, "SDCC_USR_CTL: %x\n", 152 140 rgmii_readl(ethqos, SDCC_USR_CTL)); 153 - dev_dbg(&ethqos->pdev->dev, "RGMII_IO_MACRO_CONFIG2: %x\n", 141 + dev_dbg(dev, "RGMII_IO_MACRO_CONFIG2: %x\n", 154 142 rgmii_readl(ethqos, RGMII_IO_MACRO_CONFIG2)); 155 - dev_dbg(&ethqos->pdev->dev, "RGMII_IO_MACRO_DEBUG1: %x\n", 143 + dev_dbg(dev, "RGMII_IO_MACRO_DEBUG1: %x\n", 156 144 rgmii_readl(ethqos, RGMII_IO_MACRO_DEBUG1)); 157 - dev_dbg(&ethqos->pdev->dev, "EMAC_SYSTEM_LOW_POWER_DEBUG: %x\n", 145 + dev_dbg(dev, "EMAC_SYSTEM_LOW_POWER_DEBUG: %x\n", 158 146 rgmii_readl(ethqos, EMAC_SYSTEM_LOW_POWER_DEBUG)); 159 147 } 160 148 ··· 165 151 #define RGMII_ID_MODE_10_LOW_SVS_CLK_FREQ (5 * 1000 * 1000UL) 166 152 167 153 static void 168 - ethqos_update_rgmii_clk(struct qcom_ethqos *ethqos, unsigned int speed) 154 + ethqos_update_link_clk(struct qcom_ethqos *ethqos, unsigned int speed) 169 155 { 170 156 switch (speed) { 171 157 case SPEED_1000: 172 - ethqos->rgmii_clk_rate = RGMII_1000_NOM_CLK_FREQ; 158 + ethqos->link_clk_rate = RGMII_1000_NOM_CLK_FREQ; 173 159 break; 174 160 175 161 case SPEED_100: 176 - ethqos->rgmii_clk_rate = RGMII_ID_MODE_100_LOW_SVS_CLK_FREQ; 162 + ethqos->link_clk_rate = RGMII_ID_MODE_100_LOW_SVS_CLK_FREQ; 177 163 break; 178 164 179 165 case SPEED_10: 180 - ethqos->rgmii_clk_rate = RGMII_ID_MODE_10_LOW_SVS_CLK_FREQ; 166 + ethqos->link_clk_rate = RGMII_ID_MODE_10_LOW_SVS_CLK_FREQ; 181 167 break; 182 168 } 183 169 184 - clk_set_rate(ethqos->rgmii_clk, ethqos->rgmii_clk_rate); 170 + clk_set_rate(ethqos->link_clk, ethqos->link_clk_rate); 185 171 } 186 172 187 173 static void ethqos_set_func_clk_en(struct qcom_ethqos *ethqos) ··· 203 189 .por = emac_v2_3_0_por, 204 190 .num_por = ARRAY_SIZE(emac_v2_3_0_por), 205 191 .rgmii_config_loopback_en = true, 206 - .has_emac3 = false, 192 + .has_emac_ge_3 = false, 207 193 }; 208 194 209 195 static const struct ethqos_emac_por emac_v2_1_0_por[] = { ··· 219 205 .por = emac_v2_1_0_por, 220 206 .num_por = ARRAY_SIZE(emac_v2_1_0_por), 221 207 .rgmii_config_loopback_en = false, 222 - .has_emac3 = false, 208 + .has_emac_ge_3 = false, 223 209 }; 224 210 225 211 static const struct ethqos_emac_por emac_v3_0_0_por[] = { ··· 235 221 .por = emac_v3_0_0_por, 236 222 .num_por = ARRAY_SIZE(emac_v3_0_0_por), 237 223 .rgmii_config_loopback_en = false, 238 - .has_emac3 = true, 224 + .has_emac_ge_3 = true, 225 + .dwmac4_addrs = { 226 + .dma_chan = 0x00008100, 227 + .dma_chan_offset = 0x1000, 228 + .mtl_chan = 0x00008000, 229 + .mtl_chan_offset = 0x1000, 230 + .mtl_ets_ctrl = 0x00008010, 231 + .mtl_ets_ctrl_offset = 0x1000, 232 + .mtl_txq_weight = 0x00008018, 233 + .mtl_txq_weight_offset = 0x1000, 234 + .mtl_send_slp_cred = 0x0000801c, 235 + .mtl_send_slp_cred_offset = 0x1000, 236 + .mtl_high_cred = 0x00008020, 237 + .mtl_high_cred_offset = 0x1000, 238 + .mtl_low_cred = 0x00008024, 239 + .mtl_low_cred_offset = 0x1000, 240 + }, 241 + }; 242 + 243 + static const struct ethqos_emac_por emac_v4_0_0_por[] = { 244 + { .offset = RGMII_IO_MACRO_CONFIG, .value = 0x40c01343 }, 245 + { .offset = SDCC_HC_REG_DLL_CONFIG, .value = 0x2004642c }, 246 + { .offset = SDCC_HC_REG_DDR_CONFIG, .value = 0x80040800 }, 247 + { .offset = SDCC_HC_REG_DLL_CONFIG2, .value = 0x00200000 }, 248 + { .offset = SDCC_USR_CTL, .value = 0x00010800 }, 249 + { .offset = RGMII_IO_MACRO_CONFIG2, .value = 0x00002060 }, 250 + }; 251 + 252 + static const struct ethqos_emac_driver_data emac_v4_0_0_data = { 253 + .por = emac_v4_0_0_por, 254 + .num_por = ARRAY_SIZE(emac_v3_0_0_por), 255 + .rgmii_config_loopback_en = false, 256 + .has_emac_ge_3 = true, 257 + .link_clk_name = "phyaux", 258 + .has_integrated_pcs = true, 239 259 .dwmac4_addrs = { 240 260 .dma_chan = 0x00008100, 241 261 .dma_chan_offset = 0x1000, ··· 290 242 291 243 static int ethqos_dll_configure(struct qcom_ethqos *ethqos) 292 244 { 245 + struct device *dev = &ethqos->pdev->dev; 293 246 unsigned int val; 294 247 int retry = 1000; 295 248 ··· 310 261 rgmii_updatel(ethqos, SDCC_DLL_CONFIG_DLL_EN, 311 262 SDCC_DLL_CONFIG_DLL_EN, SDCC_HC_REG_DLL_CONFIG); 312 263 313 - if (!ethqos->has_emac3) { 264 + if (!ethqos->has_emac_ge_3) { 314 265 rgmii_updatel(ethqos, SDCC_DLL_MCLK_GATING_EN, 315 266 0, SDCC_HC_REG_DLL_CONFIG); 316 267 ··· 328 279 retry--; 329 280 } while (retry > 0); 330 281 if (!retry) 331 - dev_err(&ethqos->pdev->dev, "Clear CK_OUT_EN timedout\n"); 282 + dev_err(dev, "Clear CK_OUT_EN timedout\n"); 332 283 333 284 /* Set CK_OUT_EN */ 334 285 rgmii_updatel(ethqos, SDCC_DLL_CONFIG_CK_OUT_EN, ··· 345 296 retry--; 346 297 } while (retry > 0); 347 298 if (!retry) 348 - dev_err(&ethqos->pdev->dev, "Set CK_OUT_EN timedout\n"); 299 + dev_err(dev, "Set CK_OUT_EN timedout\n"); 349 300 350 301 /* Set DDR_CAL_EN */ 351 302 rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_DDR_CAL_EN, 352 303 SDCC_DLL_CONFIG2_DDR_CAL_EN, SDCC_HC_REG_DLL_CONFIG2); 353 304 354 - if (!ethqos->has_emac3) { 305 + if (!ethqos->has_emac_ge_3) { 355 306 rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_DLL_CLOCK_DIS, 356 307 0, SDCC_HC_REG_DLL_CONFIG2); 357 308 ··· 371 322 372 323 static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos) 373 324 { 325 + struct device *dev = &ethqos->pdev->dev; 374 326 int phase_shift; 375 - int phy_mode; 376 327 int loopback; 377 328 378 329 /* Determine if the PHY adds a 2 ns TX delay or the MAC handles it */ 379 - phy_mode = device_get_phy_mode(&ethqos->pdev->dev); 380 - if (phy_mode == PHY_INTERFACE_MODE_RGMII_ID || 381 - phy_mode == PHY_INTERFACE_MODE_RGMII_TXID) 330 + if (ethqos->phy_mode == PHY_INTERFACE_MODE_RGMII_ID || 331 + ethqos->phy_mode == PHY_INTERFACE_MODE_RGMII_TXID) 382 332 phase_shift = 0; 383 333 else 384 334 phase_shift = RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN; ··· 421 373 /* PRG_RCLK_DLY = TCXO period * TCXO_CYCLES_CNT / 2 * RX delay ns, 422 374 * in practice this becomes PRG_RCLK_DLY = 52 * 4 / 2 * RX delay ns 423 375 */ 424 - if (ethqos->has_emac3) { 376 + if (ethqos->has_emac_ge_3) { 425 377 /* 0.9 ns */ 426 378 rgmii_updatel(ethqos, SDCC_DDR_CONFIG_PRG_RCLK_DLY, 427 379 115, SDCC_HC_REG_DDR_CONFIG); ··· 456 408 rgmii_updatel(ethqos, RGMII_CONFIG2_RSVD_CONFIG15, 457 409 0, RGMII_IO_MACRO_CONFIG2); 458 410 459 - if (ethqos->has_emac3) 411 + if (ethqos->has_emac_ge_3) 460 412 rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP, 461 413 RGMII_CONFIG2_RX_PROG_SWAP, 462 414 RGMII_IO_MACRO_CONFIG2); ··· 496 448 RGMII_IO_MACRO_CONFIG); 497 449 rgmii_updatel(ethqos, RGMII_CONFIG2_RSVD_CONFIG15, 498 450 0, RGMII_IO_MACRO_CONFIG2); 499 - if (ethqos->has_emac3) 451 + if (ethqos->has_emac_ge_3) 500 452 rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP, 501 453 RGMII_CONFIG2_RX_PROG_SWAP, 502 454 RGMII_IO_MACRO_CONFIG2); ··· 516 468 loopback, RGMII_IO_MACRO_CONFIG); 517 469 break; 518 470 default: 519 - dev_err(&ethqos->pdev->dev, 520 - "Invalid speed %d\n", ethqos->speed); 471 + dev_err(dev, "Invalid speed %d\n", ethqos->speed); 521 472 return -EINVAL; 522 473 } 523 474 524 475 return 0; 525 476 } 526 477 527 - static int ethqos_configure(struct qcom_ethqos *ethqos) 478 + static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos) 528 479 { 480 + struct device *dev = &ethqos->pdev->dev; 529 481 volatile unsigned int dll_lock; 530 482 unsigned int i, retry = 1000; 531 483 ··· 545 497 rgmii_updatel(ethqos, SDCC_DLL_CONFIG_PDN, 546 498 SDCC_DLL_CONFIG_PDN, SDCC_HC_REG_DLL_CONFIG); 547 499 548 - if (ethqos->has_emac3) { 500 + if (ethqos->has_emac_ge_3) { 549 501 if (ethqos->speed == SPEED_1000) { 550 502 rgmii_writel(ethqos, 0x1800000, SDCC_TEST_CTL); 551 503 rgmii_writel(ethqos, 0x2C010800, SDCC_USR_CTL); ··· 575 527 SDCC_HC_REG_DLL_CONFIG); 576 528 577 529 /* Set USR_CTL bit 26 with mask of 3 bits */ 578 - if (!ethqos->has_emac3) 530 + if (!ethqos->has_emac_ge_3) 579 531 rgmii_updatel(ethqos, GENMASK(26, 24), BIT(26), 580 532 SDCC_USR_CTL); 581 533 ··· 588 540 retry--; 589 541 } while (retry > 0); 590 542 if (!retry) 591 - dev_err(&ethqos->pdev->dev, 592 - "Timeout while waiting for DLL lock\n"); 543 + dev_err(dev, "Timeout while waiting for DLL lock\n"); 593 544 } 594 545 595 546 if (ethqos->speed == SPEED_1000) ··· 599 552 return 0; 600 553 } 601 554 555 + static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos) 556 + { 557 + int val; 558 + 559 + val = readl(ethqos->mac_base + MAC_CTRL_REG); 560 + 561 + switch (ethqos->speed) { 562 + case SPEED_1000: 563 + val &= ~ETHQOS_MAC_CTRL_PORT_SEL; 564 + rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG, 565 + RGMII_CONFIG2_RGMII_CLK_SEL_CFG, 566 + RGMII_IO_MACRO_CONFIG2); 567 + break; 568 + case SPEED_100: 569 + val |= ETHQOS_MAC_CTRL_PORT_SEL | ETHQOS_MAC_CTRL_SPEED_MODE; 570 + break; 571 + case SPEED_10: 572 + val |= ETHQOS_MAC_CTRL_PORT_SEL; 573 + val &= ~ETHQOS_MAC_CTRL_SPEED_MODE; 574 + break; 575 + } 576 + 577 + writel(val, ethqos->mac_base + MAC_CTRL_REG); 578 + 579 + return val; 580 + } 581 + 582 + static int ethqos_configure(struct qcom_ethqos *ethqos) 583 + { 584 + return ethqos->configure_func(ethqos); 585 + } 586 + 602 587 static void ethqos_fix_mac_speed(void *priv, unsigned int speed) 603 588 { 604 589 struct qcom_ethqos *ethqos = priv; 605 590 606 591 ethqos->speed = speed; 607 - ethqos_update_rgmii_clk(ethqos, speed); 592 + ethqos_update_link_clk(ethqos, speed); 608 593 ethqos_configure(ethqos); 594 + } 595 + 596 + static int qcom_ethqos_serdes_powerup(struct net_device *ndev, void *priv) 597 + { 598 + struct qcom_ethqos *ethqos = priv; 599 + int ret; 600 + 601 + ret = phy_init(ethqos->serdes_phy); 602 + if (ret) 603 + return ret; 604 + 605 + ret = phy_power_on(ethqos->serdes_phy); 606 + if (ret) 607 + return ret; 608 + 609 + return phy_set_speed(ethqos->serdes_phy, ethqos->speed); 610 + } 611 + 612 + static void qcom_ethqos_serdes_powerdown(struct net_device *ndev, void *priv) 613 + { 614 + struct qcom_ethqos *ethqos = priv; 615 + 616 + phy_power_off(ethqos->serdes_phy); 617 + phy_exit(ethqos->serdes_phy); 609 618 } 610 619 611 620 static int ethqos_clks_config(void *priv, bool enabled) ··· 670 567 int ret = 0; 671 568 672 569 if (enabled) { 673 - ret = clk_prepare_enable(ethqos->rgmii_clk); 570 + ret = clk_prepare_enable(ethqos->link_clk); 674 571 if (ret) { 675 - dev_err(&ethqos->pdev->dev, "rgmii_clk enable failed\n"); 572 + dev_err(&ethqos->pdev->dev, "link_clk enable failed\n"); 676 573 return ret; 677 574 } 678 575 ··· 683 580 */ 684 581 ethqos_set_func_clk_en(ethqos); 685 582 } else { 686 - clk_disable_unprepare(ethqos->rgmii_clk); 583 + clk_disable_unprepare(ethqos->link_clk); 687 584 } 688 585 689 586 return ret; 690 587 } 691 588 589 + static void ethqos_clks_disable(void *data) 590 + { 591 + ethqos_clks_config(data, false); 592 + } 593 + 692 594 static int qcom_ethqos_probe(struct platform_device *pdev) 693 595 { 694 596 struct device_node *np = pdev->dev.of_node; 597 + const struct ethqos_emac_driver_data *data; 695 598 struct plat_stmmacenet_data *plat_dat; 696 599 struct stmmac_resources stmmac_res; 697 - const struct ethqos_emac_driver_data *data; 600 + struct device *dev = &pdev->dev; 698 601 struct qcom_ethqos *ethqos; 699 602 int ret; 700 603 ··· 710 601 711 602 plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac); 712 603 if (IS_ERR(plat_dat)) { 713 - dev_err(&pdev->dev, "dt configuration failed\n"); 604 + dev_err(dev, "dt configuration failed\n"); 714 605 return PTR_ERR(plat_dat); 715 606 } 716 607 717 608 plat_dat->clks_config = ethqos_clks_config; 718 609 719 - ethqos = devm_kzalloc(&pdev->dev, sizeof(*ethqos), GFP_KERNEL); 610 + ethqos = devm_kzalloc(dev, sizeof(*ethqos), GFP_KERNEL); 720 611 if (!ethqos) { 721 612 ret = -ENOMEM; 722 - goto err_mem; 613 + goto out_config_dt; 614 + } 615 + 616 + ethqos->phy_mode = device_get_phy_mode(dev); 617 + switch (ethqos->phy_mode) { 618 + case PHY_INTERFACE_MODE_RGMII: 619 + case PHY_INTERFACE_MODE_RGMII_ID: 620 + case PHY_INTERFACE_MODE_RGMII_RXID: 621 + case PHY_INTERFACE_MODE_RGMII_TXID: 622 + ethqos->configure_func = ethqos_configure_rgmii; 623 + break; 624 + case PHY_INTERFACE_MODE_SGMII: 625 + ethqos->configure_func = ethqos_configure_sgmii; 626 + break; 627 + case -ENODEV: 628 + ret = -ENODEV; 629 + goto out_config_dt; 630 + default: 631 + ret = -EINVAL; 632 + goto out_config_dt; 723 633 } 724 634 725 635 ethqos->pdev = pdev; 726 636 ethqos->rgmii_base = devm_platform_ioremap_resource_byname(pdev, "rgmii"); 727 637 if (IS_ERR(ethqos->rgmii_base)) { 728 638 ret = PTR_ERR(ethqos->rgmii_base); 729 - goto err_mem; 639 + goto out_config_dt; 730 640 } 731 641 732 - data = of_device_get_match_data(&pdev->dev); 642 + ethqos->mac_base = stmmac_res.addr; 643 + 644 + data = of_device_get_match_data(dev); 733 645 ethqos->por = data->por; 734 646 ethqos->num_por = data->num_por; 735 647 ethqos->rgmii_config_loopback_en = data->rgmii_config_loopback_en; 736 - ethqos->has_emac3 = data->has_emac3; 648 + ethqos->has_emac_ge_3 = data->has_emac_ge_3; 737 649 738 - ethqos->rgmii_clk = devm_clk_get(&pdev->dev, "rgmii"); 739 - if (IS_ERR(ethqos->rgmii_clk)) { 740 - ret = PTR_ERR(ethqos->rgmii_clk); 741 - goto err_mem; 650 + ethqos->link_clk = devm_clk_get(dev, data->link_clk_name ?: "rgmii"); 651 + if (IS_ERR(ethqos->link_clk)) { 652 + ret = PTR_ERR(ethqos->link_clk); 653 + goto out_config_dt; 742 654 } 743 655 744 656 ret = ethqos_clks_config(ethqos, true); 745 657 if (ret) 746 - goto err_mem; 658 + goto out_config_dt; 659 + 660 + ret = devm_add_action_or_reset(dev, ethqos_clks_disable, ethqos); 661 + if (ret) 662 + goto out_config_dt; 663 + 664 + ethqos->serdes_phy = devm_phy_optional_get(dev, "serdes"); 665 + if (IS_ERR(ethqos->serdes_phy)) { 666 + ret = PTR_ERR(ethqos->serdes_phy); 667 + goto out_config_dt; 668 + } 747 669 748 670 ethqos->speed = SPEED_1000; 749 - ethqos_update_rgmii_clk(ethqos, SPEED_1000); 671 + ethqos_update_link_clk(ethqos, SPEED_1000); 750 672 ethqos_set_func_clk_en(ethqos); 751 673 752 674 plat_dat->bsp_priv = ethqos; 753 675 plat_dat->fix_mac_speed = ethqos_fix_mac_speed; 754 676 plat_dat->dump_debug_regs = rgmii_dump; 755 677 plat_dat->has_gmac4 = 1; 756 - if (ethqos->has_emac3) 678 + if (ethqos->has_emac_ge_3) 757 679 plat_dat->dwmac4_addrs = &data->dwmac4_addrs; 758 680 plat_dat->pmt = 1; 759 681 plat_dat->tso_en = of_property_read_bool(np, "snps,tso"); 760 682 if (of_device_is_compatible(np, "qcom,qcs404-ethqos")) 761 683 plat_dat->rx_clk_runs_in_lpi = 1; 684 + plat_dat->has_integrated_pcs = data->has_integrated_pcs; 762 685 763 - ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 686 + if (ethqos->serdes_phy) { 687 + plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup; 688 + plat_dat->serdes_powerdown = qcom_ethqos_serdes_powerdown; 689 + } 690 + 691 + ret = stmmac_dvr_probe(dev, plat_dat, &stmmac_res); 764 692 if (ret) 765 - goto err_clk; 693 + goto out_config_dt; 766 694 767 695 return ret; 768 696 769 - err_clk: 770 - ethqos_clks_config(ethqos, false); 771 - 772 - err_mem: 697 + out_config_dt: 773 698 stmmac_remove_config_dt(pdev, plat_dat); 774 699 775 700 return ret; 776 701 } 777 702 778 - static void qcom_ethqos_remove(struct platform_device *pdev) 779 - { 780 - struct qcom_ethqos *ethqos = get_stmmac_bsp_priv(&pdev->dev); 781 - 782 - stmmac_pltfr_remove(pdev); 783 - ethqos_clks_config(ethqos, false); 784 - } 785 - 786 703 static const struct of_device_id qcom_ethqos_match[] = { 787 704 { .compatible = "qcom,qcs404-ethqos", .data = &emac_v2_3_0_data}, 705 + { .compatible = "qcom,sa8775p-ethqos", .data = &emac_v4_0_0_data}, 788 706 { .compatible = "qcom,sc8280xp-ethqos", .data = &emac_v3_0_0_data}, 789 707 { .compatible = "qcom,sm8150-ethqos", .data = &emac_v2_1_0_data}, 790 708 { } ··· 820 684 821 685 static struct platform_driver qcom_ethqos_driver = { 822 686 .probe = qcom_ethqos_probe, 823 - .remove_new = qcom_ethqos_remove, 687 + .remove_new = stmmac_pltfr_remove, 824 688 .driver = { 825 689 .name = "qcom-ethqos", 826 690 .pm = &stmmac_pltfr_pm_ops,
+1 -1
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
··· 5798 5798 } 5799 5799 5800 5800 /* PCS link status */ 5801 - if (priv->hw->pcs) { 5801 + if (priv->hw->pcs && !priv->plat->has_integrated_pcs) { 5802 5802 if (priv->xstats.pcs_link) 5803 5803 netif_carrier_on(priv->dev); 5804 5804 else
+1
include/linux/stmmac.h
··· 293 293 bool sph_disable; 294 294 bool serdes_up_after_phy_linkup; 295 295 const struct dwmac4_addrs *dwmac4_addrs; 296 + bool has_integrated_pcs; 296 297 }; 297 298 #endif