diff options
author | Tom Rini <trini@konsulko.com> | 2022-01-17 08:35:11 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-01-17 08:35:11 -0500 |
commit | d928b365cc73426b0de883249700b3057b738cf3 (patch) | |
tree | 576648536fb0b380fd23a39301fb6510cfff856d | |
parent | d71dbe657c3c22f50ecb3df133e5cdd884daae7d (diff) | |
parent | 046bf8d4c512ad6501fe9e77508bbe1292a29fef (diff) | |
download | u-boot-d928b365cc73426b0de883249700b3057b738cf3.tar.gz u-boot-d928b365cc73426b0de883249700b3057b738cf3.tar.bz2 u-boot-d928b365cc73426b0de883249700b3057b738cf3.zip |
Merge branch 'next' of https://source.denx.de/u-boot/custodians/u-boot-net
- PXE label override support
- Fastboot UDP configurable port
- new phy driver: TI DP83869HM
- and few minor fixes to dsa.
-rw-r--r-- | boot/pxe_utils.c | 15 | ||||
-rw-r--r-- | doc/README.pxe | 6 | ||||
-rw-r--r-- | drivers/fastboot/Kconfig | 7 | ||||
-rw-r--r-- | drivers/net/eth-phy-uclass.c | 2 | ||||
-rw-r--r-- | drivers/net/fm/memac_phy.c | 2 | ||||
-rw-r--r-- | drivers/net/fsl_ls_mdio.c | 4 | ||||
-rw-r--r-- | drivers/net/phy/Kconfig | 6 | ||||
-rw-r--r-- | drivers/net/phy/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/phy/dp83869.c | 507 | ||||
-rw-r--r-- | drivers/net/phy/ti_phy_init.c | 4 | ||||
-rw-r--r-- | drivers/net/phy/ti_phy_init.h | 1 | ||||
-rw-r--r-- | drivers/net/sja1105.c | 6 | ||||
-rw-r--r-- | include/dt-bindings/net/ti-dp83869.h | 60 | ||||
-rw-r--r-- | include/fsl_memac.h | 1 | ||||
-rw-r--r-- | net/dsa-uclass.c | 11 | ||||
-rw-r--r-- | net/fastboot.c | 5 |
16 files changed, 623 insertions, 15 deletions
diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c index a32acca8ee..fcfee5e8b9 100644 --- a/boot/pxe_utils.c +++ b/boot/pxe_utils.c @@ -1355,9 +1355,11 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg) struct pxe_label *label; struct list_head *pos; struct menu *m; + char *label_override; int err; int i = 1; char *default_num = NULL; + char *override_num = NULL; /* * Create a menu and add items for all the labels. @@ -1367,6 +1369,8 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg) if (!m) return NULL; + label_override = env_get("pxe_label_override"); + list_for_each(pos, &cfg->labels) { label = list_entry(pos, struct pxe_label, list); @@ -1378,6 +1382,17 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg) if (cfg->default_label && (strcmp(label->name, cfg->default_label) == 0)) default_num = label->num; + if (label_override && !strcmp(label->name, label_override)) + override_num = label->num; + } + + + if (label_override) { + if (override_num) + default_num = override_num; + else + printf("Missing override pxe label: %s\n", + label_override); } /* diff --git a/doc/README.pxe b/doc/README.pxe index b67151ca51..a1f0423adb 100644 --- a/doc/README.pxe +++ b/doc/README.pxe @@ -92,6 +92,12 @@ pxe boot fdtoverlay_addr_r - location in RAM at which 'pxe boot' will temporarily store fdt overlay(s) before applying them to the fdt blob stored at 'fdt_addr_r'. + pxe_label_override - override label to be used, if exists, instead of the + default label. This will allow consumers to choose a pxe label at + runtime instead of having to prompt the user. If "pxe_label_override" is set + but does not exist in the pxe menu, pxe would fallback to the default label if + given, and no failure is returned but rather a warning message. + pxe file format =============== The pxe file format is nearly a subset of the PXELINUX file format; see diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig index d5e4a02098..b97c67bf60 100644 --- a/drivers/fastboot/Kconfig +++ b/drivers/fastboot/Kconfig @@ -21,6 +21,13 @@ config UDP_FUNCTION_FASTBOOT help This enables the fastboot protocol over UDP. +config UDP_FUNCTION_FASTBOOT_PORT + depends on UDP_FUNCTION_FASTBOOT + int "Define FASTBOOT UDP port" + default 5554 + help + The fastboot protocol requires a UDP port number. + if FASTBOOT config FASTBOOT_BUF_ADDR diff --git a/drivers/net/eth-phy-uclass.c b/drivers/net/eth-phy-uclass.c index a9b358ee23..1f285f7afd 100644 --- a/drivers/net/eth-phy-uclass.c +++ b/drivers/net/eth-phy-uclass.c @@ -103,7 +103,7 @@ struct mii_dev *eth_phy_get_mdio_bus(struct udevice *eth_dev) return uc_priv->mdio_bus; } } else { - log_notice("FEC: can't find phy-handle\n"); + log_debug("Can't find phy-handle for %s\n", eth_dev->name); } return NULL; diff --git a/drivers/net/fm/memac_phy.c b/drivers/net/fm/memac_phy.c index 72b500a6d1..3ddae97e09 100644 --- a/drivers/net/fm/memac_phy.c +++ b/drivers/net/fm/memac_phy.c @@ -64,7 +64,7 @@ static int memac_wait_until_done(struct memac_mdio_controller *regs) { unsigned int timeout = MAX_NUM_RETRIES; - while ((memac_in_32(®s->mdio_data) & MDIO_DATA_BSY) && timeout--) + while ((memac_in_32(®s->mdio_stat) & MDIO_STAT_BSY) && timeout--) ; if (!timeout) { diff --git a/drivers/net/fsl_ls_mdio.c b/drivers/net/fsl_ls_mdio.c index 6d4e682fdf..f213e0dd85 100644 --- a/drivers/net/fsl_ls_mdio.c +++ b/drivers/net/fsl_ls_mdio.c @@ -84,7 +84,7 @@ static int dm_fsl_ls_mdio_read(struct udevice *dev, int addr, memac_out_32(®s->mdio_ctl, mdio_ctl); /* Wait till the MDIO write is complete */ - while ((memac_in_32(®s->mdio_data)) & MDIO_DATA_BSY) + while ((memac_in_32(®s->mdio_stat)) & MDIO_STAT_BSY) ; /* Return all Fs if nothing was there */ @@ -107,7 +107,7 @@ static int dm_fsl_ls_mdio_write(struct udevice *dev, int addr, int devad, memac_out_32(®s->mdio_data, MDIO_DATA(val)); /* Wait till the MDIO write is complete */ - while ((memac_in_32(®s->mdio_data)) & MDIO_DATA_BSY) + while ((memac_in_32(®s->mdio_stat)) & MDIO_STAT_BSY) ; return 0; diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index e69cd8a4b3..4f8d33ce8f 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -280,6 +280,12 @@ config PHY_TI_DP83867 ---help--- Adds support for the TI DP83867 1Gbit PHY. +config PHY_TI_DP83869 + select PHY_TI + bool "Texas Instruments Ethernet DP83869 PHY support" + ---help--- + Adds support for the TI DP83869 1Gbit PHY. + config PHY_TI_GENERIC select PHY_TI bool "Texas Instruments Generic Ethernet PHYs support" diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index 218b8c7669..77f7f60621 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_PHY_SMSC) += smsc.o obj-$(CONFIG_PHY_TERANETICS) += teranetics.o obj-$(CONFIG_PHY_TI) += ti_phy_init.o obj-$(CONFIG_PHY_TI_DP83867) += dp83867.o +obj-$(CONFIG_PHY_TI_DP83869) += dp83869.o obj-$(CONFIG_PHY_XILINX) += xilinx_phy.o obj-$(CONFIG_PHY_XILINX_GMII2RGMII) += xilinx_gmii2rgmii.o obj-$(CONFIG_PHY_VITESSE) += vitesse.o diff --git a/drivers/net/phy/dp83869.c b/drivers/net/phy/dp83869.c new file mode 100644 index 0000000000..c9461185cf --- /dev/null +++ b/drivers/net/phy/dp83869.c @@ -0,0 +1,507 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * TI PHY drivers + * + */ + +#include <common.h> +#include <phy.h> +#include <linux/compat.h> +#include <malloc.h> + +#include <dm.h> +#include <dt-bindings/net/ti-dp83869.h> + +/* TI DP83869 */ +#define DP83869_DEVADDR 0x1f + +#define MII_DP83869_PHYCTRL 0x10 +#define MII_DP83869_MICR 0x12 +#define MII_DP83869_CFG2 0x14 +#define MII_DP83869_BISCR 0x16 +#define DP83869_CTRL 0x1f +#define DP83869_CFG4 0x1e + +/* Extended Registers */ +#define DP83869_GEN_CFG3 0x0031 +#define DP83869_RGMIICTL 0x0032 +#define DP83869_STRAP_STS1 0x006E +#define DP83869_RGMIIDCTL 0x0086 +#define DP83869_IO_MUX_CFG 0x0170 +#define DP83869_OP_MODE 0x01df +#define DP83869_FX_CTRL 0x0c00 + +#define DP83869_SW_RESET BIT(15) +#define DP83869_SW_RESTART BIT(14) + +/* MICR Interrupt bits */ +#define MII_DP83869_MICR_AN_ERR_INT_EN BIT(15) +#define MII_DP83869_MICR_SPEED_CHNG_INT_EN BIT(14) +#define MII_DP83869_MICR_DUP_MODE_CHNG_INT_EN BIT(13) +#define MII_DP83869_MICR_PAGE_RXD_INT_EN BIT(12) +#define MII_DP83869_MICR_AUTONEG_COMP_INT_EN BIT(11) +#define MII_DP83869_MICR_LINK_STS_CHNG_INT_EN BIT(10) +#define MII_DP83869_MICR_FALSE_CARRIER_INT_EN BIT(8) +#define MII_DP83869_MICR_SLEEP_MODE_CHNG_INT_EN BIT(4) +#define MII_DP83869_MICR_WOL_INT_EN BIT(3) +#define MII_DP83869_MICR_XGMII_ERR_INT_EN BIT(2) +#define MII_DP83869_MICR_POL_CHNG_INT_EN BIT(1) +#define MII_DP83869_MICR_JABBER_INT_EN BIT(0) + +#define MII_DP83869_BMCR_DEFAULT (BMCR_ANENABLE | \ + BMCR_FULLDPLX | \ + BMCR_SPEED1000) + +/* This is the same bit mask as the BMCR so re-use the BMCR default */ +#define DP83869_FX_CTRL_DEFAULT MII_DP83869_BMCR_DEFAULT + +/* CFG1 bits */ +#define DP83869_CFG1_DEFAULT (ADVERTISE_1000HALF | \ + ADVERTISE_1000FULL | \ + CTL1000_AS_MASTER) + +/* RGMIICTL bits */ +#define DP83869_RGMII_TX_CLK_DELAY_EN BIT(1) +#define DP83869_RGMII_RX_CLK_DELAY_EN BIT(0) + +/* STRAP_STS1 bits */ +#define DP83869_STRAP_OP_MODE_MASK GENMASK(2, 0) +#define DP83869_STRAP_STS1_RESERVED BIT(11) +#define DP83869_STRAP_MIRROR_ENABLED BIT(12) + +/* PHY CTRL bits */ +#define DP83869_PHYCR_RX_FIFO_DEPTH_SHIFT 12 +#define DP83869_PHYCR_RX_FIFO_DEPTH_MASK GENMASK(13, 12) +#define DP83869_PHYCR_TX_FIFO_DEPTH_SHIFT 14 +#define DP83869_PHYCR_TX_FIFO_DEPTH_MASK GENMASK(15, 14) +#define DP83869_PHYCR_RESERVED_MASK BIT(11) +#define DP83869_PHYCR_MDI_CROSSOVER_SHIFT 5 +#define DP83869_PHYCR_MDI_CROSSOVER_MDIX 2 +#define DP83869_PHY_CTRL_DEFAULT 0x48 + +/* RGMIIDCTL bits */ +#define DP83869_RGMII_TX_CLK_DELAY_SHIFT 4 +#define DP83869_CLK_DELAY_DEF 7 + +/* CFG2 bits */ +#define MII_DP83869_CFG2_SPEEDOPT_10EN 0x0040 +#define MII_DP83869_CFG2_SGMII_AUTONEGEN 0x0080 +#define MII_DP83869_CFG2_SPEEDOPT_ENH 0x0100 +#define MII_DP83869_CFG2_SPEEDOPT_CNT 0x0800 +#define MII_DP83869_CFG2_SPEEDOPT_INTLOW 0x2000 +#define MII_DP83869_CFG2_MASK 0x003F + +/* User setting - can be taken from DTS */ +#define DEFAULT_FIFO_DEPTH DP83869_PHYCR_FIFO_DEPTH_4_B_NIB + +/* IO_MUX_CFG bits */ +#define DP83869_IO_MUX_CFG_IO_IMPEDANCE_CTRL 0x1f + +#define DP83869_IO_MUX_CFG_IO_IMPEDANCE_MAX 0x0 +#define DP83869_IO_MUX_CFG_IO_IMPEDANCE_MIN 0x1f +#define DP83869_IO_MUX_CFG_CLK_O_DISABLE BIT(6) +#define DP83869_IO_MUX_CFG_CLK_O_SEL_SHIFT 8 +#define DP83869_IO_MUX_CFG_CLK_O_SEL_MASK \ + GENMASK(0x1f, DP83869_IO_MUX_CFG_CLK_O_SEL_SHIFT) + +/* CFG3 bits */ +#define DP83869_CFG3_PORT_MIRROR_EN BIT(0) + +/* OP MODE bits */ +#define DP83869_OP_MODE_MII BIT(5) +#define DP83869_SGMII_RGMII_BRIDGE BIT(6) + +enum { + DP83869_PORT_MIRRORING_KEEP, + DP83869_PORT_MIRRORING_EN, + DP83869_PORT_MIRRORING_DIS, +}; + +struct dp83869_private { + int tx_fifo_depth; + int rx_fifo_depth; + s32 rx_int_delay; + s32 tx_int_delay; + int io_impedance; + int port_mirroring; + bool set_clk_output; + int clk_output_sel; + int mode; +}; + +static int dp83869_readext(struct phy_device *phydev, int addr, int devad, int reg) +{ + return phy_read_mmd(phydev, devad, reg); +} + +static int dp83869_writeext(struct phy_device *phydev, int addr, int devad, int reg, u16 val) +{ + return phy_write_mmd(phydev, devad, reg, val); +} + +static int dp83869_config_port_mirroring(struct phy_device *phydev) +{ + struct dp83869_private *dp83869 = + (struct dp83869_private *)phydev->priv; + u16 val; + + val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_CFG4); + + if (dp83869->port_mirroring == DP83869_PORT_MIRRORING_EN) + val |= DP83869_CFG3_PORT_MIRROR_EN; + else + val &= ~DP83869_CFG3_PORT_MIRROR_EN; + + phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_CFG4, val); + + return 0; +} + +#ifdef CONFIG_DM_ETH +static const int dp83869_internal_delay[] = {250, 500, 750, 1000, 1250, 1500, + 1750, 2000, 2250, 2500, 2750, 3000, + 3250, 3500, 3750, 4000}; + +static int dp83869_set_strapped_mode(struct phy_device *phydev) +{ + struct dp83869_private *dp83869 = phydev->priv; + int val; + + val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_STRAP_STS1); + if (val < 0) + return val; + + dp83869->mode = val & DP83869_STRAP_OP_MODE_MASK; + + return 0; +} + +/** + * dp83869_data_init - Convenience function for setting PHY specific data + * + * @phydev: the phy_device struct + */ +static int dp83869_of_init(struct phy_device *phydev) +{ + struct dp83869_private * const dp83869 = phydev->priv; + const int delay_entries = ARRAY_SIZE(dp83869_internal_delay); + int ret; + ofnode node; + + node = phy_get_ofnode(phydev); + if (!ofnode_valid(node)) + return -EINVAL; + + dp83869->io_impedance = -EINVAL; + + /* Optional configuration, set to default if required */ + dp83869->clk_output_sel = ofnode_read_u32_default(node, "ti,clk-output-sel", + DP83869_CLK_O_SEL_CHN_A_RCLK); + + if (dp83869->clk_output_sel > DP83869_CLK_O_SEL_REF_CLK && + dp83869->clk_output_sel != DP83869_CLK_O_SEL_OFF) + dp83869->clk_output_sel = DP83869_CLK_O_SEL_REF_CLK; + + /* If operation mode is not set use setting from straps */ + ret = ofnode_read_s32(node, "ti,op-mode", &dp83869->mode); + if (ret == 0) { + if (dp83869->mode < DP83869_RGMII_COPPER_ETHERNET || + dp83869->mode > DP83869_SGMII_COPPER_ETHERNET) + return -EINVAL; + } else { + ret = dp83869_set_strapped_mode(phydev); + if (ret) + return ret; + } + + if (ofnode_read_bool(node, "ti,max-output-impedance")) + dp83869->io_impedance = DP83869_IO_MUX_CFG_IO_IMPEDANCE_MAX; + else if (ofnode_read_bool(node, "ti,min-output-impedance")) + dp83869->io_impedance = DP83869_IO_MUX_CFG_IO_IMPEDANCE_MIN; + + if (ofnode_read_bool(node, "enet-phy-lane-swap")) { + dp83869->port_mirroring = DP83869_PORT_MIRRORING_EN; + } else { + ret = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_STRAP_STS1); + + if (ret < 0) + return ret; + + if (ret & DP83869_STRAP_MIRROR_ENABLED) + dp83869->port_mirroring = DP83869_PORT_MIRRORING_EN; + else + dp83869->port_mirroring = DP83869_PORT_MIRRORING_DIS; + } + + dp83869->rx_fifo_depth = ofnode_read_s32_default(node, "rx-fifo-depth", + DP83869_PHYCR_FIFO_DEPTH_4_B_NIB); + + dp83869->tx_fifo_depth = ofnode_read_s32_default(node, "tx-fifo-depth", + DP83869_PHYCR_FIFO_DEPTH_4_B_NIB); + + /* RX delay *must* be specified if internal delay of RX is used. */ + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || + phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { + dp83869->rx_int_delay = ofnode_read_u32_default(node, "rx-internal-delay-ps", + DP83869_CLK_DELAY_DEF); + if (dp83869->rx_int_delay > delay_entries) { + dp83869->rx_int_delay = DP83869_CLK_DELAY_DEF; + pr_debug("rx-internal-delay-ps not set/invalid, default to %ups\n", + dp83869_internal_delay[dp83869->rx_int_delay]); + } + + dp83869->rx_int_delay = dp83869_internal_delay[dp83869->rx_int_delay]; + } + + /* TX delay *must* be specified if internal delay of RX is used. */ + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || + phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { + dp83869->tx_int_delay = ofnode_read_u32_default(node, "tx-internal-delay-ps", + DP83869_CLK_DELAY_DEF); + if (dp83869->tx_int_delay > delay_entries) { + dp83869->tx_int_delay = DP83869_CLK_DELAY_DEF; + pr_debug("tx-internal-delay-ps not set/invalid, default to %ups\n", + dp83869_internal_delay[dp83869->tx_int_delay]); + } + + dp83869->tx_int_delay = dp83869_internal_delay[dp83869->tx_int_delay]; + } + + return 0; +} +#else +static int dp83869_of_init(struct phy_device *phydev) +{ + struct dp83869_private *dp83869 = phydev->priv; + + dp83869->rx_int_delay = DP83869_RGMIIDCTL_2_25_NS; + dp83869->tx_int_delay = DP83869_RGMIIDCTL_2_75_NS; + dp83869->fifo_depth = DEFAULT_FIFO_DEPTH; + dp83869->io_impedance = -EINVAL; + + return 0; +} +#endif /* CONFIG_OF_MDIO */ + +static int dp83869_configure_rgmii(struct phy_device *phydev, + struct dp83869_private *dp83869) +{ + int ret = 0, val; + + if (phy_interface_is_rgmii(phydev)) { + val = phy_read(phydev, MDIO_DEVAD_NONE, MII_DP83869_PHYCTRL); + if (val < 0) + return val; + + val &= ~(DP83869_PHYCR_TX_FIFO_DEPTH_MASK | DP83869_PHYCR_RX_FIFO_DEPTH_MASK); + val |= (dp83869->tx_fifo_depth << DP83869_PHYCR_TX_FIFO_DEPTH_SHIFT); + val |= (dp83869->rx_fifo_depth << DP83869_PHYCR_RX_FIFO_DEPTH_SHIFT); + + ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83869_PHYCTRL, val); + if (ret) + return ret; + } + + if (dp83869->io_impedance >= 0) { + val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_IO_MUX_CFG); + + val &= ~DP83869_IO_MUX_CFG_IO_IMPEDANCE_CTRL; + val |= dp83869->io_impedance & DP83869_IO_MUX_CFG_IO_IMPEDANCE_CTRL; + + ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_IO_MUX_CFG, val); + + if (ret) + return ret; + } + + return ret; +} + +static int dp83869_configure_mode(struct phy_device *phydev, + struct dp83869_private *dp83869) +{ + int phy_ctrl_val; + int ret, val; + + if (dp83869->mode < DP83869_RGMII_COPPER_ETHERNET || + dp83869->mode > DP83869_SGMII_COPPER_ETHERNET) + return -EINVAL; + + /* Below init sequence for each operational mode is defined in + * section 9.4.8 of the datasheet. + */ + ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_OP_MODE, + dp83869->mode); + if (ret) + return ret; + + ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, MII_DP83869_BMCR_DEFAULT); + if (ret) + return ret; + + phy_ctrl_val = (dp83869->rx_fifo_depth << DP83869_PHYCR_RX_FIFO_DEPTH_SHIFT | + dp83869->tx_fifo_depth << DP83869_PHYCR_TX_FIFO_DEPTH_SHIFT | + DP83869_PHY_CTRL_DEFAULT); + + switch (dp83869->mode) { + case DP83869_RGMII_COPPER_ETHERNET: + ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83869_PHYCTRL, + phy_ctrl_val); + if (ret) + return ret; + + ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, DP83869_CFG1_DEFAULT); + if (ret) + return ret; + + ret = dp83869_configure_rgmii(phydev, dp83869); + if (ret) + return ret; + break; + case DP83869_RGMII_SGMII_BRIDGE: + val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_OP_MODE); + + val |= DP83869_SGMII_RGMII_BRIDGE; + + ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_OP_MODE, val); + + if (ret) + return ret; + + ret = phy_write_mmd(phydev, DP83869_DEVADDR, + DP83869_FX_CTRL, DP83869_FX_CTRL_DEFAULT); + if (ret) + return ret; + + break; + case DP83869_1000M_MEDIA_CONVERT: + ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83869_PHYCTRL, + phy_ctrl_val); + if (ret) + return ret; + + ret = phy_write_mmd(phydev, DP83869_DEVADDR, + DP83869_FX_CTRL, DP83869_FX_CTRL_DEFAULT); + if (ret) + return ret; + break; + case DP83869_100M_MEDIA_CONVERT: + ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83869_PHYCTRL, + phy_ctrl_val); + if (ret) + return ret; + break; + case DP83869_SGMII_COPPER_ETHERNET: + ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83869_PHYCTRL, + phy_ctrl_val); + if (ret) + return ret; + + ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, DP83869_CFG1_DEFAULT); + if (ret) + return ret; + + ret = phy_write_mmd(phydev, DP83869_DEVADDR, + DP83869_FX_CTRL, DP83869_FX_CTRL_DEFAULT); + if (ret) + return ret; + + break; + default: + return -EINVAL; + } + + return ret; +} + +static int dp83869_config(struct phy_device *phydev) +{ + struct dp83869_private *dp83869; + unsigned int val; + int ret; + + dp83869 = (struct dp83869_private *)phydev->priv; + + ret = dp83869_of_init(phydev); + if (ret) + return ret; + + ret = dp83869_configure_mode(phydev, dp83869); + if (ret) + return ret; + + if (dp83869->port_mirroring != DP83869_PORT_MIRRORING_KEEP) + dp83869_config_port_mirroring(phydev); + + /* Clock output selection if muxing property is set */ + if (dp83869->clk_output_sel != DP83869_CLK_O_SEL_REF_CLK) { + val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_IO_MUX_CFG); + + val &= ~DP83869_IO_MUX_CFG_CLK_O_SEL_MASK; + val |= dp83869->clk_output_sel << DP83869_IO_MUX_CFG_CLK_O_SEL_SHIFT; + + ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_IO_MUX_CFG, val); + + if (ret) + return ret; + } + + if (phy_interface_is_rgmii(phydev)) { + ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIIDCTL, + dp83869->rx_int_delay | + dp83869->tx_int_delay << DP83869_RGMII_TX_CLK_DELAY_SHIFT); + if (ret) + return ret; + + val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIICTL); + val |= (DP83869_RGMII_TX_CLK_DELAY_EN | + DP83869_RGMII_RX_CLK_DELAY_EN); + + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) + val &= ~(DP83869_RGMII_TX_CLK_DELAY_EN | + DP83869_RGMII_RX_CLK_DELAY_EN); + + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) + val &= ~DP83869_RGMII_TX_CLK_DELAY_EN; + + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) + val &= ~DP83869_RGMII_RX_CLK_DELAY_EN; + + ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIICTL, + val); + } + + genphy_config_aneg(phydev); + return 0; +} + +static int dp83869_probe(struct phy_device *phydev) +{ + struct dp83869_private *dp83869; + + dp83869 = kzalloc(sizeof(*dp83869), GFP_KERNEL); + if (!dp83869) + return -ENOMEM; + + phydev->priv = dp83869; + return 0; +} + +static struct phy_driver DP83869_driver = { + .name = "TI DP83869", + .uid = 0x2000a0f1, + .mask = 0xfffffff0, + .features = PHY_GBIT_FEATURES, + .probe = dp83869_probe, + .config = &dp83869_config, + .startup = &genphy_startup, + .shutdown = &genphy_shutdown, + .readext = dp83869_readext, + .writeext = dp83869_writeext +}; + +int phy_dp83869_init(void) +{ + phy_register(&DP83869_driver); + return 0; +} diff --git a/drivers/net/phy/ti_phy_init.c b/drivers/net/phy/ti_phy_init.c index 50eff77692..075b19a39f 100644 --- a/drivers/net/phy/ti_phy_init.c +++ b/drivers/net/phy/ti_phy_init.c @@ -88,6 +88,10 @@ int phy_ti_init(void) phy_dp83867_init(); #endif +#ifdef CONFIG_PHY_TI_DP83869 + phy_dp83869_init(); +#endif + #ifdef CONFIG_PHY_TI_GENERIC phy_register(&dp83822_driver); phy_register(&dp83825s_driver); diff --git a/drivers/net/phy/ti_phy_init.h b/drivers/net/phy/ti_phy_init.h index 6c7f6c640a..bcb3d320d3 100644 --- a/drivers/net/phy/ti_phy_init.h +++ b/drivers/net/phy/ti_phy_init.h @@ -11,5 +11,6 @@ #define _TI_GEN_PHY_H int phy_dp83867_init(void); +int phy_dp83869_init(void); #endif /* _TI_GEN_PHY_H */ diff --git a/drivers/net/sja1105.c b/drivers/net/sja1105.c index 17bab33edd..4ca8709e34 100644 --- a/drivers/net/sja1105.c +++ b/drivers/net/sja1105.c @@ -3276,12 +3276,6 @@ static int sja1105_check_device_id(struct sja1105_private *priv) sja1105_packing(packed_buf, &device_id, 31, 0, SJA1105_SIZE_DEVICE_ID, UNPACK); - if (device_id != priv->info->device_id) { - printf("Expected device ID 0x%llx but read 0x%llx\n", - priv->info->device_id, device_id); - return -ENODEV; - } - rc = sja1105_xfer_buf(priv, SPI_READ, regs->prod_id, packed_buf, SJA1105_SIZE_DEVICE_ID); if (rc < 0) diff --git a/include/dt-bindings/net/ti-dp83869.h b/include/dt-bindings/net/ti-dp83869.h new file mode 100644 index 0000000000..b3a5ac4a17 --- /dev/null +++ b/include/dt-bindings/net/ti-dp83869.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * TI DP83869 PHY drivers + * + */ + +#ifndef _DT_BINDINGS_TI_DP83869_H +#define _DT_BINDINGS_TI_DP83869_H + +/* PHY CTRL bits */ +#define DP83869_PHYCR_FIFO_DEPTH_3_B_NIB 0x00 +#define DP83869_PHYCR_FIFO_DEPTH_4_B_NIB 0x01 +#define DP83869_PHYCR_FIFO_DEPTH_6_B_NIB 0x02 +#define DP83869_PHYCR_FIFO_DEPTH_8_B_NIB 0x03 + +/* RGMIIDCTL internal delay for rx and tx */ +#define DP83869_RGMIIDCTL_250_PS 0x0 +#define DP83869_RGMIIDCTL_500_PS 0x1 +#define DP83869_RGMIIDCTL_750_PS 0x2 +#define DP83869_RGMIIDCTL_1_NS 0x3 +#define DP83869_RGMIIDCTL_1_25_NS 0x4 +#define DP83869_RGMIIDCTL_1_50_NS 0x5 +#define DP83869_RGMIIDCTL_1_75_NS 0x6 +#define DP83869_RGMIIDCTL_2_00_NS 0x7 +#define DP83869_RGMIIDCTL_2_25_NS 0x8 +#define DP83869_RGMIIDCTL_2_50_NS 0x9 +#define DP83869_RGMIIDCTL_2_75_NS 0xa +#define DP83869_RGMIIDCTL_3_00_NS 0xb +#define DP83869_RGMIIDCTL_3_25_NS 0xc +#define DP83869_RGMIIDCTL_3_50_NS 0xd +#define DP83869_RGMIIDCTL_3_75_NS 0xe +#define DP83869_RGMIIDCTL_4_00_NS 0xf + +/* IO_MUX_CFG - Clock output selection */ +#define DP83869_CLK_O_SEL_CHN_A_RCLK 0x0 +#define DP83869_CLK_O_SEL_CHN_B_RCLK 0x1 +#define DP83869_CLK_O_SEL_CHN_C_RCLK 0x2 +#define DP83869_CLK_O_SEL_CHN_D_RCLK 0x3 +#define DP83869_CLK_O_SEL_CHN_A_RCLK_DIV5 0x4 +#define DP83869_CLK_O_SEL_CHN_B_RCLK_DIV5 0x5 +#define DP83869_CLK_O_SEL_CHN_C_RCLK_DIV5 0x6 +#define DP83869_CLK_O_SEL_CHN_D_RCLK_DIV5 0x7 +#define DP83869_CLK_O_SEL_CHN_A_TCLK 0x8 +#define DP83869_CLK_O_SEL_CHN_B_TCLK 0x9 +#define DP83869_CLK_O_SEL_CHN_C_TCLK 0xA +#define DP83869_CLK_O_SEL_CHN_D_TCLK 0xB +#define DP83869_CLK_O_SEL_REF_CLK 0xC +/* Special flag to indicate clock should be off */ +#define DP83869_CLK_O_SEL_OFF 0xFFFFFFFF + +/* OPMODE - Operation mode */ +#define DP83869_RGMII_COPPER_ETHERNET 0x00 +#define DP83869_RGMII_1000_BASE 0x01 +#define DP83869_RGMII_100_BASE 0x02 +#define DP83869_RGMII_SGMII_BRIDGE 0x03 +#define DP83869_1000M_MEDIA_CONVERT 0x04 +#define DP83869_100M_MEDIA_CONVERT 0x05 +#define DP83869_SGMII_COPPER_ETHERNET 0x06 + +#endif diff --git a/include/fsl_memac.h b/include/fsl_memac.h index d067f1511c..6ac1e558b9 100644 --- a/include/fsl_memac.h +++ b/include/fsl_memac.h @@ -254,7 +254,6 @@ struct memac_mdio_controller { #define MDIO_CTL_READ (1 << 15) #define MDIO_DATA(x) (x & 0xffff) -#define MDIO_DATA_BSY (1 << 31) struct fsl_enet_mac; diff --git a/net/dsa-uclass.c b/net/dsa-uclass.c index 606b1539a7..9ff55a02fb 100644 --- a/net/dsa-uclass.c +++ b/net/dsa-uclass.c @@ -466,6 +466,8 @@ static int dsa_pre_probe(struct udevice *dev) { struct dsa_pdata *pdata = dev_get_uclass_plat(dev); struct dsa_priv *priv = dev_get_uclass_priv(dev); + struct dsa_ops *ops = dsa_get_ops(dev); + int err; priv->num_ports = pdata->num_ports; priv->cpu_port = pdata->cpu_port; @@ -477,6 +479,15 @@ static int dsa_pre_probe(struct udevice *dev) uclass_find_device_by_ofnode(UCLASS_ETH, pdata->master_node, &priv->master_dev); + + /* Simulate a probing event for the CPU port */ + if (ops->port_probe) { + err = ops->port_probe(dev, priv->cpu_port, + priv->cpu_port_fixed_phy); + if (err) + return err; + } + return 0; } diff --git a/net/fastboot.c b/net/fastboot.c index 7e7a601b9f..139233b86c 100644 --- a/net/fastboot.c +++ b/net/fastboot.c @@ -9,9 +9,6 @@ #include <net.h> #include <net/fastboot.h> -/* Fastboot port # defined in spec */ -#define WELL_KNOWN_PORT 5554 - enum { FASTBOOT_ERROR = 0, FASTBOOT_QUERY = 1, @@ -310,7 +307,7 @@ void fastboot_start_server(void) printf("Using %s device\n", eth_get_name()); printf("Listening for fastboot command on %pI4\n", &net_ip); - fastboot_our_port = WELL_KNOWN_PORT; + fastboot_our_port = CONFIG_UDP_FUNCTION_FASTBOOT_PORT; #if CONFIG_IS_ENABLED(FASTBOOT_FLASH) fastboot_set_progress_callback(fastboot_timed_send_info); |