From 1ccb2bee054f26865d6f2283c08c399f9d0b2c01 Mon Sep 17 00:00:00 2001
From: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
Date: Wed, 1 Aug 2007 11:54:42 -0500
Subject: [PATCH] Added NAND Flash support and I2C support.

Signed-off-by: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
---
 board/freescale/m5329evb/m5329evb.c |   83 +++++++++++++++++++++
 include/asm-m68k/bitops.h           |   39 ++++++++++
 include/asm-m68k/errno.h            |  138 +++++++++++++++++++++++++++++++++++
 include/configs/M5329EVB.h          |   97 ++++++++++++++++--------
 4 files changed, 325 insertions(+), 32 deletions(-)
 create mode 100644 include/asm-m68k/errno.h

diff --git a/board/freescale/m5329evb/m5329evb.c b/board/freescale/m5329evb/m5329evb.c
index 242eb1a..d23b1c2 100644
--- a/board/freescale/m5329evb/m5329evb.c
+++ b/board/freescale/m5329evb/m5329evb.c
@@ -26,6 +26,7 @@
 
 #include <config.h>
 #include <common.h>
+#include <asm/io.h>
 #include <asm/immap.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -86,3 +87,85 @@ int testdram(void)
 
 	return (0);
 }
+
+#if (CONFIG_COMMANDS & CFG_CMD_NAND)
+#include <nand.h>
+#include <linux/mtd/mtd.h>
+
+#define SET_CLE	0x10
+#define CLR_CLE	~SET_CLE
+#define SET_ALE	0x08
+#define CLR_ALE	~SET_ALE
+
+static void nand_hwcontrol(struct mtd_info *mtdinfo, int cmd)
+{
+	struct nand_chip *this = mtdinfo->priv;
+	volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS;
+	u32 nand_baseaddr = (u32) this->IO_ADDR_W;
+
+	switch (cmd) {
+	case NAND_CTL_SETNCE:
+	case NAND_CTL_CLRNCE:
+		break;
+	case NAND_CTL_SETCLE:
+		nand_baseaddr |= SET_CLE;
+		break;
+	case NAND_CTL_CLRCLE:
+		nand_baseaddr &= CLR_CLE;
+		break;
+	case NAND_CTL_SETALE:
+		nand_baseaddr |= SET_ALE;
+		break;
+	case NAND_CTL_CLRALE:
+		nand_baseaddr |= CLR_ALE;
+		break;
+	case NAND_CTL_SETWP:
+		fbcs->csmr2 |= CSMR_WP;
+		break;
+	case NAND_CTL_CLRWP:
+		fbcs->csmr2 &= ~CSMR_WP;
+		break;
+	}
+	this->IO_ADDR_W = (void __iomem *)(nand_baseaddr);
+}
+
+static void nand_write_byte(struct mtd_info *mtdinfo, u_char byte)
+{
+	struct nand_chip *this = mtdinfo->priv;
+	*((volatile u8 *)(this->IO_ADDR_W)) = byte;
+}
+
+static u8 nand_read_byte(struct mtd_info *mtdinfo)
+{
+	struct nand_chip *this = mtdinfo->priv;
+	return (u8) (*((volatile u8 *)this->IO_ADDR_R));
+}
+
+static int nand_dev_ready(struct mtd_info *mtdinfo)
+{
+	return 1;
+}
+
+int board_nand_init(struct nand_chip *nand)
+{
+	volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO;
+
+	*((volatile u16 *)CFG_LATCH_ADDR) |= 0x0004;
+
+	/* set up pin configuration */
+	gpio->par_timer &= ~GPIO_PAR_TIN3_TIN3;
+	gpio->pddr_timer |= 0x08;
+	gpio->ppd_timer |= 0x08;
+	gpio->pclrr_timer = 0;
+	gpio->podr_timer = 0;
+
+	nand->chip_delay = 50;
+	nand->eccmode = NAND_ECC_SOFT;
+	nand->hwcontrol = nand_hwcontrol;
+	nand->read_byte = nand_read_byte;
+	nand->write_byte = nand_write_byte;
+	nand->dev_ready = nand_dev_ready;
+
+	return 0;
+}
+#endif
diff --git a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h
index 3283714..0f9e8ab 100644
--- a/include/asm-m68k/bitops.h
+++ b/include/asm-m68k/bitops.h
@@ -15,4 +15,43 @@ extern int test_and_set_bit(int nr, volatile void *addr);
 extern int test_and_clear_bit(int nr, volatile void *addr);
 extern int test_and_change_bit(int nr, volatile void *addr);
 
