• 88Q2110 通过C22方式访问C45 phy地址


    问题现象

            MTK T800平台,内核版本4.19.98,使用两片88Q2110芯片,分别RGMII和SGMII,驱动识别phy id失败:

    DTS配置

            88Q2110支持C45和C22访问:

             phy id的电阻没有焊接,默认地址0:

     C22访问寄存器

             配置和驱动默认使用C45访问寄存器,但使用C45读phy id失败,改为C22访问寄存器:

            使用C22方式通过访问外部寄存器13和14读写寄存器:

             C45读寄存器:

             没看懂怎么操作的。

    1. static int get_phy_c45_devs_in_pkg(struct mii_bus *bus, int addr, int dev_addr,
    2. u32 *devices_in_package)
    3. {
    4. int phy_reg, reg_addr;
    5. reg_addr = MII_ADDR_C45 | dev_addr << 16 | MDIO_DEVS2;
    6. phy_reg = mdiobus_read(bus, addr, reg_addr);
    7. if (phy_reg < 0)
    8. return -EIO;
    9. *devices_in_package = (phy_reg & 0xffff) << 16;
    10. reg_addr = MII_ADDR_C45 | dev_addr << 16 | MDIO_DEVS1;
    11. phy_reg = mdiobus_read(bus, addr, reg_addr);
    12. if (phy_reg < 0)
    13. return -EIO;
    14. *devices_in_package |= (phy_reg & 0xffff);
    15. return 0;
    16. }

            C22读寄存器:

    1. static int get_phy_c45_devs_in_pkg(struct mii_bus *bus, int addr, int dev_addr,
    2. u32 *devices_in_package)
    3. {
    4. int phy_reg, reg_addr;
    5. mdiobus_write(bus, addr, 0xd, 0x0001);
    6. mdiobus_write(bus, addr, 0xe, 0x0002);
    7. mdiobus_write(bus, addr, 0xd, 0x4001);
    8. phy_reg = mdiobus_read(bus, addr, 0xe);
    9. printk("PHY_REG = %x\n",phy_reg);
    10. if (phy_reg < 0)
    11. return -EIO;
    12. *devices_in_package = (phy_reg & 0xffff) << 16;
    13. mdiobus_write(bus, addr, 0xd, 0x0001);
    14. mdiobus_write(bus, addr, 0xe, 0x0003);
    15. mdiobus_write(bus, addr, 0xd, 0x4001);
    16. phy_reg = mdiobus_read(bus, addr, 0xe);
    17. if (phy_reg < 0)
    18. return -EIO;
    19. *devices_in_package |= (phy_reg & 0xffff);
    20. printk("phy IDDDD = %x\n",*devices_in_package);
    21. return 0;
    22. }

    步骤:

            mdiobus_write(bus, addr, 0xd, 0x0001);

            1、先写寄存器13(0xd),写00到bit[15:14]表示00=Address地址功能,写1到bit[4:0]表示设备地址。

            mdiobus_write(bus, addr, 0xe, 0x0002);

            2、后写寄存器14(0xe),写0x0002到bit[15:0]表示寄存器地址,表示读设备ID

             mdiobus_write(bus, addr, 0xd, 0x4001);

             3、写寄存器13(0xd),写01到[15:14]表示从寄存器读写数据功能,写1到bit[4:0]表示设备地址。

            phy_reg = mdiobus_read(bus, addr, 0xe);

            4、读寄存器14(0xe),返回寄存器0x0002的数据。

            获取到设备ID数据是0x2B,

             0x0003寄存器读出是0x0982,10,011000 ,0010,对应0x02,0x18,0x2。修订编号为2,这就一一对应上了。

     寄存器操作命令

       yike支持客户通过读写文件得方式进行设置和读取PHY寄存器,具体命令格式如下。

       (1)通过如下命令读取寄存器:

          echo 协议类型r 寄存器地址 > /sys/devices/platform/11021000.ethernet/stmmac

          例如:通过clause22协议读取寄存器0x1:

          echo cl22r 1 > /sys/devices/platform/soc/1101a000.eth/stmmac

        (2)通过如下命令写寄存器:

         echo 协议类型w 寄存器地址 value > /sys/devices/platform/11021000.ethernet/stmmac

         例如:通过clause22协议写寄存器0x0值为0x5040

          echo cl22w 0 0x5040 > /sys/devices/platform/11021000.ethernet/stmmac

    以realtek8211F PHY为例,

    (1)设置phy为loopback模式

    echo cl22r 0 > /sys/devices/platform/11021000.ethernet/stmmac (读出 PHY register0的值)

    echo cl45r 1 0x834  > /sys/devices/platform/11021000.ethernet/stmmac(c45读方式

    echo cl22w 0 xxx > /sys/devices/platform/11021000.ethernet/stmmac (xxx:为上一步register0读出的值,将bit14置1后的十六进制值)

    echo cl45w 1 0x834 0x8001 > /sys/devices/platform/11021000.ethernet/stmmac

    (2)复位phy,进行reset

    echo cl22r 0 > /sys/devices/platform/11021000.ethernet/stmmac (读出 PHY register0的值)

    echo cl22w 0 0x9040> /sys/devices/platform/11021000.ethernet/stmmac (xxx:为上一步register0读出的值,将bit15置1后的十六进制值)

    疑问:为何T800使用C45就读不出ID呢?

  • 相关阅读:
    AUTOPOI导入Excel文件(可获取表头数据)
    C++ 课堂实验 编写一个能判断数字大小的小程序
    Java 垃圾收集器
    not read Username for “https://gitee.com“: Device not configured
    Navicat for MySQL 11软件下载及安装教程
    (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
    狄克斯特拉(Dijkstra)算法详解
    Vue——webpack项目(没有安装vue-cli脚手架时)解决请求项目启动问题、跨域问题和请求转发报404的问题
    ES6新特性
    MeiliSearch-轻量级且美丽的搜索引擎
  • 原文地址:https://blog.csdn.net/TSZ0000/article/details/126241948