uboot移植(九)移植网卡DM9000

uboot移植(九)移植网卡DM9000

TQ210 板载的网卡芯片是 DM9000A,接在 S5PV210 SROM 控制器的 BANK1 上。
S5PV210 SROM 控制器支持 8/16 NOR Flash/PROM/SRAM 内存。 分为 6 bank,每个 bank
址空间达
128MB。 每个 bank 有一个片选信号 nGCS[5:0], 用来选通外接的内存芯片。 当发的地址在
bank1 的寻址范围内(0x88000000~0x8FFFFFFF)时,表示在访问 bank1, 此时 nGCS1 信号被拉低,
这就选中了接在
bank1 上的 DM9000A 网卡芯片。 S5PV210 手册给出了每个 bank 的地址空间
uboot移植(九)移植网卡DM9000

当对某个地址进行读操作时, S5PV210 Xm0OEn 信号被自动拉低,这个信号引脚接在 DM9000A
nIOR 上, 这就对 DM9000A 进行了读使能,可以从 DM9000A 读数据; 当对某个地址进行写操作时,
S5PV210 Xm0WEn 信号被自动拉低,这个信号引脚接在 DM9000A nIOW 上,这就对 DM9000A
进行了写使能,可以向 DM9000A 写数据。 DM9000A 16 根数据线全部接在 S5PV210 的数据线上。

DM9000A 包含一系列可被访问的控制状态寄存器,这些寄存器是字节对齐的,他们在硬件或软件复
位时被设置成初始值。
DM9000A 2 个端口: DATA INDEX(即地址)。 DM9000A 的地址和数据线
复用, 当
CMD 引脚为低电平时,操作的是 INDEX 端口,当 CMD 引脚为高电平时操作的是 DATA 端口。
CMD 引脚接在 S5PV210 的地址线 Xm0ADDR2 上。 


