Add NAND flash/YAFFS2 patches for RB532 by David Goodenough Read the kernel command line from an otherwise unused area of the kernel image (will be used for changing the command line on the fly when copying the system from CF to NAND)

SVN-Revision: 5296
This commit is contained in:
Felix Fietkau 2006-10-26 01:08:41 +00:00
parent 673622720a
commit 1a94b0d4a0
7 changed files with 11649 additions and 93 deletions

View file

@ -6,6 +6,7 @@
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/image.mk
include $(INCLUDE_DIR)/kernel.mk
LOADADDR = 0x81000000 # RAM start + 16M
KERNEL_ENTRY = 0x80101000
@ -23,19 +24,41 @@ define Build/Clean
$(MAKE) -C ../generic/lzma-loader $(LOADER_MAKEOPTS) clean
endef
CMDLINE_SIZE=512
CMDLINE_OFFSET=4112
define Image/Prepare
cat $(KDIR)/vmlinux | $(STAGING_DIR)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux.lzma
$(MAKE) -C ../generic/lzma-loader $(LOADER_MAKEOPTS) clean compile
echo 'root=/dev/cfa2 ' | \
dd bs=$(CMDLINE_SIZE) count=1 conv=sync | \
dd of=$(LINUX_DIR)/vmlinux bs=$(CMDLINE_OFFSET) conv=notrunc seek=1
$(KERNEL_CROSS)objcopy -O binary -R .reginfo -R .note -R .comment -R .mdebug -S $(LINUX_DIR)/vmlinux $(LINUX_KERNEL)
endef
define Image/BuildKernel
cat $(KDIR)/vmlinux | $(STAGING_DIR)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux.lzma
$(MAKE) -C ../generic/lzma-loader $(LOADER_MAKEOPTS) clean compile
$(CP) $(KDIR)/loader.elf $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-vmlinux
endef
PARTITION1=\x80\x01\x01\x00\x27\x01\x20\x7b\x20\x00\x00\x00\xe0\x1e\x00\x00# 4 MB (kernel part)
PARTITION2=\x00\x00\x01\x7c\x83\x01\xa0\x64\x00\x1f\x00\x00\x40\x7a\x00\x00# 16 MB (rootfs part)
define Image/Build/jffs2-128k
define Image/cmdline/jffs2-64k
block2mtd.block2mtd=/dev/cfa2,65536 root=/dev/mtdblock0 rootfstype=jffs2
endef
define Image/cmdline/jffs2-128k
block2mtd.block2mtd=/dev/cfa2,131072 root=/dev/mtdblock0 rootfstype=jffs2
endef
define Image/cmdline/ext2
root=/dev/cfa2 rootfstype=ext2
endef
define Image/Build
echo '$(strip $(call Image/cmdline/$(1))) ' | \
dd bs=$(CMDLINE_SIZE) count=1 conv=sync | \
dd of=$(LINUX_DIR)/vmlinux bs=$(CMDLINE_OFFSET) conv=notrunc seek=1
( \
echo -ne OWRT | dd bs=$$$$((0x1be)) conv=sync; \
( \
@ -44,14 +67,10 @@ define Image/Build/jffs2-128k
) | dd bs=$$$$((0x40)) conv=sync; \
echo -ne '\x55\xaa'; \
dd if=/dev/zero bs=$$$$((0x3e00)) conv=sync count=1; \
dd if=$(KDIR)/loader.elf bs=$$$$((0x3dc000)) conv=sync; \
dd if=$(LINUX_DIR)/vmlinux bs=$$$$((0x3dc000)) conv=sync; \
cat $(KDIR)/root.$(1); \
echo -ne '\xde\xad\xc0\xde'; \
) > $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(1).bin
endef
define Image/Build
$(call Image/Build/$(1),$(1))
endef
$(eval $(call BuildImage))

View file

