rk30 nand driver.
authorzhaoyifeng <zyf@rock-chips.com>
Tue, 7 Feb 2012 07:16:46 +0000 (15:16 +0800)
committerzhaoyifeng <zyf@rock-chips.com>
Tue, 7 Feb 2012 07:16:46 +0000 (15:16 +0800)
arch/arm/mach-rk30/board-rk30-sdk.c [changed mode: 0644->0755]
drivers/mtd/rknand/Makefile
drivers/mtd/rknand/epphal.h
drivers/mtd/rknand/nand_config.h
drivers/mtd/rknand/rknand_base_ko.c

old mode 100644 (file)
new mode 100755 (executable)
index 4a68cf2..494cc9b
 
 #include <mach/board.h>
 #include <mach/hardware.h>
+//#include "devices.h"
+#include <mach/io.h>
+
+#if defined(CONFIG_MTD_NAND_RK29XX)  
+
+static struct resource rk30xxnand_resources[] = {
+       {
+               .start  = RK30_NANDC_PHYS,
+               .end    = RK30_NANDC_PHYS+RK30_NANDC_SIZE -1,
+               .flags  = IORESOURCE_MEM,
+       }
+};
+
+struct platform_device rk30xx_device_nand = {
+       .name   = "rk30xxnand", 
+       .id             =  -1, 
+       .resource       = rk30xxnand_resources,
+       .num_resources= ARRAY_SIZE(rk30xxnand_resources),
+};
+#endif
+
+static struct platform_device *devices[] __initdata = {
+#ifdef CONFIG_MTD_NAND_RK29XX
+       &rk30xx_device_nand,
+#endif
+};
+static void __init machine_rk30_board_init(void)
+{
+    platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
 
 static void __init rk30_reserve(void)
 {
@@ -46,4 +77,5 @@ MACHINE_START(RK30, "RK30board")
        .init_irq       = rk30_init_irq,
        .timer          = &rk30_timer,
     .reserve    = &rk30_reserve,
+       .init_machine   = machine_rk30_board_init,
 MACHINE_END
index c10b5b6165416ecb3b6f59987646f42afc5c5e02..32176787dfbc4c5371620616227e855d0f9f3ff1 100755 (executable)
@@ -4,6 +4,6 @@
 # $Id: Makefile,v 1.3 2011/01/21 10:12:56 Administrator Exp $\r
 #\r
 obj-$(CONFIG_MTD_NAND_RK29XX)          += rknand_base_ko.o \r
-\r
+obj-$(CONFIG_MTD_RKNAND_BUFFER)                += rk30xxnand_ko.o\r
 \r
 \r
index 960913bf6640cb50e310a991532558d5cb6db2f7..b966cea8a404b6b7e2fe327351476c78b07b63a5 100755 (executable)
@@ -428,67 +428,39 @@ typedef enum _CRU_RST
 }eCRU_RST;\r
 \r
 //GRF Registers\r
- typedef volatile struct tagGRF_REG\r
-{\r
-    uint32 GRF_GPIO0_DIR;\r
-    uint32 GRF_GPIO1_DIR;\r
-    uint32 GRF_GPIO2_DIR;\r
-    uint32 GRF_GPIO3_DIR;\r
-    uint32 GRF_GPIO4_DIR;\r
-    uint32 GRF_GPIO5_DIR;\r
-    uint32 GRF_GPIO0_DO;\r
-    uint32 GRF_GPIO1_DO;\r
-    uint32 GRF_GPIO2_DO;\r
-    uint32 GRF_GPIO3_DO;\r
-    uint32 GRF_GPIO4_DO;\r
-    uint32 GRF_GPIO5_DO;\r
-    uint32 GRF_GPIO0_EN;\r
-    uint32 GRF_GPIO1_EN;\r
-    uint32 GRF_GPIO2_EN;\r
-    uint32 GRF_GPIO3_EN;\r
-    uint32 GRF_GPIO4_EN;\r
-    uint32 GRF_GPIO5_EN;\r
-    uint32 GRF_GPIO0L_IOMUX;\r
-    uint32 GRF_GPIO0H_IOMUX;\r
-    uint32 GRF_GPIO1L_IOMUX;\r
-    uint32 GRF_GPIO1H_IOMUX;\r
-    uint32 GRF_GPIO2L_IOMUX;\r
-    uint32 GRF_GPIO2H_IOMUX;\r
-    uint32 GRF_GPIO3L_IOMUX;\r
-    uint32 GRF_GPIO3H_IOMUX;\r
-    uint32 GRF_GPIO4L_IOMUX;\r
-    uint32 GRF_GPIO4H_IOMUX;\r
-    uint32 GRF_GPIO5L_IOMUX;\r
-    uint32 GRF_GPIO5H_IOMUX; \r
-    uint32 GRF_GPIO0_PULL1;\r
-    uint32 GRF_GPIO1_PULL1;\r
-    uint32 GRF_GPIO2_PULL1;\r
-    uint32 GRF_GPIO3_PULL1;\r
-    uint32 GRF_GPIO4_PULL1;\r
-    uint32 GRF_GPIO5_PULL1;\r
-    uint32 GRF_GPIO6_PULL1;\r
-    uint32 GRF_UOC0_CON0;\r
-    uint32 GRF_UOC1_CON0;\r
-    uint32 GRF_USB_CON;\r
-    uint32 GRF_CPU_CON0;\r
-    uint32 GRF_CPU_CON1;\r
-    uint32 GRF_CPU_STATUS;\r
-    uint32 GRF_MEM_CON;\r
-    uint32 GRF_MEM_STATUS0;\r
-    uint32 GRF_MEM_STATUS1;\r
-    uint32 GRF_MEM_STATUS2;\r
-    uint32 GRF_SOC_CON0;\r
-    uint32 GRF_SOC_CON1;\r
-    uint32 GRF_SOC_CON2;\r
-    uint32 GRF_SOC_CON3;\r
-    uint32 GRF_SOC_CON4;\r
-    uint32 GRF_OS_REG0;\r
-    uint32 GRF_OS_REG1;\r
-    uint32 GRF_OS_REG2;\r
-    uint32 GRF_OS_REG3;\r
+    typedef struct tagGPIO_LH\r
+    {\r
+        uint32 GPIOL;\r
+        uint32 GPIOH;\r
+    }GPIO_LH_T;\r
+    \r
+    typedef struct tagGPIO_IOMUX\r
+    {\r
+        uint32 GPIOA_IOMUX;\r
+        uint32 GPIOB_IOMUX;\r
+        uint32 GPIOC_IOMUX;\r
+        uint32 GPIOD_IOMUX;\r
+    }GPIO_IOMUX_T;\r
+    //REG FILE registers\r
+    typedef volatile struct tagGRF_REG\r
+    {\r
+        GPIO_LH_T GRF_GPIO_DIR[7];\r
+        GPIO_LH_T GRF_GPIO_DO[7];\r
+        GPIO_LH_T GRF_GPIO_EN[7];\r
+        GPIO_IOMUX_T GRF_GPIO_IOMUX[7];\r
+        GPIO_LH_T GRF_GPIO_PULL[7];\r
+        uint32 GRF_SOC_CON[3];\r
+        uint32 GRF_SOC_STATUS0;\r
+        uint32 GRF_DMAC1_CON[3];\r
+        uint32 GRF_DMAC2_CON[4];\r
+        uint32 GRF_UOC0_CON[3];\r
+        uint32 GRF_UOC1_CON[4];\r
+        uint32 GRF_DDRC_CON0;\r
+        uint32 GRF_DDRC_STAT;\r
+        uint32 reserved[(0x1c8-0x1a0)/4];\r
+        uint32 GRF_OS_REG[4];\r
+    } GRF_REG, *pGRF_REG;\r
     \r
-}GRF_REG, *pGRF_REG,*pAPB_REG, *pREG_FILE;\r
\r
 //TIMER Registers\r
 typedef volatile struct tagTIMER_STRUCT\r
 {\r
@@ -522,7 +494,7 @@ typedef struct tagSCU_CLK_INFO
     uint32 armFreqLast;\r
 }SCU_CLK_INFO,*pSCU_CLK_INFO;\r
  \r
-#define g_cruReg ((pCRU_REG)RK29_CRU_BASE)\r
+#define g_cruReg ((pCRU_REG)RK29_CRU_REG_BASE)\r
 \r
 #endif\r
        \r
index ecdb030d97b05b1fd1acd99c3ee14a871f9f0ecb..d9483401b553c682df11d45bec0a6cc6b080e5c4 100755 (executable)
@@ -23,10 +23,16 @@ Revision:   1.00
 #include    <mach/board.h>\r
 #include    <mach/gpio.h>\r
 #include    <asm/dma.h>\r
-#include    <mach/rk29-dma-pl330.h>\r
 #include    "typedef.h"\r
+\r
+#ifdef CONFIG_MACH_RK30_SDK\r
+#include    <mach/io.h>\r
+#include    <mach/irqs.h>\r
+#else\r
 #include    <mach/rk29_iomap.h>\r
 #include    <mach/iomux.h>\r
+#endif\r
+\r
 #include    <linux/interrupt.h>\r
 #include    "epphal.h"\r
 \r
@@ -64,7 +70,7 @@ extern void rkNand_cond_resched(void);
 \r
 extern unsigned long rk_dma_mem_alloc(int size);\r
 extern unsigned long rk_dma_mem_free(unsigned long buf);\r
-\r
+#undef PRINTF\r
 #define PRINTF RKNAND_DEBUG\r
 #endif\r
 \r
index 5effa3d67160b13b4f2ecfeccc6cc3577575a684..79681db50944544f78f1020aa14780acc5b1500b 100755 (executable)
@@ -24,8 +24,8 @@
 #include "rknand_base.h"\r
 \r
 \r
-#define DRIVER_NAME    "rk29xxnand"\r
-const char rknand_base_version[] = "rknand_base.c version: 4.30 20111009";\r
+#define DRIVER_NAME    "rk30xxnand"\r
+const char rknand_base_version[] = "rknand_base.c version: 4.32 20120103";\r
 #define NAND_DEBUG_LEVEL0 0\r
 #define NAND_DEBUG_LEVEL1 1\r
 #define NAND_DEBUG_LEVEL2 2\r
@@ -58,10 +58,50 @@ static const int s_debug = 0;
 #define NANDPROC_ROOT  NULL\r
 #endif\r
 \r
+//#define RKNAND_TRAC_EN\r
+#ifdef RKNAND_TRAC_EN\r
+static struct proc_dir_entry *my_trac_proc_entry;\r
+#define MAX_TRAC_BUFFER_SIZE     (long)(2048 * 8 * 512) //sector\r
+static char grknand_trac_buf[MAX_TRAC_BUFFER_SIZE];\r
+static char *ptrac_buf = grknand_trac_buf;\r
+void trac_log(long lba,int len, int mod)\r
+{\r
+    if(mod)\r
+        ptrac_buf += sprintf(ptrac_buf,"W %d %d \n",lba,len);\r
+    else\r
+        ptrac_buf += sprintf(ptrac_buf,"R %d %d \n",lba,len);\r
+}\r
+\r
+static int rkNand_trac_read(char *page, char **start, off_t off, int count, int *eof,\r
+                   void *data)\r
+{\r
+       char *p = page;\r
+       int len;\r
+\r
+        len = ptrac_buf - grknand_trac_buf - off;\r
+     printk("rkNand_trac_read: page=%x,off=%x,count=%x ,len=%x \n",(int)page,(int)off,count,len);\r
+\r
+       if (len < 0)\r
+               len = 0;\r
+               \r
+        if(len > count)\r
+           len = count;\r
+\r
+        memcpy(p,grknand_trac_buf + off,len);\r
+\r
+       *eof = (len <  count) ? 1 : 0;\r
+       *start = page;\r
+       if(len < count)\r
+        ptrac_buf = grknand_trac_buf;\r
+       return len;\r
+}\r
+\r
+#endif\r
+\r
 #define     DATA_LEN            (1024*8*2/4)              //Êý¾Ý¿éµ¥Î»word\r
 #define     SPARE_LEN           (32*8*2/4)               //УÑéÊý¾Ý³¤¶È\r
 #define     PAGE_LEN            (DATA_LEN+SPARE_LEN)    //ÿ¸öÊý¾Ýµ¥Î»µÄ³¤¶È\r
-#define MAX_BUFFER_SIZE     (long)(2048 * 8) //sector\r
+#define     MAX_BUFFER_SIZE     (long)(2048 * 8) //sector\r
 long grknand_buf[MAX_BUFFER_SIZE * 512/4] __attribute__((aligned(4096)));\r
 long grknand_dma_buf[PAGE_LEN*4*5] __attribute__((aligned(4096)));\r
 \r
@@ -82,6 +122,9 @@ static int rkNand_proc_read(char *page,
             buf += gpNandInfo->proc_ftlread(buf);\r
         if(gpNandInfo->proc_bufread)\r
             buf += gpNandInfo->proc_bufread(buf);\r
+#ifdef RKNAND_TRAC_EN\r
+        buf += sprintf(buf, "trac data len:%d\n", ptrac_buf - grknand_trac_buf);\r
+#endif\r
     }\r
        return buf - page < count ? buf - page : count;\r
 }\r