+#ifdef __KERNEL__
+
+/*
+ * ffs: find first bit set. This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+extern __inline__ int ffs(int x)
+{
+	int r = 1;
+
+	if (!x)
+		return 0;
+	if (!(x & 0xffff)) {
+		x >>= 16;
+		r += 16;
+	}
+	if (!(x & 0xff)) {
+		x >>= 8;
+		r += 8;
+	}
+	if (!(x & 0xf)) {
+		x >>= 4;
+		r += 4;
+	}
+	if (!(x & 3)) {
+		x >>= 2;
+		r += 2;
+	}
+	if (!(x & 1)) {
+		x >>= 1;
+		r += 1;
+	}
+	return r;
+}
+#define __ffs(x) (ffs(x) - 1)
+
+#endif /* __KERNEL__ */
+
 #endif /* _M68K_BITOPS_H */
diff --git a/include/asm-m68k/errno.h b/include/asm-m68k/errno.h
new file mode 100644
index 0000000..6a71c2a
--- /dev/null
+++ b/include/asm-m68k/errno.h
@@ -0,0 +1,138 @@
+#ifndef _MCF_ERRNO_H
+#define _MCF_ERRNO_H
+
+#define	EPERM		 1	/* Operation not permitted */
+#define	ENOENT		 2	/* No such file or directory */
+#define	ESRCH		 3	/* No such process */
+#define	EINTR		 4	/* Interrupted system call */
+#define	EIO		 5	/* I/O error */
+#define	ENXIO		 6	/* No such device or address */
+#define	E2BIG		 7	/* Arg list too long */
+#define	ENOEXEC		 8	/* Exec format error */
+#define	EBADF		 9	/* Bad file number */
+#define	ECHILD		10	/* No child processes */
+#define	EAGAIN		11	/* Try again */
+#define	ENOMEM		12	/* Out of memory */
+#define	EACCES		13	/* Permission denied */
+#define	EFAULT		14	/* Bad address */
+#define	ENOTBLK		15	/* Block device required */
+#define	EBUSY		16	/* Device or resource busy */
+#define	EEXIST		17	/* File exists */
+#define	EXDEV		18	/* Cross-device link */
+#define	ENODEV		19	/* No such device */
+#define	ENOTDIR		20	/* Not a directory */
+#define	EISDIR		21	/* Is a directory */
+#define	EINVAL		22	/* Invalid argument */
+#define	ENFILE		23	/* File table overflow */
+#define	EMFILE		24	/* Too many open files */
+#define	ENOTTY		25	/* Not a typewriter */
+#define	ETXTBSY		26	/* Text file busy */
+#define	EFBIG		27	/* File too large */
+#define	ENOSPC		28	/* No space left on device */
+#define	ESPIPE		29	/* Illegal seek */
+#define	EROFS		30	/* Read-only file system */
+#define	EMLINK		31	/* Too many links */
+#define	EPIPE		32	/* Broken pipe */
+#define	EDOM		33	/* Math argument out of domain of func */
+#define	ERANGE		34	/* Math result not representable */
+#define	EDEADLK		35	/* Resource deadlock would occur */
+#define	ENAMETOOLONG	36	/* File name too long */
+#define	ENOLCK		37	/* No record locks available */
+#define	ENOSYS		38	/* Function not implemented */
+#define	ENOTEMPTY	39	/* Directory not empty */
+#define	ELOOP		40	/* Too many symbolic links encountered */
+#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
+#define	ENOMSG		42	/* No message of desired type */
+#define	EIDRM		43	/* Identifier removed */
+#define	ECHRNG		44	/* Channel number out of range */
+#define	EL2NSYNC	45	/* Level 2 not synchronized */
+#define	EL3HLT		46	/* Level 3 halted */
+#define	EL3RST		47	/* Level 3 reset */
+#define	ELNRNG		48	/* Link number out of range */
+#define	EUNATCH		49	/* Protocol driver not attached */
+#define	ENOCSI		50	/* No CSI structure available */
+#define	EL2HLT		51	/* Level 2 halted */
+#define	EBADE		52	/* Invalid exchange */
+#define	EBADR		53	/* Invalid request descriptor */
+#define	EXFULL		54	/* Exchange full */
+#define	ENOANO		55	/* No anode */
+#define	EBADRQC		56	/* Invalid request code */
+#define	EBADSLT		57	/* Invalid slot */
+#define	EDEADLOCK	58	/* File locking deadlock error */
+#define	EBFONT		59	/* Bad font file format */
+#define	ENOSTR		60	/* Device not a stream */
+#define	ENODATA		61	/* No data available */
+#define	ETIME		62	/* Timer expired */
+#define	ENOSR		63	/* Out of streams resources */
+#define	ENONET		64	/* Machine is not on the network */
+#define	ENOPKG		65	/* Package not installed */
+#define	EREMOTE		66	/* Object is remote */
+#define	ENOLINK		67	/* Link has been severed */
+#define	EADV		68	/* Advertise error */
+#define	ESRMNT		69	/* Srmount error */
+#define	ECOMM		70	/* Communication error on send */
+#define	EPROTO		71	/* Protocol error */
+#define	EMULTIHOP	72	/* Multihop attempted */
+#define	EDOTDOT		73	/* RFS specific error */
+#define	EBADMSG		74	/* Not a data message */
+#define	EOVERFLOW	75	/* Value too large for defined data type */
+#define	ENOTUNIQ	76	/* Name not unique on network */
+#define	EBADFD		77	/* File descriptor in bad state */
+#define	EREMCHG		78	/* Remote address changed */
+#define	ELIBACC		79	/* Can not access a needed shared library */
+#define	ELIBBAD		80	/* Accessing a corrupted shared library */
+#define	ELIBSCN		81	/* .lib section in a.out corrupted */
+#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
+#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
+#define	EILSEQ		84	/* Illegal byte sequence */
+#define	ERESTART	85	/* Interrupted system call should be restarted */
+#define	ESTRPIPE	86	/* Streams pipe error */
+#define	EUSERS		87	/* Too many users */
+#define	ENOTSOCK	88	/* Socket operation on non-socket */
+#define	EDESTADDRREQ	89	/* Destination address required */
+#define	EMSGSIZE	90	/* Message too long */
+#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	92	/* Protocol not available */
+#define	EPROTONOSUPPORT	93	/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
+#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
+#define	EPFNOSUPPORT	96	/* Protocol family not supported */
+#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
+#define	EADDRINUSE	98	/* Address already in use */
+#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
+#define	ENETDOWN	100	/* Network is down */
+#define	ENETUNREACH	101	/* Network is unreachable */
+#define	ENETRESET	102	/* Network dropped connection because of reset */
+#define	ECONNABORTED	103	/* Software caused connection abort */
+#define	ECONNRESET	104	/* Connection reset by peer */
+#define	ENOBUFS		105	/* No buffer space available */
+#define	EISCONN		106	/* Transport endpoint is already connected */
+#define	ENOTCONN	107	/* Transport endpoint is not connected */
+#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
+#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
+#define	ETIMEDOUT	110	/* Connection timed out */
+#define	ECONNREFUSED	111	/* Connection refused */
+#define	EHOSTDOWN	112	/* Host is down */
+#define	EHOSTUNREACH	113	/* No route to host */
+#define	EALREADY	114	/* Operation already in progress */
+#define	EINPROGRESS	115	/* Operation now in progress */
+#define	ESTALE		116	/* Stale NFS file handle */
+#define	EUCLEAN		117	/* Structure needs cleaning */
+#define	ENOTNAM		118	/* Not a XENIX named type file */
+#define	ENAVAIL		119	/* No XENIX semaphores available */
+#define	EISNAM		120	/* Is a named type file */
+#define	EREMOTEIO	121	/* Remote I/O error */
+#define	EDQUOT		122	/* Quota exceeded */
+
+#define	ENOMEDIUM	123	/* No medium found */
+#define	EMEDIUMTYPE	124	/* Wrong medium type */
+
+/* Should never be seen by user programs */
+#define ERESTARTSYS	512
+#define ERESTARTNOINTR	513
+#define ERESTARTNOHAND	514	/* restart if no handler.. */
+#define ENOIOCTLCMD	515	/* No ioctl command */
+
+#define _LAST_ERRNO	515
+
+#endif
diff --git a/include/configs/M5329EVB.h b/include/configs/M5329EVB.h
index 2becb59..c141db4 100644
--- a/include/configs/M5329EVB.h
+++ b/include/configs/M5329EVB.h
@@ -36,6 +36,7 @@
  */
 #define CONFIG_MCF532x		/* define processor family */
 #define CONFIG_M5329		/* define processor type */
