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