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

📄 cstm_mips_ixx.c

📁 老版本的mtd-snap
💻 C
字号:
/* * $Id: cstm_mips_ixx.c,v 1.13 2005/01/12 22:34:35 gleixner Exp $ * * Mapping of a custom board with both AMD CFI and JEDEC flash in partitions. * Config with both CFI and JEDEC device support. * * Basically physmap.c with the addition of partitions and  * an array of mapping info to accomodate more than one flash type per board. * * Copyright 2000 MontaVista Software Inc. * *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT, *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *  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., *  675 Mass Ave, Cambridge, MA 02139, USA. */#include <linux/module.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/init.h>#include <asm/io.h>#include <linux/mtd/mtd.h>#include <linux/mtd/map.h>#include <linux/mtd/partitions.h>#include <linux/config.h>#include <linux/delay.h>#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)#define CC_GCR             0xB4013818#define CC_GPBCR           0xB401380A#define CC_GPBDR           0xB4013808#define CC_M68K_DEVICE     1#define CC_M68K_FUNCTION   6#define CC_CONFADDR        0xB8004000#define CC_CONFDATA        0xB8004004#define CC_FC_FCR          0xB8002004#define CC_FC_DCR          0xB8002008#define CC_GPACR           0xB4013802#define CC_GPAICR          0xB4013804#endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp){	static DEFINE_SPINLOCK(vpp_lock);	static int vpp_count = 0;	unsigned long flags;	spin_lock_irqsave(&vpp_lock, flags);	if (vpp) {		if (!vpp_count++) {			__u16	data;			__u8	data1;			static u8 first = 1;					// Set GPIO port B pin3 to high			data = *(__u16 *)(CC_GPBCR);			data = (data & 0xff0f) | 0x0040;			*(__u16 *)CC_GPBCR = data;			*(__u8 *)CC_GPBDR = (*(__u8*)CC_GPBDR) | 0x08;			if (first) {				first = 0;				/* need to have this delay for first				   enabling vpp after powerup */				udelay(40);			}		}	} else {		if (!--vpp_count) {			__u16	data;					// Set GPIO port B pin3 to high			data = *(__u16 *)(CC_GPBCR);			data = (data & 0xff3f) | 0x0040;			*(__u16 *)CC_GPBCR = data;			*(__u8 *)CC_GPBDR = (*(__u8*)CC_GPBDR) & 0xf7;		}	}	spin_unlock_irqrestore(&vpp_lock, flags);}#endif/* board and partition description */#define MAX_PHYSMAP_PARTITIONS    8struct cstm_mips_ixx_info {	char *name;	unsigned long window_addr;	unsigned long window_size;	int bankwidth;	int num_partitions;};#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)#define PHYSMAP_NUMBER  1  // number of board desc structs needed, one per contiguous flash type const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] = {    {   // 28F128J3A in 2x16 configuration        "big flash",     // name	0x08000000,      // window_addr	0x02000000,      // window_size        4,               // bankwidth	1,               // num_partitions    }};static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {{   // 28F128J3A in 2x16 configuration	{		.name = "main partition ",		.size = 0x02000000, // 128 x 2 x 128k byte sectors		.offset = 0,	},},};#else /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */#define PHYSMAP_NUMBER  1  // number of board desc structs needed, one per contiguous flash type const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] = {    {          "MTD flash",                   // name	CONFIG_MTD_CSTM_MIPS_IXX_START,      // window_addr	CONFIG_MTD_CSTM_MIPS_IXX_LEN,        // window_size        CONFIG_MTD_CSTM_MIPS_IXX_BUSWIDTH,   // bankwidth	1,                             // num_partitions    },};static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {{ 	{		.name = "main partition",		.size =  CONFIG_MTD_CSTM_MIPS_IXX_LEN,		.offset = 0,	},},};#endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */struct map_info cstm_mips_ixx_map[PHYSMAP_NUMBER];int __init init_cstm_mips_ixx(void){	int i;	int jedec;        struct mtd_info *mymtd;        struct mtd_partition *parts;	/* Initialize mapping */	for (i=0;i<PHYSMAP_NUMBER;i++) {		printk(KERN_NOTICE "cstm_mips_ixx flash device: 0x%lx at 0x%lx\n", 		       cstm_mips_ixx_board_desc[i].window_size, cstm_mips_ixx_board_desc[i].window_addr);		cstm_mips_ixx_map[i].phys = cstm_mips_ixx_board_desc[i].window_addr;		cstm_mips_ixx_map[i].virt = ioremap(cstm_mips_ixx_board_desc[i].window_addr, cstm_mips_ixx_board_desc[i].window_size);		if (!cstm_mips_ixx_map[i].virt) {			printk(KERN_WARNING "Failed to ioremap\n");			return -EIO;	        }		cstm_mips_ixx_map[i].name = cstm_mips_ixx_board_desc[i].name;		cstm_mips_ixx_map[i].size = cstm_mips_ixx_board_desc[i].window_size;		cstm_mips_ixx_map[i].bankwidth = cstm_mips_ixx_board_desc[i].bankwidth;#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)                cstm_mips_ixx_map[i].set_vpp = cstm_mips_ixx_set_vpp;#endif		simple_map_init(&cstm_mips_ixx_map[i]);		//printk(KERN_NOTICE "cstm_mips_ixx: ioremap is %x\n",(unsigned int)(cstm_mips_ixx_map[i].virt));	}#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)        setup_ITE_IVR_flash();#endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */	for (i=0;i<PHYSMAP_NUMBER;i++) {                parts = &cstm_mips_ixx_partitions[i][0];		jedec = 0;		mymtd = (struct mtd_info *)do_map_probe("cfi_probe", &cstm_mips_ixx_map[i]);		//printk(KERN_NOTICE "phymap %d cfi_probe: mymtd is %x\n",i,(unsigned int)mymtd);		if (!mymtd) {			jedec = 1;			mymtd = (struct mtd_info *)do_map_probe("jedec", &cstm_mips_ixx_map[i]);		        printk(KERN_NOTICE "cstm_mips_ixx %d jedec: mymtd is %x\n",i,(unsigned int)mymtd);		}		if (mymtd) {			mymtd->owner = THIS_MODULE;	                cstm_mips_ixx_map[i].map_priv_2 = (unsigned long)mymtd;		        add_mtd_partitions(mymtd, parts, cstm_mips_ixx_board_desc[i].num_partitions);		}		else	           return -ENXIO;	}	return 0;}static void __exit cleanup_cstm_mips_ixx(void){	int i;        struct mtd_info *mymtd;	for (i=0;i<PHYSMAP_NUMBER;i++) {	        mymtd = (struct mtd_info *)cstm_mips_ixx_map[i].map_priv_2;		if (mymtd) {			del_mtd_partitions(mymtd);			map_destroy(mymtd);		}		if (cstm_mips_ixx_map[i].virt) {			iounmap((void *)cstm_mips_ixx_map[i].virt);			cstm_mips_ixx_map[i].virt = 0;		}	}}#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)void PCISetULongByOffset(__u32 DevNumber, __u32 FuncNumber, __u32 Offset, __u32 data){	__u32	offset;	offset = ( unsigned long )( 0x80000000 | ( DevNumber << 11 ) + ( FuncNumber << 8 ) + Offset) ;	*(__u32 *)CC_CONFADDR = offset;		*(__u32 *)CC_CONFDATA = data;}void setup_ITE_IVR_flash(){		__u32	size, base;		size = 0x0e000000;		// 32MiB		base = (0x08000000) >> 8 >>1; // Bug: we must shift one more bit		/* need to set ITE flash to 32 bits instead of default 8 */#ifdef CONFIG_MIPS_IVR		*(__u32 *)CC_FC_FCR = 0x55;		*(__u32 *)CC_GPACR = 0xfffc;#else		*(__u32 *)CC_FC_FCR = 0x77;#endif		/* turn bursting off */		*(__u32 *)CC_FC_DCR = 0x0;		/* setup for one chip 4 byte PCI access */		PCISetULongByOffset(CC_M68K_DEVICE, CC_M68K_FUNCTION, 0x60, size | base);		PCISetULongByOffset(CC_M68K_DEVICE, CC_M68K_FUNCTION, 0x64, 0x02);}#endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */module_init(init_cstm_mips_ixx);module_exit(cleanup_cstm_mips_ixx);MODULE_LICENSE("GPL");MODULE_AUTHOR("Alice Hennessy <ahennessy@mvista.com>");MODULE_DESCRIPTION("MTD map driver for ITE 8172G and Globespan IVR boards");

⌨️ 快捷键说明

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