+#define CONFIG_M5329EVB		/* define platform */
 
 #undef DEBUG
 
@@ -47,20 +48,28 @@
 #undef CONFIG_WATCHDOG
 #define CONFIG_WATCHDOG_TIMEOUT	5000	/* timeout in milliseconds, max timeout is 6.71sec */
 
-#define CONFIG_COMMANDS		( CONFIG_CMD_DFL | \
-				  CFG_CMD_CACHE | \
-				  CFG_CMD_DATE | \
-				  CFG_CMD_ELF | \
-				  CFG_CMD_FLASH | \
+#define DEFAULT_COMMANDS	( CONFIG_CMD_DFL	| \
+				  CFG_CMD_CACHE		| \
+				  CFG_CMD_DATE		| \
+				  CFG_CMD_ELF		| \
+				  CFG_CMD_FLASH		| \
+				  CFG_CMD_JFFS2		| \
+				  CFG_CMD_I2C		| \
 				  (CFG_CMD_LOADB | CFG_CMD_LOADS) | \
-				  CFG_CMD_MEMORY | \
-				  CFG_CMD_MISC | \
-				  CFG_CMD_MII | \
-				  CFG_CMD_NET | \
-				  CFG_CMD_PING | \
-				  CFG_CMD_REGINFO \
+				  CFG_CMD_MEMORY	| \
+				  CFG_CMD_MISC		| \
+				  CFG_CMD_MII		| \
+				  CFG_CMD_NET		| \
+				  CFG_CMD_PING		| \
+				  CFG_CMD_REGINFO 	  \
 				)
 
