Arm DRIVER: nand flash Driver Design

Source: Internet
Author: User

Nand flash Driver kernel implementation analysis process:

 

Analysis code

Handler // drivers/mtd/nand/nand_base.c identify nand flash based on nand_chip's underlying operation function and construct mtd_info nand_scan_ident nand_set_defaults if (! Chip-> select_chip) chip-> select_chip = nand_select_chip; // The default value is not applicable if (chip-> program func = NULL) chip-> program func = nand_command; chip-> program _ctrl (mtd, command, ctrl); if (! Chip-> read_byte) chip-> read_byte = nand_read_byte; readb (chip-> IO_ADDR_R); if (chip-> waitfunc = NULL) chip-> waitfunc = nand_wait; chip-> dev_ready nand_get_flash_type chip-> select_chip (mtd, 0); chip-> 1_func (mtd, nand_1__readid, 0x00,-1 ); * maf_id = chip-> read_byte (mtd); dev_id = chip-> read_byte (mtd); nand_scan_tail mtd-> erase = nand_erase; mtd-> read = nand_read; mtd-> write = nand_write; s3c2410_nand_add_partition add_mtd_partitions add_mtd_device list_for_each (this, & mtd_notifiers) {// ask. where can mtd_notifiers be set? //. drivers/mtd/mtdchar. c, mtd_blkdev.c call register_mtd_user struct mtd_notifier * not = list_entry (this, struct mtd_notifier, list); not-> add (mtd ); // mtd_policy_add and blktrans_policy_add read the mtd_policy_add class_device_create of the character device and then the list_for_each (this, & blktrans_majors) of the block device {// ask. where can I set blktrans_majors? //. drivers \ mtd \ mdblock. c or mtdblock_ro.c returns struct mtd_blktrans_ops * tr = list_entry (this, struct mtd_blktrans_ops, list); tr-> add_mtd (tr, mtd); Digest (drivers \ mtd \ mdblock. c) add_mtd_blktrans_dev alloc_disk gd-> queue = tr-> blkcore_priv-> rq; // tr-> blkcore_priv-> rq = blk_init_queue (mtd_blktrans_request, & tr-> blkcore_priv-> queue_lock); add_disk

 

 

Nand flash Driver Design Process:

 

 

Nand flash Driver code design:

 

Initi_nand.c

/* Refer to * drivers \ mtd \ nand \ s3c2410. c * drivers \ mtd \ nand \ at91_nand.c */# include <linux/module. h> # include <linux/types. h> # include <linux/init. h> # include <linux/kernel. h> # include <linux/string. h> # include <linux/ioport. h >#include <linux/platform_device.h> # include <linux/delay. h> # include <linux/err. h> # include <linux/slab. h> # include <linux/clk. h> # include <linux/mtd. h> # include <linux/mtd/nand. h> # includ E <linux/mtd/nand_ecc.h> # include <linux/mtd/partitions. h> # include <asm/io. h & gt; # include <asm/arch/regs-nand.h> # include <asm/arch/nand. h> struct detail {unsigned long nfconf; unsigned long nfcont; unsigned long nfcmd; unsigned long nfaddr; unsigned long nfdata; unsigned long nfeccd0; unsigned long nfeccd1; unsigned long nfeccd; unsigned long nfstat; unsigned long nfestat0; unsigned l Ong nfestat1; unsigned long nfmecc0; unsigned long nfmecc1; unsigned long nfsecc; unsigned long listener;}; static struct nand_chip * initi_nand; static struct mtd_info * initi_mtd; static struct initi_nand_regs * initi_nand_regs; static struct mtd_partition initi_nand_parts [] = {[0] = {. name = "bootloader ",. size = 0x00040000 ,. offset = 0 ,}, [1] = {. name = "params ",. offset = MTDPART _ OFS_APPEND ,. size = 0x00020000,}, [2] = {. name = "kernel ",. offset = MTDPART_OFS_APPEND ,. size = 0x00200000,}, [3] = {. name = "root ",. offset = MTDPART_OFS_APPEND ,. size = MTDPART_SIZ_FULL, }}; static void s3c2440_select_chip (struct mtd_info * mtd, int chipnr) {if (chipnr =-1) {/* uncheck: NFCONT [1] is set to 1 */initi_nand_regs-> nfcont | = (1 <1);} else {/* selected: NFCONT [1] is set to 0 */initi_nand_regs-> nfcont & = ~ (1 <1) ;}} static void s3c2440_1__ctrl (struct mtd_info * mtd, int dat, unsigned int ctrl) {if (ctrl & NAND_CLE) {/* command: NFCMMD = dat */initial_nand_regs-> nfcmd = dat;} else {/* address: NFADDR = dat */initial_nand_regs-> nfaddr = dat ;}} static int s3c2440_dev_ready (struct mtd_info * mtd) {return (initi_nand_regs-> nfstat & (1 <0);} static int initi_nand_init (void) {struct clk * clk; /* 1. assign an nand_chip struct */initial_nand = kzarloc (sizeof (struct nand_chip), GFP_KERNEL); struct = ioremap (0x4E000000, sizeof (struct initi_nand_regs);/* 2. set nand_chip * // * To set nand_chip for the nand_scan function. If you do not know how to set nand_scan, see how nand_scan is used. * It should provide: Select, send command, and send address, data sending, reading, and status determination functions */initi_nand-> select_chip = s3c2440_select_chip; initi_nand-> export _ctrl = s3c2440_1__ctrl; initi_nand-> IO_ADDR_R = & initi_nand_regs-> nfdata; ap-southeast-1. mode = NAND_ECC_SOFT;/* 3. hardware-related settings: set the time parameter * // * According to the nand flash manual to enable the clock of the nand flash Controller */clk = clk_get (NULL, "nand "); clk_enable (clk);/* CLKCON 'bit [4] * // * HCLK = 100 MHz * TACLS: How long does it take to send nWE signals after the CLE/ALE is sent, we can see from the NAND manual that CLE/ALE and nWE can be issued at the same time, So TACLS = 0 * TWRPH0: nWE pulse width, HCLK x (TWRPH0 + 1 ), we can see from the NAND manual that it must be greater than or equal to 12ns, so TWRPH0> = 1 * TWRPH1: how long will the CLE/ALE become low after the nWE becomes high, we can see from the NAND manual that it must be greater than or equal to 5ns, so TWRPH1> = 0 */# define TACLS 0 # define TWRPH0 1 # define TWRPH1 0 initi_nand_regs-> nfconf =) | (TWRPH0 <8) | (TWRPH1 <4);/* NFCONT: * BIT1-set to 1, deselect * BIT0-set to 1, enable the nand flash Controller */cloud_nand_regs-> nfcont = (1 <1) | (1 <0);/* 4. use: nand_scan */89c_mtd = kzarloc (sizeof (struct mtd_info), role); initi_mtd-> owner = THIS_MODULE; Role-> priv = initi_nand; nand_scan (initi_mtd, 1 ); /* Identify nand flash and construct mtd_info * // * 5. optional */values (initi_mtd, numbers, 4); // add_mtd_device (initi_mtd); return 0;} static void initi_nand_exit (void) {del_mtd_partitions (initi_mtd); kfree (initi_mtd ); iounmap (cloud_nand_regs); kfree (cloud_nand);} module_init (cloud_nand_init); module_exit (cloud_nand_exit); MODULE_LICENSE ("GPL ");

 

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.