移植OK6410'S dm9000ae驅動到u-boot

Cited from: http://blog.csdn.net/willand1981/archive/2010/07/01/5706424.aspx
u-boot版本1.1.6

(1)在smdk6410.h中註釋掉CS8900信息,添加DM9000信息
注意參考原理圖,DM9000使用了CSn1,基地址爲18000000

//#define CONFIG_DRIVER_CS8900 0 /* we have a CS8900 on-board */
//#define CS8900_BASE   0x18800300
//#define CS8900_BUS16   1 /* the Linux driver does accesses as shorts */
//#endif

#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_BASE 0x18000300 //0x20000300
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE+4)
#define CONFIG_DM9000_USE_16BIT

(2)編譯,測試,出現以下問題,MAC不對
kyon6410 # ping 192.168.0.1
dm9000 not found at 0x0112a9ac id: 0x24242424
MAC: 24:24:24:24:24:24
operating at 10M full duplex mode
rx fifo error
rx crc error
rx length too big

ARP Retry count exceeded; starting again
rx fifo error
rx crc error
rx length too big

在dm9000x.c中註釋以下內容:

/* Set Node address */
/* for (i = 0; i < 6; i++)
   ((u16 *) bd->bi_enetaddr)[i] = read_srom_word(i);
*/

添加以下內容,後來用了1.3.3的dm9000x.c文件,發現已經有了。
        char *s, *e;
        s = getenv ("ethaddr");
        for (i = 0; i < 6; ++i)
{
            bd->bi_enetaddr[i] = s ?
                simple_strtoul (s, &e, 16) : 0;
            if (s)
                s = (*e) ? e + 1 : e;
        }
// kyon


繼續測試:

kyon6410 # ping 192.168.0.1
dm9000 not found at 0x0112a9ac id: 0x24242424
MAC: 00:40:5c:26:0a:5b
operating at 10M full duplex mode
rx fifo error
rx crc error
rx length too big

ARP Retry count exceeded; starting again
rx fifo error
rx crc error
rx length too big

MAC地址讀出來了,其他還是不對

然後發現0x18000000寫成18000000了,囧

(3)將地址修改爲0x18000000,繼續:

dm9000 i/o: 0x18000300, id: 0x90000a46
MAC: 00:40:5c:26:0a:5b
operating at 100M full duplex mode

能正確識別網卡,ping不通

註釋以下內容:
#if 0
i = 0;
while (!(phy_read(1) & 0x20)) { /* autonegation complete bit */
   udelay(1000);
   i++;
   if (i == 10000) {
    printf("could not establish link\n");
    return 0;
   }
}
#endif

註釋後省去檢查網卡的過程,還是不行,tftp貌似只能傳一個數據包。

(4)打開調試宏進行調試,網上還有人可能是bank沒有被正確配置爲16bit寬度導致問題。
查看smdk6410.c,發現已經正確初始化了CSn1,雖然用的是CS8900的代碼:
/* ------------------------------------------------------------------------- */
#define CS8900_Tacs (0x0) // 0clk   address set-up
#define CS8900_Tcos (0x0) // 4clk   chip selection set-up
#define CS8900_Tacc (0x7) // e 14clk access cycle
#define CS8900_Tcoh (0x0) // 1clk   chip selection hold
#define CS8900_Tah (0x0) // 4clk   address holding time
#define CS8900_Tacp (0x0) // 6clk   page mode access cycle
#define CS8900_PMC (0x0) // normal(1data)page mode configuration

static void cs8900_pre_init(void)
{
SROM_BW_REG &= ~(0xf << 4);
SROM_BW_REG |= (1<<7) | (1<<6) | (1<<4);
SROM_BC1_REG = ((CS8900_Tacs<<28)+(CS8900_Tcos<<24)+(CS8900_Tacc<<16)+(CS8900_Tcoh<<12)+(CS8900_Tah<<8)+(CS8900_Tacp<<4)+(CS8900_PMC));
}

順便按照資料優化了一下總線時序,dm9000很快的。


(5)以上是昨晚的調試過程,非常鬱悶的回去睡覺了。早上過來想看看mini2440的原理圖,看看他們怎麼做的。
結果被鬱悶到了,原來mini2440使用的是dm9000,我這裏的芯片是dm9000ae!兩者引腳都不一樣!
在網上搜索dm9000ae,發現許多人都是按照dm9000的方法移植,都出現我昨晚的問題,能夠識別,ping不通。

