RK3566 Android 11平台上适配YT8512C 100M PHY

bash 复制代码
RK3566代码之前适配的1000M IC RTL8211F ,
现在需要在之前的基础上修改PHY IC 为裕泰的YT8512C
----------------------------------------------------------------------

+//将1000M 的配置关掉,改为100M 配置,查看RK3566 资料关于以太网的配置即可知道如何修改
#if 0
&gmac1 {
	phy-mode = "rgmii";
	clock_in_out = "input";

	snps,reset-gpio = <&gpio4 RK_PC2 GPIO_ACTIVE_LOW>;
	snps,reset-active-low;
	/* Reset time is 20ms, 100ms for rtl8211f */
	snps,reset-delays-us = <0 20000 100000>;

	assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
	assigned-clock-parents =  <&cru SCLK_GMAC1_RGMII_SPEED>, <&gmac1_clkin>;

	assigned-clock-rates = <0>, <125000000>;
	pinctrl-names = "default";
	pinctrl-0 = <&gmac1m1_miim
		     &gmac1m1_tx_bus2
		     &gmac1m1_rx_bus2
		     &gmac1m1_rgmii_clk
		     &gmac1m1_rgmii_bus
		     &gmac1m1_clkinout>;

	tx_delay = <0x4b>;
	rx_delay = <0x2b>;

	phy-handle = <&rgmii_phy1>;
	status = "okay";
};
#else
//gmac1m0
&gmac1_clkin {
        clock-frequency = <50000000>;
};
&gmac1 {
        phy-mode = "rmii";
        clock_in_out = "input";

	snps,reset-gpio = <&gpio4 RK_PC2 GPIO_ACTIVE_LOW>;
        snps,reset-active-low;
        /* Reset time is 20ms, 100ms for rtl8211f */
        snps,reset-delays-us = <0 20000 100000>;

        assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
        assigned-clock-parents = <&cru SCLK_GMAC1_RMII_SPEED>, <&gmac1_clkin>;
	//assigned-clock-rates = <0>, <50000000>;

        pinctrl-names = "default";
        pinctrl-0 = <&gmac1m0_miim
                     &gmac1m0_clkinout
                     &gmac1m0_tx_bus2
                     &gmac1m0_rx_bus2>;
        //tx_delay = <0x4f>;
        //rx_delay = <0x26>;
        phy-handle = <&rmii_phy1>;
        status = "okay";
};

#endif

+//rgmii 1000M 改为100M
-&mdio1 {
-	rgmii_phy1: phy@0 {
-		compatible = "ethernet-phy-ieee802.3-c22";
-		reg = <0x0>;
-	};
-};

+&mdio1 {
+	rmii_phy1: phy@0 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x0>;
+	};
+};



//修改1000M 为100M ETH 的VDDIO 需要从1.8V 改为3.3V
&pmu_io_domains {
	status = "okay";
	pmuio2-supply = <&vcc_3v3>;
	vccio1-supply = <&vcc_3v3>;
	vccio3-supply = <&vcc_3v3>;
	vccio4-supply = <&vcc_1v8>;
	vccio5-supply = <&vcc_3v3>;
    -vccio6-supply = <&vcc_1v8>;
	+vccio6-supply = <&vcc_3v3>;
	vccio7-supply = <&vcc_3v3>;
};


-----------------------------
[   23.957084] rk_gmac-dwmac fe010000.ethernet eth0: No Safety Features support found
[   23.957124] rk_gmac-dwmac fe010000.ethernet eth0: IEEE 1588-2008 Advanced Timestamp supported
[   23.958316] rk_gmac-dwmac fe010000.ethernet eth0: registered PTP clock
[   23.960237] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready

[ 1609.817567] rk_gmac-dwmac fe010000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[ 1609.817709] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
-----------------------------
参照文档修改,发现以太网初始化正常,节点eth0 正常生成,也能够ping通数据