@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.17
# Sun Jun 18 17:29:23 2006
# Wed Oct 25 20:06:48 2006
#
CONFIG_MIPS=y
@ -156,7 +156,9 @@ CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
CONFIG_INITRAMFS_SOURCE="../../root"
CONFIG_INITRAMFS_ROOT_UID=0
CONFIG_INITRAMFS_ROOT_GID=0
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_EMBEDDED=y
# CONFIG_KALLSYMS is not set
@ -294,7 +296,7 @@ CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_IPCOMP=m
CONFIG_INET6_XFRM_TUNNEL=m
# CONFIG_INET6_TUNNEL is not set
CONFIG_INET6_TUNNEL=m
# CONFIG_IPV6_TUNNEL is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
@ -637,7 +639,12 @@ CONFIG_MTD_BLOCK2MTD=y
#
# NAND Flash Device Drivers
#
# CONFIG_MTD_NAND is not set
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_VERIFY_WRITE=y
CONFIG_MTD_NAND_RB500=y
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_NANDSIM is not set
#
# OneNAND Flash Device Drivers
@ -806,13 +813,6 @@ CONFIG_NET_WIRELESS_RTNETLINK=y
# Obsolete Wireless cards support (pre-802.11)
#
# CONFIG_STRIP is not set
# CONFIG_PCMCIA_WAVELAN is not set
# CONFIG_PCMCIA_NETWAVE is not set
#
# Wireless 802.11 Frequency Hopping cards support
#
# CONFIG_PCMCIA_RAYCS is not set
#
# Wireless 802.11b ISA/PCI cards support
@ -822,12 +822,6 @@ CONFIG_NET_WIRELESS_RTNETLINK=y
# CONFIG_HERMES is not set
# CONFIG_ATMEL is not set
#
# Wireless 802.11b Pcmcia/Cardbus cards support
#
# CONFIG_AIRO_CS is not set
# CONFIG_PCMCIA_WL3501 is not set
#
# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
#
@ -837,15 +831,9 @@ CONFIG_HOSTAP_FIRMWARE=y
CONFIG_HOSTAP_FIRMWARE_NVRAM=y
# CONFIG_HOSTAP_PLX is not set
# CONFIG_HOSTAP_PCI is not set
CONFIG_HOSTAP_CS=m
# CONFIG_BCM43XX is not set
CONFIG_NET_WIRELESS=y
#
# PCMCIA network device support
#
# CONFIG_NET_PCMCIA is not set
#
# Wan interfaces
#
@ -918,7 +906,6 @@ CONFIG_INPUT=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
# CONFIG_SERIAL_8250_PCI is not set
# CONFIG_SERIAL_8250_CS is not set
CONFIG_SERIAL_8250_NR_UARTS=2
CONFIG_SERIAL_8250_RUNTIME_UARTS=2
# CONFIG_SERIAL_8250_EXTENDED is not set
@ -951,13 +938,6 @@ CONFIG_UNIX98_PTYS=y
# Ftape, the floppy tape device driver
#
# CONFIG_DRM is not set
#
# PCMCIA character devices
#
# CONFIG_SYNCLINK_CS is not set
# CONFIG_CARDMAN_4000 is not set
# CONFIG_CARDMAN_4040 is not set
# CONFIG_RAW_DRIVER is not set
#
@ -1068,7 +1048,7 @@ CONFIG_LEDS_TRIGGER_TIMER=y
#
# File systems
#
CONFIG_EXT2_FS=m
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=m
@ -1140,6 +1120,7 @@ CONFIG_RAMFS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
CONFIG_YAFFS_FS=y
# CONFIG_JFFS_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
@ -1270,7 +1251,7 @@ CONFIG_NLS_UTF8=m
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_FS is not set
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE="root=/dev/mtdblock1 rootfstype=squashfs,jffs2 noinitrd console=ttyS0,115200"
CONFIG_CMDLINE="noinitrd console=ttyS0,115200"
#
# Security options

View file

