今天對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的開發板上DM9000在BANK4,所以為了很好的使用DM9000,我們就要設定儲存控制器BANK4相關的兩個寄存器,BWSCON,BKCON4。對於BWSCON我們設定BANK4的相關4位;設定如下:
#if defined(CONFIG_ARCH_S3C2410)
/*
*wuxf:BANK4佔用BWSCON的4*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的資料手冊,先看寫時序:
T1:IOW有效之前地址訊號有效時間
T2:寫訊號的有效期間
T3:資料在IOW訊號消失之前資料的時間
T4:資料的保持時間
T5: 地址在IOW訊號消失之前的保持時間
T6:下一個寫訊號與這個訊號結束之間的時間間隔
T7: 地址訊號有效IO16,IO32的有效時間
T8:地址訊號無效IO16,IO32有效時間
各個時間段我們都看清楚了,現在我們看我們的S3C2440怎麼給這個時間序了,對了,我們只要找到我們對應的連線就可以了,參考S3C2440原理圖我們的S3C2440和DM9000的連線如下:
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的時序序列有:
我們找出s3c2440和dm9000的時序段對應關係:
Dm9000 s3c2440
T1 Tcos
T2 Tacc
T3 Tacs+Tcos+Tacc
T4 Tacp+Toch+Tcah
T5 Tacp+Toch
T6 Tacp+Toch+Tcah+Tacs+Tcos
在HCLK為100MHZ的情況下(BANK4使用HCLK),一個刻度為10ns,根據T1-T6的最少時間(註:我們是可以把時間拉長,但是也要有個適度,因為時間的拉長應該會導致網卡的處理速度減慢,這個可以通過設定兩種不同長短的時序,在看ping的延時,在同一網路)我們給Tcos等賦值為:
T1----Tcos 2個時鐘20ns>5ns
T2---Tacc 6個時鐘 60ns>22ns 注意的是使用WAIT訊號的時候Tacc要大於等於4個clock
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);
}
具體是怎麼開啟的,可以對S3C2440的BSP函數跟蹤一下就知道了,呵呵
開始編譯
#make
…
結果檢測運行:ping 一個內網成功。網卡移植成功。
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/diantouxiao/archive/2010/04/02/5446130.aspx