summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2023-06-22 09:59:24 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2023-06-22 09:59:24 +0200
commit2c4523beb1aaa54d5ff2af2ad89b0c900d31cf39 (patch)
tree26a5845e79fe9e807ae63e7bb1cf8d8563588d54 /drivers/net
parent47f6d253d678f97108b50d0c99a599f082de6a87 (diff)
parentb1185e4a6a935b14dfe24654a4cb058dce5b93aa (diff)
downloadbarebox-2c4523beb1aaa54d5ff2af2ad89b0c900d31cf39.tar.gz
barebox-2c4523beb1aaa54d5ff2af2ad89b0c900d31cf39.tar.xz
Merge branch 'for-next/misc'
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/phy/Kconfig5
-rw-r--r--drivers/net/phy/Makefile1
-rw-r--r--drivers/net/phy/dp83867.c37
-rw-r--r--drivers/net/phy/motorcomm.c129
-rw-r--r--drivers/net/phy/mv88e6xxx/chip.c8
-rw-r--r--drivers/net/phy/phy.c23
-rw-r--r--drivers/net/r8169_main.c1
7 files changed, 197 insertions, 7 deletions
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index cd20e1de27..e95e2a3228 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -50,6 +50,11 @@ config MICREL_PHY
help
Supports the KSZ9021, VSC8201, KS8001 PHYs.
+config MOTORCOMM_PHY
+ bool "Driver for Motorcomm PHYs"
+ help
+ Currently supports the YT8511 PHY.
+
config NATIONAL_PHY
bool "Driver for National Semiconductor PHYs"
help
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 83f46f11d3..26e4ad884d 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_DAVICOM_PHY) += davicom.o
obj-$(CONFIG_LXT_PHY) += lxt.o
obj-$(CONFIG_MARVELL_PHY) += marvell.o
obj-$(CONFIG_MICREL_PHY) += micrel.o
+obj-$(CONFIG_MOTORCOMM_PHY) += motorcomm.o
obj-$(CONFIG_NATIONAL_PHY) += national.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
obj-$(CONFIG_SMSC_PHY) += smsc.o
diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
index 375dcd0753..d8109172df 100644
--- a/drivers/net/phy/dp83867.c
+++ b/drivers/net/phy/dp83867.c
@@ -96,6 +96,9 @@
#define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX 0x0
#define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN 0x1f
+#define DP83867_IO_MUX_CFG_CLK_O_DISABLE BIT(6)
+#define DP83867_IO_MUX_CFG_CLK_O_SEL_MASK (0x1f << 8)
+#define DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT 8
/* CFG4 bits */
#define DP83867_CFG4_PORT_MIRROR_EN BIT(0)
@@ -113,6 +116,8 @@ struct dp83867_private {
int io_impedance;
int port_mirroring;
bool rxctrl_strap_quirk;
+ bool set_clk_output;
+ u32 clk_output_sel;
};
static int dp83867_read_status(struct phy_device *phydev)
@@ -174,6 +179,22 @@ static int dp83867_of_init(struct phy_device *phydev)
dp83867->io_impedance = -EINVAL;
/* Optional configuration */
+ ret = of_property_read_u32(of_node, "ti,clk-output-sel",
+ &dp83867->clk_output_sel);
+ /* If not set, keep default */
+ if (!ret) {
+ dp83867->set_clk_output = true;
+ /* Valid values are 0 to DP83867_CLK_O_SEL_REF_CLK or
+ * DP83867_CLK_O_SEL_OFF.
+ */
+ if (dp83867->clk_output_sel > DP83867_CLK_O_SEL_REF_CLK &&
+ dp83867->clk_output_sel != DP83867_CLK_O_SEL_OFF) {
+ dev_err(&phydev->dev, "ti,clk-output-sel value %u out of range\n",
+ dp83867->clk_output_sel);
+ return -EINVAL;
+ }
+ }
+
if (of_property_read_bool(of_node, "ti,max-output-impedance"))
dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX;
else if (of_property_read_bool(of_node, "ti,min-output-impedance"))
@@ -308,6 +329,22 @@ static int dp83867_config_init(struct phy_device *phydev)
if (dp83867->port_mirroring != DP83867_PORT_MIRROING_KEEP)
dp83867_config_port_mirroring(phydev);
+ /* Clock output selection if muxing property is set */
+ if (dp83867->set_clk_output) {
+ u16 mask = DP83867_IO_MUX_CFG_CLK_O_DISABLE;
+
+ if (dp83867->clk_output_sel == DP83867_CLK_O_SEL_OFF) {
+ val = DP83867_IO_MUX_CFG_CLK_O_DISABLE;
+ } else {
+ mask |= DP83867_IO_MUX_CFG_CLK_O_SEL_MASK;
+ val = dp83867->clk_output_sel <<
+ DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT;
+ }
+
+ phy_modify_mmd_indirect(phydev, DP83867_IO_MUX_CFG,
+ DP83867_DEVADDR, mask, val);
+ }
+
return 0;
}
diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
new file mode 100644
index 0000000000..d4cd05a1f6
--- /dev/null
+++ b/drivers/net/phy/motorcomm.c
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * drivers/net/phy/motorcomm.c
+ *
+ * Driver for Motorcomm PHYs
+ *
+ * Author: Peter Geis <pgwipeout@gmail.com>
+ */
+
+#include <common.h>
+#include <init.h>
+#include <linux/phy.h>
+#include <linux/mdio.h>
+
+#define PHY_ID_YT8511 0x0000010a
+
+#define YT8511_PAGE_SELECT 0x1e
+#define YT8511_PAGE 0x1f
+#define YT8511_EXT_CLK_GATE 0x0c
+#define YT8511_EXT_DELAY_DRIVE 0x0d
+#define YT8511_EXT_SLEEP_CTRL 0x27
+
+/* 2b00 25m from pll
+ * 2b01 25m from xtl *default*
+ * 2b10 62.m from pll
+ * 2b11 125m from pll
+ */
+#define YT8511_CLK_125M (BIT(2) | BIT(1))
+#define YT8511_PLLON_SLP BIT(14)
+
+/* RX Delay enabled = 1.8ns 1000T, 8ns 10/100T */
+#define YT8511_DELAY_RX BIT(0)
+
+/* TX Gig-E Delay is bits 7:4, default 0x5
+ * TX Fast-E Delay is bits 15:12, default 0xf
+ * Delay = 150ps * N - 250ps
+ * On = 2000ps, off = 50ps
+ */
+#define YT8511_DELAY_GE_TX_EN (0xf << 4)
+#define YT8511_DELAY_GE_TX_DIS (0x2 << 4)
+#define YT8511_DELAY_FE_TX_EN (0xf << 12)
+#define YT8511_DELAY_FE_TX_DIS (0x2 << 12)
+
+static int yt8511_read_page(struct phy_device *phydev)
+{
+ return phy_read(phydev, YT8511_PAGE_SELECT);
+};
+
+static int yt8511_write_page(struct phy_device *phydev, int page)
+{
+ return phy_write(phydev, YT8511_PAGE_SELECT, page);
+};
+
+static int yt8511_config_init(struct phy_device *phydev)
+{
+ int oldpage, ret = 0;
+ unsigned int ge, fe;
+
+ oldpage = phy_select_page(phydev, YT8511_EXT_CLK_GATE);
+ if (oldpage < 0)
+ goto err_restore_page;
+
+ /* set rgmii delay mode */
+ switch (phydev->interface) {
+ case PHY_INTERFACE_MODE_RGMII:
+ ge = YT8511_DELAY_GE_TX_DIS;
+ fe = YT8511_DELAY_FE_TX_DIS;
+ break;
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ ge = YT8511_DELAY_RX | YT8511_DELAY_GE_TX_DIS;
+ fe = YT8511_DELAY_FE_TX_DIS;
+ break;
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ ge = YT8511_DELAY_GE_TX_EN;
+ fe = YT8511_DELAY_FE_TX_EN;
+ break;
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ ge = YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN;
+ fe = YT8511_DELAY_FE_TX_EN;
+ break;
+ default: /* do not support other modes */
+ ret = -EOPNOTSUPP;
+ goto err_restore_page;
+ }
+
+ ret = phy_modify(phydev, YT8511_PAGE, (YT8511_DELAY_RX | YT8511_DELAY_GE_TX_EN), ge);
+ if (ret < 0)
+ goto err_restore_page;
+
+ /* set clock mode to 125mhz */
+ ret = phy_modify(phydev, YT8511_PAGE, 0, YT8511_CLK_125M);
+ if (ret < 0)
+ goto err_restore_page;
+
+ /* fast ethernet delay is in a separate page */
+ ret = phy_write(phydev, YT8511_PAGE_SELECT, YT8511_EXT_DELAY_DRIVE);
+ if (ret < 0)
+ goto err_restore_page;
+
+ ret = phy_modify(phydev, YT8511_PAGE, YT8511_DELAY_FE_TX_EN, fe);
+ if (ret < 0)
+ goto err_restore_page;
+
+ /* leave pll enabled in sleep */
+ ret = phy_write(phydev, YT8511_PAGE_SELECT, YT8511_EXT_SLEEP_CTRL);
+ if (ret < 0)
+ goto err_restore_page;
+
+ ret = phy_modify(phydev, YT8511_PAGE, 0, YT8511_PLLON_SLP);
+ if (ret < 0)
+ goto err_restore_page;
+
+err_restore_page:
+ return phy_restore_page(phydev, oldpage, ret);
+}
+
+static struct phy_driver motorcomm_phy_drvs[] = {
+ {
+ .phy_id = PHY_ID_YT8511,
+ .phy_id_mask = 0xffffffff,
+ .drv.name = "YT8511 Gigabit Ethernet",
+ .config_init = yt8511_config_init,
+ .features = PHY_GBIT_FEATURES,
+ .read_page = yt8511_read_page,
+ .write_page = yt8511_write_page,
+ },
+};
+
+device_phy_drivers(motorcomm_phy_drvs);
diff --git a/drivers/net/phy/mv88e6xxx/chip.c b/drivers/net/phy/mv88e6xxx/chip.c
index 0c37ba9594..b9b02c52f2 100644
--- a/drivers/net/phy/mv88e6xxx/chip.c
+++ b/drivers/net/phy/mv88e6xxx/chip.c
@@ -832,11 +832,6 @@ static int mv88e6xxx_eeprom_write(void *ctx, unsigned offset, const void *val, s
return chip->info->ops->set_eeprom(chip, &eeprom, (void *)val);
}
-static const struct nvmem_bus mv88e6xxx_eeprom_nvmem_bus = {
- .write = mv88e6xxx_eeprom_write,
- .read = mv88e6xxx_eeprom_read,
-};
-
static int mv88e6xxx_probe(struct device *dev)
{
struct device_node *np = dev->of_node;
@@ -911,7 +906,8 @@ static int mv88e6xxx_probe(struct device *dev)
.stride = 1,
.size = eeprom_len,
.read_only = false,
- .bus = &mv88e6xxx_eeprom_nvmem_bus,
+ .reg_write = mv88e6xxx_eeprom_write,
+ .reg_read = mv88e6xxx_eeprom_read,
};
if (IS_ERR(nvmem_register(&config)))
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index dbc30b66b8..74381949b4 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -882,6 +882,29 @@ void phy_write_mmd_indirect(struct phy_device *phydev, int prtad, int devad,
phy_write(phydev, MII_MMD_DATA, data);
}
+/**
+ * phy_modify_mmd_indirect - Convenience function for modifying a MMD register
+ * @phydev: phy device
+ * @prtad: MMD Address
+ * @devad: MMD DEVAD
+ * @mask: bit mask of bits to clear
+ * @set: new value of bits set in @mask
+ *
+ */
+int phy_modify_mmd_indirect(struct phy_device *phydev, int prtad, int devad,
+ u16 mask, u16 set)
+{
+ int ret;
+
+ ret = phy_read_mmd_indirect(phydev, prtad, devad);
+ if (ret < 0)
+ return ret;
+
+ phy_write_mmd_indirect(phydev, prtad, devad, (ret & ~mask) | set);
+
+ return 0;
+}
+
int genphy_config_init(struct phy_device *phydev)
{
int val;
diff --git a/drivers/net/r8169_main.c b/drivers/net/r8169_main.c
index 9c28c92ded..fd53ec1bc3 100644
--- a/drivers/net/r8169_main.c
+++ b/drivers/net/r8169_main.c
@@ -17,7 +17,6 @@
#include <linux/pci.h>
#include <linux/sizes.h>
#include <asm/unaligned.h>
-#include <asm/system.h>
#include "r8169.h"
#include "r8169_firmware.h"