DP83848作为一款高性价比的PHY芯片,越来越多的客户在AM335X的平台上去使用。
关于AM335X与DP83848进行配合使用,小结如下:
1.硬件连接见如下框图
注意点:
1)采用RMII时,推荐上述连接,如采用MII时,可以使用25M crystal
2) 使用的50M OSC有要求+- 50 ppm,详细可参考DP83848 DATASHEET。
2. Layout要求
1)上述信号线除了MDIO的两条线之外,其他信号线要作等长处理。
2)EMAC到PHY之间的走线距离要小于2inch。
3. 驱动修改调试
由于TI的SDK包中使用的general PHY driver,所以修改很简单,更明确地说,是确认配置。
建议调试在u-boot中进行,方便确认问题。
u-boot下主要确认三点:
1)Program GMII_SEL in control module with 0x5 for RMII Interface
2)Pinmux configuration to support rmii interface
3)Phy ID setting in Platform data(由PHY的硬件电路决定,通过在PHY_ID的三个管脚上下拉来决定)
Linux下调试也是确认以上三点。
leo chen:
DP83848 是百兆的PHY吧,有没有千兆的PHY推荐的
Gary Wu:
回复 leo chen:
关于千兆的PHY,可以参考EVM,使用AR8031。
也有客户使用KSZ9021,调试可以参考http://e2e.ti.com/support/arm/sitara_arm/f/791/t/182794.aspx
xuan su:
你好 :
这个GMII_SEL在那里配置,我怎么找不到。。小白路过。谢谢 我用的是am1808和dp83848 现在无法ping通 能读取到寄存器 Pinmux 配置应该没有问题。
liang liu3:
回复 xuan su:
你好,你的问题解决了吗,我现在也遇到了同样的问题了
Yalan Han:
回复 xuan su:
请问您解决了么?我也是不知道在哪里配置,谢谢啦
Steven Liu1:
回复 xuan su:
GMII_SEL在AM335x的TRM手册第九章control module。
在9.3.1节中,偏移量为650的地方就是该寄存器的地址。
shupeng hu:
回复 Gary Wu:
请问,把GMII_SEL设置为no internal delay的作用是什么呢。
shupeng hu:
回复 Steven Liu1:
你好,请问把GMII_SEL设置为no interl delay的作用是什么呢。设置了这个就可以支持千兆了。。。
Bernie Chen:
回复 shupeng hu:
我也想知道! 盼TI精英能夠解答
在 u-boot & kernel 下 gmii_sel 都是處於 disable internel delay。我在 sdk8 內,am335x-evmsk.dts 內有一個 phy-mode="rgmii-txid",她回傳直到 cpsw.c,進而影響 at803x.c 內的 tx delay function,我的疑問是,既然u-boot 和 kernel 都是把 internal delay 關掉,那位啥 dts 預設為rgmii-txid 阿?
我卡了幾個月了
謝謝。
mingliang su:
回复 Steven Liu1:
你好!我在用AM3352与DP83848J连时,通过仿真器在CCS6.1下将U-BOOT的文件导入板子,通过串口打印可以看到,在DP83848J初始化时,在运行到CPSW.c下的cpsw_mdio_init函数时,_raw_writel(div | CONTROL_ENABLE, &mdio_regs->control);这个执行语句运行通过不了。在调试时通过各种方法对&mdio_regs->control进行赋值操作,都不能成功,对0x4a101000这个地址进行赋值操作也不成功;
static void cpsw_mdio_init(char *name, u32 mdio_base, u32 div){ struct mii_dev *bus = mdio_alloc();
mdio_regs = (struct cpsw_mdio_regs *)mdio_base;
/* set enable and clock divider */ __raw_writel(div | CONTROL_ENABLE, &mdio_regs->control);
我的网口设置的是MII模式,外接25M时钟。GMII_SEL 设置为0. 原理图如下,
上面这个图我接的是DP83848J的PHY,PHY的ID号设置的为7,
上图这个,我接的IP175D的交换芯片,IP175D的ID号设置为0-6;现在的代码还没有增加IP175D交换芯片的驱动,现在只对DP83848进行驱动,都有成功
更改的代码的如下:
static struct cpsw_slave_data cpsw_slaves[] = { { .slave_reg_ofs = 0x208, .sliver_reg_ofs = 0xd80, .phy_addr = 7, }, { .slave_reg_ofs = 0x308, .sliver_reg_ofs = 0xdc0, .phy_addr = 1, },};
static struct cpsw_platform_data cpsw_data = { .mdio_base = CPSW_MDIO_BASE, .cpsw_base = CPSW_BASE, .mdio_div = 0xff, .channels = 8, .cpdma_reg_ofs = 0x800, .slaves = 1, .slave_data = cpsw_slaves, .ale_reg_ofs = 0xd00, .ale_entries = 1024, .host_port_reg_ofs = 0x108, .hw_stats_reg_ofs = 0x900, .bd_ram_ofs = 0x2000, .mac_control = (1 << 5), .control = cpsw_control, .host_port_num = 0, .version = CPSW_CTRL_VERSION_2,};#endif
int board_eth_init(bd_t *bis){ int rv, n = 0; uint8_t mac_addr[6]; uint32_t mac_hi, mac_lo; __maybe_unused struct am335x_baseboard_id header;
/* try reading mac address from efuse */ mac_addr[0] = 0x01; mac_addr[1] = 0x00; mac_addr[2] = 0x50; mac_addr[3] = 0x84; mac_addr[4] = 0x16; mac_addr[5] = 0x00; setenv("ethaddr","00:16:84:50:00:01");#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \ (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD)) if (!getenv("ethaddr")) { printf("<ethaddr> not set. Validating first E-fuse MAC\n");
if (is_valid_ether_addr(mac_addr)) eth_setenv_enetaddr("ethaddr", mac_addr); }
#ifdef CONFIG_DRIVER_TI_CPSW/* mac_lo = readl(&cdev->macid1l); mac_hi = readl(&cdev->macid1h); mac_addr[0] = mac_hi & 0xFF; mac_addr[1] = (mac_hi & 0xFF00) >> 8; mac_addr[2] = (mac_hi & 0xFF0000) >> 16; mac_addr[3] = (mac_hi & 0xFF000000) >> 24; mac_addr[4] = mac_lo & 0xFF; mac_addr[5] = (mac_lo & 0xFF00) >> 8;
if (!getenv("eth1addr")) { if (is_valid_ether_addr(mac_addr)) eth_setenv_enetaddr("eth1addr", mac_addr); }*/ if (read_eeprom(&header) < 0) puts("Could not get board ID.\n");
if (board_is_bone(&header) || board_is_bone_lt(&header) || board_is_idk(&header)) { writel(MII_MODE_ENABLE, &cdev->miisel); cpsw_slaves[0].phy_if = cpsw_slaves[1].phy_if = PHY_INTERFACE_MODE_MII; } else { writel(MII_MODE_ENABLE, &cdev->miisel); cpsw_slaves[0].phy_if = cpsw_slaves[1].phy_if = PHY_INTERFACE_MODE_MII; }
puts("call cpsw_register\n"); rv = cpsw_register(&cpsw_data); if (rv < 0) printf("Error %d registering CPSW switch\n", rv); else n += rv;#endif puts("after cpsw_register\n");
麻烦各位给我看看,谢谢!