DM8168 Uboot使用EMAC1(TI源码使用默认的EMAC0)

最近生产了一批板卡,但是只焊接了EMAC1的网卡芯片,没有焊接EMAC0。这就无法直接使用了TI给的UBoot源码了。所以必须修改Uboot源码支持EMAC1.

首先先要弄明白EMAC工作原理。

管理EMAC的MII接口在初始化话的时候会读取网卡芯片的PHY地址,并保存在一个32位的寄存器中。比如我的PHY地址是3,那么这个寄存器的读取的值会成为0x00000008,即第三位置为1. 我们在源码中arch/arm/include/asm/arch-ti81xx/emac_defs.h 需要修改 EMAC_MDIO_PHY_NUM 为 3 . 源码中有这么一行: 

#define EMAC_MDIO_PHY_MASK              (1 << EMAC_MDIO_PHY_NUM)

所以MDIO的掩码是0x08。

我们需要使用EMAC1,就必须修改EMAC对应的基地址,所以相应的我们也在这个文件中添加:

  //#define EMAC0

  #ifdef EMAC0

  #define EMAC_MDIO_PHY_NUM               (1)
  #define EMAC_BASE_ADDR                  (0x4A100000)
  #define EMAC_WRAPPER_BASE_ADDR          (0x4A100900)
  #define EMAC_WRAPPER_RAM_ADDR           (0x4A102000)
 
  #else
 
  #define EMAC_MDIO_PHY_NUM               (3)
  #define EMAC_WRAPPER_RAM_ADDR           (0x4A122000)
  #define EMAC_WRAPPER_BASE_ADDR          (0x4A120900)
  #define EMAC_BASE_ADDR                  (0x4A120000)
 
  #endif
 
  #define EMAC_MDIO_BASE_ADDR             (0x4A100800)
  #define DAVINCI_EMAC_VERSION2
  #define DAVINCI_EMAC_GIG_ENABLE
 
  #define EMAC_MDIO_BUS_FREQ              (250000000UL)
  #define EMAC_MDIO_CLOCK_FREQ            (2000000UL)

之前我以为执行到这里,我的源码就修改完成了。结果我发现我从MDIO通信中的确识别了网卡,但是之后使用ping操作的时候,都不好使。找了好久终于发现了问题。

原来处理器默认使用EMAC0,所以初始化了EMAC0的相关IO。

但是EMAC1的IO没有初始化。打开drivers/net/davinci_emac.c

在函数davinci_emac_initialize() 的开始位置添加:

 #ifndef EMAC0
  #define EMAC1_PINCTRL_BASE       *( volatile unsigned int* )( 0x481408C8 )
    /*Initialize EMAC1 pins */
         pReg = &EMAC1_PINCTRL_BASE;
             for ( i = 0 ; i < 24 ; i++ )
             {
                 debug_emac("Before : 0x%08x\t",readl(pReg));
                 writel(readl(pReg)|0x01,pReg);
                 debug_emac("After : 0x%08x\n",readl(pReg));
                 pReg++;
             }
 #endif

直到现在,已经完成了99%,也许好用,也许不好用。原因很特别:


看函数davinci_emac_initialize() 中的

for (i = 0; i < 256; i++) {
                 alive = readl(&adap_mdio->ALIVE);
         //      printf("times:%03d,alive:0x%08x\n",i,alive);
                 if (alive)
                         break;
                 udelay(10);
         }

为什么要读这么多次?

可能是因为网卡没有初始完毕,CPU读得太快,所以需要重复读取。

当我使用双网卡的时候,我发现我的网卡地址分别是1和3. 所以我读取这个寄存器的时候,总会先返回了0x02然后再过一段时候之后再返回0x0a。所以这里需要自己做一些处理,需要一些延时或者重复读取的处理。


本文链接:https://my.lmcjl.com/post/6164.html

展开阅读全文

4 评论

留下您的评论.