2.接下来需要修改 以太网的网络接口状态灯:
  根据数据规格书:
  LED0 0x40c0寄存器写0x30 
  LED1 0x40c3寄存器写0x1300

commit bd71fd55f47f18acb35f8974ebaf6dd696ba7738
Author: amediatech <jiangsai@amediatech.cn>
Date:   Wed Dec 27 17:53:17 2023 +0800

    modify led control

diff --git a/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index e75d44b987..f1f304e6f2 100644
--- a/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -26,6 +26,7 @@
 
 #include <linux/clk.h>
 #include <linux/kernel.h>
+#include <linux/version.h>
 #include <linux/interrupt.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
@@ -57,7 +58,21 @@
 
 #define	STMMAC_ALIGN(x)		ALIGN(ALIGN(x, SMP_CACHE_BYTES), 16)
 #define	TSO_MAX_BUFF_SIZE	(SZ_16K - 1)
-
+#define REG_DEBUG_ADDR_OFFSET           0x1e
+#define REG_DEBUG_DATA                  0x1f
+#define YT8512_LED0_ACT_BLK_IND         0x1000
+#define YT8512_LED0_DIS_LED_AN_TRY      0x0001
+#define YT8512_LED0_BT_BLK_EN           0x0002
+#define YT8512_LED0_HT_BLK_EN           0x0004
+#define YT8512_LED0_COL_BLK_EN          0x0008
+#define YT8512_LED0_BT_ON_EN            0x0010
+#define YT8512_LED1_BT_ON_EN            0x0010
+#define YT8512_LED1_TXACT_BLK_EN        0x0100
+#define YT8512_LED1_RXACT_BLK_EN        0x0200
+#define YT8512_EXTREG_LED0              0x40c0
+#define YT8512_EXTREG_LED1              0x40c3
+//#define RTL_8211F_PHY_ID        0x001cc916
+#define YT8512C_PHY_ID	0x00000128
 /* Module parameters */
 #define TX_TIMEO	5000
 static int watchdog = TX_TIMEO;
@@ -4270,6 +4285,122 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
 
 	return 0;
 }
