香橙派orangepi 4 lts开发板的有线网卡是裕泰YT8531C,最近想在u-boot中开启有线网络功能,以便使用tftp加载内核和设备树。

orangepi-build的u-boot中默认已经使能了gmac,

arch/arm/dts/rk3399-orangepi-4.dts
&gmac {
        phy-supply = <&vcc_phy>;
        phy-mode = "rgmii";
        clock_in_out = "input";
        snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
        snps,reset-active-low;
        snps,reset-delays-us = <0 10000 50000>;
        assigned-clocks = <&cru SCLK_RMII_SRC>;
        assigned-clock-parents = <&clkin_gmac>;
        pinctrl-names = "default";
        pinctrl-0 = <&rgmii_pins>;
        tx_delay = <0x28>;
        rx_delay = <0x11>;
        status = "okay";
};

所以只需要添加phy驱动。

进入orangepi-build/u-boot/v2020.10-rockchip64目录。
在driver/net/phy/Makefile中加入

diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 6e722331..103d58cb 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -33,3 +33,4 @@ obj-$(CONFIG_PHY_VITESSE) += vitesse.o
 obj-$(CONFIG_PHY_MSCC) += mscc.o
 obj-$(CONFIG_PHY_FIXED) += fixed.o
 obj-$(CONFIG_PHY_NCSI) += ncsi.o
+obj-$(CONFIG_PHY_YUTAI) += motorcomm.o

在driver/net/phy/Kconfig中加入

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 4e1a93be..7ef159c9 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -247,6 +247,9 @@ config RTL8201F_PHY_S700_RMII_TIMINGS
 config PHY_SMSC
        bool  "Microchip(SMSC) Ethernet PHYs support"
 
+config PHY_YUTAI
+       bool  "YUTAI Ethernet PHYs support"
+
 config PHY_TERANETICS
        bool "Teranetics Ethernet PHYs support"

在driver/net/phy/phy.c中加入

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index f6d478fd..e85919f8 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -553,6 +553,9 @@ int phy_init(void)
 #endif
 #ifdef CONFIG_PHY_XILINX_GMII2RGMII
        phy_xilinx_gmii2rgmii_init();
+#endif
+#ifdef CONFIG_PHY_YUTAI
+       phy_yutai_init();
 #endif
        genphy_init();

u-boot中yt8531c 驱动driver/net/phy/motorcomm.c,参考u-boot中的realtek和linux中的yt8531c驱动创建如下:

#include <common.h>
#include <linux/bitops.h>
#include <phy.h>
#include <linux/delay.h>

#define PHY_ID_YT8531		0x4f51e91b
#define MOTORCOMM_PHY_ID_MASK	0x00000fff
/* yt8531c PHY Status Register */
#define REG_PHY_SPEC_STATUS		0x11
#define REG_DEBUG_ADDR_OFFSET		0x1e
#define REG_DEBUG_DATA			0x1f

#define EXTREG_SLEEP_CONTROL            0x27
#define EXTREG_SYNCE_CFG                0xa012

#define PHY_AUTONEGOTIATE_TIMEOUT       5000

#define YT8531_SPEED_MODE_BIT_MASK      0xc000
#define YT8531_PHYSTAT_1000_BIT         0x8000
#define YT8531_PHYSTAT_100_BIT          0x4000
#define YT8531_DUPLEX_BIT_MASK		0x2000
#define YT8531_LINK_STATUS_BIT_MASK     0x0400

static int ytphy_read_ext(struct phy_device *phydev, int regnum)
{
	int ret;
	int val;

	ret = phy_write(phydev, MDIO_DEVAD_NONE, REG_DEBUG_ADDR_OFFSET, regnum);
	if (ret < 0)
		return ret;

	val = phy_read(phydev, MDIO_DEVAD_NONE, REG_DEBUG_DATA);

	return val;
}

static int ytphy_write_ext(struct phy_device *phydev, int regnum, u16 val)
{
	int ret;

	ret = phy_write(phydev, MDIO_DEVAD_NONE, REG_DEBUG_ADDR_OFFSET, regnum);
	if (ret < 0)
		return ret;

	ret = phy_write(phydev, MDIO_DEVAD_NONE, REG_DEBUG_DATA, val);

	return ret;
}

static int yt8531c_probe(struct phy_device *phydev)
{
#ifdef CONFIG_YT8531C_PHY_FORCE_EEE_RXC_ON
	phydev->flags |= PHY_YT8531C_FORCE_EEE_RXC_ON;
#endif

	return 0;
}