假设要读取 DM9000A 的寄存器 RSRRX Status Register),需要分 2 步:
1) INDEX 端口写入 RSR 寄存器的地址(0x06
        条件:
nGCS1 信号拉低、 Xm0WEn 信号拉低、 Xm0ADDR2 拉低, 或者说向下面的地址写数据 0x06
(0x88000000~0x8FFFFFFF
& ~(1 << 2)
2)
DATA 端口读取 RSR 寄存器的值
        条件:
nGCS1 信号拉低、 Xm0OEn 信号拉低、 Xm0ADDR2 拉高, 或者说从下面的地址读数据
(0x88000000~0x8FFFFFFF| (1 << 2)

假设要向 DM9000A 的寄存器 TCRTX Control Register)写数据 0x56,同样需要 2
1) INDEX 端口写入 TCR 寄存器的地址(0x02
条件:
nGCS1 信号拉低、 Xm0WEn 信号拉低、 Xm0ADDR2 拉低, 或者说向下面的地址写数据 0x02
(0x88000000~0x8FFFFFFF
& ~(1 << 2)
个人 QQ809205580 技术交流群: 153530783 个人博客: http://blog.csdn.net/zjhsucceed_329
2) 将要写入的数据(0x56) 写入 DATA 端口
条件:
nGCS1 信号拉低、 Xm0WEn 信号拉低、 Xm0ADDR2 拉高,或者说向下面的地址写数据 0x56
(0x88000000~0x8FFFFFFF
| (1 << 2)
有了这些理论知识就可以确定 DM9000A 的基地址了,在后面会用到。

下面开始移植
首先我们要初始化
S5PV210 SROM 控制器,设置相关时序。 针对 SROM 控制器的每一个 bank 只有
2 个寄存器: SROM_BW SROM_BC,我要配置的是 bank1,所以只需配置 SROM_BW SROM_BC1
SROM_BW 寄存器中,我们只关心与 bank1 相关的域
uboot移植(九)移植网卡DM9000

上面分析过, DM9000A 16 根数据线全部接在 S5PV210 的数据线上,所以 DataWidth1 设置为 1
DM9000A
的地址是按字节存取的,所以 AddrMode1 设置为 1,通过查看原理图,没有使用 Xm0WAITn
Xm0BEn 引脚,所以 WaitEnable1 ByteEnable1 均设置为 0
SROM_BW[7:4]=0x3


下面分析时序,设置 SROM_BC1 寄存器
uboot移植(九)移植网卡DM9000

uboot移植(九)移植网卡DM9000

上面 2 个时序图分别为 S5PV210 SROM 控制器读时序和 DM9000A 的读时序
Tacs:地址发出后等多长时间发片选, DM9000A CS CMD(地址)同时发出,所以 Tacs=0ns
Tcos
:发出片选信号后等多长时间发出读使能信号(nOWIOR),在 DM9000A 的时序图上对应 T1
最小为
0,我们稍微设置大点 Tcos=5ns
Tacc
:读使能信号持续时间,在 DM9000A 的时序图上对应 T2,我们设置为设置 Tacc=15ns
Tcoh
:读使能信号结束后,片选信号保持时间,在 DM9000A 的时序图中对应 T5,所以可以设置
Tcoh=5ns
Tcah
:片选结束后,地址保存时间, DM9000A 中片选和地址同时结束,所以 Tcah=0
Tacp
:页模式,不管
PMC:页模式,不管
S5PV210 SROM 控制器使用 MSYS 域提供 HCLK 时钟,为 200MHz,一个 clock 5ns
u-boot 已经自带了 DM9000A 的驱动,另外,在 u-boot 源码中的 dm9000x.c 的注释中有一段话
uboot移植(九)移植网卡DM9000

专门为 DM9000A 升级了该驱动。
通过跟踪代码进入到
board.c 中的 board_init_r 函数
uboot移植(九)移植网卡DM9000

如果定义了 CONFIG_CMD_NET,就调用 eth_initialize(gd->bd)进行网卡初始化。这个宏在
config_cmd_default.h 中定义,这个头文件又被单板配置文件 smdkv210.h 所包含。
uboot移植(九)移植网卡DM9000

eth_initialize 函数在 u-boot-2014.04/net/eth.c 中定义
uboot移植(九)移植网卡DM9000

这里已经有注释,如果定义了单板相关的初始化函数就调用它,否则调用 CPU 相关的初始化函数。
我们继续看下
__def_eth_init 函数,同样在 u-boot-2014.04/net/eth.c 中定义
uboot移植(九)移植网卡DM9000

这里用到了 gcc 的弱符号和别名属性, 前面分析过。 如果我们没有定义自己的 board_eth_init 函数,
board_eth_init 就和__def_eth_init 相同,调用 board_eth_init 就相当于调用__def_eth_init,现在就
能明白上面的
if 判断语句了。
board_eth_init u-boot-2014.04/board/samsung/smdkv210/smdkv210.c 中定义
uboot移植(九)移植网卡DM9000

这里通过配置宏来决定调用哪个网卡初始化函数, 同时在 smdkv210.c 中还有个函数 smc9115_pre_init
这个函数用来设置 SROM 控制器。
我们使用的是
DM9000A,我们先查看下 DM9000A 的源码,看下使用哪个初始化函数
u-boot-2014.04/drivers/net/DM9000Ax.c
uboot移植(九)移植网卡DM9000

看到这个函数比较像,并且它需要一个 bd_t *类型参数,而 board_eth_init 也传进来一个 bd_t *的参
数,因此就调用这个
DM9000A 的初始化函数,在这个函数中 dm9000_get_enetaddr EEPROM 加载
MAC地址,这个函数根据宏CONFIG_DM9000_NO_SROM 来决定是否从EEPROM 加载MAC地址, TQ210
上的 DM9000A 没有接 EEPROM,我们将在 smdkv210.h 中定义这个宏,表示不从 EEPROM 加载 MAC
地址。 另外,我们还需要知道如何才能把 DM9000A 的驱动编译进 u-boo.bint,我们查看
u-boot-2014.04/drivers/net/Makefile
uboot移植(九)移植网卡DM9000

Makefile 得知,需要定义 CONFIG_DRIVER_DM9000 这个宏。
修改
board_eth_init 函数
uboot移植(九)移植网卡DM9000

同时我们看到在 smdkv210.c 中的 board_init 函数还调用了 smc9115 的初始化,我们不需要,把它屏
蔽掉,然后仿照实现
dm9000_pre_init 函数,初始化 SROM
uboot移植(九)移植网卡DM9000

uboot移植(九)移植网卡DM9000

uboot移植(九)移植网卡DM9000

然后在配置文件 smdkv210.h 中添加宏 CONFIG_DRIVER_DM9000A,同时屏蔽掉 smc9111 的相关宏
uboot移植(九)移植网卡DM9000

现在编译 u-boot.bin,执行 make all,出错
uboot移植(九)移植网卡DM9000

没有定义 CONFIG_DM9000A_BASEDM9000A_DATA DM9000A_IO
CONFIG_DM9000A_BASE
DM9000A 的基地址
DM9000A_DATA DM9000A DATA 端口地址
DM9000A_IO DM9000A INDEX 端口地址
在前面分析过如何确定这些地址。另外,我们还需要添加一些
u-boot 的命令,比如 pingtftpboot
ping 命令用来检查网络是否通畅, tftpboot 用来从 tftp 服务器下载文件。
如何知道
u-boot 支持哪些命令,查看头文件: u-boot-2014.04/include/config_cmd_all.h
uboot移植(九)移植网卡DM9000

该头文件的注释也说明, 该文件列出了所有可用的命令。
uboot移植(九)移植网卡DM9000

另外在 smdkv210.h 中包含了头文件 config_cmd_default.h,里面定义了一些命令,这是 u-boot 默认
配置的命令,我们看下里面有没有我们需要配置的,如果没有,我们就需要自己配置

uboot移植(九)移植网卡DM9000

可以看到 CONFIG_CMD_NET 已经配置了,所以我们只需要配置 CONFIG_CMD_PING 命令。
smdkv210.h 中定义这些宏
uboot移植(九)移植网卡DM9000

这里的 DM9000A_DATA 定义为基地址+0x4,刚好把 Xm0ADDR2 拉高,即把 CMD 拉高。
网上很多文章说什么基地址要加
0x300,全是无稽之谈,还解释得头头是道。
再次编译,成功生成 u-boot.bin,将 u-boot.bin 烧尽 SD 卡,从 SD 卡启动开发板
uboot移植(九)移植网卡DM9000

有的时候能读取到 DM9000A ID,连续操作就能读取到 DM9000A ID,但间隔一会操作就读取不
DM9000A ID,通过调试,在 dm9000x.c d dm9000_reset 函数中加一句延时操作,就可以正
常读取
DM9000A ID 了。
uboot移植(九)移植网卡DM9000

uboot移植(九)移植网卡DM9000

首先设置环境变量
ipaddru-boot IP
ethaddr
u-boot MAC 地址
serveripu-boot 通过 tftpboot 从哪里下载文件的 PC 机的 IP
我的电脑的 IP 192.168.1.101,进行如下设置
uboot移植(九)移植网卡DM9000

可以 ping
下面使用
tftpboot 下载文件到内存,首先打开 tftp 服务器软件 tftpd32.exe
uboot移植(九)移植网卡DM9000

uboot移植(九)移植网卡DM9000

uboot移植(九)移植网卡DM9000

下载成功。
另外,我们可以在单板配置文件
smdkv210.h 中定义这些环境变量
uboot移植(九)移植网卡DM9000

再次编译,烧写到 SD 卡,启动后可以直接使用
uboot移植(九)移植网卡DM9000