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: