详解ARM学习之网卡DM9000

一口Linux
关注

5) GPY6CON

三、SROM 控制器

 1. 概念

SROM是高速存储器,Cache技术就是通过在DROM和CPU之间插入一小块SROM来减小CPU和存储之间的速度差异的。

本篇参考开发板FS4412,DM9000挂接到exynos 4412的SROM控制器上

EXYNOS 4412包含了SROM控制器,特性如下:

外部 8/16位 NOR Flash/PROM/ SRAM memory.4组内存,每块内存最多16 MB

首先我们要初始化 exynos4412的 SROM 控制器,设置总线宽度和相关时序。

针对 SROM 控制器的每一个 bank 只有2 个寄存器:SROM_BW 和 SROM_BC。

2. SROM_BW

在 SROM_BW 寄存器中,我们只关心与 bank1 相关的域。

上面分析过,DM9000A 的 16 根数据线全部接在 exynos 4412的数据线上,所以 DataWidth1 设置为 1;DM9000A 的地址是按字节存取的,所以 AddrMode1 设置为 1;通过查看原理图,没有使用 Xm0WAITn和 Xm0BEn 引脚;所以 WaitEnable1 和 ByteEnable1 均设置为 0。

SROM_BW[7:4]=0x3
3. SROM_BC1

SROM 控制器读时序和 DM9000A 的读时序主要通过SROM_BCn控制寄存器设置。

设置这些时序之前,首先来看DM9000A芯片手册时序图和exynos4412的时序图

详尽时序分析:,内存控制器使用HCLK作为时钟,在HCLK为100MHz时,1个clock大约为10ns。信号值的设定如下:

信号含义最低时间(ns)Tacs地址发出后等多长时间发片选, DM9000AE 中 CS 和 CMD(地址)同时发出,所以 Tacs最低为0ns0Tcos发出片选信号后等多长时间发出读使能信号(nOW、 IOR),在 DM9000A 的时序图上对应 T1,最小为 00Tacc读使能信号持续时间,access cycle ,读写使能后,多久才能访问数据,在 DM9000A 的时序图上对应 T210Tcoh当DM9000A的写信号取消后,数据线上的数据还需要至少3ns才消失(nOE读写取消后,片选需要维持多长时间)在 DM9000A 的时序图中对应 T43Tcah片选结束后,地址保存时间, DM9000A 中CS和cmd同时结束,所以 Tcah=00Tacp页模式,不管0PMC页模式,不管0

从DM9000A的读写时序图中可以看出,T2+T6实际上构成了DM9000A的一个访问周期,因此还需要满足:Tacs + Tcos + Tacc + Tcoh + Tcah>= T2+T6,最终使用下面的表达式来表达:(Tacs >= 0 && Tacs <= 4) && (Tcos >= 0 && Tcos <= 4) && (Tacc >= 1 && Tacc <= 14 ) && (Tcoh >=1 && Tcoh <= 4 )

寄存器SROM_BCn (n = 0 to 3)定义如下:

故设置参考值为:

#define DM9000_Tacs     (0x1)   // address set-up
#define DM9000_Tcos     (0x1)   // chip selection set-up
#define DM9000_Tacc     (0x5)   // access cycle
#define DM9000_Tcoh     (0x1)   // chip selection hold
#define DM9000_Tah      (0xC)   // address holding time
#define DM9000_Tacp     (0x9)   // page mode access cycle
#define DM9000_PMC      (0x1)   // normal(1data)page mode configuration
4. SROM初始化

u-boot 已经自带了 DM9000系列网卡的驱动,在 u-boot 源码中的 driver/net/dm9000x.c 的有一段说明:

      06/03/2008 Remy Bohmer <linux@bohmer.net>
  - Fixed the driver to work with DM9000A.
    (check on ISR receive status bit before reading the
    FIFO as described in DM9000 programming guide and
    application notes)
  - Added autodetect of databus width.
  - Made debug code compile again.
  - Adapt eth_send such that it matches the DM9000*
    application notes. Needed to make it work properly
    for DM9000A.
  - Adapted reset procedure to match DM9000 application
    notes (i.e. double reset)
  - some minor code cleanups
  These changes are tested with DM9000{A,EP,E} together
  with a 200MHz Atmel AT91SAM9261 core