+#ifdef NANDFLASH_SIZE
+#	define CONFIG_COMMANDS	(DEFAULT_COMMANDS | CFG_CMD_NAND)
+#else
+#	define CONFIG_COMMANDS	(DEFAULT_COMMANDS)
+#endif
+
 #define CFG_UNIFY_CACHE
 
 #define CONFIG_MCFFEC
@@ -93,14 +102,23 @@
 #define CONFIG_MCFTMR
 #undef CONFIG_MCFPIT
 
+/* I2c */
+#define CONFIG_FSL_I2C
+#define CONFIG_HARD_I2C		/* I2C with hardware support*/
+#undef	CONFIG_SOFT_I2C			/* I2C bit-banged		*/
+#define CFG_I2C_SPEED		80000	/* I2C speed and slave address	*/
+#define CFG_I2C_SLAVE		0x7F
+#define CFG_I2C_OFFSET		0x58000
+#define CFG_IMMR		CFG_MBAR
+
 /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
 #include <cmd_confdefs.h>
 #define CONFIG_BOOTDELAY	1	/* autoboot after 5 seconds */
 #ifdef CONFIG_MCFFEC
-#	define CONFIG_ETHADDR		00:e0:0c:bc:e5:60
-#	define CONFIG_IPADDR		192.162.1.2
-#	define CONFIG_NETMASK		255.255.255.0
-#	define CONFIG_SERVERIP		192.162.1.1
+#	define CONFIG_ETHADDR	00:e0:0c:bc:e5:60
+#	define CONFIG_IPADDR	192.162.1.2
+#	define CONFIG_NETMASK	255.255.255.0
+#	define CONFIG_SERVERIP	192.162.1.1
 #	define CONFIG_GATEWAYIP	192.162.1.1
 #	define CONFIG_OVERWRITE_ETHADDR_ONCE
 #endif				/* FEC_ENET */
@@ -118,26 +136,28 @@
 	"save\0"	\
 	""
 
