Merge branch 'master' of git://git.denx.de/u-boot-net
- Basic bug fixes and minor features for 2019.07.
This commit is contained in:
commit
55cae6458d
66
Documentation/devicetree/bindings/net/ethernet.txt
Normal file
66
Documentation/devicetree/bindings/net/ethernet.txt
Normal file
@ -0,0 +1,66 @@
|
||||
The following properties are common to the Ethernet controllers:
|
||||
|
||||
NOTE: All 'phy*' properties documented below are Ethernet specific. For the
|
||||
generic PHY 'phys' property, see
|
||||
Documentation/devicetree/bindings/phy/phy-bindings.txt.
|
||||
|
||||
- local-mac-address: array of 6 bytes, specifies the MAC address that was
|
||||
assigned to the network device;
|
||||
- mac-address: array of 6 bytes, specifies the MAC address that was last used by
|
||||
the boot program; should be used in cases where the MAC address assigned to
|
||||
the device by the boot program is different from the "local-mac-address"
|
||||
property;
|
||||
- nvmem-cells: phandle, reference to an nvmem node for the MAC address;
|
||||
- nvmem-cell-names: string, should be "mac-address" if nvmem is to be used;
|
||||
- max-speed: number, specifies maximum speed in Mbit/s supported by the device;
|
||||
- max-frame-size: number, maximum transfer unit (IEEE defined MTU), rather than
|
||||
the maximum frame size (there's contradiction in the Devicetree
|
||||
Specification).
|
||||
- phy-mode: string, operation mode of the PHY interface. This is now a de-facto
|
||||
standard property; supported values are:
|
||||
* "internal"
|
||||
* "mii"
|
||||
* "gmii"
|
||||
* "sgmii"
|
||||
* "qsgmii"
|
||||
* "tbi"
|
||||
* "rev-mii"
|
||||
* "rmii"
|
||||
* "rgmii" (RX and TX delays are added by the MAC when required)
|
||||
* "rgmii-id" (RGMII with internal RX and TX delays provided by the PHY, the
|
||||
MAC should not add the RX or TX delays in this case)
|
||||
* "rgmii-rxid" (RGMII with internal RX delay provided by the PHY, the MAC
|
||||
should not add an RX delay in this case)
|
||||
* "rgmii-txid" (RGMII with internal TX delay provided by the PHY, the MAC
|
||||
should not add an TX delay in this case)
|
||||
* "rtbi"
|
||||
* "smii"
|
||||
* "xgmii"
|
||||
* "trgmii"
|
||||
* "2000base-x",
|
||||
* "2500base-x",
|
||||
* "rxaui"
|
||||
* "xaui"
|
||||
* "10gbase-kr" (10GBASE-KR, XFI, SFI)
|
||||
- phy-connection-type: the same as "phy-mode" property but described in the
|
||||
Devicetree Specification;
|
||||
- phy-handle: phandle, specifies a reference to a node representing a PHY
|
||||
device; this property is described in the Devicetree Specification and so
|
||||
preferred;
|
||||
- phy: the same as "phy-handle" property, not recommended for new bindings.
|
||||
- phy-device: the same as "phy-handle" property, not recommended for new
|
||||
bindings.
|
||||
- rx-fifo-depth: the size of the controller's receive fifo in bytes. This
|
||||
is used for components that can have configurable receive fifo sizes,
|
||||
and is useful for determining certain configuration settings such as
|
||||
flow control thresholds.
|
||||
- tx-fifo-depth: the size of the controller's transmit fifo in bytes. This
|
||||
is used for components that can have configurable fifo sizes.
|
||||
- managed: string, specifies the PHY management type. Supported values are:
|
||||
"auto", "in-band-status". "auto" is the default, it usess MDIO for
|
||||
management if fixed-link is not specified.
|
||||
|
||||
Child nodes of the Ethernet controller are typically the individual PHY devices
|
||||
connected via the MDIO bus (sometimes the MDIO bus controller is separate).
|
||||
They are described in the phy.txt file in this same directory.
|
||||
For non-MDIO PHY management see fixed-link.txt.
|
@ -28,6 +28,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
|
||||
imply CMD_PING
|
||||
imply CLK_SIFIVE
|
||||
imply CLK_SIFIVE_FU540_PRCI
|
||||
imply CLK_SIFIVE_GEMGXL_MGMT
|
||||
imply DOS_PARTITION
|
||||
imply EFI_PARTITION
|
||||
imply IP_DYN
|
||||
|
@ -54,7 +54,10 @@ static int mdio_write_ranges(struct mii_dev *bus,
|
||||
|
||||
for (devad = devadlo; devad <= devadhi; devad++) {
|
||||
for (reg = reglo; reg <= reghi; reg++) {
|
||||
if (!extended)
|
||||
if (!phydev)
|
||||
err = bus->write(bus, addr, devad,
|
||||
reg, data);
|
||||
else if (!extended)
|
||||
err = phy_write_mmd(phydev, devad,
|
||||
reg, data);
|
||||
else
|
||||
@ -88,7 +91,9 @@ static int mdio_read_ranges(struct mii_dev *bus,
|
||||
for (reg = reglo; reg <= reghi; reg++) {
|
||||
int val;
|
||||
|
||||
if (!extended)
|
||||
if (!phydev)
|
||||
val = bus->read(bus, addr, devad, reg);
|
||||
else if (!extended)
|
||||
val = phy_read_mmd(phydev, devad, reg);
|
||||
else
|
||||
val = phydev->drv->readext(phydev, addr,
|
||||
|
@ -17,3 +17,10 @@ config CLK_SIFIVE_FU540_PRCI
|
||||
Supports the Power Reset Clock interface (PRCI) IP block found in
|
||||
FU540 SoCs. If this kernel is meant to run on a SiFive FU540 SoC,
|
||||
enable this driver.
|
||||
|
||||
config CLK_SIFIVE_GEMGXL_MGMT
|
||||
bool "GEMGXL management for SiFive FU540 SoCs"
|
||||
depends on CLK_SIFIVE
|
||||
help
|
||||
Supports the GEMGXL management IP block found in FU540 SoCs to
|
||||
control GEM TX clock operation mode for 10/100/1000 Mbps.
|
||||
|
@ -3,3 +3,5 @@
|
||||
obj-$(CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC) += wrpll-cln28hpc.o
|
||||
|
||||
obj-$(CONFIG_CLK_SIFIVE_FU540_PRCI) += fu540-prci.o
|
||||
|
||||
obj-$(CONFIG_CLK_SIFIVE_GEMGXL_MGMT) += gemgxl-mgmt.o
|
||||
|
60
drivers/clk/sifive/gemgxl-mgmt.c
Normal file
60
drivers/clk/sifive/gemgxl-mgmt.c
Normal file
@ -0,0 +1,60 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2019, Bin Meng <bmeng.cn@gmail.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <clk-uclass.h>
|
||||
#include <dm.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
struct gemgxl_mgmt_regs {
|
||||
__u32 tx_clk_sel;
|
||||
};
|
||||
|
||||
struct gemgxl_mgmt_platdata {
|
||||
struct gemgxl_mgmt_regs *regs;
|
||||
};
|
||||
|
||||
static int gemgxl_mgmt_ofdata_to_platdata(struct udevice *dev)
|
||||
{
|
||||
struct gemgxl_mgmt_platdata *plat = dev_get_platdata(dev);
|
||||
|
||||
plat->regs = (struct gemgxl_mgmt_regs *)dev_read_addr(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ulong gemgxl_mgmt_set_rate(struct clk *clk, ulong rate)
|
||||
{
|
||||
struct gemgxl_mgmt_platdata *plat = dev_get_platdata(clk->dev);
|
||||
|
||||
/*
|
||||
* GEMGXL TX clock operation mode:
|
||||
*
|
||||
* 0 = GMII mode. Use 125 MHz gemgxlclk from PRCI in TX logic
|
||||
* and output clock on GMII output signal GTX_CLK
|
||||
* 1 = MII mode. Use MII input signal TX_CLK in TX logic
|
||||
*/
|
||||
writel(rate != 125000000, &plat->regs->tx_clk_sel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct clk_ops gemgxl_mgmt_ops = {
|
||||
.set_rate = gemgxl_mgmt_set_rate,
|
||||
};
|
||||
|
||||
static const struct udevice_id gemgxl_mgmt_match[] = {
|
||||
{ .compatible = "sifive,cadencegemgxlmgmt0", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sifive_gemgxl_mgmt) = {
|
||||
.name = "sifive-gemgxl-mgmt",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = gemgxl_mgmt_match,
|
||||
.ofdata_to_platdata = gemgxl_mgmt_ofdata_to_platdata,
|
||||
.platdata_auto_alloc_size = sizeof(struct gemgxl_mgmt_platdata),
|
||||
.ops = &gemgxl_mgmt_ops,
|
||||
};
|
@ -488,15 +488,58 @@ static int macb_phy_find(struct macb_device *macb, const char *name)
|
||||
|
||||
/**
|
||||
* macb_linkspd_cb - Linkspeed change callback function
|
||||
* @regs: Base Register of MACB devices
|
||||
* @dev/@regs: MACB udevice (DM version) or
|
||||
* Base Register of MACB devices (non-DM version)
|
||||
* @speed: Linkspeed
|
||||
* Returns 0 when operation success and negative errno number
|
||||
* when operation failed.
|
||||
*/
|
||||
#ifdef CONFIG_DM_ETH
|
||||
int __weak macb_linkspd_cb(struct udevice *dev, unsigned int speed)
|
||||
{
|
||||
#ifdef CONFIG_CLK
|
||||
struct clk tx_clk;
|
||||
ulong rate;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* "tx_clk" is an optional clock source for MACB.
|
||||
* Ignore if it does not exist in DT.
|
||||
*/
|
||||
ret = clk_get_by_name(dev, "tx_clk", &tx_clk);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
switch (speed) {
|
||||
case _10BASET:
|
||||
rate = 2500000; /* 2.5 MHz */
|
||||
break;
|
||||
case _100BASET:
|
||||
rate = 25000000; /* 25 MHz */
|
||||
break;
|
||||
case _1000BASET:
|
||||
rate = 125000000; /* 125 MHz */
|
||||
break;
|
||||
default:
|
||||
/* does not change anything */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tx_clk.dev) {
|
||||
ret = clk_set_rate(&tx_clk, rate);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int __weak macb_linkspd_cb(void *regs, unsigned int speed)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DM_ETH
|
||||
static int macb_phy_init(struct udevice *dev, const char *name)
|
||||
@ -589,7 +632,11 @@ static int macb_phy_init(struct macb_device *macb, const char *name)
|
||||
|
||||
macb_writel(macb, NCFGR, ncfgr);
|
||||
|
||||
#ifdef CONFIG_DM_ETH
|
||||
ret = macb_linkspd_cb(dev, _1000BASET);
|
||||
#else
|
||||
ret = macb_linkspd_cb(macb->regs, _1000BASET);
|
||||
#endif
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -614,9 +661,17 @@ static int macb_phy_init(struct macb_device *macb, const char *name)
|
||||
ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD) | GEM_BIT(GBE));
|
||||
if (speed) {
|
||||
ncfgr |= MACB_BIT(SPD);
|
||||
#ifdef CONFIG_DM_ETH
|
||||
ret = macb_linkspd_cb(dev, _100BASET);
|
||||
#else
|
||||
ret = macb_linkspd_cb(macb->regs, _100BASET);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef CONFIG_DM_ETH
|
||||
ret = macb_linkspd_cb(dev, _10BASET);
|
||||
#else
|
||||
ret = macb_linkspd_cb(macb->regs, _10BASET);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ret)
|
||||
|
@ -455,6 +455,26 @@ static int eth_pre_unbind(struct udevice *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool eth_dev_get_mac_address(struct udevice *dev, u8 mac[ARP_HLEN])
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_OF_CONTROL)
|
||||
const uint8_t *p;
|
||||
|
||||
p = dev_read_u8_array_ptr(dev, "mac-address", ARP_HLEN);
|
||||
if (!p)
|
||||
p = dev_read_u8_array_ptr(dev, "local-mac-address", ARP_HLEN);
|
||||
|
||||
if (!p)
|
||||
return false;
|
||||
|
||||
memcpy(mac, p, ARP_HLEN);
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int eth_post_probe(struct udevice *dev)
|
||||
{
|
||||
struct eth_device_priv *priv = dev->uclass_priv;
|
||||
@ -489,9 +509,13 @@ static int eth_post_probe(struct udevice *dev)
|
||||
|
||||
priv->state = ETH_STATE_INIT;
|
||||
|
||||
/* Check if the device has a MAC address in ROM */
|
||||
if (eth_get_ops(dev)->read_rom_hwaddr)
|
||||
eth_get_ops(dev)->read_rom_hwaddr(dev);
|
||||
/* Check if the device has a valid MAC address in device tree */
|
||||
if (!eth_dev_get_mac_address(dev, pdata->enetaddr) ||
|
||||
!is_valid_ethaddr(pdata->enetaddr)) {
|
||||
/* Check if the device has a MAC address in ROM */
|
||||
if (eth_get_ops(dev)->read_rom_hwaddr)
|
||||
eth_get_ops(dev)->read_rom_hwaddr(dev);
|
||||
}
|
||||
|
||||
eth_env_get_enetaddr_by_index("eth", dev->seq, env_enetaddr);
|
||||
if (!is_zero_ethaddr(env_enetaddr)) {
|
||||
@ -524,6 +548,8 @@ static int eth_post_probe(struct udevice *dev)
|
||||
#endif
|
||||
}
|
||||
|
||||
eth_write_hwaddr(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user