@ -567,7 +567,7 @@ diff -urN linux.old/arch/mips/pci/pci-rc32434.c linux.dev/arch/mips/pci/pci-rc32
diff -urN linux.old/arch/mips/rb500/devices.c linux.dev/arch/mips/rb500/devices.c
--- linux.old/arch/mips/rb500/devices.c 1970-01-01 01:00:00.000000000 +0100
+++ linux.dev/arch/mips/rb500/devices.c 2006-10-11 21:56:38.000000000 +0200
@@ -0,0 +1,211 @@
@@ -0,0 +1,198 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
@ -677,10 +677,25 @@ diff -urN linux.old/arch/mips/rb500/devices.c linux.dev/arch/mips/rb500/devices.
+ .num_resources = ARRAY_SIZE(cf_slot0_res),
+};
+
+/* Resources and device for NAND. There is no data needed and no irqs, so just define the memory used. */
+static struct resource nand_slot0_res[] = {
+ {
+ .name = "nand_membase",
+ .flags = IORESOURCE_MEM
+ }
+};
+
+static struct platform_device nand_slot0 = {
+ .id = 0,
+ .name = "rb500-nand",
+ .resource = nand_slot0_res,
+ .num_resources = ARRAY_SIZE(nand_slot0_res),
+};
+
+
+static struct platform_device *rb500_devs[] = {
+ &korina_dev0,
+ &nand_slot0,
+ &cf_slot0
+};
+
@ -711,6 +726,7 @@ diff -urN linux.old/arch/mips/rb500/devices.c linux.dev/arch/mips/rb500/devices.
+
+/* DEVICE CONTROLLER 1 */
+#define CFG_DC_DEV1 (void*)0xb8010010
+#define CFG_DC_DEV2 (void*)0xb8010020
+#define CFG_DC_DEVBASE 0x0
+#define CFG_DC_DEVMASK 0x4
+#define CFG_DC_DEVC 0x8
@ -726,6 +742,10 @@ diff -urN linux.old/arch/mips/rb500/devices.c linux.dev/arch/mips/rb500/devices.
+ cf_slot0_res[0].start = readl(CFG_DC_DEV1 + CFG_DC_DEVBASE);
+ cf_slot0_res[0].end = cf_slot0_res[0].start + 0x1000;
+ }
+
+ /* There is always a NAND device */
+ nand_slot0_res[0].start = readl( CFG_DC_DEV2 + CFG_DC_DEVBASE);
+ nand_slot0_res[0].end = nand_slot0_res[0].start + 0x1000;
+
+ return platform_add_devices(rb500_devs, ARRAY_SIZE(rb500_devs));
+}
@ -745,39 +765,6 @@ diff -urN linux.old/arch/mips/rb500/devices.c linux.dev/arch/mips/rb500/devices.
+extern void block2mtd_setup(char *initstr);
+extern void mount_devfs_fs(void);
+
+static int __init setup_mtd(void)
+{
+ struct hd_struct **part;
+ int num = 0, i;
+ char initstr[64];
+
+ if (cf_slot0_data.gd == NULL)
+ return 0;
+
+ /* count partitions */
+ part = cf_slot0_data.gd->part;
+ while (part[num] != NULL) {
+ num++;
+ }
+
+ if (num < 2)
+ return 0;
+
+ mount_devfs_fs();
+ printk("Setting up block2mtd devices\n");
+
+ block2mtd_setup("/dev/cf/card0/part1,131072,kernel");
+ block2mtd_setup("/dev/cf/card0/part2,131072,rootfs");
+
+ for (i = 2; part[i]; i++) {
+ sprintf(initstr, "/dev/cf/card0/part%d,131072,part%d", i + 1, i + 1);
+ block2mtd_setup(initstr);
+ }
+
+ return 0;
+}
+
+late_initcall(setup_mtd);
+#endif
diff -urN linux.old/arch/mips/rb500/early_serial.c linux.dev/arch/mips/rb500/early_serial.c
--- linux.old/arch/mips/rb500/early_serial.c 1970-01-01 01:00:00.000000000 +0100
@ -1262,7 +1249,7 @@ diff -urN linux.old/arch/mips/rb500/Makefile linux.dev/arch/mips/rb500/Makefile
diff -urN linux.old/arch/mips/rb500/misc.c linux.dev/arch/mips/rb500/misc.c
--- linux.old/arch/mips/rb500/misc.c 1970-01-01 01:00:00.000000000 +0100
+++ linux.dev/arch/mips/rb500/misc.c 2006-10-11 21:56:38.000000000 +0200
@@ -0,0 +1,54 @@
@@ -0,0 +1,56 @@
+#include <linux/module.h>
+#include <linux/kernel.h> /* printk() */
+#include <linux/types.h> /* size_t */
@ -1273,7 +1260,7 @@ diff -urN linux.old/arch/mips/rb500/misc.c linux.dev/arch/mips/rb500/misc.c
+#define GPIO_BADDR 0xb8050000
+
+
+static unsigned char *devCtl3Base = (unsigned char *) KSEG1ADDR(0x18010030);
+static volatile unsigned char *devCtl3Base = 0;
+static unsigned char latchU5State = 0;
+static spinlock_t clu5Lock = SPIN_LOCK_UNLOCKED;
+
@ -1294,6 +1281,8 @@ diff -urN linux.old/arch/mips/rb500/misc.c linux.dev/arch/mips/rb500/misc.c
+ unsigned flags;
+ spin_lock_irqsave(&clu5Lock, flags);
+ latchU5State = (latchU5State | orMask) & ~nandMask;
+ if( !devCtl3Base) devCtl3Base = (volatile unsigned char *)
+ KSEG1ADDR(*(volatile unsigned *) KSEG1ADDR(0x18010030));
+ *devCtl3Base = latchU5State;
+ spin_unlock_irqrestore(&clu5Lock, flags);
+}