-#define CONFIG_PRAM			512	/* 512 KB */
-#define CFG_PROMPT			"-> "
+#define CONFIG_PRAM		512	/* 512 KB */
+#define CFG_PROMPT		"-> "
 #define CFG_LONGHELP		/* undef to save memory */
 
 #if (CONFIG_COMMANDS & CFG_CMD_KGDB)
-#	define CFG_CBSIZE			1024	/* Console I/O Buffer Size */
+#	define CFG_CBSIZE	1024	/* Console I/O Buffer Size */
 #else
-#	define CFG_CBSIZE			256	/* Console I/O Buffer Size */
+#	define CFG_CBSIZE	256	/* Console I/O Buffer Size */
 #endif
 
-#define CFG_PBSIZE			(CFG_CBSIZE+sizeof(CFG_PROMPT)+16)	/* Print Buffer Size */
-#define CFG_MAXARGS			16	/* max number of command args */
+#define CFG_PBSIZE		(CFG_CBSIZE+sizeof(CFG_PROMPT)+16)	/* Print Buffer Size */
+#define CFG_MAXARGS		16		/* max number of command args */
 #define CFG_BARGSIZE		CFG_CBSIZE	/* Boot Argument Buffer Size    */
 #define CFG_LOAD_ADDR		0x40010000
 
-#define CFG_HZ				1000
-#define CFG_CLK				80000000
-#define CFG_CPU_CLK			CFG_CLK * 3
+#define CFG_HZ			1000
+#define CFG_CLK			80000000
+#define CFG_CPU_CLK		CFG_CLK * 3
 
-#define CFG_MBAR			0xFC000000
+#define CFG_MBAR		0xFC000000
+
+#define CFG_LATCH_ADDR		(CFG_CS1_BASE + 0x80000)
 
 /*
  * Low Level Configuration Settings
@@ -191,13 +211,26 @@
 #	define CFG_FLASH_CFI_DRIVER	1
 #	define CFG_FLASH_SIZE		0x800000	/* Max size that the board might have */
 #	define CFG_FLASH_CFI_WIDTH	FLASH_CFI_16BIT
-#	define CFG_MAX_FLASH_BANKS		1	/* max number of memory banks */
-#	define CFG_MAX_FLASH_SECT		137	/* max number of sectors on one chip */
-#	define CFG_FLASH_PROTECTION	/* "Real" (hardware) sectors protection */
+#	define CFG_MAX_FLASH_BANKS	1	/* max number of memory banks */
+#	define CFG_MAX_FLASH_SECT	137	/* max number of sectors on one chip */
+#	define CFG_FLASH_PROTECTION		/* "Real" (hardware) sectors protection */
+#endif
+
+#ifdef NANDFLASH_SIZE
+#	define CFG_MAX_NAND_DEVICE	1
+#	define CFG_NAND_BASE		(CFG_CS2_BASE << 16)
+#	define CFG_NAND_SIZE		1
+#	define CFG_NAND_BASE_LIST	{ CFG_NAND_BASE }
+#	define NAND_MAX_CHIPS		1
+#	define NAND_ALLOW_ERASE_ALL	1
+#	define CONFIG_JFFS2_NAND	1
+#	define CONFIG_JFFS2_DEV		"nand0"
+#	define CONFIG_JFFS2_PART_SIZE	(CFG_CS2_MASK & ~1)
+#	define CONFIG_JFFS2_PART_OFFSET	0x00000000
 #endif
 
-#define CFG_FLASH_BASE			0
-#define CFG_FLASH0_BASE			(CFG_CS0_BASE << 16)
+#define CFG_FLASH_BASE		0
+#define CFG_FLASH0_BASE		(CFG_CS0_BASE << 16)
 
 /* Configuration for environment
  * Environment is embedded in u-boot in the second sector of the flash
@@ -232,8 +265,8 @@
 #define CFG_CS1_CTRL		0x002A3780
 
 #ifdef NANDFLASH_SIZE
-#define CFG_CS2_BASE		0x00800000
-#define CFG_CS2_MASK		0x00ff0001
+#define CFG_CS2_BASE		0x2000
+#define CFG_CS2_MASK		((NANDFLASH_SIZE << 20) | 1)
 #define CFG_CS2_CTRL		0x00001f60
 #endif
 
-- 
1.5.2

