S3C2440 Linux driver transplantation——NAND driver

Publisher:自由探索Latest update time:2016-04-08 Source: eefocusKeywords:S3C2440 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1.  Modify the partition table

Open the file arch/arm/plat-s3c24xx/common-smdk.c and modify the mtd_partition structure array.

After modification, it is as follows:

 

[cpp]  view plain copy
 
  1. static  struct  mtd_partition  smdk_default_nand_part[]   
  2.     [0]   
  3.         .name    "Uboot",  
  4.         .size    0x00040000,  
  5.         .offset  0x00000000,  
  6.     },  
  7.     [1]   
  8.         .name    "Kernel",  
  9.         .offset  0x00200000,  
  10.         .size    0x00300000,  
  11.     },  
  12.     [2]   
  13.         .name    "filesystem",  
  14.         .offset  0x00500000,  
  15.         .size    MTDPART_SIZ_FULL,  
  16.      
[cpp]  view plain copy
 
  1. };  


The NAND on the TQ2440 board is 256M. Please allocate space according to the actual size of your NAND.

2. Modify NAND controller parameters

Open the file arch/arm/plat-s3c24xx/common-smdk.c and modify the smdk_nand_info structure.

After modification, it is as follows:

[cpp]  view plain copy
 
  1. static  struct  s3c2410_platform_nand  smdk_nand_info   
  2.     .tacls       0,  //10, //20,  
  3.     .twrph0      21,  //25, //60,  
  4.     .twrph1      5,  //10, //20,  
  5.     .nr_sets     ARRAY_SIZE(smdk_nand_sets),  
  6.     .sets        smdk_nand_sets,  
  7. };  


How are the three parameters tacls, twrph0, and twrph1 given? Let's analyze it.

First look at the definition of this structure, located in arch/arm/mach-s3c2410/include/mach/nand.h:

[cpp]  view plain copy
 
  1. struct  s3c2410_platform_nand   
  2.       
  3.   
  4.     int  tacls;    
  5.     int  twrph0;   
  6.     int  twrph1;   
  7.   
  8.     unsigned  int     ignore_unset_ecc:1;  
  9.   
  10.     int          nr_sets;  
  11.     struct  s3c2410_nand_set  *sets;  
  12.   
  13.     void             (*select_chip)(struct  s3c2410_nand_set  *,  
  14.                            int  chip);  
  15. };  


I have seen the description of these three parameters. It is mentioned here that the units of these three parameters are nanoseconds. Please note that.

So where do these three parameters come from? They come from the NFCONF controller of the S3C2440 nand controller, as follows:

 

 Now that we have found the origins of these three parameters, what do they mean? Let's take a look:

 

This timing diagram also comes from the S3C2440 datasheet.

Through this picture and the comments in struct s3c2410_platform_nand, we can define these three parameters as follows.

TACLS: Indicates how long it takes after CLE/ALE is pulled high before nWE is allowed to be pulled low.

TWRPH0: Indicates the duration of nWE low level.

TWRPH1: Indicates the time after nWE becomes high level, CLE/ALE is allowed to be pulled low.

After knowing the meaning of the parameters, let's look at the datasheet of the NAND chip K9F1208U0C to determine the values ​​of these three parameters.

 

From this timing diagram, we can intuitively see that twp corresponds to parameter twrph0, and tclh corresponds to parameter twrph1.

But how to get tacls? The value of this parameter cannot be directly obtained from the graph. We need to take a detour, that is, subtract twp from tcls to get tacls.

In summary, in order to obtain the three parameters required by the nand controller, we need to obtain the three timing parameters of the nand chip: twp, tcls and tclh.

By looking up the datasheet of the nand, the values ​​of the three timing parameters are as follows:

twp=21, tcls=21, tclh=5.

Convert these three timing parameters into the three parameters we need, in nanoseconds (ns):

tacls = tcls-twp = 21 - 21 = 0 ns

twrph0 = twp = 21 ns

twrph1 = tclh = 5 ns

At this point, the values ​​of the three parameters have been successfully calculated  .

3. Configure the kernel

4. Verification

 After the above steps, compile the kernel and load it into nand, and start the system. In the Linux startup information, there will be the following output:

......

S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c24xx-nand s3c2440-nand: Tacls=1, 10ns Twrph0=3 30ns, Twrph1=1 10ns
s3c24xx-nand s3c2440-nand: NAND hardware ECC
NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit)
Scanning device for bad blocks
Bad eraseblock 781 at 0x0000061a0000
Bad eraseblock 1113 at 0x000008b20000
Bad eraseblock 1117 at 0x000008ba0000
Bad eraseblock 1481 at 0x00000b9 20000
Bad eraseblock 1566 at 0x00000c3c0000
Bad eraseblock 1885 at 0x00000eba0000
Creating 3 MTD partitions on "NAND 256MiB 3,3V 8-bit":
0x000000000000-0x000000040000 : "Uboot"
0x0000002000 00-0x000000500000 : "Kernel"
0x000000500000-0x000010000000 : "filesystem"

......

The above information indicates that the NAND FLASH has been accessed successfully.

Here, the output of the second line is explained.

UBOOT starts the S3C2440 operating frequency FCLK:HCLK:PCLK = 8:4:1,

If FCLK is 400Mhz, then HCLK is 100Mhz. According to the description of the NFCONF register, the three parameters in the register are all related to HCLK and must be multiples of 1/HCLK.

That is, a multiple of 1/100MHz=10ns.

From the output information in the second line above, it is obvious that Twrph0 is 30ns and Twrph1 is 10ns.

Since the parameter must be a multiple of 10ns and must be greater than the value given in the datasheet, it is rounded up to a multiple of 10, that is, 5ns is rounded up to 10ns and 21ns is rounded up to 30ns.

So why is Tacls 10ns? It is clearly 0ns. Does the driver not allow the parameter to be 0ns?

In the S3C2440 nand driver, the parameter value is determined by the following function:

[cpp]  view plain copy
 
  1. static  int  s3c_nand_calc_rate(int  wanted,  unsigned  long  clk,  int  max)  
  2.  
  3.     int  result;  
  4.   
  5.     result  DIV_ROUND_UP((wanted  clk),  NS_IN_KHZ);  
  6.   
  7.     pr_debug("result  %d  from  %ld,  %d\n",  result,  clk,  wanted);  
  8.   
  9.     if  (result  max)   
  10.         printk("%d  ns  is  too  big  for  current  clock  rate  %ld\n",  wanted,  clk);  
  11.         return  -1;  
  12.      
  13.   
  14.     if  (result  1)  
  15.         result  1;  
  16.   
  17.     return  result;  
  18.  


The parameter wanted is 0 (ns), and clk is HCLK/1000.

The DIV_ROUND_UP macro will return 0, but if restricts result, that is, it is not allowed to be less than 0, so the parameter value is set to 1 and returned to the calling function.

Keywords:S3C2440 Reference address:S3C2440 Linux driver transplantation——NAND driver

Previous article:STM32 timer input capture and output comparison
Next article:About the relationship between 3C2440 FCLK, HCLK, PCLK

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号