View file

@ -1,7 +1,7 @@
diff -urN linux.old/drivers/block/Kconfig linux.dev/drivers/block/Kconfig
--- linux.old/drivers/block/Kconfig 2006-06-08 20:20:52.000000000 +0200
+++ linux.dev/drivers/block/Kconfig 2006-06-08 22:14:58.000000000 +0200
@@ -453,4 +453,12 @@
--- linux.old/drivers/block/Kconfig 2006-10-26 02:43:39.000000000 +0200
+++ linux.dev/drivers/block/Kconfig 2006-10-26 00:11:14.000000000 +0200
@@ -456,4 +456,12 @@
This driver provides Support for ATA over Ethernet block
devices like the Coraid EtherDrive (R) Storage Blade.
@ -14,9 +14,18 @@ diff -urN linux.old/drivers/block/Kconfig linux.dev/drivers/block/Kconfig
+ device driver for it.
+
endmenu
diff -urN linux.old/drivers/block/Makefile linux.dev/drivers/block/Makefile
--- linux.old/drivers/block/Makefile 2006-06-18 03:49:35.000000000 +0200
+++ linux.dev/drivers/block/Makefile 2006-10-26 02:44:10.000000000 +0200
@@ -29,4 +29,5 @@
obj-$(CONFIG_VIODASD) += viodasd.o
obj-$(CONFIG_BLK_DEV_SX8) += sx8.o
obj-$(CONFIG_BLK_DEV_UB) += ub.o
+obj-$(CONFIG_BLK_DEV_CF_MIPS) += rb500/
diff -urN linux.old/drivers/block/rb500/ata.c linux.dev/drivers/block/rb500/ata.c
--- linux.old/drivers/block/rb500/ata.c 1970-01-01 01:00:00.000000000 +0100
+++ linux.dev/drivers/block/rb500/ata.c 2006-06-09 01:58:40.000000000 +0200
+++ linux.dev/drivers/block/rb500/ata.c 2006-10-26 00:11:14.000000000 +0200
@@ -0,0 +1,474 @@
+#include <linux/kernel.h> /* printk() */
+#include <linux/module.h> /* module to be loadable */
@ -494,7 +503,7 @@ diff -urN linux.old/drivers/block/rb500/ata.c linux.dev/drivers/block/rb500/ata.
+/*eof*/
diff -urN linux.old/drivers/block/rb500/ata.h linux.dev/drivers/block/rb500/ata.h
--- linux.old/drivers/block/rb500/ata.h 1970-01-01 01:00:00.000000000 +0100
+++ linux.dev/drivers/block/rb500/ata.h 2006-06-09 00:15:23.000000000 +0200
+++ linux.dev/drivers/block/rb500/ata.h 2006-10-26 00:11:14.000000000 +0200
@@ -0,0 +1,132 @@
+#ifndef __CFMIPS_ATA_H__
+#define __CFMIPS_ATA_H__
@ -630,7 +639,7 @@ diff -urN linux.old/drivers/block/rb500/ata.h linux.dev/drivers/block/rb500/ata.
+#endif
diff -urN linux.old/drivers/block/rb500/bdev.c linux.dev/drivers/block/rb500/bdev.c
--- linux.old/drivers/block/rb500/bdev.c 1970-01-01 01:00:00.000000000 +0100
+++ linux.dev/drivers/block/rb500/bdev.c 2006-06-15 16:29:04.000000000 +0200
+++ linux.dev/drivers/block/rb500/bdev.c 2006-10-26 00:11:14.000000000 +0200
@@ -0,0 +1,340 @@
+/* CF-mips driver
+ This is a block driver for the direct (mmaped) interface to the CF-slot,
@ -974,17 +983,8 @@ diff -urN linux.old/drivers/block/rb500/bdev.c linux.dev/drivers/block/rb500/bde
+
diff -urN linux.old/drivers/block/rb500/Makefile linux.dev/drivers/block/rb500/Makefile
--- linux.old/drivers/block/rb500/Makefile 1970-01-01 01:00:00.000000000 +0100
+++ linux.dev/drivers/block/rb500/Makefile 2006-06-08 22:14:58.000000000 +0200
+++ linux.dev/drivers/block/rb500/Makefile 2006-10-26 00:11:14.000000000 +0200
@@ -0,0 +1,3 @@
+## Makefile for the RB532 CF port
+
+obj-y += bdev.o ata.o
diff -urN linux.old/drivers/Makefile linux.dev/drivers/Makefile
--- linux.old/drivers/Makefile 2006-06-08 20:20:52.000000000 +0200
+++ linux.dev/drivers/Makefile 2006-06-08 22:14:58.000000000 +0200
@@ -73,3 +73,4 @@
obj-y += firmware/
obj-$(CONFIG_CRYPTO) += crypto/
obj-$(CONFIG_SUPERH) += sh/
+obj-$(CONFIG_BLK_DEV_CF_MIPS) += block/rb500/
\ No newline at end of file

View file

@ -0,0 +1,33 @@
diff -ur linux.old/arch/mips/kernel/head.S linux.dev/arch/mips/kernel/head.S
--- linux.old/arch/mips/kernel/head.S 2006-10-26 00:11:13.000000000 +0200
+++ linux.dev/arch/mips/kernel/head.S 2006-10-26 02:40:10.000000000 +0200
@@ -132,6 +132,8 @@
j kernel_entry
nop
+ nop
+EXPORT(_image_cmdline)
/*
* Reserved space for exception handlers.
diff -ur linux.old/arch/mips/rb500/prom.c linux.dev/arch/mips/rb500/prom.c
--- linux.old/arch/mips/rb500/prom.c 2006-10-26 00:11:14.000000000 +0200
+++ linux.dev/arch/mips/rb500/prom.c 2006-10-26 02:40:46.000000000 +0200
@@ -128,6 +128,7 @@
/* FIXME: STUB */
}
+extern char _image_cmdline;
void __init prom_setup_cmdline(void){
char cmd_line[CL_SIZE];
char *cp;
@@ -163,6 +164,9 @@
strcpy(cp,prom_argv[i]);
cp+=strlen(prom_argv[i]);
}
+ *(cp++) = ' ';
+ strcpy(cp,&_image_cmdline);
+ cp += strlen(&_image_cmdline);
i=strlen(arcs_cmdline);
if (i>0){

View file

@ -0,0 +1,248 @@
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index cfe288a..c528024 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -55,6 +55,12 @@ config MTD_NAND_TOTO
help
Support for NAND flash on Texas Instruments Toto platform.
+config MTD_NAND_RB500
+ tristate "NAND Flash device on RB500 board"
+ depends on MTD_NAND
+ help
+ Support for NAND flash on RB500 platform.
+
config MTD_NAND_IDS
tristate
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 4174202..2be57c1 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.
obj-$(CONFIG_MTD_NAND_SPIA) += spia.o
obj-$(CONFIG_MTD_NAND_TOTO) += toto.o
+obj-$(CONFIG_MTD_NAND_RB500) += rbmipsnand.o
obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o
obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o
obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o
diff --git a/drivers/mtd/nand/rbmipsnand.c b/drivers/mtd/nand/rbmipsnand.c
new file mode 100644
index 0000000..6f7452a
--- /dev/null
+++ b/drivers/mtd/nand/rbmipsnand.c
@@ -0,0 +1,211 @@
+#include <linux/init.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/bootinfo.h>
+//#include <asm/rb/rb100.h>
+
+#define IDT434_REG_BASE ((volatile void *) KSEG1ADDR(0x18000000))
+
+#define SMEM1(x) (*((volatile unsigned char *) (KSEG1ADDR(SMEM1_BASE) + x)))
+
+#define GPIOF 0x050000
+#define GPIOC 0x050004
+#define GPIOD 0x050008
+
+#define GPIO_RDY (1 << 0x08)
+#define GPIO_WPX (1 << 0x09)
+#define GPIO_ALE (1 << 0x0a)
+#define GPIO_CLE (1 << 0x0b)
+
+#define NAND_RW_REG 0x0 //data register
+#define NAND_SET_CEn 0x1 //CE# low
+#define NAND_CLR_CEn 0x2 //CE# high
+#define NAND_CLR_CLE 0x3 //CLE low
+#define NAND_SET_CLE 0x4 //CLE high
+#define NAND_CLR_ALE 0x5 //ALE low
+#define NAND_SET_ALE 0x6 //ALE high
+#define NAND_SET_SPn 0x7 //SP# low (use spare area)
+#define NAND_CLR_SPn 0x8 //SP# high (do not use spare area)
+#define NAND_SET_WPn 0x9 //WP# low
+#define NAND_CLR_WPn 0xA //WP# high
+#define NAND_STS_REG 0xB //Status register
+
+#define DEV2BASE 0x010020
+
+#define LO_WPX (1 << 0)
+#define LO_ALE (1 << 1)
+#define LO_CLE (1 << 2)
+#define LO_CEX (1 << 3)
+#define LO_FOFF (1 << 5)
+#define LO_SPICS (1 << 6)
+#define LO_ULED (1 << 7)
+
+#define MEM32(x) *((volatile unsigned *) (x))
+static void __iomem *p_nand;
+
+extern void changeLatchU5(unsigned char orMask, unsigned char nandMask);
+
+static int rb500_dev_ready(struct mtd_info *mtd) {
+ return MEM32(IDT434_REG_BASE + GPIOD) & GPIO_RDY;
+}
+/*
+static int rb100_dev_ready(struct mtd_info *mtd) {
+ return SMEM1(NAND_STS_REG) & 0x80;
+}
+*/
+static unsigned long iflags = 0;
+static int ioff = 0;
+/*
+static void rbmips_hwcontrol400(struct mtd_info *mtd, int cmd) {
+ switch (cmd) {
+ case NAND_CTL_SETCLE:
+ MEM32(IDT434_REG_BASE + GPIOD) |= GPIO_CLE;
+ break;
+ case NAND_CTL_CLRCLE:
+ MEM32(IDT434_REG_BASE + GPIOD) &= ~GPIO_CLE;
+ break;
+ case NAND_CTL_SETALE:
+ MEM32(IDT434_REG_BASE + GPIOD) |= GPIO_ALE;
+ break;
+ case NAND_CTL_CLRALE:
+ MEM32(IDT434_REG_BASE + GPIOD) &= ~GPIO_ALE;
+ break;
+ default:
+ break;
+ }
+}
+*/
+static void rbmips_hwcontrol500(struct mtd_info *mtd, int cmd) {
+ switch (cmd) {
+ case NAND_CTL_SETCLE:
+ changeLatchU5(LO_CLE, 0);
+ break;
+ case NAND_CTL_CLRCLE:
+ changeLatchU5(0, LO_CLE);
+ break;
+ case NAND_CTL_SETALE:
+ changeLatchU5(LO_ALE, 0);
+ break;
+ case NAND_CTL_CLRALE:
+ changeLatchU5(0, LO_ALE);
+ break;
+ default:
+ break;
+ }
+}
+/*
+static void rbmips_hwcontrol100(struct mtd_info *mtd, int cmd){
+ switch(cmd){
+ case NAND_CTL_SETCLE:
+ SMEM1(NAND_SET_CLE) = 0x01;
+ break;
+ case NAND_CTL_CLRCLE:
+ SMEM1(NAND_CLR_CLE) = 0x01;
+ break;
+ case NAND_CTL_SETALE:
+ SMEM1(NAND_SET_ALE) = 0x01;
+ break;
+ case NAND_CTL_CLRALE:
+ SMEM1(NAND_CLR_ALE) = 0x01;
+ break;
+ case NAND_CTL_SETNCE:
+ SMEM1(NAND_SET_CEn) = 0x01;
+ break;
+ case NAND_CTL_CLRNCE:
+ SMEM1(NAND_CLR_CEn) = 0x01;
+ break;
+ }
+}
+*/
+static struct mtd_partition partition_info[] = {
+ {
+ name: "RouterBoard NAND Boot",
+ offset: 0,
+ size: 4 * 1024 * 1024
+ },
+ {
+ name: "RouterBoard NAND Main",
+ offset: MTDPART_OFS_NXTBLK,
+ size: MTDPART_SIZ_FULL
+ }
+};
+
+static struct mtd_info rmtd;
+static struct nand_chip rnand;
+
+static unsigned init_ok = 0;
+
+unsigned get_rbnand_block_size(void) {
+ if (init_ok) return rmtd.oobblock; else return 0;
+}
+
+EXPORT_SYMBOL(get_rbnand_block_size);
+
+int __init rbmips_init(void) {
+ memset(&rmtd, 0, sizeof(rmtd));
+ memset(&rnand, 0, sizeof(rnand));
+/*
+ if (is_rb500()) {
+ if (is_rb400()) {
+ printk("RB400 nand\n");
+ MEM32(IDT434_REG_BASE + GPIOD) |= GPIO_WPX;
+ MEM32(IDT434_REG_BASE + GPIOD) &= ~GPIO_CLE;
+ MEM32(IDT434_REG_BASE + GPIOD) &= ~GPIO_ALE;
+ rnand.hwcontrol = rbmips_hwcontrol400;
+ } else {
+*/
+ printk("RB500 nand\n");
+ changeLatchU5(LO_WPX | LO_FOFF | LO_CEX,
+ LO_ULED | LO_ALE | LO_CLE);
+ rnand.hwcontrol = rbmips_hwcontrol500;
+// }
+
+ rnand.dev_ready = rb500_dev_ready;
+ rnand.IO_ADDR_W = (unsigned char *)
+ KSEG1ADDR(MEM32(IDT434_REG_BASE + DEV2BASE));
+ rnand.IO_ADDR_R = rnand.IO_ADDR_W;
+/* } else if (is_rb100()) {
+ printk("RB100 nand\n");
+ MEM32(0xB2000064) = 0x100;
+ MEM32(0xB2000008) = 0x1;
+ SMEM1(NAND_SET_SPn) = 0x01;
+ SMEM1(NAND_CLR_WPn) = 0x01;
+ rnand.IO_ADDR_R = (unsigned char *)KSEG1ADDR(SMEM1_BASE);
+ rnand.IO_ADDR_W = rnand.IO_ADDR_R;
+ rnand.hwcontrol = rbmips_hwcontrol100;
+ rnand.dev_ready = rb100_dev_ready;
+ }
+*/
+ p_nand = (void __iomem *)ioremap(( void*)0x18a20000, 0x1000);
+ if (!p_nand) {
+ printk("RBnand Unable ioremap buffer");
+ return -ENXIO;
+ }
+ rnand.eccmode = NAND_ECC_SOFT;
+ rnand.chip_delay = 25;
+ rnand.options |= NAND_NO_AUTOINCR;
+ rmtd.priv = &rnand;
+
+ int *b = ( int *)KSEG1ADDR( 0x18010020);
+ printk( "dev2base 0x%08x mask 0x%08x c 0x%08x tc 0x%08x\n", b[ 0], b[ 1], b[ 2], b[ 3]);
+
+ if (nand_scan(&rmtd, 1) && nand_scan(&rmtd, 1)
+ && nand_scan(&rmtd, 1) && nand_scan(&rmtd, 1)) {
+ printk("RBxxx nand device not found");
+ iounmap ((void *)p_nand);
+ return -ENXIO;
+ }
+
+ add_mtd_partitions(&rmtd, partition_info, 2);
+ init_ok = 1;
+ return 0;
+}
+
+module_init(rbmips_init);
+
+
+
+
+

File diff suppressed because it is too large Load diff