可见,2008年Remy Bohmer已经为 DM9000A 添加了驱动,但是我们仍然需要针对板子做一些修改。

前一章我们针对参考的fs4412开发板移植了DM9000A的驱动,下面我们来详细分析DM9000A驱动程序。

分析驱动涉及到以下几个文件:

arch/arm/lib/board.c
board/samsung/origen/origen.c
drivers/net/Dm9000x.c
drivers/net/Dm9000x.h
include/config_cmd_default.h
include/configs/origen.h
include/net.h
net/eth.c
5. 宏定义

在include/configs/origen.h中需要定义DM9000A基地址和编译的宏。其中最重要的几个宏如下:

名称说明值CONFIG_DM9000_BASEDM9000A 的基地址0x05000000DM9000_IODM9000A 的 INDEX 端口地址CONFIG_DM9000_BASEDM9000_DATADM9000A 的 DATA 端口地址(CONFIG_DM9000_BASE + 4)CONFIG_DRIVER_DM9000Makefile中用于控制dm9000驱动是否编译1CONFIG_DM9000_USE_16BITDM9000A数据宽度
CONFIG_DM9000_NO_SROM表示没有使用SROM1

其中DM9000_DATA 定义为基地址+0x4,刚好把 Xm0ADDR2 拉高,即把 CMD 拉高。

查看文件drivers/net/Makefile:

从 Makefile 得知,要把 DM9000A 的驱动编译进 u-boot中,需要定义 CONFIG_DRIVER_DM9000 这个宏。

宏定义如下:

#ifdef CONFIG_CMD_NET
#define CONFIG_NET_MULTI
#define CONFIG_DRIVER_DM9000      1
#define CONFIG_DM9000_BASE        0x05000000
#define DM9000_IO           CONFIG_DM9000_BASE
#define DM9000_DATA         (CONFIG_DM9000_BASE + 4)
#define CONFIG_DM9000_USE_16BIT
#define CONFIG_DM9000_NO_SROM     1
#define CONFIG_ETHADDR      11:22:33:44:55:66
#define CONFIG_IPADDR       192.168.6.187
#define CONFIG_SERVERIP           192.168.6.186
#define CONFIG_GATEWAYIP          192.168.6.1
#define CONFIG_NETMASK      255.255.255.0
#endif

除此以外我们还需要添加一些 u-boot 的命令,比如 ping 命令用来检查网络是否通畅,tftp用来下载文件。

uboot通过宏来控制是否编译这些命令,include/configs/origen.h定义了一些宏,但是有的是undefine,我们要打开它们。

Command definition
#include <config_cmd_default.h>
#define CONFIG_CMD_PING
#define CONFIG_CMD_ELF
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_MMC
#define CONFIG_CMD_FAT
#define CONFIG_CMD_NET
#undef CONFIG_CMD_NFS
#define CONFIG_CMD_HELLO
#define CONFIG_CMD_LEDA

除此之外头文件:u-boot-2013.01/include/config_cmd_all.h 也列出了一些可用的命令。

#define CONFIG_CMD_BDI   bdinfo  
#define CONFIG_CMD_BOOTD  bootd  
#define CONFIG_CMD_CONSOLE  coninfo  
#define CONFIG_CMD_ECHO   echo arguments  
#define CONFIG_CMD_EDITENV  editenv  
#define CONFIG_CMD_FPGA   FPGA configuration Support
#define CONFIG_CMD_IMI   iminfo  
#define CONFIG_CMD_ITEST  Integer (and string) test
#ifndef CONFIG_SYS_NO_FLASH
#define CONFIG_CMD_FLASH  flinfo, erase, protect
#define CONFIG_CMD_IMLS   List all found images
#endif
#define CONFIG_CMD_LOADB  loadb  
#define CONFIG_CMD_LOADS  loads  
#define CONFIG_CMD_MEMORY  md mm nm mw cp cmp crc base loop mtest
#define CONFIG_CMD_MISC   Misc functions like sleep etc
#define CONFIG_CMD_NET   bootp, tftpboot, rarpboot
#define CONFIG_CMD_NFS   NFS support  
#define CONFIG_CMD_RUN   run command in env variable
#define CONFIG_CMD_SAVEENV  saveenv  
#define CONFIG_CMD_SETGETDCR  DCR support on 4xx  
#define CONFIG_CMD_SOURCE  "source" command support
#define CONFIG_CMD_XIMG   Load part of Multi Image
6. 初始化srom

