LS1043A+AQR115C万兆网口调试
一、介绍
1. 环境:
- SDK:flexbuild_lsdk1806
- 网口:3个千兆+1个10G,XFI+AQR115C、2*(RGMII+YT85210)、SGMII+YT8521
- 编译命令:
flex-builder -c linux -a arm64 -m ls1043ardb #单独编译内核
flex-builder -c rcw -a arm64 -m ls1043ardb #单独编译rcw
flex-builder -c uboot -a arm64 -m ls1043ardb #单独编译uboot
flex-builder -i mkallfw -m ls1043ardb #编译RCW和uboot,并生成一个包含RCW和uboot的img。
2.AQR115C ethernet phy介绍
AQR115C是Marvell的以太网PHY芯片,同系列的还包括AQR113C、AQR114C以及AQR113、AQR114、AQR115。其中带"C"封装尺寸是7mm X 7mm,不带"C"的封装尺寸是7mm X 11mm。两者之间的差异参见下表:
以上型号使用时都需要通过SPI接口外挂一个flash,用于存放固件。在未正常加载固件的情况下PHY将不能正常工作,软复位寄存器一直处于软复位状态。其次AQR113、AQR114、AQR115支持"菊花链"(英文Daisy Chain,不晓得翻译的对不对。)连接方式,在包含有多个PHY的情况下,只需要一个flash就能为所有的PHY提供固件。连接方式如下图:
接口支持XFI/USXGMII/5GSXGMII/5GBASE-R/2500BASE-X/SGMII。但是不同型号支持的最大速率不同,AQR113/AQR113C最大支持10G,AQR114/AQR114C支持到5G,AQR115/AQR115C支持到2.5G,但是通过设置"PAUSE"可以将所有速率自适应到XFI和将10M/100M/1G自适应到2500BASE-X。
其次万兆PHY的寄存器访问方式和千兆PHY不同,遵循的是clause45,千兆PHY遵循的则是clause22。这个差异影响内核dts中PHY的配置。
- clause22中MDIO可直接访问的寄存器地址0~31共32个。
- clause45中MDIO通过设备地址和寄存器地址可访问寄存器空间更加丰富。例如在AQR115C的手册中寄存器定义如:1E.C885、7.1等,其句号前面的是设备地址,逗号后面的是寄存器地址。
3.ls1043A网口介绍
LS1043A支持网络接口包括:RGMII、SGMII、SGMII(2.5G)、QSGMII和XFI,其中2路RGMII由RCW的RCW416:418、RCW419:121位控制其复用功能。其它网络接口功能由"serdes protocols"来控制对应RCW[128:143]位。SerDes中定义了4个lane,对应引脚如"Table 33-1",这4个lane选择的功能组合是固定的,参考"Figure33-1"可以查找每种功能组合对应RCW[128:143]的值。
A-D列中对应项的具体含义如下:
"Figure33-1"的最后一列给出了每个通道对应的PLL、在根据"Table 33-3"可以得到RCW[160:161]中关于参考时钟的配置值。
二、Reset configuration word (RCW)
RCW简单的说就是配置一些复用的功能,系统在loader阶段会根据这个配置进行初始化。RCW的详细介绍可参见《QorIQ LS1043A Reference Manual》的4.4.6章节,在ls1043A中RCW的SRDS_PRTCL_S1(第128-143位)字段用于配置“SerDes protocol ”,SerDes中包含有4个line,通过SRDS_PRTCL_S1的配置可以选择lane A~D功能(“Figure33-1”)。
SDK中默认采用了"Figure33-1"中1455的配置(laneA=XFI.m9、laneB=qs.m1,2,5,6、laneC=PCIe#2、laneD=PCIe#3).根据我自己的硬件设计需要修改为1355配置(laneA=XFI.m9、laneB=sg.m2、laneC=PCIe#2、laneD=PCIe#3).
1).查找"Figure33-1"可以得到上面需要的配置对应的RCW[128:143]=0x1355既SRDS_PRTCL_S1=4949。“PLL mapping"为"1222”,既laneA使用PLL1,其它lane选择PLL2。
2).对照"Table 33-3"可以看到XFI需要设置PLL1=1既参考时钟为156.25MHz,PLL2=0则选用100MHz,所以可以得到RCW[160:161]=0x02既SRDS_PLL_REF_CLK_SEL_S1=2。
3).然后根据这两个结果修改SDK中RCW的配置。
$ cd packages/firmware/rcw/ls1043ardb
$ cp -rf RR_FQPP_1455/ RR_FSPP_1355/ #当前目录下的README中有目录命名规则的说明。
对新创建的RR_FSPP_1355目录下的内容进行修改。这里只需要关注以".rcw"结尾的文件即可。其中“rcw_1600_qspiboot.rcw”是我们编译qspiboot.img所用到的配置字。编辑修改“rcw_1600_qspiboot.rcw”,将SRDS_PRTCL_S1字段修改成4949(0x1355的十进制),因为时钟上没有变化,所以SRDS_PLL_REF_CLK_SEL_S1=2保持不变。
编辑“packages/firmware/rcw/qspi_swap_list.txt”文件,添加刚创建的配置,注意:这里面的bin文件是由RCW编译生成的。
编译时和“qspi_swap_list.txt”在同一目录下的“qspi_swap.sh”脚本,逐行解析“qspi_swap_list.txt”,并将对应的bin文件转换成“.swapped”的文件和原来的bin文件放在同一目录下。
修改“configs/board/ls1043ardb/manifest”文件,指定之前修改的rcw的位置。
4).重新编译烧写后可以在uboot的log中看到RCW的配置。
三、u-boot
uboot中原来只有对1455的支持,下面我们添加一个1355的配置。主要修改以下文件。
include/configs/ls1043ardb.h
添加phy地址的宏定义,如下:
board/freescale/ls1043ardb/eth.c
int board_eth_init(bd_t *bis)
{
#ifdef CONFIG_FMAN_ENETint i;struct memac_mdio_info dtsec_mdio_info;struct memac_mdio_info tgec_mdio_info;struct mii_dev *dev;u32 srds_s1;struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);srds_s1 = in_be32(&gur->rcwsr[4]) &FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;srds_s1 >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;dtsec_mdio_info.regs =(struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR;dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME;/* Register the 1G MDIO bus */fm_memac_mdio_init(bis, &dtsec_mdio_info);tgec_mdio_info.regs =(struct memac_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR;tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME;/* Register the 10G MDIO bus */fm_memac_mdio_init(bis, &tgec_mdio_info);/* Set the two on-board RGMII PHY address */fm_info_set_phy_address(FM1_DTSEC3, RGMII_PHY1_ADDR);fm_info_set_phy_address(FM1_DTSEC4, RGMII_PHY2_ADDR);printf("Invalid SerDes protocol for LS1043ARDB,srds_s1=0x%x\n",srds_s1);switch (srds_s1) {case 0x1455:/* QSGMII on lane B, MAC 1/2/5/6 */fm_info_set_phy_address(FM1_DTSEC1, QSGMII_PORT1_PHY_ADDR);fm_info_set_phy_address(FM1_DTSEC2, QSGMII_PORT2_PHY_ADDR);fm_info_set_phy_address(FM1_DTSEC5, QSGMII_PORT3_PHY_ADDR);fm_info_set_phy_address(FM1_DTSEC6, QSGMII_PORT4_PHY_ADDR);run_command("setenv product c3", 0);run_command("setenv serdes1 1455", 0);break;case 0x1355:/* SGMII on lane B, MAC 2*/fm_info_set_phy_address(FM1_DTSEC2, SGMII_PHY2_ADDR); run_command("setenv product c3", 0); //这两个环境变量是为了区别加载的dtsrun_command("setenv serdes1 1355", 0);break;default:printf("Invalid SerDes protocol 0x%x for LS1043ARDB\n",srds_s1);break;}dev = miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME);for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++)fm_info_set_mdio(i, dev);switch(srds_s1) {case 0x1355:case 0x1455:/* XFI on lane A, MAC 9 */fm_info_set_phy_address(FM1_10GEC1, FM1_10GEC1_PHY_ADDR);
// dev = miiphy_get_dev_by_name(DEFAULT_FM_TGEC_MDIO_NAME);dev = miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME);fm_info_set_mdio(FM1_10GEC1, dev);break;}cpu_eth_init(bis);
#endifreturn pci_eth_init(bis);
}
修改完成后可通过“flex-builder -i mkallfw -m ls1043ardb”进行编译,编译会生成firmware_ls1043ardb_uboot_qspiboot.img镜像,存放于SDK的“build/images”目录下。
启动后可在uboot的命令行下通过mdio测试是否能正常读写PHY。
mdio list //列举出所有识别到的PHY设备。
mdio read 8 1E.C885 //读取PHY地址是8,设备地址是0x1E的寄存器0xC885的值
mdio write 8 1E.C885 0x01 //设置PHY地址是8,设备地址是0x1E的寄存器0xC885的值为0x01
四、内核
内核dts可参考1455的配置修改。
/* lane B sg.m2 */ethernet@e2000 {
// phy-handle = <&qsgmii_phy2>;
// phy-connection-type = "qsgmii";phy-handle = <&sgmii_phy2>;phy-connection-type = "sgmii";};/* 下面是两路RGMII的配置 */ethernet@e4000 {phy-handle = <&rgmii_phy1>;phy-connection-type = "rgmii-txid";};ethernet@e6000 {phy-handle = <&rgmii_phy2>;phy-connection-type = "rgmii-txid";};/*lane A xfi.m9 */ethernet@f0000 { /* 10GEC1 */
// fixed-link = <0 1 1000 0 0>;phy-handle = <&aqr115c_phy>;phy-connection-type = "xgmii";};/* 连接在MDIO1上的phy */mdio@fc000