aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-5.4/701-net-0382-enetc-Make-MDIO-accessors-more-generic-and-export-to.patch
diff options
context:
space:
mode:
authorYangbo Lu <yangbo.lu@nxp.com>2020-04-10 10:47:05 +0800
committerPetr Štetiar <ynezz@true.cz>2020-05-07 12:53:06 +0200
commitcddd4591404fb4c53dc0b3c0b15b942cdbed4356 (patch)
tree392c1179de46b0f804e3789edca19069b64e6b44 /target/linux/layerscape/patches-5.4/701-net-0382-enetc-Make-MDIO-accessors-more-generic-and-export-to.patch
parentd1d2c0b5579ea4f69a42246c9318539d61ba1999 (diff)
downloadupstream-cddd4591404fb4c53dc0b3c0b15b942cdbed4356.tar.gz
upstream-cddd4591404fb4c53dc0b3c0b15b942cdbed4356.tar.bz2
upstream-cddd4591404fb4c53dc0b3c0b15b942cdbed4356.zip
layerscape: add patches-5.4
Add patches for linux-5.4. The patches are from NXP LSDK-20.04 release which was tagged LSDK-20.04-V5.4. https://source.codeaurora.org/external/qoriq/qoriq-components/linux/ For boards LS1021A-IOT, and Traverse-LS1043 which are not involved in LSDK, port the dts patches from 4.14. The patches are sorted into the following categories: 301-arch-xxxx 302-dts-xxxx 303-core-xxxx 701-net-xxxx 801-audio-xxxx 802-can-xxxx 803-clock-xxxx 804-crypto-xxxx 805-display-xxxx 806-dma-xxxx 807-gpio-xxxx 808-i2c-xxxx 809-jailhouse-xxxx 810-keys-xxxx 811-kvm-xxxx 812-pcie-xxxx 813-pm-xxxx 814-qe-xxxx 815-sata-xxxx 816-sdhc-xxxx 817-spi-xxxx 818-thermal-xxxx 819-uart-xxxx 820-usb-xxxx 821-vfio-xxxx Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
Diffstat (limited to 'target/linux/layerscape/patches-5.4/701-net-0382-enetc-Make-MDIO-accessors-more-generic-and-export-to.patch')
-rw-r--r--target/linux/layerscape/patches-5.4/701-net-0382-enetc-Make-MDIO-accessors-more-generic-and-export-to.patch446
1 files changed, 446 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-5.4/701-net-0382-enetc-Make-MDIO-accessors-more-generic-and-export-to.patch b/target/linux/layerscape/patches-5.4/701-net-0382-enetc-Make-MDIO-accessors-more-generic-and-export-to.patch
new file mode 100644
index 0000000000..6a1e647acc
--- /dev/null
+++ b/target/linux/layerscape/patches-5.4/701-net-0382-enetc-Make-MDIO-accessors-more-generic-and-export-to.patch
@@ -0,0 +1,446 @@
+From 126e6f022c749ac1bf3a607269a106ccd87d0594 Mon Sep 17 00:00:00 2001
+From: Claudiu Manoil <claudiu.manoil@nxp.com>
+Date: Mon, 12 Aug 2019 20:26:42 +0300
+Subject: [PATCH] enetc: Make MDIO accessors more generic and export to
+ include/linux/fsl
+
+Within the LS1028A SoC, the register map for the ENETC MDIO controller
+is instantiated a few times: for the central (external) MDIO controller,
+for the internal bus of each standalone ENETC port, and for the internal
+bus of the Felix switch.
+
+Refactoring is needed to support multiple MDIO buses from multiple
+drivers. The enetc_hw structure is made an opaque type and a smaller
+enetc_mdio_priv is created.
+
+'mdio_base' - MDIO registers base address - is being parameterized, to
+be able to work with different MDIO register bases.
+
+The ENETC MDIO bus operations are exported from the fsl-enetc-mdio
+kernel object, the same that registers the central MDIO controller (the
+dedicated PF). The ENETC main driver has been changed to select it, and
+use its exported helpers to further register its private MDIO bus. The
+DSA Felix driver will do the same.
+
+Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+Conflicts:
+ drivers/net/ethernet/freescale/enetc/enetc_mdio.c
+ drivers/net/ethernet/freescale/enetc/enetc_mdio.h
+ drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c
+ drivers/net/ethernet/freescale/enetc/enetc_pf.c
+ drivers/net/ethernet/freescale/enetc/enetc_pf.h
+
+mostly with the previous (downstream version of this commit) patch
+572ee5d842da ("enetc: Make mdio accessors more generic"), which couldn't
+be reverted cleanly due to the existing downstream workaround for the
+MDIO erratum.
+---
+ drivers/net/ethernet/freescale/enetc/Kconfig | 1 +
+ drivers/net/ethernet/freescale/enetc/Makefile | 2 +-
+ drivers/net/ethernet/freescale/enetc/enetc_mdio.c | 76 ++++------------------
+ drivers/net/ethernet/freescale/enetc/enetc_mdio.h | 12 ----
+ .../net/ethernet/freescale/enetc/enetc_pci_mdio.c | 41 +++++++-----
+ drivers/net/ethernet/freescale/enetc/enetc_pf.c | 71 ++++++++++++++++++++
+ drivers/net/ethernet/freescale/enetc/enetc_pf.h | 5 --
+ include/linux/fsl/enetc_mdio.h | 55 ++++++++++++++++
+ 8 files changed, 163 insertions(+), 100 deletions(-)
+ delete mode 100644 drivers/net/ethernet/freescale/enetc/enetc_mdio.h
+ create mode 100644 include/linux/fsl/enetc_mdio.h
+
+--- a/drivers/net/ethernet/freescale/enetc/Kconfig
++++ b/drivers/net/ethernet/freescale/enetc/Kconfig
+@@ -2,6 +2,7 @@
+ config FSL_ENETC
+ tristate "ENETC PF driver"
+ depends on PCI && PCI_MSI && (ARCH_LAYERSCAPE || COMPILE_TEST)
++ select FSL_ENETC_MDIO
+ select PHYLIB
+ help
+ This driver supports NXP ENETC gigabit ethernet controller PCIe
+--- a/drivers/net/ethernet/freescale/enetc/Makefile
++++ b/drivers/net/ethernet/freescale/enetc/Makefile
+@@ -3,7 +3,7 @@
+ common-objs := enetc.o enetc_cbdr.o enetc_ethtool.o
+
+ obj-$(CONFIG_FSL_ENETC) += fsl-enetc.o
+-fsl-enetc-y := enetc_pf.o enetc_mdio.o $(common-objs)
++fsl-enetc-y := enetc_pf.o $(common-objs)
+ fsl-enetc-$(CONFIG_PCI_IOV) += enetc_msg.o
+ fsl-enetc-$(CONFIG_FSL_ENETC_QOS) += enetc_qos.o
+ fsl-enetc-$(CONFIG_ENETC_TSN) += enetc_tsn.o
+--- a/drivers/net/ethernet/freescale/enetc/enetc_mdio.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc_mdio.c
+@@ -1,13 +1,13 @@
+ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+ /* Copyright 2019 NXP */
+
++#include <linux/fsl/enetc_mdio.h>
+ #include <linux/mdio.h>
+ #include <linux/of_mdio.h>
+ #include <linux/iopoll.h>
+ #include <linux/of.h>
+
+ #include "enetc_pf.h"
+-#include "enetc_mdio.h"
+
+ #define ENETC_MDIO_CFG 0x0 /* MDIO configuration and status */
+ #define ENETC_MDIO_CTL 0x4 /* MDIO control */
+@@ -99,6 +99,7 @@ int enetc_mdio_write(struct mii_bus *bus
+
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(enetc_mdio_write);
+
+ int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
+ {
+@@ -154,73 +155,18 @@ int enetc_mdio_read(struct mii_bus *bus,
+
+ return value;
+ }
++EXPORT_SYMBOL_GPL(enetc_mdio_read);
+
+-int enetc_mdio_probe(struct enetc_pf *pf)
++struct enetc_hw *enetc_hw_alloc(struct device *dev, void __iomem *port_regs)
+ {
+- struct device *dev = &pf->si->pdev->dev;
+- struct enetc_mdio_priv *mdio_priv;
+- struct device_node *np;
+- struct mii_bus *bus;
+- int err;
+-
+- bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
+- if (!bus)
+- return -ENOMEM;
+-
+- bus->name = "Freescale ENETC MDIO Bus";
+- bus->read = enetc_mdio_read;
+- bus->write = enetc_mdio_write;
+- bus->parent = dev;
+- mdio_priv = bus->priv;
+- mdio_priv->hw = &pf->si->hw;
+- mdio_priv->mdio_base = ENETC_EMDIO_BASE;
+- snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
+-
+- np = of_get_child_by_name(dev->of_node, "mdio");
+- if (!np) {
+- dev_err(dev, "MDIO node missing\n");
+- return -EINVAL;
+- }
+-
+- err = of_mdiobus_register(bus, np);
+- if (err) {
+- of_node_put(np);
+- dev_err(dev, "cannot register MDIO bus\n");
+- return err;
+- }
+-
+- of_node_put(np);
+- pf->mdio = bus;
+-
+- return 0;
+-}
++ struct enetc_hw *hw;
+
+-void enetc_mdio_remove(struct enetc_pf *pf)
+-{
+- if (pf->mdio)
+- mdiobus_unregister(pf->mdio);
+-}
+-
+-int enetc_imdio_init(struct enetc_pf *pf)
+-{
+- struct device *dev = &pf->si->pdev->dev;
+- struct enetc_mdio_priv *mdio_priv;
+- struct mii_bus *bus;
++ hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
++ if (!hw)
++ return ERR_PTR(-ENOMEM);
+
+- bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
+- if (!bus)
+- return -ENOMEM;
++ hw->port = port_regs;
+
+- bus->name = "FSL ENETC internal MDIO Bus";
+- bus->read = enetc_mdio_read;
+- bus->write = enetc_mdio_write;
+- bus->parent = dev;
+- mdio_priv = bus->priv;
+- mdio_priv->hw = &pf->si->hw;
+- mdio_priv->mdio_base = ENETC_PM_IMDIO_BASE;
+- snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
+-
+- pf->imdio = bus;
+-
+- return 0;
++ return hw;
+ }
++EXPORT_SYMBOL_GPL(enetc_hw_alloc);
+--- a/drivers/net/ethernet/freescale/enetc/enetc_mdio.h
++++ /dev/null
+@@ -1,12 +0,0 @@
+-/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+-/* Copyright 2019 NXP */
+-
+-#include <linux/phy.h>
+-
+-struct enetc_mdio_priv {
+- struct enetc_hw *hw;
+- int mdio_base;
+-};
+-
+-int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value);
+-int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum);
+--- a/drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c
+@@ -1,8 +1,8 @@
+ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+ /* Copyright 2019 NXP */
++#include <linux/fsl/enetc_mdio.h>
+ #include <linux/of_mdio.h>
+ #include "enetc_pf.h"
+-#include "enetc_mdio.h"
+
+ #define ENETC_MDIO_DEV_ID 0xee01
+ #define ENETC_MDIO_DEV_NAME "FSL PCIe IE Central MDIO"
+@@ -14,17 +14,29 @@ static int enetc_pci_mdio_probe(struct p
+ {
+ struct enetc_mdio_priv *mdio_priv;
+ struct device *dev = &pdev->dev;
++ void __iomem *port_regs;
+ struct enetc_hw *hw;
+ struct mii_bus *bus;
+ int err;
+
+- hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
+- if (!hw)
+- return -ENOMEM;
++ port_regs = pci_iomap(pdev, 0, 0);
++ if (!port_regs) {
++ dev_err(dev, "iomap failed\n");
++ err = -ENXIO;
++ goto err_ioremap;
++ }
++
++ hw = enetc_hw_alloc(dev, port_regs);
++ if (IS_ERR(enetc_hw_alloc)) {
++ err = PTR_ERR(hw);
++ goto err_hw_alloc;
++ }
+
+ bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
+- if (!bus)
+- return -ENOMEM;
++ if (!bus) {
++ err = -ENOMEM;
++ goto err_mdiobus_alloc;
++ }
+
+ bus->name = ENETC_MDIO_BUS_NAME;
+ bus->read = enetc_mdio_read;
+@@ -39,7 +51,7 @@ static int enetc_pci_mdio_probe(struct p
+ err = pci_enable_device_mem(pdev);
+ if (err) {
+ dev_err(dev, "device enable failed\n");
+- return err;
++ goto err_pci_enable;
+ }
+
+ err = pci_request_region(pdev, 0, KBUILD_MODNAME);
+@@ -48,13 +60,6 @@ static int enetc_pci_mdio_probe(struct p
+ goto err_pci_mem_reg;
+ }
+
+- hw->port = pci_iomap(pdev, 0, 0);
+- if (!hw->port) {
+- err = -ENXIO;
+- dev_err(dev, "iomap failed\n");
+- goto err_ioremap;
+- }
+-
+ err = of_mdiobus_register(bus, dev->of_node);
+ if (err)
+ goto err_mdiobus_reg;
+@@ -64,12 +69,14 @@ static int enetc_pci_mdio_probe(struct p
+ return 0;
+
+ err_mdiobus_reg:
+- iounmap(mdio_priv->hw->port);
+-err_ioremap:
+ pci_release_mem_regions(pdev);
+ err_pci_mem_reg:
+ pci_disable_device(pdev);
+-
++err_pci_enable:
++err_mdiobus_alloc:
++ iounmap(port_regs);
++err_hw_alloc:
++err_ioremap:
+ return err;
+ }
+
+--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+@@ -2,6 +2,7 @@
+ /* Copyright 2017-2019 NXP */
+
+ #include <linux/module.h>
++#include <linux/fsl/enetc_mdio.h>
+ #include <linux/of_mdio.h>
+ #include <linux/of_net.h>
+ #include "enetc_pf.h"
+@@ -760,6 +761,52 @@ static void enetc_pf_netdev_setup(struct
+ enetc_get_primary_mac_addr(&si->hw, ndev->dev_addr);
+ }
+
++static int enetc_mdio_probe(struct enetc_pf *pf)
++{
++ struct device *dev = &pf->si->pdev->dev;
++ struct enetc_mdio_priv *mdio_priv;
++ struct device_node *np;
++ struct mii_bus *bus;
++ int err;
++
++ bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
++ if (!bus)
++ return -ENOMEM;
++
++ bus->name = "Freescale ENETC MDIO Bus";
++ bus->read = enetc_mdio_read;
++ bus->write = enetc_mdio_write;
++ bus->parent = dev;
++ mdio_priv = bus->priv;
++ mdio_priv->hw = &pf->si->hw;
++ mdio_priv->mdio_base = ENETC_EMDIO_BASE;
++ snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
++
++ np = of_get_child_by_name(dev->of_node, "mdio");
++ if (!np) {
++ dev_err(dev, "MDIO node missing\n");
++ return -EINVAL;
++ }
++
++ err = of_mdiobus_register(bus, np);
++ if (err) {
++ of_node_put(np);
++ dev_err(dev, "cannot register MDIO bus\n");
++ return err;
++ }
++
++ of_node_put(np);
++ pf->mdio = bus;
++
++ return 0;
++}
++
++static void enetc_mdio_remove(struct enetc_pf *pf)
++{
++ if (pf->mdio)
++ mdiobus_unregister(pf->mdio);
++}
++
+ static int enetc_of_get_phy(struct enetc_pf *pf)
+ {
+ struct device *dev = &pf->si->pdev->dev;
+@@ -846,6 +893,30 @@ static void enetc_configure_sxgmii(struc
+ ENETC_PCS_CR_LANE_RESET | ENETC_PCS_CR_RESET_AN);
+ }
+
++static int enetc_imdio_init(struct enetc_pf *pf)
++{
++ struct device *dev = &pf->si->pdev->dev;
++ struct enetc_mdio_priv *mdio_priv;
++ struct mii_bus *bus;
++
++ bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
++ if (!bus)
++ return -ENOMEM;
++
++ bus->name = "FSL ENETC internal MDIO Bus";
++ bus->read = enetc_mdio_read;
++ bus->write = enetc_mdio_write;
++ bus->parent = dev;
++ mdio_priv = bus->priv;
++ mdio_priv->hw = &pf->si->hw;
++ mdio_priv->mdio_base = ENETC_PM_IMDIO_BASE;
++ snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
++
++ pf->imdio = bus;
++
++ return 0;
++}
++
+ static int enetc_configure_serdes(struct enetc_ndev_priv *priv)
+ {
+ struct enetc_pf *pf = enetc_si_priv(priv->si);
+--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h
++++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
+@@ -53,8 +53,3 @@ struct enetc_pf {
+ int enetc_msg_psi_init(struct enetc_pf *pf);
+ void enetc_msg_psi_free(struct enetc_pf *pf);
+ void enetc_msg_handle_rxmsg(struct enetc_pf *pf, int mbox_id, u16 *status);
+-
+-/* MDIO */
+-int enetc_mdio_probe(struct enetc_pf *pf);
+-void enetc_mdio_remove(struct enetc_pf *pf);
+-int enetc_imdio_init(struct enetc_pf *pf);
+--- /dev/null
++++ b/include/linux/fsl/enetc_mdio.h
+@@ -0,0 +1,55 @@
++/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
++/* Copyright 2019 NXP */
++
++#ifndef _FSL_ENETC_MDIO_H_
++#define _FSL_ENETC_MDIO_H_
++
++#include <linux/phy.h>
++
++/* PCS registers */
++#define ENETC_PCS_LINK_TIMER1 0x12
++#define ENETC_PCS_LINK_TIMER1_VAL 0x06a0
++#define ENETC_PCS_LINK_TIMER2 0x13
++#define ENETC_PCS_LINK_TIMER2_VAL 0x0003
++#define ENETC_PCS_IF_MODE 0x14
++#define ENETC_PCS_IF_MODE_SGMII_EN BIT(0)
++#define ENETC_PCS_IF_MODE_USE_SGMII_AN BIT(1)
++#define ENETC_PCS_IF_MODE_SGMII_SPEED(x) (((x) << 2) & GENMASK(3, 2))
++
++/* Not a mistake, the SerDes PLL needs to be set at 3.125 GHz by Reset
++ * Configuration Word (RCW, outside Linux control) for 2.5G SGMII mode. The PCS
++ * still thinks it's at gigabit.
++ */
++enum enetc_pcs_speed {
++ ENETC_PCS_SPEED_10 = 0,
++ ENETC_PCS_SPEED_100 = 1,
++ ENETC_PCS_SPEED_1000 = 2,
++ ENETC_PCS_SPEED_2500 = 2,
++};
++
++struct enetc_hw;
++
++struct enetc_mdio_priv {
++ struct enetc_hw *hw;
++ int mdio_base;
++};
++
++#if IS_REACHABLE(CONFIG_FSL_ENETC_MDIO)
++
++int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum);
++int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value);
++struct enetc_hw *enetc_hw_alloc(struct device *dev, void __iomem *port_regs);
++
++#else
++
++static inline int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
++{ return -EINVAL; }
++static inline int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum,
++ u16 value)
++{ return -EINVAL; }
++struct enetc_hw *enetc_hw_alloc(struct device *dev, void __iomem *port_regs)
++{ return ERR_PTR(-EINVAL); }
++
++#endif
++
++#endif