@@ -98,6 +141,17 @@ static void rk28nand_create_procfs(void)
         my_proc_entry->read_proc = rkNand_proc_read;\r
         my_proc_entry->data = NULL;\r
     } \r
+#ifdef RKNAND_TRAC_EN\r
+    /* Install the proc_fs entry */\r
+    my_trac_proc_entry = create_proc_entry("rknand_trac",\r
+                           S_IRUGO | S_IFREG,\r
+                           NANDPROC_ROOT);\r
+    if (my_trac_proc_entry) {\r
+        my_trac_proc_entry->write_proc = NULL;\r
+        my_trac_proc_entry->read_proc = rkNand_trac_read;\r
+        my_trac_proc_entry->data = NULL;\r
+    } \r
+#endif\r
 }\r
 \r
 void printk_write_log(long lba,int len, const u_char *pbuf)\r
@@ -117,6 +171,10 @@ static int rk28xxnand_read(struct mtd_info *mtd, loff_t from, size_t len,
        int ret = 0;\r
        int sector = len>>9;\r
        int LBA = (int)(from>>9);\r
+#ifdef RKNAND_TRAC_EN\r
+    //trac_log(LBA,sector,0);\r
+#endif\r
+       //printk("R %d %d \n",(int)LBA,sector);\r
        //if(rknand_debug)\r
     //   printk("rk28xxnand_read: from=%x,sector=%x,\n",(int)LBA,sector);\r
     if(sector && gpNandInfo->ftl_read)\r
@@ -133,6 +191,11 @@ static int rk28xxnand_write(struct mtd_info *mtd, loff_t from, size_t len,
        int ret = 0;\r
        int sector = len>>9;\r
        int LBA = (int)(from>>9);\r
+#ifdef RKNAND_TRAC_EN\r
+    trac_log(LBA,sector,1);\r
+#endif\r
+       //printk("W %d %d \n",(int)LBA,sector);\r
+    //return 0;\r
        //printk("*");\r
        //if(rknand_debug)\r
     //    printk(KERN_NOTICE "write: from=%lx,sector=%x\n",(int)LBA,sector);\r
@@ -141,7 +204,7 @@ static int rk28xxnand_write(struct mtd_info *mtd, loff_t from, size_t len,
        {\r
                if(LBA < SysImageWriteEndAdd)//0x4E000)\r
                {\r
-                       NAND_DEBUG(NAND_DEBUG_LEVEL0,">>> FtlWriteImage: LBA=0x%08X  sector=%d\n",LBA, sector);\r
+                       //NAND_DEBUG(NAND_DEBUG_LEVEL0,">>> FtlWriteImage: LBA=0x%08X  sector=%d\n",LBA, sector);\r
             ret = gpNandInfo->ftl_write(LBA, sector, (void *)buf,1);\r
         }\r
                else\r
@@ -163,7 +226,7 @@ static int rk28xxnand_erase(struct mtd_info *mtd, struct erase_info *instr)
 \r
 static void rk28xxnand_sync(struct mtd_info *mtd)\r
 {\r
-       NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk28xxnand_sync: \n");\r
+       NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk30xxnand_sync: \n");\r
     if(gpNandInfo->ftl_sync)\r
         gpNandInfo->ftl_sync();\r
 }\r
@@ -291,6 +354,68 @@ static int rk28xxnand_init(struct rknand_info *nand_info)
 #ifdef CONFIG_MTD_CMDLINE_PARTS\r
 const char *part_probes[] = { "cmdlinepart", NULL }; \r
 #endif \r
+static struct mtd_partition rk30_partition_info[] = {\r
+       { \r
+         name: "misc",\r
+         offset:  0x2000*0x200,\r
+         size:    0x2000*0x200,//100MB\r
+       },\r
+\r
+       { \r
+         name: "kernel",\r
+         offset:  0x4000*0x200,\r
+         size:   0x4000*0x200,//200MB\r
+       },\r
+\r
+       { \r
+         name: "boot",\r
+         offset:  0x8000*0x200,\r
+         size:   0x8000*0x200,//200MB\r
+       },\r
+       \r
+       { \r
+         name: "recovery",\r
+         offset:  0x10000*0x200,\r
+         size:   0x8000*0x200,//200MB\r
+       },\r
+       \r
+       { \r
+         name: "backup",\r
+         offset:  0x00018000*0x200,\r
+         size:   0x000C0000*0x200,//200MB\r
+       },\r
+       \r
+       { \r
+         name: "cache",\r
+         offset:  0x000D8000*0x200,\r
+         size:   0x00040000*0x200,//200MB\r
+       },\r
+       \r
+       { \r
+         name: "userdata",\r
+         offset:  0x00118000*0x200,\r
+         size:   0x00100000*0x200,//200MB\r
+       },\r
+       \r
+       { \r
+         name: "kpanic",\r
+         offset:  0x00218000*0x200,\r
+         size:   0x00002000*0x200,//200MB\r
+       },\r
+       \r
+       { \r
+         name: "system",\r
+         offset:  0x0021A000*0x200,\r
+         size:   0x000A0000*0x200,//200MB\r
+       },\r
+       \r
+       { \r
+         name: "user",\r
+         offset:  0x002BA000*0x200,\r
+         size:   0x000A0000*0x200,//200MB\r
+       },\r
+};\r
+\r
 \r
 static int rk29xxnand_add_partitions(struct rknand_info *nand_info)\r
 {\r
@@ -317,6 +442,14 @@ static int rk29xxnand_add_partitions(struct rknand_info *nand_info)
 #endif\r
     } \r
 #endif \r
+    g_num_partitions = 10;\r
+    rknand_parts = rk30_partition_info;\r
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))\r
+               return mtd_device_register(&rknand_mtd, rknand_parts, g_num_partitions);\r
+#else\r
+               return add_mtd_partitions(&(rknand_mtd), rknand_parts, g_num_partitions);\r
+#endif\r
+\r
        return 0;\r
 }\r
 \r
@@ -343,6 +476,10 @@ int add_rknand_device(struct rknand_info * prknand_Info)
     }\r
 \r
     gpNandInfo->SysImageWriteEndAdd = SysImageWriteEndAdd;\r
+    \r
+    //if(gpNandInfo->nand_timing_config)\r
+    //    gpNandInfo->nand_timing_config(100*1000);\r
+        \r
     return 0;\r
 }\r
 \r
@@ -358,7 +495,8 @@ static int rknand_probe(struct platform_device *pdev)
 {\r
        struct rknand_info *nand_info;\r
        int err = 0;\r
-       NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk28xxnand_probe: \n");\r
+       printk("nand init...\n");\r
+       NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk30xxnand_probe: \n");\r
        gpNandInfo = kzalloc(sizeof(struct rknand_info), GFP_KERNEL);\r
        if (!gpNandInfo)\r
                return -ENOMEM;\r