(6)
無奈參考Linux內核中代碼,發現Linux的dm9000在rx函數中添加do while循環,於是按照Linux內核源碼在u-boot中也添加do while循環。
do{
/* Check packet ready or not */
DM9000_ior(DM9000_MRCMDX); /* Dummy read */
rxbyte = DM9000_inb(DM9000_DATA); /* Got most updated data */
if (rxbyte == 0)
   return 0;

/* Status check: this byte must be 0 or 1 */
if (rxbyte > 1) {
   DM9000_iow(DM9000_RCR, 0x00); /* Stop Device */
   DM9000_iow(DM9000_ISR, 0x80); /* Stop INT request */
   DM9000_DBG("rx status check: %d\n", rxbyte);
}
DM9000_DBG("receiving packet\n");

/* A packet ready now & Get status/length */
DM9000_outb(DM9000_MRCMD, DM9000_IO);

     /* */
RxStatus = DM9000_inw(DM9000_DATA);
RxLen = DM9000_inw(DM9000_DATA);

     /* */
DM9000_DBG("rx status: 0x%04x rx len: %d\n", RxStatus, RxLen);

/* Move data from DM9000 */
/* Read received packet from RX SRAM */
tmplen = (RxLen + 1) / 2;
for (i = 0; i < tmplen; i++)
   {
    ((u16 *) rdptr)[i] = DM9000_inw(DM9000_DATA);
    //printf("%d ",((u16 *) rdptr)[i]);
   }
     /* */
if ((RxStatus & 0xbf00) || (RxLen < 0x40)
     || (RxLen > DM9000_PKT_MAX)) {
   if (RxStatus & 0x100) {
    printf("rx fifo error\n");
   }
   if (RxStatus & 0x200) {
    printf("rx crc error\n");
   }
   if (RxStatus & 0x8000) {
    printf("rx length error\n");
   }
   if (RxLen > DM9000_PKT_MAX) {
    printf("rx length too big\n");
    dm9000_reset();
   }
} else {

   /* Pass to upper layer */
   DM9000_DBG("passing packet to upper layer\n");
   NetReceive(NetRxPackets[0], RxLen);
   //return RxLen;
}
}
while (rxbyte == DM9000_PKT_RDY);
//return 0;

return RxLen;

測試結果:
大部分時候都可以ping通了,因爲有調試信息,tftp速度十幾k。

網上還有個建議在tx函數前加入以上內容清空dm9000ae寄存器
DM9000_ior(DM9000_MRRH);
DM9000_ior(DM9000_MRRL);

我放在do的前面,貌似也有一定作用


(7)
每次ping結束後都會進入eth_halt,關閉網絡,可能導致傳輸出現問題,遂屏蔽halt函數內容。
void
eth_halt(void)
{
DM9000_DBG("eth_halt dummy by kyon\n");

/* RESET devie */
//phy_write(0, 0x8000); /* PHY RESET */
//DM9000_iow(DM9000_GPR, 0x01); /* Power-Down PHY */
//DM9000_iow(DM9000_IMR, 0x80); /* Disable all interrupt */
//DM9000_iow(DM9000_RCR, 0x00); /* Disable RX */
}

(8)至此dm9000ae基本能夠使用,只是用來加載內核已經足夠了。
測試傳輸速度有1.2MB,很快!


U-Boot 1.1.6 (Jul 8 2009 - 11:31:24) for SMDK6410

****************************************
**    UT-S3C6410 Nand boot v0.18      **
**    ShenZhen Urbetter Technology    **
**   
Http://www.urbetter.com         **
****************************************

CPU:     S3C6410@532MHz
         Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode)
Board:   SMDK6410
DRAM:    128 MB
Flash:   0 kB
NAND:    256 MB
In:      serial
Out:     serial
Err:     serial
Hit any key to stop autoboot: 0
dm9000 i/o: 0x18000300, id: 0x90000a46
MAC: 00:40:5c:26:0a:5b
operating at 100M full duplex mode
TFTP from server 192.168.0.1; our IP address is 192.168.0.4
Filename 'zimage'.
Load address: 0xc0008000
Loading: T #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ##############################
done
Bytes transferred = 1813092 (1baa64 hex)
Boot with zImage

Starting kernel ...

Uncompressing Linux...................................................................................................................... done, booting the kernel.
Linux version 2.6.24.2 (
fusq@fusq-urbetter) (gcc version 4.2.2) #343 Sat Jun 20 13:24:05 CST 2009
CPU: ARMv6-compatible processor [410fb766] revision 6 (ARMv7), cr=00c5387f
Machine: SMDK6410


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章