Reprinted from: http://blog.csdn.net/dos5gw/article/details/5824461
Http://caiming1987612.blog.163.com/blog/static/118556676200961752714307/
Http://blog.chinaunix.net/u1/34474/showart_401078.html
Http://hi.baidu.com/%D3%F3%C4%E0%C4%EA%B8%E2/blog/item/6256fea7bfceac98d0435819.html
Timing Diagram and pin connection: http://blog.chinaunix.net/u1/57901/showart_2023852.html
(I) Open ARCH/ARM/mach-s3c2440/mach-test2440.c
Add the following code:
# Define mach_test2440_dm9k_base (s3c2410_cs4 + 0x300)
/* S3c2410_cs4 is defined as 0x20000000 (bank4 base address ),
Dm9000 on bank4, 0x20000300
0x80000300 */
Static struct resource test2440_dm9k_resource [] = {
[0] = {
. Start = mach_test2440_dm9k_base,// 0x20000300, send
. End = mach_test2440_dm9k_base + 3,
. Flags = ioresource_mem
},
[1] = {
. Start = mach_test2440_dm9k_base + 4,// 0x20000304, Transmission
. End = mach_test2440_dm9k_base + 7,
. Flags = ioresource_mem
},
[2] = {
. Start = irq_eint7,/* Interrupt number, connect the eint7 pin of S3C2440 */
. End = irq_eint7,
. Flags = ioresource_irq | ioresource_irq_highedge,/* Trigger the rising edge */
}
};
Static struct dm9000_plat_data test2440_dm9k_pdata = {
. Flags = (dm9000_platf_16bitonly | dm9000_platf_no_eeprom ),
};// Dm9000 data related to the Development Board. When dm9000 is accessed, the data bit width is 16.
Static struct platform_device test2440_device_eth = {/* register a platform device */
. Name = "dm9000 ",
. ID =-1,
. Num_resources = array_size (test2440_dm9k_resource ),
. Resource = test2440_dm9k_resource,
. Dev = {
. Platform_data = & test2440_dm9k_pdata,
},
};
(2) register the platform device test2440_device_eth:
Static struct platform_device * test2440_devices [] _ initdata = {
& Initi_device_usb,
& Amp; cloud_device_ LCD,
& Amp; cloud_device_wdt,
& Amp; cloud_device_i2c0,
& Amp; cloud_device_iis,
& Amp; cloud_device_nand,
// & Amp; s3c24xx_uda134x,
// & Amp; initi_device_sdi,
// & Amp; initi_device_usbgadget,
& Test2440_device_eth,// Add the dm9000 Nic device here
};
(3) Modify Drivers/NET/dm9000.c
1. Add at the beginning:
# If defined (config_arch_s3c2410)
# Include
# Endif
2. In the static int _ devinit dm9000_probe (struct platform_device * pdev) function
/* Try reading the node address from the attached EEPROM */
For (I = 0; I <6; I + = 2)
Dm9000_read_eeprom (dB, I/2, ndev-> dev_addr + I );
If (! Is_valid_ether_addr (ndev-> dev_addr) & pdata! = NULL ){
Mac_src = "Platform Data ";
Memcpy (ndev-> dev_addr, pdata-> dev_addr, 6 );
}
If (! Is_valid_ether_addr (ndev-> dev_addr )){
/* Try reading from MAC */
Mac_src = "chip ";
For (I = 0; I <6; I ++)
Ndev-> dev_addr [I] = ior (dB, I + dm9000_par );
}
Memcpy (ndev-> dev_addr, "/x08/x90/x90/x90/x90/x90", 6); // newly added
3. added
# If defined (config_arch_s3c2410)
Unsigned int oldval_bwscon = * (volatile unsigned int *) s3c2410_bwscon;
Unsigned int oldval_bankcon4 = * (volatile unsigned int *) s3c2410_bankcon4;
* (Volatile unsigned int *) s3c2410_bwscon) =
(Oldval_bwscon &~ (3 <16) | s3c2410_bwscon_dw4_16 | s3c2410_bwscon_ws4 | s3c2410_bwscon_st4;
* (Volatile unsigned int *) s3c2410_bankcon4) = 0x1f7c;
# Endif
After verification, the added third part of the code (of course, including the header file Mach/regs-mem.h) affects network performance. So let's take a look at the role of this part of code.
First, we can see from the schematic diagram of the Development Board that the aen pin of the dm9000 Nic is connected to ngcs4 (bank4) of S3C2440 ).
Return to the code.
# If defined (config_arch_s3c2410)
Unsigned int oldval_bwscon = * (volatile unsigned int *) s3c2410_bwscon;
Unsigned int oldval_bankcon4 = * (volatile unsigned int *) s3c2410_bankcon4;
* (Volatile unsigned int *) s3c2410_bwscon) =
(Oldval_bwscon &~ (3 <16) | s3c2410_bwscon_dw4_16 | s3c2410_bwscon_ws4 | s3c2410_bwscon_st4;
* (Volatile unsigned int *) s3c2410_bankcon4) = 0x1f7c;
# Endif
Bit Width & Wait Status Register bwscon (bus width & Wait Status control register), controls a memory bank every four digits. According to the S3C2440 manual, the four pins involving dm9000 are 16 ~ 19. The default value is 0x000000.
1. st4 [19]: whether the SRAM uses UB/lb (upper byte/lower byte ). 0: Do not use UB/LB; 1: Use UB/lb.
2. ws4 [18]: Wait Status. 0: Disable wait; 1: Enable wait.
3. dw4 [16: 17]: data bus width. ; 11: Reserved.
Next, the bank4 control register bankcon4 (bank control register) is used to control the access time sequence of the external bank4 device. The default value is 0x0700.
1. TACs []: Address creation time. Clock cycle; clock cycle.
2. TCOs []: The time when the slice is created. Clock cycle; clock cycle.
3. tacc []: Address cycle. : Clock cycle;...: 14 clock cycle.
4. tcoh []: chip selection holding time. Clock cycle; clock cycle.
5. tcah []: address retention time. Clock cycle; clock cycle.
6. TCAP [3: 2]: Page Mode Access cycle. Clock cycle; clock cycle.
7. PMC [1:0]: Page mode configuration. Data; data.
Finally, in arch/ARM/mach-s3c2410/include/Mach/regs-mem.h,
# Define s3c2410_bwscon_dw4_16 (1 <16)
# Define s3c2410_bwscon_ws4 (1 <18)
# Define s3c2410_bwscon_st4 (1 <19)
After understanding the meaning of registers bwscon and bankcon4, the role of the above Code is obvious.
* (Volatile unsigned int *) s3c2410_bwscon) =
(Oldval_bwscon &~ (3 <16) | s3c2410_bwscon_dw4_16 | s3c2410_bwscon_ws4 | s3c2410_bwscon_st4; // The data bus width is 16 bits. Use UB/lb to enable wait.
* (Volatile unsigned int *) s3c2410_bankcon4) = 0x1f7c; // modified the access time sequence of dm9000.