s3c2440 DM9000驱动移植

今天对DM9000进行了移植,大概情况如下;首先要移植我们应该了解LINUX管理驱动的架构,这个我们在前面已经知道了;

arch/arm/plat-s3c24xx/common-smdk.c加入以下代码,登记资源和把网卡加入设备表:

/* DM9000 */

#if defined(CONFIG_DM9000)|| defined(CONFIG_DM9000_MODULE)

static struct resource s3c_dm9k_resource[] = {

        [0] = {

                .start = S3C2410_CS4,

                .end   = S3C2410_CS4 + 3,

                .flags = IORESOURCE_MEM,

            },

        [1] = {

                .start = S3C2410_CS4 + 4,

                .end   = S3C2410_CS4 + 4 + 3,

                .flags = IORESOURCE_MEM,

            },

        [2] = {

                .start = IRQ_EINT7,

                .end   = IRQ_EINT7,

                .flags = IORESOURCE_IRQ,

            }

};

 

/* for the moment we limit ourselves to 16bit IO until some

 * better IO routines can be written and tested

 */

 

 static struct dm9000_plat_data s3c_dm9k_platdata = {

        .flags      = DM9000_PLATF_16BITONLY,

 };

static struct platform_device s3c_device_dm9k = {

        .name       = "dm9000",

        .id     = 0,

        .num_resources  = ARRAY_SIZE(s3c_dm9k_resource),

        .resource   = s3c_dm9k_resource,

        .dev        = {

                    .platform_data = &s3c_dm9k_platdata,

                    }

 };

#endif

加入到内核设备列表中

static struct platform_device __initdata *smdk_devs[] = {

#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)

    &s3c_device_dm9k,

#endif

    &s3c_device_nand,

    &smdk_led4,

    &smdk_led5,

    &smdk_led6,

    &smdk_led7,

};

 

现在要进行对应的代码修改了,修改哪里呢,修改dm9000_probe它完成的是硬件的枚举,即初始化的,要针对性的修改,修改之前还有些东西需要知道;在mini2440的开发板上DM9000BANK4,所以为了很好的使用DM9000,我们就要设置存储控制器BANK4相关的两个寄存器,BWSCON,BKCON4。对于BWSCON我们设置BANK4的相关4位;设置如下:

#if defined(CONFIG_ARCH_S3C2410)

/*

*wuxf:BANK4占用BWSCON4*4=16位,从第16位依此设置为:位宽为16位,使用wait信号,数据掩码引脚为0*/

    oldval_bwscon= *((volatile unsigned int *)S3C2410_BWSCON);

    *((volatile unsigned int *)S3C2410_BWSCON)=(oldval_bwscon & ~(3<<16))/

    |S3C2410_BWSCON_DW4_16 | S3C2410_BWSCON_WS4 | S3C2410_BWSCON_ST4;

 

/*

*wuxf:这个需要参考S3C2440的数据手册

*/

    oldval_bankcon4 = *((volatile unsigned int *)S3C2410_BANKCON4);

    *((volatile unsigned int *)S3C2410_BANKCON4) = 0x345c;

#endif

关于BANCON4的:看数据手册

这个上面写的是什么啊,呵呵,我们操作一个时序器件的话时序是很重要的,而那写就是操作器件时序,我们设置好了的话,以后操作硬件S3C2440会自动给相应的器件时序,这样我们就设置一次就可以了,方便吧。那么这些时序是什么意思呢?那我们来看看吧。对于器件时序那我们就要分析器件的数据手册了,我们找到dm9000的数据手册,先看写时序:

T1IOW有效之前地址信号有效的时间

T2:写信号的有效期

T3:数据在IOW信号消失之前数据的时间

T4:数据的保持时间

T5:  地址在IOW信号消失之前的保持时间

T6:下一个写信号与这个信号结束之间的时间间隔

T7:  地址信号有效IO16,IO32的有效时间

T8:地址信号无效IO16,IO32有效的时间

 

各个时间段我们都看清楚了,现在我们看我们的S3C2440怎么给这个时间序了,对了,我们只要找到我们对应的连线就可以了,参考S3C2440原理图我们的S3C2440DM9000的连线如下:

DM9000         简介层(为了好看加的)    s3c2440