int yt8531_config_out_125m(struct phy_device *phydev)
{
	int val;
	int ret;

	mdelay(100);
	ytphy_write_ext(phydev, EXTREG_SYNCE_CFG, 0xd0);
	mdelay(100);
	val = ytphy_read_ext(phydev, EXTREG_SYNCE_CFG);
	if (val != 0xd0) {
		printf("yt8531 config out 125m error\n");
		return -1;
	}

	/* disable auto sleep */
	val = ytphy_read_ext(phydev, EXTREG_SLEEP_CONTROL);
	val &= (~BIT(15));
	ret = ytphy_write_ext(phydev, EXTREG_SLEEP_CONTROL, val);
	if (ret < 0)
		return ret;
	/* enable RXC clock when no wire plug */
	val = ytphy_read_ext(phydev, 0xc);
	if (val < 0)
		return val;
	val |= (3 << 1);
	ret = ytphy_write_ext(phydev, 0xc, val);
	//printf("yt8531 config out 125m, phy clk out, val = %#08x\n", val);
	return ret;
}


static int yt8531c_config(struct phy_device *phydev)
{
	int ret;

	printf("YT8531C\n");

	ret = yt8531_config_out_125m(phydev);
	genphy_config_aneg(phydev);

	return ret;
}

static int yt8531c_parse_status(struct phy_device *phydev)
{
	unsigned int speed;
	unsigned int mii_reg;
	int i = 0;

	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, REG_PHY_SPEC_STATUS);

	phydev->link = 1;
	while (!(mii_reg & YT8531_LINK_STATUS_BIT_MASK)) {
		if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
			puts(" TIMEOUT !\n");
			phydev->link = 0;
			break;
		}

		if ((i++ % 1000) == 0)
			putc('.');
		udelay(1000);
		mii_reg = phy_read(phydev, MDIO_DEVAD_NONE,
				REG_PHY_SPEC_STATUS);
	}

	if (mii_reg & YT8531_DUPLEX_BIT_MASK)
		phydev->duplex = DUPLEX_FULL;
	else
		phydev->duplex = DUPLEX_HALF;

	speed = (mii_reg & YT8531_SPEED_MODE_BIT_MASK);

	switch (speed) {
		case YT8531_PHYSTAT_1000_BIT:
			phydev->speed = SPEED_1000;
			break;
		case YT8531_PHYSTAT_100_BIT:
			phydev->speed = SPEED_100;
			break;
		default:
			phydev->speed = SPEED_10;
	}

	return 0;
}

static int yt8531c_startup(struct phy_device *phydev)
{
	int ret;

	ret = genphy_update_link(phydev);
	if (ret)
		return ret;
	/* Read the Status (2x to make sure link is right) */
	return yt8531c_parse_status(phydev);
}

/* Support for yt8531c PHY */
static struct phy_driver yt8531c_driver = {
	.name = "YUTAI yt8531c",
	.uid = PHY_ID_YT8531,
	.mask = MOTORCOMM_PHY_ID_MASK,
	.features = PHY_GBIT_FEATURES,
	.probe = &yt8531c_probe,
	.config = &yt8531c_config,
	.startup = &yt8531c_startup,
	.shutdown = &genphy_shutdown,
	.readext = &ytphy_read_ext,
	.writeext = &ytphy_write_ext,
};

int phy_yutai_init(void)
{
	phy_register(&yt8531c_driver);

	return 0;
}

现在u-boot中已经可以使用有线网络了。

U-Boot 2020.10-orangepi (Mar 24 2024 - 15:34:14 +0800)

Model: OrangePi 4 AI board
DRAM:  3.9 GiB
MMC:   mmc@fe320000: 1, sdhci@fe330000: 0
Loading Environment from MMC... OK
In:    serial
Out:   serial
Err:   serial
Model: OrangePi 4 AI board
Net:   YT8531C
eth0: ethernet@fe300000
Hit any key to stop autoboot:  0 
=> 
=> 
=> ping 192.168.2.9
Speed: 1000, full duplex
Using ethernet@fe300000 device
host 192.168.2.9 is alive
=> 
=> tftp 20008000 uImage
Speed: 1000, full duplex
Using ethernet@fe300000 device
TFTP from server 192.168.2.9; our IP address is 192.168.2.88
Filename 'uImage'.
Load address: 0x20008000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #####################################
         4.3 MiB/s
done
Bytes transferred = 4345760 (424fa0 hex)
=>
Logo

昇腾计算产业是基于昇腾系列(HUAWEI Ascend)处理器和基础软件构建的全栈 AI计算基础设施、行业应用及服务,https://devpress.csdn.net/organization/setting/general/146749包括昇腾系列处理器、系列硬件、CANN、AI计算框架、应用使能、开发工具链、管理运维工具、行业应用及服务等全产业链

更多推荐