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

📄 nand.patch

📁 patches for linux-2.6.
💻 PATCH
📖 第 1 页 / 共 2 页
字号:
 	return 0; } +static void au1xxx_nand_select_chip(struct mtd_info *mtd, int chip)+{+	switch(chip) {+	case -1:+		/* deassert chip enable */+		au_writel(au_readl(MEM_STNDCTL) & ~(1<<(4+NAND_CS)), MEM_STNDCTL);+		break;+	case 0:+		/* assert (force assert) chip enable */+		au_writel(au_readl(MEM_STNDCTL) | (1<<(4+NAND_CS)) , MEM_STNDCTL);+		break;++	default:+		BUG();+	}+} -static void au1550_hwcontrol(struct mtd_info *mtd, int cmd)+static void au1xxx_nand_command (struct mtd_info *mtd, unsigned command,+		int column, int page_addr) { 	register struct nand_chip *this = mtd->priv; -	switch(cmd){+	/*+	 * Write out the command to the device.+	 */+	if (command == NAND_CMD_SEQIN) {+		int readcmd; -	case NAND_CTL_SETCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_CMD; break;-	case NAND_CTL_CLRCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; break;+		if (column >= mtd->oobblock) {+			/* OOB area */+			column -= mtd->oobblock;+			readcmd = NAND_CMD_READOOB;+		} else if (column < 256) {+			/* First 256 bytes --> READ0 */+			readcmd = NAND_CMD_READ0;+		} else {+			column -= 256;+			readcmd = NAND_CMD_READ1;+		}+		write_cmd_reg(readcmd);+	}+	write_cmd_reg(command);++	if (column != -1 || page_addr != -1) {++		/* Serially input address */+		if (column != -1)+			write_addr_reg(column);+		if (page_addr != -1) {+			write_addr_reg((unsigned char) (page_addr & 0xff));+			write_addr_reg(((page_addr >> 8) & 0xff));+			/* One more address cycle for higher density devices */+			if (mtd->size & 0x0c000000)+				write_addr_reg((unsigned char) ((page_addr >> 16) & 0x0f));+		}+	} -	case NAND_CTL_SETALE: this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR; break;-	case NAND_CTL_CLRALE: -		this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; -		/* FIXME: Nobody knows why this is neccecary, -		 * but it works only that way */-		udelay(1); +	switch (command) {++	case NAND_CMD_PAGEPROG:+	case NAND_CMD_ERASE1:+	case NAND_CMD_ERASE2:+	case NAND_CMD_SEQIN:+	case NAND_CMD_STATUS: 		break; -	case NAND_CTL_SETNCE: -		/* assert (force assert) chip enable */-		au_writel((1<<(4+NAND_CS)) , MEM_STNDCTL); break;+	case NAND_CMD_RESET:+		if (this->dev_ready) 		break;+		udelay(this->chip_delay);+		write_cmd_reg(NAND_CMD_STATUS);+		while ( !(read_data_reg() & 0x40));+		return; -	case NAND_CTL_CLRNCE: - 		/* deassert chip enable */-		au_writel(0, MEM_STNDCTL); break;-		break;+	/* This applies to read commands */+	default:+		udelay (this->chip_delay); 	} -	this->IO_ADDR_R = this->IO_ADDR_W;-	-	/* Drain the writebuffer */-	au_sync();+	/* wait until command is processed */+	while (!this->dev_ready(mtd)); } -int au1550_device_ready(struct mtd_info *mtd)-{-	int ret = (au_readl(MEM_STSTAT) & 0x1) ? 1 : 0;-	au_sync();-	return ret;-}  /*  * Main initialization routine  */-int __init au1550_init (void)+int __init au1xxx_nand_init (void) { 	struct nand_chip *this; 	u16 boot_swapboot = 0; /* default value */-	int retval;+	u32 mem_staddr;+	u32 nand_phys;  	/* Allocate memory for MTD device structure and private data */-	au1550_mtd = kmalloc (sizeof(struct mtd_info) + +	au1xxx_nand_mtd = kmalloc (sizeof(struct mtd_info) + 			sizeof (struct nand_chip), GFP_KERNEL);-	if (!au1550_mtd) {+	if (!au1xxx_nand_mtd) { 		printk ("Unable to allocate NAND MTD dev structure.\n"); 		return -ENOMEM; 	}  	/* Get pointer to private data */-	this = (struct nand_chip *) (&au1550_mtd[1]);+	this = (struct nand_chip *) (&au1xxx_nand_mtd[1]);  	/* Initialize structures */-	memset((char *) au1550_mtd, 0, sizeof(struct mtd_info));+	memset((char *) au1xxx_nand_mtd, 0, sizeof(struct mtd_info)); 	memset((char *) this, 0, sizeof(struct nand_chip));  	/* Link the private data with the MTD structure */-	au1550_mtd->priv = this;+	au1xxx_nand_mtd->priv = this; +	/* disable interrupts */+	au_writel(au_readl(MEM_STNDCTL) & ~(1<<8), MEM_STNDCTL); -	/* MEM_STNDCTL: disable ints, disable nand boot */-	au_writel(0, MEM_STNDCTL);+	/* disable NAND boot */+	au_writel(au_readl(MEM_STNDCTL) & ~(1<<0), MEM_STNDCTL);  #ifdef CONFIG_MIPS_PB1550 	/* set gpio206 high */ 	au_writel(au_readl(GPIO2_DIR) & ~(1<<6), GPIO2_DIR); +	/* Pb1550: check boot configuration to make sure NAND is visible */ 	boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) |  		((bcsr->status >> 6)  & 0x1); 	switch (boot_swapboot) {@@ -381,6 +302,7 @@ int __init au1550_init (void) 		case 0xD: 			/* x16 NAND Flash */ 			nand_width = 0;+			printk("Pb1550 NAND: 16-bit NAND not supported by MTD\n"); 			break; 		case 1: 		case 9:@@ -392,86 +314,123 @@ int __init au1550_init (void) 			break; 		default: 			printk("Pb1550 NAND: bad boot:swap\n");-			retval = -EINVAL;-			goto outmem;+			kfree(au1xxx_nand_mtd);+			return 1; 	} #endif -	/* Configure RCE1 - should be done by YAMON */-	au_writel(0x5 | (nand_width << 22), 0xB4001010); /* MEM_STCFG1 */-	au_writel(NAND_TIMING, 0xB4001014); /* MEM_STTIME1 */-	au_sync();--	/* setup and enable chip select, MEM_STADDR1 */-	/* we really need to decode offsets only up till 0x20 */-	au_writel((1<<28) | (NAND_PHYS_ADDR>>4) | -			(((NAND_PHYS_ADDR + 0x1000)-1) & (0x3fff<<18)>>18), -			MEM_STADDR1);-	au_sync();+	/* Configure chip-select; normally done by boot code, e.g. YAMON */+#ifdef NAND_STCFG+	if (NAND_CS == 0) {+		au_writel(NAND_STCFG,  MEM_STCFG0);+		au_writel(NAND_STTIME, MEM_STTIME0);+		au_writel(NAND_STADDR, MEM_STADDR0);+	}+	if (NAND_CS == 1) {+		au_writel(NAND_STCFG,  MEM_STCFG1);+		au_writel(NAND_STTIME, MEM_STTIME1);+		au_writel(NAND_STADDR, MEM_STADDR1);+	}+	if (NAND_CS == 2) {+		au_writel(NAND_STCFG,  MEM_STCFG2);+		au_writel(NAND_STTIME, MEM_STTIME2);+		au_writel(NAND_STADDR, MEM_STADDR2);+	}+	if (NAND_CS == 3) {+		au_writel(NAND_STCFG,  MEM_STCFG3);+		au_writel(NAND_STTIME, MEM_STTIME3);+		au_writel(NAND_STADDR, MEM_STADDR3);+	}+#endif -	p_nand = ioremap(NAND_PHYS_ADDR, 0x1000);+	/* Locate NAND chip-select in order to determine NAND physical address */+	mem_staddr = 0x00000000;+	if (((au_readl(MEM_STCFG0) & 0x7) == 0x5) && (NAND_CS == 0))+		mem_staddr = au_readl(MEM_STADDR0);+	else+	if (((au_readl(MEM_STCFG1) & 0x7) == 0x5) && (NAND_CS == 1))+		mem_staddr = au_readl(MEM_STADDR1);+	else+	if (((au_readl(MEM_STCFG2) & 0x7) == 0x5) && (NAND_CS == 2))+		mem_staddr = au_readl(MEM_STADDR2);+	else+	if (((au_readl(MEM_STCFG3) & 0x7) == 0x5) && (NAND_CS == 3))+		mem_staddr = au_readl(MEM_STADDR3);++	if (mem_staddr == 0x00000000) {+		printk("Au1xxx NAND: ERROR WITH NAND CHIP-SELECT\n");+		kfree(au1xxx_nand_mtd);+		return 1;+	}+	nand_phys = (mem_staddr << 4) & 0xFFFC0000;++	p_nand = (volatile struct nand_regs *)ioremap(nand_phys, 0x1000);++	/* make controller and MTD agree */+	if (NAND_CS == 0)+		nand_width = au_readl(MEM_STCFG0) & (1<<22);+	if (NAND_CS == 1)+		nand_width = au_readl(MEM_STCFG1) & (1<<22);+	if (NAND_CS == 2)+		nand_width = au_readl(MEM_STCFG2) & (1<<22);+	if (NAND_CS == 3)+		nand_width = au_readl(MEM_STCFG3) & (1<<22);  	/* Set address of hardware control function */-	this->hwcontrol = au1550_hwcontrol;-	this->dev_ready = au1550_device_ready;+	this->hwcontrol = au1xxx_hwcontrol;+	this->dev_ready = au1xxx_device_ready; 	/* 30 us command delay time */ 	this->chip_delay = 30;		-	this->eccmode = NAND_ECC_SOFT;--	this->options = NAND_NO_AUTOINCR; -	if (!nand_width)-		this->options |= NAND_BUSWIDTH_16;+	this->cmdfunc = au1xxx_nand_command;+	this->select_chip = au1xxx_nand_select_chip;+	this->write_byte = au1xxx_nand_write_byte;+	this->read_byte = au1xxx_nand_read_byte;+	this->write_buf = au1xxx_nand_write_buf;+	this->read_buf = au1xxx_nand_read_buf;+	this->verify_buf = au1xxx_nand_verify_buf;+	this->eccmode = NAND_ECC_SOFT; -	this->read_byte = (!nand_width) ? au_read_byte16 : au_read_byte;-	this->write_byte = (!nand_width) ? au_write_byte16 : au_write_byte;-	this->write_word = au_write_word;-	this->read_word = au_read_word;-	this->write_buf = (!nand_width) ? au_write_buf16 : au_write_buf;-	this->read_buf = (!nand_width) ? au_read_buf16 : au_read_buf;-	this->verify_buf = (!nand_width) ? au_verify_buf16 : au_verify_buf;+	/* Set internal data buffer */+	this->data_buf = data_buf;+	this->oob_buf = oob_buf;  	/* Scan to find existence of the device */-	if (nand_scan (au1550_mtd, 1)) {-		retval = -ENXIO;-		goto outio;+	if (nand_scan (au1xxx_nand_mtd, 1)) {+		kfree (au1xxx_nand_mtd);+		return -ENXIO; 	}  	/* Register the partitions */-	add_mtd_partitions(au1550_mtd, partition_info, NUM_PARTITIONS);+	add_mtd_partitions(au1xxx_nand_mtd, partition_info, NB_OF(partition_info));  	return 0;-- outio:-	iounmap ((void *)p_nand);-	- outmem:-	kfree (au1550_mtd);-	return retval; } -module_init(au1550_init);+module_init(au1xxx_nand_init);  /*  * Clean up routine  */ #ifdef MODULE-static void __exit au1550_cleanup (void)+static void __exit au1xxx_nand_cleanup (void) {-	struct nand_chip *this = (struct nand_chip *) &au1550_mtd[1];+	struct nand_chip *this = (struct nand_chip *) &au1xxx_nand_mtd[1]; -	/* Release resources, unregister device */-	nand_release (au1550_mtd);+	iounmap ((void *)p_nand); -	/* Free the MTD device structure */-	kfree (au1550_mtd);+	/* Unregister partitions */+	del_mtd_partitions(au1xxx_nand_mtd); -	/* Unmap */-	iounmap ((void *)p_nand);+	/* Unregister the device */+	del_mtd_device (au1xxx_nand_mtd);++	/* Free the MTD device structure */+	kfree (au1xxx_nand_mtd); }-module_exit(au1550_cleanup);+module_exit(au1xxx_nand_cleanup); #endif  MODULE_LICENSE("GPL"); MODULE_AUTHOR("Embedded Edge, LLC");-MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on Pb1550 board");+MODULE_DESCRIPTION("NAND flash support for Alchemy");diff -rwbupN linux26-cvs/drivers/mtd/nand/Kconfig linux26-nand/drivers/mtd/nand/Kconfig--- linux26-cvs/drivers/mtd/nand/Kconfig	2005-06-14 23:48:19.000000000 -0500+++ linux26-nand/drivers/mtd/nand/Kconfig	2005-06-15 00:04:36.260027624 -0500@@ -73,11 +73,11 @@ config MTD_NAND_TX4938NDFMC 	  Toshiba RBTX4938 reference board.  config MTD_NAND_AU1550-	tristate "Au1550 NAND support"-	depends on SOC_AU1550 && MTD_NAND+	tristate "Au1550/1200 NAND support"+	depends on (SOC_AU1200 || SOC_AU1550) && MTD_NAND 	help 	  This enables the driver for the NAND flash controller on the-	  AMD/Alchemy 1550 SOC.+	  AMD/Alchemy 1550/1200 SOC .  config MTD_NAND_RTC_FROM4 	tristate "Renesas Flash ROM 4-slot interface board (FROM_BOARD4)"

⌨️ 快捷键说明

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