PW_RST        ->nREST                             ->nREST

SD0-SD15      àLDATA0-LDATA15          ->DATA0-DATA15

CMD             ->LADDR2                          ->ADDR2

IRT               ->I_LAN                             ->EINT7

IOR               ->LnOE                               ->nOE

IOW                     ->LnWE                              ->nWE

IOWAIT        ->Nwait                              ->nWAIT

AEN              -> nLAN_cs                        ->GPS4

 所以要知道IOW,IOR等给出的时间序列,也就是看nOE,new等的序列就是了,我们继续看S3C2440找关于BANK4的时序序列有:

我们找出s3c2440dm9000的时序段对应关系:

Dm9000                       s3c2440

T1                               Tcos

T2                               Tacc

T3                               Tacs+Tcos+Tacc

T4                               Tacp+Toch+Tcah

T5                               Tacp+Toch

T6                               Tacp+Toch+Tcah+Tacs+Tcos

HCLK100MHZ的情况下(BANK4使用HCLK),一个时钟周期为10ns,根据T1-T6的最少时间(注:我们是可以把时间拉长,但是也要有个适度,因为时间的拉长应该会导致网卡的处理速度减慢,这个可以通过设置两种不同长短的时序,在看ping的延时,在同一网络)我们给Tcos等赋值为:

T1----Tcos                          2个时钟20ns>5ns

T2---Tacc                           6个时钟 60ns>22ns   注意的是使用WAIT信号的时候Tacc要大于等于4clock

T3---Tacs+Tcos+Tacc         Tacs       一个时钟:10+20+60=80ns>22ns

T5--- Tacp+Toch                 Toch一个时钟,Tacp六个时钟:10+60=70ns>5ns

T4--- Tacp+Toch+Tcah              Tcah一个时钟:60+10+10=80ns>5ns

T6--- Tacp+Toch+Tcah+Tacs+Tcos   60+10+10+10+20=110>84ns

我们在对照:Tacs:01,Tcos:10,Tacc:100,Tcoh:01,Tcah:01,Tacp:11,PMC:00(1个周期只能处理1个数据,所以PMC应该为normal(1data)),所以对应的BANCON4:0x345c

 

对代码修改也差不多了,现在就是把代码编译进内核,这就需要修改内核配置把dm9000相关代码编译进内核:

Make menuconfigàDevice DriversàNetwork device support(Ethernet (10 or 100Mbit))à <*> DM9000 support   就可以了。

 

#make

……

运行修改对应IP,看能否运行,结果是网卡识别,但是ping不同任何一台机子。问题出在那里呢?Google

 

原来可能是我的网卡中断没有初始化,导致网卡收到数据没法中断,导致ping不通,这应该是问题所在,继续看网卡中断相关的了。我们网卡中断接的是EINT7,所以我们要如下设置:

1)GPFCON (56000050) GPF7 [15:14] 10 ,功能设置为EINT7

这可以用函数实现:s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF3_EINT7);

2)EXTINT0 (56000088) [30:28] 0 低电平触发中断 (复位默认为全0,可能不必设)

3)外部中断屏蔽寄存器。EINTMASK (560000a4) [7] 0 enable interrupt EINT7

4)全局中断屏蔽寄存器  INTMASK (4A000008) 4] 0 使能EINT4_7

在函数里面可以这样添加:

static int

dm9000_probe(struct platform_device *pdev){

/*added by wuxf inorder to support net*/

 

    extint0=ioremap_nocache(EXTINT0,4);// 

 

    intmsk=ioremap_nocache(INTMSK,4);

 

    eintmsk=ioremap_nocache(EINTMASK ,4);

 

    s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_EINT7);

 

    writel(readl(extint0)&0x8fffffff,extint0); //eint7 low level 

 

    writel(readl(intmsk)&(~(1<<4)),intmsk); //     

 

    writel(readl(extint0)&(~(1<<7)),extint0);

 

    iounmap(intmsk);

 

    iounmap(extint0);

 

    iounmap(eintmsk);

}

具体是怎么打开的,可以对S3C2440BSP函数跟踪一下就知道了,呵呵

开始编译

#make

结果检测运行:ping 一个内网成功。网卡移植成功。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值