在arch/arm/lib/board.c的函数board_init_r中有如下代码:

void board_init_r(gd_t *id, ulong dest_addr)

……
board_init();  Setup chipselects
……

函数board_init()定义在board/samsung/origen/origen.c中,我们在该函数中添加了初始化srom代码:

int board_init(void)

gpio1 = (struct exynos4_gpio_part1 *) EXYNOS4_GPIO_PART1_BASE;
gpio2 = (struct exynos4_gpio_part2 *) EXYNOS4_GPIO_PART2_BASE;
gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);
#ifdef CONFIG_DRIVER_DM9000
dm9000aep_pre_init();
#endif
return 0;

函数dm9000aep_pre_init用来设置 SROM 控制器。

static void dm9000aep_pre_init(void)

unsigned int tmp;
unsigned char smc_bank_num = 1;
unsigned int     smc_bw_conf=0;
unsigned int     smc_bc_conf=0;
 gpio configuration
writel(0x00220020, 0x11000000 + 0x120);//GPY0CON
writel(0x00002222, 0x11000000 + 0x140);//GPY1CON
 16 Bit bus width
writel(0x22222222, 0x11000000 + 0x180);//GPY3CON
writel(0x0000FFFF, 0x11000000 + 0x188);//GPY3PUD
writel(0x22222222, 0x11000000 + 0x1C0);//GPY5CON
writel(0x0000FFFF, 0x11000000 + 0x1C8);//GPY5PUD
writel(0x22222222, 0x11000000 + 0x1E0);//GPY6CON
writel(0x0000FFFF, 0x11000000 + 0x1E8);//GPY6PUD
             
smc_bw_conf &= ~(0xf<<4);
smc_bw_conf |= (1<<7) | (1<<6) | (1<<5) | (1<<4);
smc_bc_conf = ((DM9000_Tacs << 28)
  | (DM9000_Tcos << 24)
  | (DM9000_Tacc << 16)
  | (DM9000_Tcoh << 12)
  | (DM9000_Tah << 8)
  | (DM9000_Tacp << 4)
  | (DM9000_PMC));
exynos_config_sromc(smc_bank_num,smc_bw_conf,smc_bc_conf);

*  exynos_config_sromc() - select the proper SROMC Bank and configure the
*  band width control and bank control registers
*  srom_bank    - SROM
*  srom_bw_conf  - SMC Band witdh reg configuration value
*  srom_bc_conf  - SMC Bank Control reg configuration value

void exynos_config_sromc(u32 srom_bank, u32 srom_bw_conf, u32 srom_bc_conf)

unsigned int tmp;
struct exynos_sromc *srom = (struct exynos_sromc *)(EXYNOS4412_SROMC_BASE);
 Configure SMC_BW register to handle proper SROMC
 * bank
tmp = srom->bw;
tmp &= ~(0xF << (srom_bank * 4));
tmp |= srom_bw_conf;
srom->bw = tmp;
 Configure SMC_BC
 * register
srom->bc[srom_bank] = srom_bc_conf;

声明: 本文由入驻OFweek维科号的作者撰写,观点仅代表作者本人,不代表OFweek立场。如有侵权或其他问题,请联系举报。
侵权投诉

下载OFweek,一手掌握高科技全行业资讯

还不是OFweek会员,马上注册
打开app,查看更多精彩资讯 >
  • 长按识别二维码
  • 进入OFweek阅读全文
长按图片进行保存