⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 omap-nor-flash.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************	omap-nor-flash.c	Self-Contained MTD driver for OMAP NOR Flash	- Supports Intel 28F256L18T and Intel 28F128L18T	- Automatically detects which one of the supported flashes is used        - Automatically detects the location of the supported flashes (CS3 or CS2B)	Author: MontaVista Software, Inc. <source@mvista.com>	Copyright (c) 2003 MontaVista Software, Inc.	The code for this driver is based on board/omap1610inn/flash.c from 	U-Boot 0.4.3:		 * (C) Copyright 2001	 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net	 *	 * (C) Copyright 2001	 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.	 *	 * (C) Copyright 2003	 * Texas Instruments, <www.ti.com>	 * Kshitij Gupta <Kshitij@ti.com>	The code for this driver is also based on syncflash.c:	 * MTD driver for Micron SyncFlash flash memory.	 *	 * Author: Jon McClintock <jonm@bluemug.com>	 *	 * Based loosely upon the LART flash driver, authored by 	 * Abraham vd Merwe	 * <abraham@2d3d.co.za>.	 *	 * Copyright 2003, Blue Mug, Inc. for Motorola, Inc.	 * Copyright 2003, MontaVista Software, Inc	 *	 * References:	 *	 *	 *     [1] MTD internal API documentation	 *             - http://www.linux-mtd.infradead.org/tech/	 *	Modifications:	Feb 2004, Texas Instruments, <www.ti.com>	- Ported to 2.6 Kernel (Feb 2004)	- Added address probing (Sept 2004)	This program is free software; you can redistribute it and/or	modify it under the terms of the GNU General Public License	as published by the Free Software Foundation; either version 2	of the License, or (at your option) any later version.	This program is distributed in the hope that it will be useful,	but WITHOUT ANY WARRANTY; without even the implied warranty of	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the	GNU General Public License for more details.	You should have received a copy of the GNU General Public License	along with this program; if not, write to the Free Software	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.*******************************************************************************/#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/types.h>#include <linux/version.h>#include <linux/errno.h>#include <linux/mtd/mtd.h>#include <asm/io.h>#include <linux/delay.h>#include <linux/mtd/partitions.h>#include <asm/arch/hardware.h>#ifdef CONFIG_MTD_PARTITIONS_MODULE#define CONFIG_MTD_PARTITIONS 1#endif#define NB_OF(x) (sizeof (x) / sizeof (x[0]))/* * General flash configuration parameters. */#define OMAP_BOOTLOADER_LEN 0x20000#define OMAP_PARAMS_LEN 0x20000#define OMAP_KERNEL_LEN 0x200000#define BUSWIDTH               2	/*warning: this is used only in some functions, the code is specific to 16-bit data bus */#define INTEL_MANUFACT	0x0089#define INTEL_ID_28F256L18T  0x880D	/* 256M = 128K x 255 + 32k x 4  */#define INTEL_ID_28F128L18T  0x880C	/* 128M = 128K x 127 + 32k x 4  */void __exit omap_flash_exit(void);int __init omap_flash_init(void);static int omap_flash_write(struct mtd_info *mtd, loff_t to,				size_t len, size_t * retlen,				const u_char * buf);static int omap_flash_write_word(__u32 offset, __u16 x);static int omap_flash_read(struct mtd_info *mtd, loff_t from,			       size_t len, size_t * retlen, u_char * buf);static int omap_flash_erase(struct mtd_info *mtd, struct erase_info *instr);static inline int omap_flash_sector_erase(__u32 offset);static int omap_flash_probe(void);static struct mtd_info mtd;#ifdef CONFIG_MACH_OMAP_H4#define E_REGIONS 4#else#define E_REGIONS 2#endifstatic struct mtd_erase_region_info erase_regions[E_REGIONS];static unsigned long omap_nor_flash_base;DECLARE_MUTEX(omap_flash_lock);#ifdef CONFIG_MTD_PARTITIONSstatic struct mtd_partition omap_partitions[] = {	/* bootloader */	{	      name:"bootloader",	      offset:0,	      size:OMAP_BOOTLOADER_LEN,	      mask_flags:MTD_WRITEABLE, /* force read-only */	},	/* bootloader params */	{	      name:"params",	      offset:MTDPART_OFS_APPEND,	      size:OMAP_PARAMS_LEN,	      mask_flags:0, 	},	/* kernel */	{	      name:"kernel",	      offset:MTDPART_OFS_APPEND,	      size:OMAP_KERNEL_LEN,	      mask_flags:0	},	/* file system */	{	      name:"file system",	      offset:MTDPART_OFS_APPEND,	      size:MTDPART_SIZ_FULL,	      mask_flags:0	}};#endifstatic char module_name[] = "OMAP NOR FLASH";#define omap_flash_inw(o) readw((omap_nor_flash_base+(__u32)o))#define omap_flash_outw(o,d) writew((__u16)(d),(omap_nor_flash_base+(__u32)o))/* Probe for NOR Flash on OMAP board at address omap_nor_flash_base */static intomap_flash_probe(void){	__u16 mfgid, devid;        __u32 offset; 	int i, j;	memset(&mtd, 0, sizeof (mtd));	down(&omap_flash_lock);	/* Write auto select command: read Manufacturer ID */	omap_flash_outw(0, 0x0090);	mfgid = omap_flash_inw(0);	/*manufacturer ID */	switch (mfgid) {	case INTEL_MANUFACT:		break;	default:		omap_flash_outw(0, 0x00FF);	/* restore read mode */		up(&omap_flash_lock);		printk(KERN_ERR		       "%s ERROR: no supported Flash device found\n",		       module_name);		return -ENXIO;	/* no or unknown flash  */	}	devid = omap_flash_inw(2);	/* device ID  */	switch (devid) {	case INTEL_ID_28F256L18T:		erase_regions[0].offset = 0;		erase_regions[0].erasesize = 128 * 1024;		erase_regions[0].numblocks = 255;		erase_regions[1].offset =		    erase_regions[0].erasesize * erase_regions[0].numblocks;		erase_regions[1].erasesize = 32 * 1024;		erase_regions[1].numblocks = 4;#ifdef CONFIG_MACH_OMAP_H4		erase_regions[2].offset = erase_regions[1].offset +		    erase_regions[1].erasesize * erase_regions[1].numblocks;		erase_regions[2].erasesize = 128 * 1024;		erase_regions[2].numblocks = 255;		erase_regions[3].offset = erase_regions[2].offset +		    erase_regions[2].erasesize * erase_regions[2].numblocks;		erase_regions[3].erasesize = 32 * 1024;		erase_regions[3].numblocks = 4;#endif		printk(KERN_INFO "%s: Intel 28F256L18T found at 0x%lx\n", module_name, omap_nor_flash_base);		break;	case INTEL_ID_28F128L18T:		erase_regions[0].offset = 0;		erase_regions[0].erasesize = 128 * 1024;		erase_regions[0].numblocks = 127;		erase_regions[1].offset =		    erase_regions[0].erasesize * erase_regions[0].numblocks;		erase_regions[1].erasesize = 32 * 1024;		erase_regions[1].numblocks = 4;#ifdef CONFIG_MACH_OMAP_H4		erase_regions[2].offset = erase_regions[1].offset +			erase_regions[1].erasesize * erase_regions[1].numblocks;		erase_regions[2].erasesize = 128 * 1024;		erase_regions[2].numblocks = 127;		erase_regions[3].offset = erase_regions[2].offset +		    erase_regions[2].erasesize * erase_regions[2].numblocks;		erase_regions[3].erasesize = 32 * 1024;		erase_regions[3].numblocks = 4;#endif		printk(KERN_INFO "%s: Intel 28F128L18T found at 0x%lx\n", module_name, omap_nor_flash_base);		break;	default:		omap_flash_outw(0, 0x00FF);	/* restore read mode */		up(&omap_flash_lock);		printk(KERN_ERR		       "%s ERROR: no supported Flash device found\n",		       module_name);		return -ENXIO;	/* no or unknown flash  */	}	omap_flash_outw(0, 0x00FF);	/* restore read mode */	mtd.name = module_name;	mtd.type = MTD_NORFLASH;	mtd.flags = MTD_CAP_NORFLASH;	mtd.erasesize = 128 * 1024;	mtd.numeraseregions = NB_OF(erase_regions);	mtd.eraseregions = erase_regions;	for (i = 0; i < NB_OF(erase_regions); i++) {		mtd.size +=		    erase_regions[i].erasesize * erase_regions[i].numblocks;		offset = erase_regions[i].offset;		for (j = 0; j < erase_regions[i].numblocks; j++) {			/* this sends the clear lock bit command */			omap_flash_outw(offset, 0x0060);			omap_flash_outw(offset, 0x00D0);			omap_flash_outw(offset, 0x00FF);/* reset to read mode */			offset += erase_regions[i].erasesize;		}	}	up(&omap_flash_lock);	mtd.owner = THIS_MODULE;	mtd.erase = omap_flash_erase;	mtd.read = omap_flash_read;	mtd.write = omap_flash_write;	return 0;}/* Erase a flash sector */static inline intomap_flash_sector_erase(__u32 offset){	__u16 status;	down(&omap_flash_lock);	/*erase sector */	omap_flash_outw(offset, 0x0050);	/* clear status register */	omap_flash_outw(offset, 0x0020);	/* erase setup */	omap_flash_outw(offset, 0x00D0);	/* erase confirm */	/* wait for erase complete while polling the status register */	while (((status = omap_flash_inw(offset)) & 0x0080) != 0x0080)		schedule_timeout(1);	omap_flash_outw(offset, 0x0050);	/* clear status register */	omap_flash_outw(offset, 0x00FF);	/* reset to read mode    */	up(&omap_flash_lock);	/* process status register */	if (status & (1 << 3)) {		printk(KERN_ERR		       "%s ERROR: erasing at address 0x%.8x: Vpp range error \n",

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -