forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/drivers/net/ethernet/broadcom/genet/bcmmii.c
....@@ -1,14 +1,11 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Broadcom GENET MDIO routines
34 *
45 * Copyright (c) 2014-2017 Broadcom
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License version 2 as
8
- * published by the Free Software Foundation.
96 */
107
11
-
8
+#include <linux/acpi.h>
129 #include <linux/types.h>
1310 #include <linux/delay.h>
1411 #include <linux/wait.h>
....@@ -98,6 +95,12 @@
9895 CMD_HD_EN |
9996 CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE);
10097 reg |= cmd_bits;
98
+ if (reg & CMD_SW_RESET) {
99
+ reg &= ~CMD_SW_RESET;
100
+ bcmgenet_umac_writel(priv, reg, UMAC_CMD);
101
+ udelay(2);
102
+ reg |= CMD_TX_EN | CMD_RX_EN;
103
+ }
101104 bcmgenet_umac_writel(priv, reg, UMAC_CMD);
102105 } else {
103106 /* done if nothing has changed */
....@@ -184,43 +187,12 @@
184187 const char *phy_name = NULL;
185188 u32 id_mode_dis = 0;
186189 u32 port_ctrl;
187
- int bmcr = -1;
188
- int ret;
189190 u32 reg;
190
-
191
- /* MAC clocking workaround during reset of umac state machines */
192
- reg = bcmgenet_umac_readl(priv, UMAC_CMD);
193
- if (reg & CMD_SW_RESET) {
194
- /* An MII PHY must be isolated to prevent TXC contention */
195
- if (priv->phy_interface == PHY_INTERFACE_MODE_MII) {
196
- ret = phy_read(phydev, MII_BMCR);
197
- if (ret >= 0) {
198
- bmcr = ret;
199
- ret = phy_write(phydev, MII_BMCR,
200
- bmcr | BMCR_ISOLATE);
201
- }
202
- if (ret) {
203
- netdev_err(dev, "failed to isolate PHY\n");
204
- return ret;
205
- }
206
- }
207
- /* Switch MAC clocking to RGMII generated clock */
208
- bcmgenet_sys_writel(priv, PORT_MODE_EXT_GPHY, SYS_PORT_CTRL);
209
- /* Ensure 5 clks with Rx disabled
210
- * followed by 5 clks with Reset asserted
211
- */
212
- udelay(4);
213
- reg &= ~(CMD_SW_RESET | CMD_LCL_LOOP_EN);
214
- bcmgenet_umac_writel(priv, reg, UMAC_CMD);
215
- /* Ensure 5 more clocks before Rx is enabled */
216
- udelay(2);
217
- }
218
-
219
- priv->ext_phy = !priv->internal_phy &&
220
- (priv->phy_interface != PHY_INTERFACE_MODE_MOCA);
221191
222192 switch (priv->phy_interface) {
223193 case PHY_INTERFACE_MODE_INTERNAL:
194
+ phy_name = "internal PHY";
195
+ fallthrough;
224196 case PHY_INTERFACE_MODE_MOCA:
225197 /* Irrespective of the actually configured PHY speed (100 or
226198 * 1000) GENETv4 only has an internal GPHY so we will just end
....@@ -232,11 +204,7 @@
232204 else
233205 port_ctrl = PORT_MODE_INT_EPHY;
234206
235
- bcmgenet_sys_writel(priv, port_ctrl, SYS_PORT_CTRL);
236
-
237
- if (priv->internal_phy) {
238
- phy_name = "internal PHY";
239
- } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
207
+ if (!phy_name) {
240208 phy_name = "MoCA";
241209 bcmgenet_moca_phy_setup(priv);
242210 }
....@@ -244,12 +212,8 @@
244212
245213 case PHY_INTERFACE_MODE_MII:
246214 phy_name = "external MII";
247
- phydev->supported &= PHY_BASIC_FEATURES;
248
- bcmgenet_sys_writel(priv,
249
- PORT_MODE_EXT_EPHY, SYS_PORT_CTRL);
250
- /* Restore the MII PHY after isolation */
251
- if (bmcr >= 0)
252
- phy_write(phydev, MII_BMCR, bmcr);
215
+ phy_set_max_speed(phydev, SPEED_100);
216
+ port_ctrl = PORT_MODE_EXT_EPHY;
253217 break;
254218
255219 case PHY_INTERFACE_MODE_REVMII:
....@@ -259,40 +223,50 @@
259223 * capabilities, use that knowledge to also configure the
260224 * Reverse MII interface correctly.
261225 */
262
- if (dev->phydev->supported & PHY_1000BT_FEATURES)
226
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
227
+ dev->phydev->supported))
263228 port_ctrl = PORT_MODE_EXT_RVMII_50;
264229 else
265230 port_ctrl = PORT_MODE_EXT_RVMII_25;
266
- bcmgenet_sys_writel(priv, port_ctrl, SYS_PORT_CTRL);
267231 break;
268232
269233 case PHY_INTERFACE_MODE_RGMII:
270234 /* RGMII_NO_ID: TXC transitions at the same time as TXD
271235 * (requires PCB or receiver-side delay)
272
- * RGMII: Add 2ns delay on TXC (90 degree shift)
273236 *
274237 * ID is implicitly disabled for 100Mbps (RG)MII operation.
275238 */
239
+ phy_name = "external RGMII (no delay)";
276240 id_mode_dis = BIT(16);
277
- /* fall through */
241
+ port_ctrl = PORT_MODE_EXT_GPHY;
242
+ break;
243
+
278244 case PHY_INTERFACE_MODE_RGMII_TXID:
279
- if (id_mode_dis)
280
- phy_name = "external RGMII (no delay)";
281
- else
282
- phy_name = "external RGMII (TX delay)";
283
- bcmgenet_sys_writel(priv,
284
- PORT_MODE_EXT_GPHY, SYS_PORT_CTRL);
245
+ /* RGMII_TXID: Add 2ns delay on TXC (90 degree shift) */
246
+ phy_name = "external RGMII (TX delay)";
247
+ port_ctrl = PORT_MODE_EXT_GPHY;
248
+ break;
249
+
250
+ case PHY_INTERFACE_MODE_RGMII_RXID:
251
+ phy_name = "external RGMII (RX delay)";
252
+ port_ctrl = PORT_MODE_EXT_GPHY;
285253 break;
286254 default:
287255 dev_err(kdev, "unknown phy mode: %d\n", priv->phy_interface);
288256 return -EINVAL;
289257 }
290258
259
+ bcmgenet_sys_writel(priv, port_ctrl, SYS_PORT_CTRL);
260
+
261
+ priv->ext_phy = !priv->internal_phy &&
262
+ (priv->phy_interface != PHY_INTERFACE_MODE_MOCA);
263
+
291264 /* This is an external PHY (xMII), so we need to enable the RGMII
292265 * block for the interface to work
293266 */
294267 if (priv->ext_phy) {
295268 reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL);
269
+ reg &= ~ID_MODE_DIS;
296270 reg |= id_mode_dis;
297271 if (GENET_IS_V1(priv) || GENET_IS_V2(priv) || GENET_IS_V3(priv))
298272 reg |= RGMII_MODE_EN_V123;
....@@ -310,7 +284,8 @@
310284 int bcmgenet_mii_probe(struct net_device *dev)
311285 {
312286 struct bcmgenet_priv *priv = netdev_priv(dev);
313
- struct device_node *dn = priv->pdev->dev.of_node;
287
+ struct device *kdev = &priv->pdev->dev;
288
+ struct device_node *dn = kdev->of_node;
314289 struct phy_device *phydev;
315290 u32 phy_flags = 0;
316291 int ret;
....@@ -333,7 +308,27 @@
333308 return -ENODEV;
334309 }
335310 } else {
336
- phydev = dev->phydev;
311
+ if (has_acpi_companion(kdev)) {
312
+ char mdio_bus_id[MII_BUS_ID_SIZE];
313
+ struct mii_bus *unimacbus;
314
+
315
+ snprintf(mdio_bus_id, MII_BUS_ID_SIZE, "%s-%d",
316
+ UNIMAC_MDIO_DRV_NAME, priv->pdev->id);
317
+
318
+ unimacbus = mdio_find_bus(mdio_bus_id);
319
+ if (!unimacbus) {
320
+ pr_err("Unable to find mii\n");
321
+ return -ENODEV;
322
+ }
323
+ phydev = phy_find_first(unimacbus);
324
+ put_device(&unimacbus->dev);
325
+ if (!phydev) {
326
+ pr_err("Unable to find PHY\n");
327
+ return -ENODEV;
328
+ }
329
+ } else {
330
+ phydev = dev->phydev;
331
+ }
337332 phydev->dev_flags = phy_flags;
338333
339334 ret = phy_connect_direct(dev, phydev, bcmgenet_mii_setup,
....@@ -355,7 +350,7 @@
355350 return ret;
356351 }
357352
358
- phydev->advertising = phydev->supported;
353
+ linkmode_copy(phydev->advertising, phydev->supported);
359354
360355 /* The internal PHY has its link interrupts routed to the
361356 * Ethernet MAC ISRs. On GENETv5 there is a hardware issue
....@@ -458,9 +453,12 @@
458453 /* Retain this platform_device pointer for later cleanup */
459454 priv->mii_pdev = ppdev;
460455 ppdev->dev.parent = &pdev->dev;
461
- ppdev->dev.of_node = bcmgenet_mii_of_find_mdio(priv);
462
- if (pdata)
456
+ if (dn)
457
+ ppdev->dev.of_node = bcmgenet_mii_of_find_mdio(priv);
458
+ else if (pdata)
463459 bcmgenet_mii_pdata_init(priv, &ppd);
460
+ else
461
+ ppd.phy_mask = ~0;
464462
465463 ret = platform_device_add_resources(ppdev, &res, 1);
466464 if (ret)
....@@ -480,12 +478,33 @@
480478 return ret;
481479 }
482480
481
+static int bcmgenet_phy_interface_init(struct bcmgenet_priv *priv)
482
+{
483
+ struct device *kdev = &priv->pdev->dev;
484
+ int phy_mode = device_get_phy_mode(kdev);
485
+
486
+ if (phy_mode < 0) {
487
+ dev_err(kdev, "invalid PHY mode property\n");
488
+ return phy_mode;
489
+ }
490
+
491
+ priv->phy_interface = phy_mode;
492
+
493
+ /* We need to specifically look up whether this PHY interface is
494
+ * internal or not *before* we even try to probe the PHY driver
495
+ * over MDIO as we may have shut down the internal PHY for power
496
+ * saving purposes.
497
+ */
498
+ if (priv->phy_interface == PHY_INTERFACE_MODE_INTERNAL)
499
+ priv->internal_phy = true;
500
+
501
+ return 0;
502
+}
503
+
483504 static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv)
484505 {
485506 struct device_node *dn = priv->pdev->dev.of_node;
486
- struct device *kdev = &priv->pdev->dev;
487507 struct phy_device *phydev;
488
- int phy_mode;
489508 int ret;
490509
491510 /* Fetch the PHY phandle */
....@@ -503,23 +522,12 @@
503522 }
504523
505524 /* Get the link mode */
506
- phy_mode = of_get_phy_mode(dn);
507
- if (phy_mode < 0) {
508
- dev_err(kdev, "invalid PHY mode property\n");
509
- return phy_mode;
510
- }
511
-
512
- priv->phy_interface = phy_mode;
513
-
514
- /* We need to specifically look up whether this PHY interface is internal
515
- * or not *before* we even try to probe the PHY driver over MDIO as we
516
- * may have shut down the internal PHY for power saving purposes.
517
- */
518
- if (priv->phy_interface == PHY_INTERFACE_MODE_INTERNAL)
519
- priv->internal_phy = true;
525
+ ret = bcmgenet_phy_interface_init(priv);
526
+ if (ret)
527
+ return ret;
520528
521529 /* Make sure we initialize MoCA PHYs with a link down */
522
- if (phy_mode == PHY_INTERFACE_MODE_MOCA) {
530
+ if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
523531 phydev = of_phy_find_device(dn);
524532 if (phydev) {
525533 phydev->link = 0;
....@@ -566,7 +574,7 @@
566574 .asym_pause = 0,
567575 };
568576
569
- phydev = fixed_phy_register(PHY_POLL, &fphy_status, -1, NULL);
577
+ phydev = fixed_phy_register(PHY_POLL, &fphy_status, NULL);
570578 if (!phydev || IS_ERR(phydev)) {
571579 dev_err(kdev, "failed to register fixed PHY device\n");
572580 return -ENODEV;
....@@ -584,10 +592,13 @@
584592
585593 static int bcmgenet_mii_bus_init(struct bcmgenet_priv *priv)
586594 {
587
- struct device_node *dn = priv->pdev->dev.of_node;
595
+ struct device *kdev = &priv->pdev->dev;
596
+ struct device_node *dn = kdev->of_node;
588597
589598 if (dn)
590599 return bcmgenet_mii_of_init(priv);
600
+ else if (has_acpi_companion(kdev))
601
+ return bcmgenet_phy_interface_init(priv);
591602 else
592603 return bcmgenet_mii_pd_init(priv);
593604 }