+#if (KERNEL_VERSION(5, 5, 0) > LINUX_VERSION_CODE)
+static inline void phy_lock_mdio_bus(struct phy_device *phydev)
+{
+#if (KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE)
+    mutex_lock(&phydev->bus->mdio_lock);
+#else
+    mutex_lock(&phydev->mdio.bus->mdio_lock);
+#endif
+}
+ 
+static inline void phy_unlock_mdio_bus(struct phy_device *phydev)
+{
+#if (KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE)
+    mutex_unlock(&phydev->bus->mdio_lock);
+#else
+    mutex_unlock(&phydev->mdio.bus->mdio_lock);
+#endif
+}
+#endif
+
+#if (KERNEL_VERSION(4, 16, 0) > LINUX_VERSION_CODE)
+static inline int __phy_read(struct phy_device *phydev, u32 regnum)
+{
+#if (KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE)
+        struct mii_bus *bus = phydev->bus;
+        int addr = phydev->addr;
+        return bus->read(bus, phydev->addr, regnum);
+#else
+        struct mii_bus *bus = phydev->mdio.bus;
+        int addr = phydev->mdio.addr;
+#endif
+        return bus->read(bus, addr, regnum);
+}
+
+static inline int __phy_write(struct phy_device *phydev, u32 regnum, u16 val)
+{
+#if (KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE)
+        struct mii_bus *bus = phydev->bus;
+        int addr = phydev->addr;
+#else
+        struct mii_bus *bus = phydev->mdio.bus;
+        int addr = phydev->mdio.addr;
+#endif
+        return bus->write(bus, addr, regnum, val);
+}
+#endif
+
+static int ytphy_read_ext(struct phy_device *phydev, u32 regnum)
+{
+    int ret;
+    
+    phy_lock_mdio_bus(phydev);
+    ret = __phy_write(phydev, REG_DEBUG_ADDR_OFFSET, regnum);
+    if (ret < 0)
+        goto err_handle;
+ 
+    ret = __phy_read(phydev, REG_DEBUG_DATA);
+    if (ret < 0)
+        goto err_handle;
+    
+err_handle:
+    phy_unlock_mdio_bus(phydev);
+    return ret;
+}
+ 
+static int ytphy_write_ext(struct phy_device *phydev, u32 regnum, u16 val)
+{
+    int ret;
+ 
+    phy_lock_mdio_bus(phydev);
+    ret = __phy_write(phydev, REG_DEBUG_ADDR_OFFSET, regnum);
+    if (ret < 0)
+        goto err_handle;
+ 
+    ret = __phy_write(phydev, REG_DEBUG_DATA, val);
+    if (ret < 0)
+        goto err_handle;
+    
+err_handle:
+    phy_unlock_mdio_bus(phydev);
+    return ret;
+}
+
+
+static int phy_yt8512c_led_fixup(struct phy_device *phydev)
+{
+	int ret;
+	int val;
+	int mask;
+	printk("-------------------------%s in.\n", __func__);
+	val = ytphy_read_ext(phydev, YT8512_EXTREG_LED0); //GREEN
+	printk("--------------------YT8512_EXTREG_LED0 read val is %d.\n",val);  //785 = 0x311;
+	if (val < 0)
+		return val;
+	//need set 0x30
+    	val |= YT8512_LED0_ACT_BLK_IND;
+	mask = YT8512_LED0_DIS_LED_AN_TRY | YT8512_LED0_BT_BLK_EN | 
+		YT8512_LED0_HT_BLK_EN | YT8512_LED0_COL_BLK_EN | 
+		YT8512_LED0_BT_ON_EN;
+	val &= ~mask;
+	printk("--------------------YT8512_EXTREG_LED0 write val is %d.\n",val);  //800 = 0x320
+	ret = ytphy_write_ext(phydev, YT8512_EXTREG_LED0, 0x30);
+	if (ret < 0)
+		return ret;
+	val = ytphy_read_ext(phydev, YT8512_EXTREG_LED1); //YELLOW 
+	printk("--------------------YT8512_EXTREG_LED1 read val is %d.\n",val);
+	if (val < 0)
+		return val;
+	//need set LED1 0x1300
+	val |= YT8512_LED1_BT_ON_EN;
+	mask = YT8512_LED1_TXACT_BLK_EN | YT8512_LED1_RXACT_BLK_EN;
+	val &= ~mask;
+	printk("--------------------YT8512_EXTREG_LED1 write val is %d.\n",val);
+	ret = ytphy_write_ext(phydev, YT8512_EXTREG_LED1, 0x1300);
+	return ret;
+}
 
 /**
  * stmmac_dvr_probe
@@ -4463,7 +4594,10 @@ int stmmac_dvr_probe(struct device *device,
 		netdev_warn(priv->dev, "%s: failed debugFS registration\n",
 			    __func__);
 #endif
-
+ret = phy_register_fixup_for_uid(YT8512C_PHY_ID, 0xffffffff, phy_yt8512c_led_fixup);
+if (ret){
+		printk("Cannot register PHY board fixup.\n");
+	}
 	return ret;
 
 error_netdev_register:
相关推荐
疯狂飙车的蜗牛22 分钟前
从零玩转CanMV-K230(4)-小核Linux驱动开发参考
linux·运维·驱动开发
xlsw_1 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹2 小时前
基于java的改良版超级玛丽小游戏
java
远游客07132 小时前
centos stream 8下载安装遇到的坑
linux·服务器·centos
马甲是掉不了一点的<.<2 小时前
本地电脑使用命令行上传文件至远程服务器
linux·scp·cmd·远程文件上传
jingyu飞鸟3 小时前
centos-stream9系统安装docker
linux·docker·centos
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭3 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫3 小时前
泛型(2)
java
超爱吃士力架3 小时前
邀请逻辑
java·linux·后端
南宫生3 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论