summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <richard@openedhand.com>2008-02-13 01:04:52 +0000
committerRichard Purdie <richard@openedhand.com>2008-02-13 01:04:52 +0000
commitb92884d1513b29ba1c74e90614bc73e768a7d833 (patch)
tree215384357b4240cbe4ef86a510dfbd42f3c2ae55
parentfaed8fc7f772e3e1a3ca41f01805850a71952416 (diff)
downloadpoky-b92884d1513b29ba1c74e90614bc73e768a7d833.tar.gz
linux-rp-2.6.23: Add patch to get zylonite mtd working (forward ported 2.6.14 driver) and set display to VGA
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@3786 311d38ba-8fff-0310-9ca6-ca027cbcb966
-rw-r--r--meta/packages/linux/linux-rp-2.6.23/defconfig-zylonite25
-rw-r--r--meta/packages/linux/linux-rp-2.6.23/zylonite_mtd-r0.patch4062
-rw-r--r--meta/packages/linux/linux-rp_2.6.23.bb3
3 files changed, 4079 insertions, 11 deletions
diff --git a/meta/packages/linux/linux-rp-2.6.23/defconfig-zylonite b/meta/packages/linux/linux-rp-2.6.23/defconfig-zylonite
index 8be4a3bd47..14ea6c355f 100644
--- a/meta/packages/linux/linux-rp-2.6.23/defconfig-zylonite
+++ b/meta/packages/linux/linux-rp-2.6.23/defconfig-zylonite
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.23-rc4 3# Linux kernel version: 2.6.23
4# Tue Sep 25 15:57:10 2007 4# Tue Feb 12 18:04:14 2008
5# 5#
6CONFIG_ARM=y 6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y 7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -65,7 +65,6 @@ CONFIG_FUTEX=y
65CONFIG_ANON_INODES=y 65CONFIG_ANON_INODES=y
66CONFIG_EPOLL=y 66CONFIG_EPOLL=y
67CONFIG_SIGNALFD=y 67CONFIG_SIGNALFD=y
68CONFIG_TIMERFD=y
69CONFIG_EVENTFD=y 68CONFIG_EVENTFD=y
70CONFIG_SHMEM=y 69CONFIG_SHMEM=y
71CONFIG_VM_EVENT_COUNTERS=y 70CONFIG_VM_EVENT_COUNTERS=y
@@ -262,6 +261,7 @@ CONFIG_BINFMT_ELF=y
262# Power management options 261# Power management options
263# 262#
264# CONFIG_PM is not set 263# CONFIG_PM is not set
264CONFIG_SUSPEND_UP_POSSIBLE=y
265 265
266# 266#
267# Networking 267# Networking
@@ -272,6 +272,7 @@ CONFIG_NET=y
272# Networking options 272# Networking options
273# 273#
274CONFIG_PACKET=m 274CONFIG_PACKET=m
275# CONFIG_PACKET_MMAP is not set
275CONFIG_UNIX=y 276CONFIG_UNIX=y
276CONFIG_XFRM=y 277CONFIG_XFRM=y
277# CONFIG_XFRM_USER is not set 278# CONFIG_XFRM_USER is not set
@@ -304,6 +305,7 @@ CONFIG_INET_TCP_DIAG=y
304CONFIG_TCP_CONG_CUBIC=y 305CONFIG_TCP_CONG_CUBIC=y
305CONFIG_DEFAULT_TCP_CONG="cubic" 306CONFIG_DEFAULT_TCP_CONG="cubic"
306# CONFIG_TCP_MD5SIG is not set 307# CONFIG_TCP_MD5SIG is not set
308# CONFIG_IP_VS is not set
307# CONFIG_IPV6 is not set 309# CONFIG_IPV6 is not set
308# CONFIG_INET6_XFRM_TUNNEL is not set 310# CONFIG_INET6_XFRM_TUNNEL is not set
309# CONFIG_INET6_TUNNEL is not set 311# CONFIG_INET6_TUNNEL is not set
@@ -370,7 +372,6 @@ CONFIG_IP_NF_RAW=m
370CONFIG_IP_NF_ARPTABLES=m 372CONFIG_IP_NF_ARPTABLES=m
371CONFIG_IP_NF_ARPFILTER=m 373CONFIG_IP_NF_ARPFILTER=m
372CONFIG_IP_NF_ARP_MANGLE=m 374CONFIG_IP_NF_ARP_MANGLE=m
373
374# CONFIG_IP_DCCP is not set 375# CONFIG_IP_DCCP is not set
375# CONFIG_IP_SCTP is not set 376# CONFIG_IP_SCTP is not set
376# CONFIG_TIPC is not set 377# CONFIG_TIPC is not set
@@ -551,6 +552,7 @@ CONFIG_MTD_NAND=y
551CONFIG_MTD_NAND_IDS=y 552CONFIG_MTD_NAND_IDS=y
552# CONFIG_MTD_NAND_DISKONCHIP is not set 553# CONFIG_MTD_NAND_DISKONCHIP is not set
553# CONFIG_MTD_NAND_SHARPSL is not set 554# CONFIG_MTD_NAND_SHARPSL is not set
555CONFIG_MTD_NAND_ZYLONITE=y
554# CONFIG_MTD_NAND_NANDSIM is not set 556# CONFIG_MTD_NAND_NANDSIM is not set
555# CONFIG_MTD_NAND_PLATFORM is not set 557# CONFIG_MTD_NAND_PLATFORM is not set
556# CONFIG_MTD_ONENAND is not set 558# CONFIG_MTD_ONENAND is not set
@@ -964,11 +966,8 @@ CONFIG_FONT_8x16=y
964CONFIG_LOGO=y 966CONFIG_LOGO=y
965CONFIG_LOGO_LINUX_MONO=y 967CONFIG_LOGO_LINUX_MONO=y
966CONFIG_LOGO_LINUX_VGA16=y 968CONFIG_LOGO_LINUX_VGA16=y
967CONFIG_LOGO_LINUX_CLUT224=y 969# CONFIG_LOGO_LINUX_CLUT224 is not set
968# CONFIG_LOGO_OHAND_CLUT224 is not set 970CONFIG_LOGO_OHAND_CLUT224=y
969# CONFIG_LOGO_OZ240_CLUT224 is not set
970# CONFIG_LOGO_OZ480_CLUT224 is not set
971# CONFIG_LOGO_OZ640_CLUT224 is not set
972 971
973# 972#
974# Sound 973# Sound
@@ -1025,7 +1024,7 @@ CONFIG_SND_VERBOSE_PROCFS=y
1025# 1024#
1026# CONFIG_SOUND_PRIME is not set 1025# CONFIG_SOUND_PRIME is not set
1027CONFIG_HID_SUPPORT=y 1026CONFIG_HID_SUPPORT=y
1028CONFIG_HID=m 1027CONFIG_HID=y
1029# CONFIG_HID_DEBUG is not set 1028# CONFIG_HID_DEBUG is not set
1030 1029
1031# 1030#
@@ -1237,7 +1236,13 @@ CONFIG_EXT2_FS=y
1237# CONFIG_EXT2_FS_XATTR is not set 1236# CONFIG_EXT2_FS_XATTR is not set
1238# CONFIG_EXT2_FS_XIP is not set 1237# CONFIG_EXT2_FS_XIP is not set
1239CONFIG_EXT3_FS=m 1238CONFIG_EXT3_FS=m
1239CONFIG_EXT3_FS_XATTR=y
1240# CONFIG_EXT3_FS_POSIX_ACL is not set
1241# CONFIG_EXT3_FS_SECURITY is not set
1240# CONFIG_EXT4DEV_FS is not set 1242# CONFIG_EXT4DEV_FS is not set
1243CONFIG_JBD=m
1244# CONFIG_JBD_DEBUG is not set
1245CONFIG_FS_MBCACHE=y
1241# CONFIG_REISERFS_FS is not set 1246# CONFIG_REISERFS_FS is not set
1242# CONFIG_JFS_FS is not set 1247# CONFIG_JFS_FS is not set
1243# CONFIG_FS_POSIX_ACL is not set 1248# CONFIG_FS_POSIX_ACL is not set
diff --git a/meta/packages/linux/linux-rp-2.6.23/zylonite_mtd-r0.patch b/meta/packages/linux/linux-rp-2.6.23/zylonite_mtd-r0.patch
new file mode 100644
index 0000000000..231b3d76c9
--- /dev/null
+++ b/meta/packages/linux/linux-rp-2.6.23/zylonite_mtd-r0.patch
@@ -0,0 +1,4062 @@
1Gross hacks to make the Zylonite boot from flash in VGA.
2
3Flash driver forward ported to 2.6.14
4
5Index: linux-2.6.23/drivers/mtd/nand/Kconfig
6===================================================================
7--- linux-2.6.23.orig/drivers/mtd/nand/Kconfig 2008-02-12 18:02:36.000000000 +0000
8+++ linux-2.6.23/drivers/mtd/nand/Kconfig 2008-02-12 18:03:07.000000000 +0000
9@@ -223,6 +223,10 @@
10 tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)"
11 depends on ARCH_PXA
12
13+config MTD_NAND_ZYLONITE
14+ tristate "Support for NAND Flash on Zylonite"
15+ depends on ARCH_PXA
16+
17 config MTD_NAND_BASLER_EXCITE
18 tristate "Support for NAND Flash on Basler eXcite"
19 depends on BASLER_EXCITE
20Index: linux-2.6.23/drivers/mtd/nand/Makefile
21===================================================================
22--- linux-2.6.23.orig/drivers/mtd/nand/Makefile 2008-02-12 18:02:36.000000000 +0000
23+++ linux-2.6.23/drivers/mtd/nand/Makefile 2008-02-12 18:03:27.000000000 +0000
24@@ -19,6 +19,7 @@
25 obj-$(CONFIG_MTD_NAND_H1900) += h1910.o
26 obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o
27 obj-$(CONFIG_MTD_NAND_SHARPSL) += sharpsl.o
28+obj-$(CONFIG_MTD_NAND_ZYLONITE) += mhn_nand.o
29 obj-$(CONFIG_MTD_NAND_TS7250) += ts7250.o
30 obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o
31 obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o
32Index: linux-2.6.23/drivers/mtd/nand/mhn_nand.c
33===================================================================
34--- /dev/null 1970-01-01 00:00:00.000000000 +0000
35+++ linux-2.6.23/drivers/mtd/nand/mhn_nand.c 2008-02-12 23:54:00.000000000 +0000
36@@ -0,0 +1,3869 @@
37+/*
38+ * drivers/mtd/nand/mhn_nand.c
39+ *
40+ * Copyright (C) 2005 Intel Coporation (chao.xie@intel.com)
41+ *
42+ * This program is free software; you can redistribute it and/or modify
43+ * it under the terms of the GNU General Public License version 2 as
44+ * published by the Free Software Foundation.
45+ *
46+ * Overview:
47+ * This is a device driver for the NAND flash device on zylonite board
48+ * which utilizes the Samsung K9K1216Q0C parts. This is a 64Mibit NAND
49+ * flash device.
50+
51+ *(C) Copyright 2006 Marvell International Ltd.
52+ * All Rights Reserved
53+ */
54+
55+#include <linux/slab.h>
56+#include <linux/module.h>
57+#include <linux/mtd/mtd.h>
58+#include <linux/mtd/nand.h>
59+#include <linux/mtd/partitions.h>
60+#include <linux/interrupt.h>
61+#include <linux/device.h>
62+#include <linux/platform_device.h>
63+#include <linux/delay.h>
64+#include <linux/dma-mapping.h>
65+#include <asm/hardware.h>
66+#include <asm/io.h>
67+#include <asm/irq.h>
68+#include <asm/delay.h>
69+#include <asm/dma.h>
70+#include <asm/arch/mfp.h>
71+//#include <asm/arch/cpu-freq-voltage-mhn.h>
72+
73+//#define NDCR 0xf0000000
74+//#define NDCR (*((volatile u32 *)0xf0000000))
75+//#define NDCR __REG_2(0x43100000) /* Data Flash Control register */
76+#define NDCR_SPARE_EN (0x1<<31)
77+#define NDCR_ECC_EN (0x1<<30)
78+#define NDCR_DMA_EN (0x1<<29)
79+#define NDCR_ND_RUN (0x1<<28)
80+#define NDCR_DWIDTH_C (0x1<<27)
81+#define NDCR_DWIDTH_M (0x1<<26)
82+#define NDCR_PAGE_SZ (0x1<<24)
83+#define NDCR_NCSX (0x1<<23)
84+#define NDCR_ND_MODE (0x3<<21)
85+#define NDCR_NAND_MODE 0x0
86+#define NDCR_CLR_PG_CNT (0x1<<20)
87+#define NDCR_CLR_ECC ( 0x1<<19)
88+#define NDCR_RD_ID_CNT_MASK (0x7<<16)
89+#define NDCR_RD_ID_CNT(x) (((x) << 16) & NDCR_RD_ID_CNT_MASK)
90+#define NDCR_RA_START (0x1<<15)
91+#define NDCR_PG_PER_BLK (0x1<<14)
92+#define NDCR_ND_ARB_EN (0x1<<12)
93+
94+//#define NDSR (*((volatile u32 *)0xf0000014))
95+//#define NDSR __REG_2(0x43100014) /* Data Controller Status Register */
96+#define NDSR_RDY (0x1<<11)
97+#define NDSR_CS0_PAGED (0x1<<10)
98+#define NDSR_CS1_PAGED (0x1<<9)
99+#define NDSR_CS0_CMDD (0x1<<8)
100+#define NDSR_CS1_CMDD (0x1<<7)
101+#define NDSR_CS0_BBD (0x1<<6)
102+#define NDSR_CS1_BBD (0x1<<5)
103+#define NDSR_DBERR (0x1<<4)
104+#define NDSR_SBERR (0x1<<3)
105+#define NDSR_WRDREQ (0x1<<2)
106+#define NDSR_RDDREQ (0x1<<1)
107+#define NDSR_WRCMDREQ (0x1)
108+
109+#define OSCR __REG(0x40A00010) /* OS Timer Counter Register */
110+//#define NDCB0 __REG_2(0x43100048) /* Data Controller Command Buffer0 */
111+//#define NDCB1 __REG_2(0x4310004C) /* Data Controller Command Buffer1 */
112+//#define NDCB2 __REG_2(0x43100050) /* Data Controller Command Buffer2 */
113+#define NDCB0_AUTO_RS (0x1<<25)
114+#define NDCB0_CSEL (0x1<<24)
115+#define NDCB0_CMD_TYPE_MASK (0x7<<21)
116+#define NDCB0_CMD_TYPE(x) (((x) << 21) & NDCB0_CMD_TYPE_MASK)
117+#define NDCB0_NC (0x1<<20)
118+#define NDCB0_DBC (0x1<<19)
119+#define NDCB0_ADDR_CYC_MASK (0x7<<16)
120+#define NDCB0_ADDR_CYC(x) (((x) << 16) & NDCB0_ADDR_CYC_MASK)
121+#define NDCB0_CMD2_MASK (0xff<<8)
122+#define NDCB0_CMD1_MASK (0xff)
123+#define NDCB0_ADDR_CYC_SHIFT (16)
124+#define DCMD0 __REG(0x4000020c) /* DMA Command Address Register Channel 0 */
125+#define DCMD1 __REG(0x4000021c) /* DMA Command Address Register Channel 1 */
126+#define DCMD2 __REG(0x4000022c) /* DMA Command Address Register Channel 2 */
127+#define DCMD3 __REG(0x4000023c) /* DMA Command Address Register Channel 3 */
128+#define DCMD4 __REG(0x4000024c) /* DMA Command Address Register Channel 4 */
129+#define DCMD5 __REG(0x4000025c) /* DMA Command Address Register Channel 5 */
130+#define DCMD6 __REG(0x4000026c) /* DMA Command Address Register Channel 6 */
131+#define DCMD7 __REG(0x4000027c) /* DMA Command Address Register Channel 7 */
132+#define DCMD8 __REG(0x4000028c) /* DMA Command Address Register Channel 8 */
133+#define DCMD9 __REG(0x4000029c) /* DMA Command Address Register Channel 9 */
134+#define DCMD10 __REG(0x400002ac) /* DMA Command Address Register Channel 10 */
135+#define DCMD11 __REG(0x400002bc) /* DMA Command Address Register Channel 11 */
136+#define DCMD12 __REG(0x400002cc) /* DMA Command Address Register Channel 12 */
137+#define DCMD13 __REG(0x400002dc) /* DMA Command Address Register Channel 13 */
138+#define DCMD14 __REG(0x400002ec) /* DMA Command Address Register Channel 14 */
139+#define DCMD15 __REG(0x400002fc) /* DMA Command Address Register Channel 15 */
140+#define DCMD(x) __REG2(0x4000020c, (x) << 4)
141+#define DCMD_INCSRCADDR (1 << 31) /* Source Address Increment Setting. */
142+#define DCMD_INCTRGADDR (1 << 30) /* Target Address Increment Setting. */
143+#define DCMD_FLOWSRC (1 << 29) /* Flow Control by the source. */
144+#define DCMD_FLOWTRG (1 << 28) /* Flow Control by the target. */
145+#define DCMD_STARTIRQEN (1 << 22) /* Start Interrupt Enable */
146+#define DCMD_ENDIRQEN (1 << 21) /* End Interrupt Enable */
147+#define DCMD_ENDIAN (1 << 18) /* Device Endian-ness. */
148+#define DCMD_BURST8 (1 << 16) /* 8 byte burst */
149+#define DCMD_BURST16 (2 << 16) /* 16 byte burst */
150+#define DCMD_BURST32 (3 << 16) /* 32 byte burst */
151+#define DCMD_WIDTH1 (1 << 14) /* 1 byte width */
152+#define DCMD_WIDTH2 (2 << 14) /* 2 byte width (HalfWord) */
153+#define DCMD_WIDTH4 (3 << 14) /* 4 byte width (Word) */
154+#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */
155+#define DCMD_RXPCDR (DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4)
156+#define DCMD_RXMCDR (DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4)
157+#define DCMD_TXPCDR (DCMD_INCSRCADDR|DCMD_FLOWTRG|DCMD_BURST32|DCMD_WIDTH4)
158+#define DRCMR(n) __REG2(0x40000100, (n)<<2)
159+#define DRCMR97 __REG(0x40001184) /* Request to Channel Map Register for NAND interface data transmit & receive Request */
160+#define DRCMR98 __REG(0x40001188) /* Reserved */
161+#define DRCMR99 __REG(0x4000118C) /* Request to Channel Map Register for NAND interface command transmit Request */
162+#define DRCMRRXSADR DRCMR2
163+#define DRCMRTXSADR DRCMR3
164+#define DRCMRRXBTRBR DRCMR4
165+#define DRCMRTXBTTHR DRCMR5
166+#define DRCMRRXFFRBR DRCMR6
167+#define DRCMRTXFFTHR DRCMR7
168+#define DRCMRRXMCDR DRCMR8
169+#define DRCMRRXMODR DRCMR9
170+#define DRCMRTXMODR DRCMR10
171+#define DRCMRRXPCDR DRCMR11
172+#define DRCMRTXPCDR DRCMR12
173+#define DRCMRRXSSDR DRCMR13
174+#define DRCMRTXSSDR DRCMR14
175+#define DRCMRRXICDR DRCMR17
176+#define DRCMRTXICDR DRCMR18
177+#define DRCMRRXSTRBR DRCMR19
178+#define DRCMRTXSTTHR DRCMR20
179+#define DRCMRRXMMC DRCMR21
180+#define DRCMRTXMMC DRCMR22
181+#define DRCMRRXMMC2 DRCMR93
182+#define DRCMRTXMMC2 DRCMR94
183+#define DRCMRRXMMC3 DRCMR100
184+#define DRCMRTXMMC3 DRCMR101
185+#define DRCMRUDC(x) DRCMR((x) + 24)
186+#define DRCMR_MAPVLD (1 << 7) /* Map Valid (read / write) */
187+#define DRCMR_CHLNUM 0x1f /* mask for Channel Number (read / write) */
188+#define DCSR0 __REG(0x40000000) /* DMA Control / Status Register for Channel 0 */
189+#define DCSR1 __REG(0x40000004) /* DMA Control / Status Register for Channel 1 */
190+#define DCSR2 __REG(0x40000008) /* DMA Control / Status Register for Channel 2 */
191+#define DCSR3 __REG(0x4000000c) /* DMA Control / Status Register for Channel 3 */
192+#define DCSR4 __REG(0x40000010) /* DMA Control / Status Register for Channel 4 */
193+#define DCSR5 __REG(0x40000014) /* DMA Control / Status Register for Channel 5 */
194+#define DCSR6 __REG(0x40000018) /* DMA Control / Status Register for Channel 6 */
195+#define DCSR7 __REG(0x4000001c) /* DMA Control / Status Register for Channel 7 */
196+#define DCSR8 __REG(0x40000020) /* DMA Control / Status Register for Channel 8 */
197+#define DCSR9 __REG(0x40000024) /* DMA Control / Status Register for Channel 9 */
198+#define DCSR10 __REG(0x40000028) /* DMA Control / Status Register for Channel 10 */
199+#define DCSR11 __REG(0x4000002c) /* DMA Control / Status Register for Channel 11 */
200+#define DCSR12 __REG(0x40000030) /* DMA Control / Status Register for Channel 12 */
201+#define DCSR13 __REG(0x40000034) /* DMA Control / Status Register for Channel 13 */
202+#define DCSR14 __REG(0x40000038) /* DMA Control / Status Register for Channel 14 */
203+#define DCSR15 __REG(0x4000003c) /* DMA Control / Status Register for Channel 15 */
204+#define DCSR16 __REG(0x40000040) /* DMA Control / Status Register for Channel 16 */
205+#define DCSR17 __REG(0x40000044) /* DMA Control / Status Register for Channel 17 */
206+#define DCSR18 __REG(0x40000048) /* DMA Control / Status Register for Channel 18 */
207+#define DCSR19 __REG(0x4000004c) /* DMA Control / Status Register for Channel 19 */
208+#define DCSR20 __REG(0x40000050) /* DMA Control / Status Register for Channel 20 */
209+#define DCSR21 __REG(0x40000054) /* DMA Control / Status Register for Channel 21 */
210+#define DCSR22 __REG(0x40000058) /* DMA Control / Status Register for Channel 22 */
211+#define DCSR23 __REG(0x4000005c) /* DMA Control / Status Register for Channel 23 */
212+#define DCSR24 __REG(0x40000060) /* DMA Control / Status Register for Channel 24 */
213+#define DCSR25 __REG(0x40000064) /* DMA Control / Status Register for Channel 25 */
214+#define DCSR26 __REG(0x40000068) /* DMA Control / Status Register for Channel 26 */
215+#define DCSR27 __REG(0x4000006c) /* DMA Control / Status Register for Channel 27 */
216+#define DCSR28 __REG(0x40000070) /* DMA Control / Status Register for Channel 28 */
217+#define DCSR29 __REG(0x40000074) /* DMA Control / Status Register for Channel 29 */
218+#define DCSR30 __REG(0x40000078) /* DMA Control / Status Register for Channel 30 */
219+#define DCSR31 __REG(0x4000007c) /* DMA Control / Status Register for Channel 31 */
220+#define DCSR(x) __REG2(0x40000000, (x) << 2)
221+#define DCSR_RUN (1 << 31) /* Run Bit (read / write) */
222+#define DCSR_NODESC (1 << 30) /* No-Descriptor Fetch (read / write) */
223+#define DCSR_STOPIRQEN (1 << 29) /* Stop Interrupt Enable (read / write) */
224+#define DCSR_EORIRQEN (1 << 28) /* End of Receive Interrupt Enable (R/W) */
225+#define DCSR_EORJMPEN (1 << 27) /* Jump to next descriptor on EOR */
226+#define DCSR_EORSTOPEN (1 << 26) /* STOP on an EOR */
227+#define DCSR_SETCMPST (1 << 25) /* Set Descriptor Compare Status */
228+#define DCSR_CLRCMPST (1 << 24) /* Clear Descriptor Compare Status */
229+#define DCSR_CMPST (1 << 10) /* The Descriptor Compare Status */
230+#define DCSR_EORINTR (1 << 9) /* The end of Receive */
231+#define DCSR_REQPEND (1 << 8) /* Request Pending (read-only) */
232+#define DCSR_RASINTR (1 << 4) /* Request After Channel Stopped */
233+#define DCSR_STOPSTATE (1 << 3) /* Stop State (read-only) */
234+#define DCSR_ENDINTR (1 << 2) /* End Interrupt (read / write) */
235+#define DCSR_STARTINTR (1 << 1) /* Start Interrupt (read / write) */
236+#define DCSR_BUSERR (1 << 0) /* Bus Error Interrupt (read / write) */
237+#define DDADR(x) __REG2(0x40000200, (x) << 4)
238+//#define __REG_2(x) (*((volatile u32 *)io_p2v_2(x)))
239+#define IRQ_NAND PXA_IRQ(45)
240+#define CKEN_NAND 4 ///< NAND Flash Controller Clock Enable
241+
242+/* #define CONFIG_MTD_NAND_MONAHANS_DEBUG */
243+#ifdef CONFIG_MTD_NAND_MONAHANS_DEBUG
244+#define D1(x) do { \
245+ printk(KERN_DEBUG "%s: ", __FUNCTION__); \
246+ x; \
247+ }while(0)
248+
249+#define DPRINTK(fmt,args...) printk(KERN_DEBUG fmt, ##args )
250+#define PRINT_BUF(buf, num) print_buf(buf, num)
251+#else
252+#define D1(x)
253+#define DPRINTK(fmt,args...)
254+#define PRINT_BUF(buf, num)
255+#endif
256+
257+/* DFC timing 0 register */
258+#define DFC_TIMING_tRP 0
259+#define DFC_TIMING_tRH 3
260+#define DFC_TIMING_tWP 8
261+#define DFC_TIMING_tWH 11
262+#define DFC_TIMING_tCS 16
263+#define DFC_TIMING_tCH 19
264+
265+/* DFC timing 1 register */
266+#define DFC_TIMING_tAR 0
267+#define DFC_TIMING_tWHR 4
268+#define DFC_TIMING_tR 16
269+
270+/* max value for each timing setting in DFC */
271+#define DFC_TIMING_MAX_tCH 7
272+#define DFC_TIMING_MAX_tCS 7
273+#define DFC_TIMING_MAX_tWH 7
274+#define DFC_TIMING_MAX_tWP 7
275+#define DFC_TIMING_MAX_tRH 7
276+#define DFC_TIMING_MAX_tRP 7
277+#define DFC_TIMING_MAX_tR 65535
278+#define DFC_TIMING_MAX_tWHR 15
279+#define DFC_TIMING_MAX_tAR 15
280+
281+/*
282+ * The Data Flash Controller Flash timing structure
283+ * For NAND flash used on Zylonite board(Samsung K9K1216Q0C),
284+ * user should use value at end of each row of following member
285+ * bracketed.
286+ */
287+struct dfc_flash_timing {
288+ uint32_t tCH; /* Enable signal hold time */
289+ uint32_t tCS; /* Enable signal setup time */
290+ uint32_t tWH; /* ND_nWE high duration */
291+ uint32_t tWP; /* ND_nWE pulse time */
292+ uint32_t tRH; /* ND_nRE high duration */
293+ uint32_t tRP; /* ND_nRE pulse width */
294+ uint32_t tR; /* ND_nWE high to ND_nRE low for read */
295+ uint32_t tWHR;/* ND_nWE high to ND_nRE low delay for status read */
296+ uint32_t tAR; /* ND_ALE low to ND_nRE low delay */
297+};
298+
299+/* DFC command type */
300+enum {
301+ DFC_CMD_READ = 0x00000000,
302+ DFC_CMD_PROGRAM = 0x00200000,
303+ DFC_CMD_ERASE = 0x00400000,
304+ DFC_CMD_READ_ID = 0x00600000,
305+ DFC_CMD_STATUS_READ = 0x00800000,
306+ DFC_CMD_RESET = 0x00a00000
307+};
308+
309+/*
310+ * The Data Flash Controller Flash specification structure
311+ * For NAND flash used on Zylonite board(Samsung K9K1216Q0C),
312+ * user should use value at end of each row of following member
313+ * bracketed.
314+ */
315+struct dfc_flash_info {
316+ struct dfc_flash_timing timing; /* NAND Flash timing */
317+
318+ int enable_arbiter;/* Data flash bus arbiter enable (ND_ARB_EN) */
319+ uint32_t page_per_block;/* Pages per block (PG_PER_BLK) */
320+ uint32_t row_addr_start;/* Row address start position (RA_START) */
321+ uint32_t read_id_bytes; /* returned ID bytes(RD_ID_CNT) */
322+ uint32_t dfc_mode; /* NAND, CARBONDALE, PIXLEY... (ND_MODE) */
323+ uint32_t ncsx; /* Chip select don't care bit (NCSX) */
324+ uint32_t page_size; /* Page size in bytes (PAGE_SZ) */
325+ uint32_t oob_size; /* OOB size */
326+ uint32_t flash_width; /* Width of Flash memory (DWIDTH_M) */
327+ uint32_t dfc_width; /* Width of flash controller(DWIDTH_C) */
328+ uint32_t num_blocks; /* Number of physical blocks in Flash */
329+ uint32_t chip_id;
330+
331+ /* command codes */
332+ uint32_t read1; /* Read */
333+ uint32_t read2; /* unused, DFC don't support yet */
334+ uint32_t program; /* two cycle command */
335+ uint32_t read_status;
336+ uint32_t read_id;
337+ uint32_t erase; /* two cycle command */
338+ uint32_t reset;
339+ uint32_t lock; /* lock whole flash */
340+ uint32_t unlock; /* two cycle command, supporting partial unlock */
341+ uint32_t lock_status; /* read block lock status */
342+
343+ /* addr2ndcb1 - encode address cycles into register NDCB1 */
344+ /* ndbbr2addr - convert register NDBBR to bad block address */
345+ int (*addr2ndcb1)(uint16_t cmd, uint32_t addr, uint32_t *p);
346+ int (*ndbbr2addr)(uint16_t cmd, uint32_t ndbbr,uint32_t *p);
347+};
348+
349+enum {
350+ DFC_FLASH_NULL = 0 ,
351+ DFC_FLASH_Samsung_512Mb_X_16 = 1,
352+ DFC_FLASH_Micron_1Gb_X_8 = 2,
353+ DFC_FLASH_Micron_1Gb_X_16 = 3,
354+ DFC_FLASH_STM_1Gb_X_16 = 4,
355+ DFC_FLASH_STM_2Gb_X_16 = 5,
356+ DFC_FLASH_END,
357+};
358+
359+static int dfc_get_flash_info(int type, struct dfc_flash_info **flash_info);
360+
361+#define DFC_NDCR 0
362+#define DFC_NDTR0CS0 1
363+#define DFC_NDTR1CS0 3
364+#define DFC_NDSR 5
365+#define DFC_NDPCR 6
366+#define DFC_NDBDR0 7
367+#define DFC_NDBDR1 8
368+#define DFC_NDDB 16
369+#define DFC_NDCB0 18
370+#define DFC_NDCB1 19
371+#define DFC_NDCB2 20
372+
373+/* The Data Flash Controller Mode structure */
374+struct dfc_mode {
375+ int enable_dma; /* DMA, or nonDMA mode */
376+ int enable_ecc; /* ECC on/off */
377+ int enable_spare; /* Spare enable */
378+ int chip_select; /* CS0 or CS1 */
379+};
380+
381+/* The Data Flash Controller Context structure */
382+struct dfc_context {
383+ unsigned char __iomem *membase; /* DFC register base */
384+ struct dfc_mode *dfc_mode; /* DFC mode */
385+ int data_dma_ch; /* Data DMA channel number */
386+ int cmd_dma_ch; /* CMD DMA channel number */
387+ struct dfc_flash_info *flash_info; /* Flash Spec */
388+ struct mtd_info *mtd;
389+};
390+
391+#define NDCB0_DMA_ADDR 0x43100048
392+#define NDDB_DMA_ADDR 0x43100040
393+
394+#define NDSR_MASK 0xFFF
395+
396+/* The following data is a rough evaluation */
397+
398+/* microsecond, for readID/readStatus/reset */
399+#define NAND_OTHER_TIMEOUT 10
400+/* microsecond, for readID/readStatus/reset */
401+#define NAND_CMD_TIMEOUT 10
402+
403+#define BBT_BLOCK_BAD 0x03
404+#define BBT_BLOCK_GOOD 0x00
405+#define BBT_BLOCK_REV1 0x01
406+#define BBT_BLOCK_REV2 0x02
407+
408+#define BUFLEN (2048 + 64)
409+
410+/*
411+ * DFC data size enumeration transfered from/to controller,
412+ * including padding (zero)to be a multiple of 32.
413+ */
414+enum {
415+ DFC_DATA_SIZE_STATUS = 8, /* ReadStatus/ReadBlockLockStatus */
416+ DFC_DATA_SIZE_ID = 7, /* ReadID */
417+
418+ DFC_DATA_SIZE_32 = 32,
419+ DFC_DATA_SIZE_512 = 512, /* R/W disabling spare area */
420+ DFC_DATA_SIZE_520 = 520, /* Spare=1, ECC=1 */
421+ DFC_DATA_SIZE_528 = 528, /* Spare=1, ECC=0 */
422+ DFC_DATA_SIZE_544 = 544, /* R/W enabling spare area.(DMA mode)*/
423+
424+ DFC_DATA_SIZE_64 = 64,
425+ DFC_DATA_SIZE_2048 = 2048, /* R/W disabling spare area */
426+ DFC_DATA_SIZE_2088 = 2088, /* R/W enabling spare area with ecc */
427+ DFC_DATA_SIZE_2112 = 2112, /* R/W enabling spare area without ecc*/
428+ DFC_DATA_SIZE_2096 = 2096, /* R/W enabling spare area */
429+ DFC_DATA_SIZE_UNUSED = 0xFFFF
430+};
431+
432+/* DFC padding size enumeration transfered from/to controller */
433+enum {
434+ /*
435+ * ReadStatus/ReadBlockLockStatus/ReadID/
436+ * Read/Program disabling spare area(Both 512 and 2048)
437+ * Read/Program enabling spare area, disabling ECC
438+ */
439+ DFC_PADDING_SIZE_0 = 0,
440+
441+ /* Read/program with SPARE_EN=1, ECC_EN=0, pgSize=512 */
442+ DFC_PADDING_SIZE_16 = 16,
443+ /* for read/program with SPARE_EN=1, ECC_EN=1, pgSize=512 and 2048 */
444+ DFC_PADDING_SIZE_24 = 24,
445+ DFC_PADDING_SIZE_UNUSED = 0xFFFF
446+};
447+
448+static unsigned int flash_config = DFC_FLASH_NULL;
449+
450+void dfc_set_timing(struct dfc_context *context, struct dfc_flash_timing *t);
451+void dfc_set_dma(struct dfc_context *context);
452+void dfc_set_ecc(struct dfc_context *context);
453+void dfc_set_spare(struct dfc_context *context);
454+
455+int dfc_get_pattern(struct dfc_context *context, uint16_t cmd,
456+ int *data_size, int *padding);
457+
458+static int dfc_wait_event(struct dfc_context *context, uint32_t event,
459+ uint32_t *event_out, uint32_t timeout, int enable_int);
460+
461+int dfc_send_cmd(struct dfc_context *context, uint16_t cmd,
462+ uint32_t addr, int num_pages);
463+
464+void dfc_stop(struct dfc_context *context);
465+void dfc_read_fifo_partial(struct dfc_context *context, uint8_t *buffer,
466+ int nbytes, int data_size);
467+void dfc_write_fifo_partial(struct dfc_context *context, uint8_t *buffer,
468+ int nbytes, int data_size);
469+
470+void dfc_read_fifo(struct dfc_context *context, uint8_t *buffer, int nbytes);
471+void dfc_write_fifo(struct dfc_context *context, uint8_t *buffer, int nbytes);
472+
473+void dfc_read_badblock_addr(struct dfc_context *context, uint32_t *bbaddr);
474+
475+void dfc_clear_int(struct dfc_context *context, uint32_t int_mask);
476+void dfc_enable_int(struct dfc_context *context, uint32_t int_mask);
477+void dfc_disable_int(struct dfc_context *context, uint32_t int_mask);
478+
479+/* high level primitives */
480+int dfc_init(struct dfc_context *context, int type);
481+int dfc_init_no_gpio(struct dfc_context *context, int type);
482+
483+int dfc_reset_flash(struct dfc_context *context);
484+
485+int dfc_setup_cmd_dma(struct dfc_context *context,
486+ uint16_t cmd, uint32_t addr, int num_pages,
487+ uint32_t *buf, uint32_t buf_phys,
488+ uint32_t next_desc_phys, uint32_t dma_int_en,
489+ struct pxa_dma_desc *dma_desc);
490+
491+int dfc_setup_data_dma(struct dfc_context *context,
492+ uint16_t cmd, uint32_t buf_phys,
493+ uint32_t next_desc_phys, uint32_t dma_int_en,
494+ struct pxa_dma_desc *dma_desc);
495+
496+void dfc_start_cmd_dma(struct dfc_context *context,
497+ struct pxa_dma_desc *dma_desc);
498+void dfc_start_data_dma(struct dfc_context *context,
499+ struct pxa_dma_desc *dma_desc);
500+static int monahans_df_dev_ready(struct mtd_info *mtd);
501+
502+#ifdef CONFIG_DVFM
503+static int mhn_nand_dvfm_notifier(unsigned cmd, void *client_data, void *info);
504+static struct mhn_fv_notifier dvfm_notifier = {
505+ .name = "monahans-nand-flash",
506+ .priority = 0,
507+ .notifier_call = mhn_nand_dvfm_notifier,
508+};
509+#endif
510+
511+static unsigned short search_rel_block(int block, struct mtd_info *mtd);
512+
513+/*****************************************************************************
514+ * The DFC registers read/write routines
515+ *****************************************************************************/
516+static inline void dfc_write(struct dfc_context *context, int offset,
517+ unsigned long value)
518+{
519+ offset <<= 2;
520+ writel(value, context->membase + offset);
521+}
522+
523+static inline unsigned int dfc_read(struct dfc_context *context, int offset)
524+{
525+ offset <<= 2;
526+ return __raw_readl(context->membase + offset);
527+}
528+
529+/****************************************************************************
530+ * Flash Information
531+ ***************************************************************************/
532+
533+static int Samsung512MbX16Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p);
534+static int Samsung512MbX16NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p);
535+
536+static struct dfc_flash_info samsung512MbX16 =
537+{
538+ .timing = {
539+ .tCH = 10, /* tCH, Enable signal hold time */
540+ .tCS = 0, /* tCS, Enable signal setup time */
541+ .tWH = 20, /* tWH, ND_nWE high duration */
542+ .tWP = 40, /* tWP, ND_nWE pulse time */
543+ .tRH = 30, /* tRH, ND_nRE high duration */
544+ .tRP = 40, /* tRP, ND_nRE pulse width */
545+ /* tR = tR+tRR+tWB+1, ND_nWE high to ND_nRE low for read */
546+ .tR = 11123,
547+ /* tWHR, ND_nWE high to ND_nRE low delay for status read */
548+ .tWHR = 110,
549+ .tAR = 10, /* tAR, ND_ALE low to ND_nRE low delay */
550+ },
551+ .enable_arbiter = 1, /* Data flash bus arbiter enable */
552+ .page_per_block = 32, /* Pages per block */
553+ .row_addr_start = 0, /* Second cycle start, Row address start position */
554+ .read_id_bytes = 2, /* 2 bytes, returned ID bytes */
555+ .dfc_mode = 0, /* NAND mode */
556+ .ncsx = 0,
557+ .page_size = 512, /* Page size in bytes */
558+ .oob_size = 16, /* OOB size in bytes */
559+ .flash_width = 16, /* Width of Flash memory */
560+ .dfc_width = 16, /* Width of flash controller */
561+ .num_blocks = 4096, /* Number of physical blocks in Flash */
562+ .chip_id = 0x46ec,
563+
564+ /* command codes */
565+ .read1 = 0x0000, /* Read */
566+ .read2 = 0x0050, /* Read1 unused, current DFC don't support */
567+ .program = 0x1080, /* Write, two cycle command */
568+ .read_status = 0x0070, /* Read status */
569+ .read_id = 0x0090, /* Read ID */
570+ .erase = 0xD060, /* Erase, two cycle command */
571+ .reset = 0x00FF, /* Reset */
572+ .lock = 0x002A, /* Lock whole flash */
573+ .unlock = 0x2423, /* Unlock, two cycle command, supporting partial unlock */
574+ .lock_status = 0x007A, /* Read block lock status */
575+ .addr2ndcb1 = Samsung512MbX16Addr2NDCB1,
576+ .ndbbr2addr = Samsung512MbX16NDBBR2Addr,
577+};
578+
579+static int Samsung512MbX16Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p)
580+{
581+ uint32_t ndcb1 = 0;
582+
583+ if (addr >= 0x4000000) return -EINVAL;
584+
585+ if (cmd == samsung512MbX16.read1 || cmd == samsung512MbX16.program) {
586+ ndcb1 = (addr & 0xFF) | ((addr >> 1) & 0x01FFFF00);
587+ } else if (cmd == samsung512MbX16.erase) {
588+ ndcb1 = ((addr >> 9) & 0x00FFFFFF);
589+ }
590+
591+ *p = ndcb1;
592+ return 0;
593+
594+}
595+
596+static int Samsung512MbX16NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p)
597+{
598+ *p = ndbbr << 9;
599+ return 0;
600+}
601+
602+static int Micron1GbX8Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p);
603+static int Micron1GbX8NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p);
604+
605+static struct dfc_flash_info micron1GbX8 =
606+{
607+ .timing = {
608+ .tCH = 10, /* tCH, Enable signal hold time */
609+ .tCS = 25, /* tCS, Enable signal setup time */
610+ .tWH = 15, /* tWH, ND_nWE high duration */
611+ .tWP = 25, /* tWP, ND_nWE pulse time */
612+ .tRH = 15, /* tRH, ND_nRE high duration */
613+ .tRP = 25, /* tRP, ND_nRE pulse width */
614+ /* tR = tR+tRR+tWB+1, ND_nWE high to ND_nRE low for read */
615+ .tR = 25000,
616+ /* tWHR, ND_nWE high to ND_nRE low delay for status read */
617+ .tWHR = 60,
618+ .tAR = 10, /* tAR, ND_ALE low to ND_nRE low delay */
619+ },
620+ .enable_arbiter = 1, /* Data flash bus arbiter enable */
621+ .page_per_block = 64, /* Pages per block */
622+ .row_addr_start = 1, /* Second cycle start, Row address start position */
623+ .read_id_bytes = 4, /* Returned ID bytes */
624+ .dfc_mode = 0, /* NAND mode */
625+ .ncsx = 0,
626+ .page_size = 2048, /* Page size in bytes */
627+ .oob_size = 64, /* OOB size in bytes */
628+ .flash_width = 8, /* Width of Flash memory */
629+ .dfc_width = 8, /* Width of flash controller */
630+ .num_blocks = 1024, /* Number of physical blocks in Flash */
631+ .chip_id = 0xa12c,
632+ /* command codes */
633+ .read1 = 0x3000, /* Read */
634+ .read2 = 0x0050, /* Read1 unused, current DFC don't support */
635+ .program = 0x1080, /* Write, two cycle command */
636+ .read_status = 0x0070, /* Read status */
637+ .read_id = 0x0090, /* Read ID */
638+ .erase = 0xD060, /* Erase, two cycle command */
639+ .reset = 0x00FF, /* Reset */
640+ .lock = 0x002A, /* Lock whole flash */
641+ .unlock = 0x2423, /* Unlock, two cycle command, supporting partial unlock */
642+ .lock_status = 0x007A, /* Read block lock status */
643+ .addr2ndcb1 = Micron1GbX8Addr2NDCB1,
644+ .ndbbr2addr = Micron1GbX8NDBBR2Addr,
645+};
646+
647+static int Micron1GbX8Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p)
648+{
649+ uint32_t ndcb1 = 0;
650+ uint32_t page;
651+
652+ if (addr >= 0x8000000)
653+ return -EINVAL;
654+ page = addr / micron1GbX8.page_size;
655+ addr = (page / micron1GbX8.page_per_block) << 18 |
656+ (page % micron1GbX8.page_per_block) << 12;
657+
658+ if (cmd == micron1GbX8.read1 || cmd == micron1GbX8.program) {
659+ ndcb1 = (addr & 0xFFF) | ((addr << 4) & 0xFFFF0000);
660+ }
661+ else if (cmd == micron1GbX8.erase) {
662+ ndcb1 = ((addr >> 18) << 6) & 0xFFFF;
663+ }
664+
665+ *p = ndcb1;
666+ return 0;
667+}
668+
669+static int Micron1GbX8NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p)
670+{
671+ if (cmd == micron1GbX8.read1 || cmd == micron1GbX8.program) {
672+ *p = ((ndbbr & 0xF) << 8) | ((ndbbr >> 8) << 16);
673+ }
674+ else if (cmd == micron1GbX8.erase) {
675+ *p = (ndbbr >> 6) << 18;
676+ }
677+
678+
679+ return 0;
680+}
681+
682+
683+static int Micron1GbX16Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p);
684+static int Micron1GbX16NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p);
685+
686+static struct dfc_flash_info micron1GbX16 =
687+{
688+ .timing = {
689+ .tCH = 10, /* tCH, Enable signal hold time */
690+ .tCS = 25, /* tCS, Enable signal setup time */
691+ .tWH = 15, /* tWH, ND_nWE high duration */
692+ .tWP = 25, /* tWP, ND_nWE pulse time */
693+ .tRH = 15, /* tRH, ND_nRE high duration */
694+ .tRP = 25, /* tRP, ND_nRE pulse width */
695+ /* tR = tR+tRR+tWB+1, ND_nWE high to ND_nRE low for read */
696+ .tR = 25000,
697+ /* tWHR, ND_nWE high to ND_nRE low delay for status read */
698+ .tWHR = 60,
699+ .tAR = 10, /* tAR, ND_ALE low to ND_nRE low delay */
700+ },
701+ .enable_arbiter = 1, /* Data flash bus arbiter enable */
702+ .page_per_block = 64, /* Pages per block */
703+ .row_addr_start = 1, /* Second cycle start, Row address start position */
704+ .read_id_bytes = 4, /* Returned ID bytes */
705+ .dfc_mode = 0, /* NAND mode */
706+ .ncsx = 0,
707+ .page_size = 2048, /* Page size in bytes */
708+ .oob_size = 64, /* OOB size in bytes */
709+ .flash_width = 16, /* Width of Flash memory */
710+ .dfc_width = 16, /* Width of flash controller */
711+ .num_blocks = 1024, /* Number of physical blocks in Flash */
712+ .chip_id = 0xb12c,
713+
714+ /* command codes */
715+ .read1 = 0x3000, /* Read */
716+ .read2 = 0x0050, /* Read1 unused, current DFC don't support */
717+ .program = 0x1080, /* Write, two cycle command */
718+ .read_status = 0x0070, /* Read status */
719+ .read_id = 0x0090, /* Read ID */
720+ .erase = 0xD060, /* Erase, two cycle command */
721+ .reset = 0x00FF, /* Reset */
722+ .lock = 0x002A, /* Lock whole flash */
723+ .unlock = 0x2423, /* Unlock, two cycle command, supporting partial unlock */
724+ .lock_status = 0x007A, /* Read block lock status */
725+ .addr2ndcb1 = Micron1GbX16Addr2NDCB1,
726+ .ndbbr2addr = Micron1GbX16NDBBR2Addr,
727+};
728+
729+static int Micron1GbX16Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p)
730+{
731+ uint32_t ndcb1 = 0;
732+ uint32_t page;
733+
734+ if (addr >= 0x8000000)
735+ return -EINVAL;
736+ page = addr / micron1GbX16.page_size;
737+ addr = (page / micron1GbX16.page_per_block) << 17 |
738+ (page % micron1GbX16.page_per_block) << 11;
739+
740+ if (cmd == micron1GbX16.read1 || cmd == micron1GbX16.program) {
741+ ndcb1 = (addr & 0x7FF) | ((addr << 5) & 0xFFFF0000);
742+ }
743+ else if (cmd == micron1GbX16.erase) {
744+ ndcb1 = ((addr >> 17) << 6) & 0xFFFF;
745+ }
746+ *p = ndcb1;
747+ return 0;
748+}
749+
750+static int Micron1GbX16NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p)
751+{
752+ if (cmd == micron1GbX16.read1 || cmd == micron1GbX16.program) {
753+ *p = ((ndbbr & 0x7) << 8) | ((ndbbr >> 8) << 16);
754+ }
755+ else if (cmd == micron1GbX16.erase) {
756+ *p = (ndbbr >> 6) << 17;
757+ }
758+
759+ return 0;
760+}
761+
762+static int STM1GbX16Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p);
763+static int STM1GbX16NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p);
764+
765+static struct dfc_flash_info stm1GbX16 =
766+{
767+ .timing = {
768+ .tCH = 10, /* tCH, Enable signal hold time */
769+ .tCS = 10, /* tCS, Enable signal setup time */
770+ .tWH = 20, /* tWH, ND_nWE high duration */
771+ .tWP = 25, /* tWP, ND_nWE pulse time */
772+ .tRH = 20, /* tRH, ND_nRE high duration */
773+ .tRP = 25, /* tRP, ND_nRE pulse width */
774+ /* tR = tR+tRR+tWB+1, ND_nWE high to ND_nRE low for read */
775+ .tR = 25000,
776+ /* tWHR, ND_nWE high to ND_nRE low delay for status read */
777+ .tWHR = 60,
778+ .tAR = 10, /* tAR, ND_ALE low to ND_nRE low delay */
779+ },
780+ .enable_arbiter = 1, /* Data flash bus arbiter enable */
781+ .page_per_block = 64, /* Pages per block */
782+ .row_addr_start = 1, /* Second cycle start, Row address start position */
783+ .read_id_bytes = 4, /* Returned ID bytes */
784+ .dfc_mode = 0, /* NAND mode */
785+ .ncsx = 0,
786+ .page_size = 2048, /* Page size in bytes */
787+ .oob_size = 64, /* OOB size in bytes */
788+ .flash_width = 16, /* Width of Flash memory */
789+ .dfc_width = 16, /* Width of flash controller */
790+ .num_blocks = 1024, /* Number of physical blocks in Flash */
791+ .chip_id = 0xb120,
792+
793+ /* command codes */
794+ .read1 = 0x3000, /* Read */
795+ .read2 = 0x0050, /* Read1 unused, current DFC don't support */
796+ .program = 0x1080, /* Write, two cycle command */
797+ .read_status = 0x0070, /* Read status */
798+ .read_id = 0x0090, /* Read ID */
799+ .erase = 0xD060, /* Erase, two cycle command */
800+ .reset = 0x00FF, /* Reset */
801+ .lock = 0x002A, /* Lock whole flash */
802+ .unlock = 0x2423, /* Unlock, two cycle command, supporting partial unlock */
803+ .lock_status = 0x007A, /* Read block lock status */
804+ .addr2ndcb1 = STM1GbX16Addr2NDCB1,
805+ .ndbbr2addr = STM1GbX16NDBBR2Addr,
806+};
807+
808+static int STM1GbX16Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p)
809+{
810+ uint32_t ndcb1 = 0;
811+ uint32_t page;
812+
813+ if (addr >= 0x8000000)
814+ return -EINVAL;
815+ page = addr / stm1GbX16.page_size;
816+ addr = (page / stm1GbX16.page_per_block) << 17 |
817+ (page % stm1GbX16.page_per_block) << 11;
818+
819+ if (cmd == stm1GbX16.read1 || cmd == stm1GbX16.program) {
820+ ndcb1 = (addr & 0x7FF) | ((addr << 5) & 0xFFFF0000);
821+ }
822+ else if (cmd == stm1GbX16.erase) {
823+ ndcb1 = ((addr >> 17) << 6) & 0xFFFF;
824+ }
825+ *p = ndcb1;
826+ return 0;
827+}
828+
829+static int STM1GbX16NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p)
830+{
831+ if (cmd == stm1GbX16.read1 || cmd == stm1GbX16.program) {
832+ *p = ((ndbbr & 0x7) << 8) | ((ndbbr >> 8) << 16);
833+ }
834+ else if (cmd == stm1GbX16.erase) {
835+ *p = (ndbbr >> 6) << 17;
836+ }
837+
838+ return 0;
839+}
840+
841+static int STM2GbX16Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p);
842+static int STM2GbX16NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p);
843+
844+static struct dfc_flash_info stm2GbX16 =
845+{
846+ .timing = {
847+ .tCH = 10, /* tCH, Enable signal hold time */
848+ .tCS = 10, /* tCS, Enable signal setup time */
849+ .tWH = 20, /* tWH, ND_nWE high duration */
850+ .tWP = 25, /* tWP, ND_nWE pulse time */
851+ .tRH = 20, /* tRH, ND_nRE high duration */
852+ .tRP = 25, /* tRP, ND_nRE pulse width */
853+ /* tR = tR+tRR+tWB+1, ND_nWE high to ND_nRE low for read */
854+ .tR = 25000,
855+ /* tWHR, ND_nWE high to ND_nRE low delay for status read */
856+ .tWHR = 60,
857+ .tAR = 10, /* tAR, ND_ALE low to ND_nRE low delay */
858+ },
859+ .enable_arbiter = 1, /* Data flash bus arbiter enable */
860+ .page_per_block = 64, /* Pages per block */
861+ .row_addr_start = 1, /* Second cycle start, Row address start position */
862+ .read_id_bytes = 4, /* Returned ID bytes */
863+ .dfc_mode = 0, /* NAND mode */
864+ .ncsx = 0,
865+ .page_size = 2048, /* Page size in bytes */
866+ .oob_size = 64, /* OOB size in bytes */
867+ .flash_width = 16, /* Width of Flash memory */
868+ .dfc_width = 16, /* Width of flash controller */
869+ .num_blocks = 2048, /* Number of physical blocks in Flash */
870+ .chip_id = 0xca20,
871+
872+ /* command codes */
873+ .read1 = 0x3000, /* Read */
874+ .read2 = 0x0050, /* Read1 unused, current DFC don't support */
875+ .program = 0x1080, /* Write, two cycle command */
876+ .read_status = 0x0070, /* Read status */
877+ .read_id = 0x0090, /* Read ID */
878+ .erase = 0xD060, /* Erase, two cycle command */
879+ .reset = 0x00FF, /* Reset */
880+ .lock = 0x002A, /* Lock whole flash */
881+ .unlock = 0x2423, /* Unlock, two cycle command, supporting partial unlock */
882+ .lock_status = 0x007A, /* Read block lock status */
883+ .addr2ndcb1 = STM2GbX16Addr2NDCB1,
884+ .ndbbr2addr = STM2GbX16NDBBR2Addr,
885+};
886+
887+static int STM2GbX16Addr2NDCB1(uint16_t cmd, uint32_t addr, uint32_t *p)
888+{
889+ uint32_t ndcb1 = 0;
890+ uint32_t page;
891+
892+ if (addr >= 0x8000000)
893+ return -EINVAL;
894+ page = addr / stm2GbX16.page_size;
895+ addr = (page / stm2GbX16.page_per_block) << 17 |
896+ (page % stm2GbX16.page_per_block) << 11;
897+
898+ if (cmd == stm2GbX16.read1 || cmd == stm2GbX16.program) {
899+ ndcb1 = (addr & 0x7FF) | ((addr << 5) & 0xFFFF0000);
900+ }
901+ else if (cmd == stm2GbX16.erase) {
902+ ndcb1 = ((addr >> 17) << 6) & 0xFFFF;
903+ }
904+ *p = ndcb1;
905+ return 0;
906+}
907+
908+static int STM2GbX16NDBBR2Addr(uint16_t cmd, uint32_t ndbbr, uint32_t *p)
909+{
910+ if (cmd == stm2GbX16.read1 || cmd == stm2GbX16.program) {
911+ *p = ((ndbbr & 0x7) << 8) | ((ndbbr >> 8) << 16);
912+ }
913+ else if (cmd == stm2GbX16.erase) {
914+ *p = (ndbbr >> 6) << 17;
915+ }
916+
917+ return 0;
918+}
919+
920+static struct {
921+ int type;
922+ struct dfc_flash_info *flash_info;
923+} type_info[] = {
924+ { DFC_FLASH_Samsung_512Mb_X_16, &samsung512MbX16},
925+ { DFC_FLASH_Micron_1Gb_X_8, &micron1GbX8},
926+ { DFC_FLASH_Micron_1Gb_X_16, &micron1GbX16},
927+ { DFC_FLASH_STM_1Gb_X_16, &stm1GbX16},
928+ { DFC_FLASH_STM_2Gb_X_16, &stm2GbX16},
929+ { DFC_FLASH_NULL, NULL},
930+};
931+
932+int dfc_get_flash_info(int type, struct dfc_flash_info **flash_info)
933+{
934+ uint32_t i = 0;
935+
936+ while(type_info[i].type != DFC_FLASH_NULL) {
937+ if (type_info[i].type == type) {
938+ *flash_info = type_info[i].flash_info;
939+ return 0;
940+ }
941+ i++;
942+ }
943+ *flash_info = NULL;
944+ return -EINVAL;
945+}
946+
947+/******************************************************************************
948+ dfc_set_timing
949+
950+ Description:
951+ This function sets flash timing property in DFC timing register
952+ according to input timing value embodied in context structure.
953+ It is called once during the hardware initialization.
954+ Input Parameters:
955+ Output Parameters:
956+ None
957+ Returns:
958+ None
959+*******************************************************************************/
960+//#if defined(CONFIG_CPU_MONAHANS_L) || defined(CONFIG_CPU_MONAHANS_LV)
961+#define DFC_CLOCK 208
962+//#else
963+//#define DFC_CLOCK 104
964+//#endif
965+#define CLOCK_NS DFC_CLOCK/1000
966+
967+void dfc_set_timing(struct dfc_context *context, struct dfc_flash_timing *t)
968+{
969+ struct dfc_flash_timing timing = *t;
970+
971+ uint32_t r0 = 0;
972+ uint32_t r1 = 0;
973+
974+ /*
975+ * num of clock cycles = time (ns) / one clock sycle (ns) + 1
976+ * - integer division will truncate the result, so add a 1 in all cases
977+ * - subtract the extra 1 cycle added to all register timing values
978+ */
979+ timing.tCH = min(((int) (timing.tCH * CLOCK_NS) + 1),
980+ DFC_TIMING_MAX_tCH);
981+ timing.tCS = min(((int) (timing.tCS * CLOCK_NS) + 1),
982+ DFC_TIMING_MAX_tCS);
983+ timing.tWH = min(((int) (timing.tWH * CLOCK_NS) + 1),
984+ DFC_TIMING_MAX_tWH);
985+ timing.tWP = min(((int) (timing.tWP * CLOCK_NS) + 1),
986+ DFC_TIMING_MAX_tWP);
987+ timing.tRH = min(((int) (timing.tRH * CLOCK_NS) + 1),
988+ DFC_TIMING_MAX_tRH);
989+ timing.tRP = min(((int) (timing.tRP * CLOCK_NS) + 1),
990+ DFC_TIMING_MAX_tRP);
991+
992+ r0 = (timing.tCH << DFC_TIMING_tCH) |
993+ (timing.tCS << DFC_TIMING_tCS) |
994+ (timing.tWH << DFC_TIMING_tWH) |
995+ (timing.tWP << DFC_TIMING_tWP) |
996+ (timing.tRH << DFC_TIMING_tRH) |
997+ (timing.tRP << DFC_TIMING_tRP);
998+
999+ dfc_write(context, DFC_NDTR0CS0, r0);
1000+
1001+ timing.tR = min(((int) (timing.tR * CLOCK_NS) + 1),
1002+ DFC_TIMING_MAX_tR);
1003+ timing.tWHR = min(((int) (timing.tWHR * CLOCK_NS) + 1),
1004+ DFC_TIMING_MAX_tWHR);
1005+ timing.tAR = min(((int) (timing.tAR * CLOCK_NS) + 1),
1006+ DFC_TIMING_MAX_tAR);
1007+
1008+ r1 = (timing.tR << DFC_TIMING_tR) |
1009+ (timing.tWHR << DFC_TIMING_tWHR) |
1010+ (timing.tAR << DFC_TIMING_tAR);
1011+
1012+ dfc_write(context, DFC_NDTR1CS0, r1);
1013+ return;
1014+}
1015+
1016+/******************************************************************************
1017+ dfc_set_dma
1018+
1019+ Description:
1020+ Enables or Disables DMA in line with setting in DFC mode of context
1021+ structure. DMA mode of DFC. Performs a read-modify-write operation that
1022+ only changes the driven DMA_EN bit field In DMA mode, all commands and
1023+ data are transferred by DMA. DMA can be enable/disable on the fly.
1024+ Input Parameters:
1025+ context -Pointer to DFC context structure
1026+ Output Parameters:
1027+ None
1028+ Returns:
1029+ None
1030+*******************************************************************************/
1031+void
1032+dfc_set_dma(struct dfc_context* context)
1033+{
1034+ uint32_t ndcr;
1035+
1036+ ndcr = dfc_read(context, DFC_NDCR);
1037+ if (context->dfc_mode->enable_dma)
1038+ ndcr |= NDCR_DMA_EN;
1039+ else
1040+ ndcr &= ~NDCR_DMA_EN;
1041+
1042+ dfc_write(context, DFC_NDCR, ndcr);
1043+
1044+ /* Read again to make sure write work */
1045+ ndcr = dfc_read(context, DFC_NDCR);
1046+ return;
1047+}
1048+
1049+
1050+/******************************************************************************
1051+ dfc_set_ecc
1052+
1053+ Description:
1054+ This function enables or disables hardware ECC capability of DFC in line
1055+ with setting in DFC mode of context structure.
1056+ Input Parameters:
1057+ context -Pointer to DFC context structure
1058+ Output Parameters:
1059+ None
1060+ Returns:
1061+ None
1062+*******************************************************************************/
1063+void
1064+dfc_set_ecc(struct dfc_context* context)
1065+{
1066+ uint32_t ndcr;
1067+
1068+ ndcr = dfc_read(context, DFC_NDCR);
1069+ if (context->dfc_mode->enable_ecc)
1070+ ndcr |= NDCR_ECC_EN;
1071+ else
1072+ ndcr &= ~NDCR_ECC_EN;
1073+
1074+ dfc_write(context, DFC_NDCR, ndcr);
1075+
1076+ /* Read again to make sure write work */
1077+ ndcr = dfc_read(context, DFC_NDCR);
1078+ return;
1079+}
1080+
1081+/******************************************************************************
1082+ dfc_set_spare
1083+
1084+ Description:
1085+ This function enables or disables accesses to spare area of NAND Flash
1086+ through DFC in line with setting in DFC mode of context structure.
1087+ Input Parameters:
1088+ context -Pointer to DFC context structure
1089+ Output Parameters:
1090+ None
1091+ Returns:
1092+ None
1093+*******************************************************************************/
1094+void
1095+dfc_set_spare(struct dfc_context* context)
1096+{
1097+ uint32_t ndcr;
1098+
1099+ ndcr = dfc_read(context, DFC_NDCR);
1100+ if (context->dfc_mode->enable_spare)
1101+ ndcr |= NDCR_SPARE_EN;
1102+ else
1103+ ndcr &= ~NDCR_SPARE_EN;
1104+
1105+ dfc_write(context, DFC_NDCR, ndcr);
1106+
1107+ /* Read again to make sure write work */
1108+ ndcr = dfc_read(context, DFC_NDCR);
1109+ return;
1110+}
1111+
1112+static unsigned int get_delta (unsigned int start)
1113+{
1114+ unsigned int stop = OSCR;
1115+ return (stop - start);
1116+}
1117+
1118+static int dfc_wait_event(struct dfc_context *context, uint32_t event,
1119+ uint32_t *event_out, uint32_t timeout, int enable_int)
1120+{
1121+ uint32_t ndsr;
1122+ uint32_t to = 3 * timeout; /* 3 ticks ~ 1us */
1123+ int status;
1124+ int start = OSCR;
1125+
1126+ if (enable_int)
1127+ dfc_enable_int(context, event);
1128+
1129+ while (1) {
1130+ ndsr = dfc_read(context, DFC_NDSR);
1131+ ndsr &= NDSR_MASK;
1132+ if (ndsr & event) {
1133+ /* event happened */
1134+ *event_out = ndsr & event;
1135+ dfc_clear_int(context, *event_out);
1136+ status = 0;
1137+ break;
1138+ } else if (get_delta(start) > to) {
1139+ status = -ETIME;
1140+ break;
1141+ }
1142+ }
1143+
1144+ if (enable_int)
1145+ dfc_disable_int(context, event);
1146+ return status;
1147+}
1148+
1149+/******************************************************************************
1150+ dfc_get_pattern
1151+
1152+ Description:
1153+ This function is used to retrieve buffer size setting for a transaction
1154+ based on cmd.
1155+ Input Parameters:
1156+ context - Pointer to DFC context structure
1157+ cmd
1158+ Specifies type of command to be sent to NAND flash .The LSB of this
1159+ parameter defines the first command code for 2-cycles command. The
1160+ MSB defines the second command code for 2-cycles command. If MSB is
1161+ set to zero, this indicates that one cycle command
1162+ Output Parameters:
1163+ data_size
1164+ It is used to retrieve length of data transferred to/from DFC,
1165+ which includes padding bytes
1166+ padding
1167+ It is used to retrieve how many padding bytes there should be
1168+ in buffer of data_size.
1169+ Returns:
1170+ 0
1171+ If size setting is returned successfully
1172+ -EINVAL
1173+ If page size specified in flash spec of context structure is not 512 or
1174+ 2048;If specified command index is not read1/program/erase/reset/readID/
1175+ readStatus.
1176+*******************************************************************************/
1177+int dfc_get_pattern(struct dfc_context *context, uint16_t cmd,
1178+ int *data_size, int *padding)
1179+{
1180+ struct dfc_mode* dfc_mode = context->dfc_mode;
1181+ struct dfc_flash_info * flash_info = context->flash_info;
1182+ uint32_t page_size = context->flash_info->page_size; /* 512 or 2048 */
1183+
1184+ if (cmd == flash_info->read1 ||
1185+ cmd == flash_info->program) {
1186+ if (512 == page_size) {
1187+ /* add for DMA */
1188+ if (dfc_mode->enable_dma) {
1189+ *data_size = DFC_DATA_SIZE_544;
1190+ if (dfc_mode->enable_ecc)
1191+ *padding = DFC_PADDING_SIZE_24;
1192+ else
1193+ *padding = DFC_PADDING_SIZE_16;
1194+ } else if (!dfc_mode->enable_spare) {
1195+ *data_size = DFC_DATA_SIZE_512;
1196+ *padding = DFC_PADDING_SIZE_0;
1197+ } else {
1198+
1199+ if (dfc_mode->enable_ecc)
1200+ *data_size = DFC_DATA_SIZE_520;
1201+ else
1202+ *data_size = DFC_DATA_SIZE_528;
1203+
1204+ *padding = DFC_PADDING_SIZE_0;
1205+ }
1206+ } else if (2048 == page_size) {
1207+ /* add for DMA */
1208+ if (dfc_mode->enable_dma) {
1209+ *data_size = DFC_DATA_SIZE_2112;
1210+ if (dfc_mode->enable_ecc)
1211+ *padding = DFC_PADDING_SIZE_24;
1212+ else
1213+ *padding = DFC_PADDING_SIZE_0;
1214+ } else if (!dfc_mode->enable_spare) {
1215+ *data_size = DFC_DATA_SIZE_2048;
1216+ *padding = DFC_PADDING_SIZE_0;
1217+ } else {
1218+
1219+ if (dfc_mode->enable_ecc)
1220+ *data_size = DFC_DATA_SIZE_2088;
1221+ else
1222+ *data_size = DFC_DATA_SIZE_2112;
1223+
1224+ *padding = DFC_PADDING_SIZE_0;
1225+ }
1226+ } else /* if the page_size is neither 512 or 2048 */
1227+ return -EINVAL;
1228+ } else if (cmd == flash_info->read_id) {
1229+ *data_size = DFC_DATA_SIZE_ID;
1230+ *padding = DFC_PADDING_SIZE_0;
1231+ } else if(cmd == flash_info->read_status) {
1232+ *data_size = DFC_DATA_SIZE_STATUS;
1233+ *padding = DFC_PADDING_SIZE_0;
1234+ } else if (cmd == flash_info->erase || cmd == flash_info->reset) {
1235+ *data_size = DFC_DATA_SIZE_UNUSED;
1236+ *padding = DFC_PADDING_SIZE_UNUSED;
1237+ } else
1238+ return -EINVAL;
1239+ return 0;
1240+}
1241+
1242+
1243+/******************************************************************************
1244+ dfc_send_cmd
1245+
1246+ Description:
1247+ This function configures DFC to send command through DFC to NAND flash
1248+ Input Parameters:
1249+ context
1250+ Pointer to DFC context structure
1251+ cmd
1252+ Specifies type of command to be sent to NAND flash .The LSB of this
1253+ parameter defines the first command code for 2-cycles command. The
1254+ MSB defines the second command code for 2-cycles command. If MSB is
1255+ set to zero, this indicates that one cycle command
1256+ addr
1257+ Address sent out to the flash device withthis command. For page read/
1258+ program commands , 4-cycles address is sent. For erase command only
1259+ 3-cycles address is sent. If it is equal to 0xFFFFFFFF, the address
1260+ should not be used.
1261+ num_pages
1262+ It specifies the number of pages of data to be transferred for
1263+ a program or read commands. Unused for any other commands than
1264+ read/program.
1265+
1266+ Output Parameters:
1267+ None
1268+ Returns:
1269+ 0
1270+ If size setting is returned successfully
1271+ -EINVAL
1272+ If specified command index is not read1/program/erase/reset/readID/
1273+ readStatus.
1274+*******************************************************************************/
1275+int dfc_send_cmd(struct dfc_context *context, uint16_t cmd,
1276+ uint32_t addr, int num_pages)
1277+{
1278+ struct dfc_flash_info *flash_info = context->flash_info;
1279+ struct dfc_mode *dfc_mode = context->dfc_mode;
1280+ uint8_t cmd2;
1281+ uint32_t event_out;
1282+ uint32_t ndcb0=0, ndcb1=0, ndcb2=0, ndcr;
1283+ int status;
1284+
1285+ /* It is a must to set ND_RUN firstly, then write command buffer
1286+ * If conversely,it does not work
1287+ */
1288+ dfc_write(context, DFC_NDSR, NDSR_MASK);
1289+
1290+ /* Set ND_RUN */
1291+ ndcr = dfc_read(context, DFC_NDCR);
1292+ dfc_write(context, DFC_NDCR, (ndcr | NDCR_ND_RUN));
1293+
1294+ // Wait for write command request
1295+ status = dfc_wait_event(context, NDSR_WRCMDREQ,
1296+ &event_out, NAND_CMD_TIMEOUT, 0);
1297+
1298+ if (status) /* Timeout */
1299+ return status;
1300+
1301+ cmd2 = (cmd>>8) & 0xFF;
1302+ ndcb0 = cmd | (dfc_mode->chip_select<<24) | ((cmd2?1:0)<<19);
1303+
1304+ if (cmd == flash_info->read1) {
1305+ if (0xFFFFFFFF != addr) {
1306+ ndcb0 |= NDCB0_ADDR_CYC(4);
1307+ status = flash_info->addr2ndcb1(cmd, addr, &ndcb1);
1308+ if (status)
1309+ return status;
1310+ ndcb2 = (num_pages - 1) << 8;
1311+ }
1312+ } else if (cmd == flash_info->program) {
1313+ ndcb0 |= NDCB0_CMD_TYPE(1) | NDCB0_AUTO_RS;
1314+ ndcb0 |= NDCB0_ADDR_CYC(4);
1315+ status = flash_info->addr2ndcb1(cmd, addr, &ndcb1);
1316+ if (status)
1317+ return status;
1318+ ndcb2 = (num_pages-1) << 8;
1319+ } else if (cmd == flash_info->erase) {
1320+ ndcb0 |= NDCB0_CMD_TYPE(2) | NDCB0_AUTO_RS;
1321+ ndcb0 |= NDCB0_ADDR_CYC(3);
1322+ status = flash_info->addr2ndcb1(cmd, addr, &ndcb1);
1323+ if (status)
1324+ return status;
1325+ } else if (cmd == flash_info->read_id) {
1326+ ndcb0 |= NDCB0_CMD_TYPE(3);
1327+ } else if(cmd == flash_info->read_status) {
1328+ ndcb0 |= NDCB0_CMD_TYPE(4);
1329+ } else if(cmd == flash_info->reset) {
1330+ ndcb0 |= NDCB0_CMD_TYPE(5);
1331+ } else if (cmd == flash_info->lock) {
1332+ ndcb0 |= NDCB0_CMD_TYPE(5);
1333+ } else
1334+ return -EINVAL;
1335+
1336+ /* Write to DFC command register */
1337+ dfc_write(context, DFC_NDCB0, ndcb0);
1338+ dfc_write(context, DFC_NDCB0, ndcb1);
1339+ dfc_write(context, DFC_NDCB0, ndcb2);
1340+
1341+ return 0;
1342+}
1343+
1344+/******************************************************************************
1345+ dfc_stop
1346+
1347+ Description:
1348+ This function clears ND_RUN bit of NDCR.
1349+ Input Parameters:
1350+ context--Pointer to DFC context structure
1351+ Output Parameters:
1352+ None
1353+ Returns:
1354+ None
1355+*******************************************************************************/
1356+void dfc_stop(struct dfc_context *context)
1357+{
1358+ unsigned int ndcr;
1359+ ndcr = dfc_read(context, DFC_NDCR);
1360+ dfc_write(context, DFC_NDCR, (ndcr & ~NDCR_ND_RUN));
1361+ ndcr = dfc_read(context, DFC_NDCR);
1362+
1363+ return;
1364+}
1365+
1366+int dfc_setup_cmd_dma(struct dfc_context *context,
1367+ uint16_t cmd, uint32_t addr, int num_pages,
1368+ uint32_t *buf, uint32_t buf_phys,
1369+ uint32_t next_desc_phys, uint32_t dma_int_en,
1370+ struct pxa_dma_desc *dma_desc)
1371+{
1372+ struct dfc_flash_info *flash_info = context->flash_info;
1373+ struct dfc_mode *dfc_mode = context->dfc_mode;
1374+ uint8_t cmd2;
1375+ uint32_t event_out;
1376+ uint32_t ndcb0=0, ndcb1=0, ndcb2=0, ndcr;
1377+ int status;
1378+
1379+ /*
1380+ * It is a must to set ND_RUN firstly, then write command buffer
1381+ * If conversely,it does not work
1382+ */
1383+ dfc_write(context, DFC_NDSR, NDSR_MASK);
1384+
1385+ /* Set ND_RUN */
1386+ ndcr = dfc_read(context, DFC_NDCR);
1387+ ndcr |= NDCR_ND_RUN;
1388+ dfc_write(context, DFC_NDCR, ndcr);
1389+
1390+ /* Wait for write command request */
1391+ status = dfc_wait_event(context, NDSR_WRCMDREQ,
1392+ &event_out, NAND_CMD_TIMEOUT, 0);
1393+
1394+ if (status)
1395+ return status; /* Timeout */
1396+
1397+ cmd2 = (cmd>>8) & 0xFF;
1398+ ndcb0 = cmd | (dfc_mode->chip_select<<24) | ((cmd2?1:0)<<19);
1399+
1400+ if (cmd == flash_info->read1) {
1401+ if (0xFFFFFFFF != addr) {
1402+ ndcb0 |= NDCB0_ADDR_CYC(4);
1403+ status = flash_info->addr2ndcb1(cmd, addr, &ndcb1);
1404+ if (status)
1405+ return status;
1406+ ndcb2 = (num_pages-1) << 8;
1407+ }
1408+ } else if (cmd == flash_info->program) {
1409+ ndcb0 |= NDCB0_CMD_TYPE(1) | NDCB0_AUTO_RS;
1410+ ndcb0 |= NDCB0_ADDR_CYC(4);
1411+
1412+ status = flash_info->addr2ndcb1(cmd, addr, &ndcb1);
1413+ if (status)
1414+ return status;
1415+ ndcb2 = (num_pages-1) << 8;
1416+ } else if (cmd == flash_info->erase) {
1417+ ndcb0 |= NDCB0_CMD_TYPE(2) | NDCB0_AUTO_RS;
1418+ ndcb0 |= NDCB0_ADDR_CYC(3);
1419+
1420+ status = flash_info->addr2ndcb1(cmd, addr, &ndcb1);
1421+ if (status)
1422+ return status;
1423+ } else if (cmd == flash_info->read_id) {
1424+ ndcb0 |= NDCB0_CMD_TYPE(3);
1425+ } else if (cmd == flash_info->read_status) {
1426+ ndcb0 |= NDCB0_CMD_TYPE(4);
1427+ } else if (cmd == flash_info->reset) {
1428+ ndcb0 |= NDCB0_CMD_TYPE(5);
1429+ } else if (cmd == flash_info->lock) {
1430+ ndcb0 |= NDCB0_CMD_TYPE(5);
1431+ } else
1432+ return -EINVAL;
1433+
1434+ *((uint32_t *)buf) = ndcb0;
1435+ *((uint32_t *)buf + 1) = ndcb1;
1436+ *((uint32_t *)buf + 2) = ndcb2;
1437+
1438+ dma_int_en &= (DCMD_STARTIRQEN | DCMD_ENDIRQEN);
1439+
1440+ dma_desc->ddadr = next_desc_phys;
1441+ dma_desc->dsadr = buf_phys;
1442+ dma_desc->dtadr = NDCB0_DMA_ADDR;
1443+ dma_desc->dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | dma_int_en |
1444+ DCMD_WIDTH4 | DCMD_BURST16 | 12;
1445+ return 0;
1446+}
1447+
1448+int dfc_setup_data_dma(struct dfc_context* context,
1449+ uint16_t cmd, uint32_t buf_phys,
1450+ uint32_t next_desc_phys, uint32_t dma_int_en,
1451+ struct pxa_dma_desc* dma_desc)
1452+{
1453+ struct dfc_flash_info * flash_info = context->flash_info;
1454+ int data_size, padding;
1455+
1456+ dfc_get_pattern(context, cmd, &data_size, &padding);
1457+
1458+ dma_desc->ddadr = next_desc_phys;
1459+ dma_int_en &= (DCMD_STARTIRQEN | DCMD_ENDIRQEN);
1460+
1461+ if (cmd == flash_info->program) {
1462+
1463+ dma_desc->dsadr = buf_phys;
1464+ dma_desc->dtadr = NDDB_DMA_ADDR;
1465+ dma_desc->dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | dma_int_en |
1466+ DCMD_WIDTH4 | DCMD_BURST32 | data_size;
1467+
1468+ } else if (cmd == flash_info->read1 || cmd == flash_info->read_id ||
1469+ cmd == flash_info->read_status) {
1470+
1471+ dma_desc->dsadr = NDDB_DMA_ADDR;
1472+ dma_desc->dtadr = buf_phys;
1473+ dma_desc->dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | dma_int_en |
1474+ DCMD_WIDTH4 | DCMD_BURST32 | data_size;
1475+ }
1476+ else
1477+ return -EINVAL;
1478+ return 0;
1479+}
1480+
1481+void dfc_start_cmd_dma(struct dfc_context* context, struct pxa_dma_desc* dma_desc)
1482+{
1483+ DRCMR99 = DRCMR_MAPVLD | context->cmd_dma_ch; /* NAND CMD DRCMR */
1484+ DDADR(context->cmd_dma_ch) = (uint32_t)dma_desc;
1485+ DCSR(context->cmd_dma_ch) |= DCSR_RUN;
1486+}
1487+
1488+void dfc_start_data_dma(struct dfc_context* context, struct pxa_dma_desc* dma_desc)
1489+{
1490+ DRCMR97 = DRCMR_MAPVLD | context->data_dma_ch;
1491+ DDADR(context->data_dma_ch) = (uint32_t)dma_desc;
1492+ DCSR(context->data_dma_ch) |= DCSR_RUN;
1493+}
1494+
1495+/******************************************************************************
1496+ dfc_read_fifo_partial
1497+
1498+ Description:
1499+ This function reads data from data buffer of DFC.Bytes can be any less than
1500+ or equal to data_size, the left is ignored by ReadFIFO though they will be
1501+ read from NDDB to clear data buffer.
1502+ Input Parameters:
1503+ context
1504+ Pointer to DFC context structure
1505+ nbytes
1506+ Indicating how much data should be read into buffer.
1507+ data_size
1508+ Specifing length of data transferred to/from DFC, which includes
1509+ padding bytes
1510+ Output Parameters:
1511+ pBuffer
1512+ Pointer to the data buffer where data should be placed.
1513+ Returns:
1514+ None
1515+*******************************************************************************/
1516+void dfc_read_fifo_partial(struct dfc_context *context, uint8_t *buffer,
1517+ int nbytes, int data_size)
1518+{
1519+ uint32_t data = 0;
1520+ uint32_t i = 0;
1521+ uint32_t bytes_multi;
1522+ uint32_t bytes_remain;
1523+
1524+
1525+ if (1 == data_size) {
1526+ data = dfc_read(context, DFC_NDDB) & 0xFF;
1527+ *buffer++ = (uint8_t)data;
1528+ } else if (2 == data_size) {
1529+ data = dfc_read(context, DFC_NDDB) & 0xFFFF;
1530+ *buffer++ = data & 0xFF;
1531+ *buffer++ = (data >> 8) & 0xFF;
1532+ } else {
1533+ bytes_multi = (nbytes & 0xFFFFFFFC);
1534+ bytes_remain = nbytes & 0x03;
1535+
1536+ i = 0;
1537+ /* Read the bytes_multi*4 bytes data */
1538+ while (i < bytes_multi) {
1539+ data = dfc_read(context, DFC_NDDB);
1540+ /* FIXME: we don't know whether the buffer
1541+ * align to 4 bytes or not. Cast the buffer
1542+ * to int is not safe here. Especially under
1543+ * gcc 4.x. Used memcpy here. But the memcpy
1544+ * may be not correct on BE architecture.
1545+ * --by Yin, Fengwei
1546+ */
1547+ memcpy(buffer, &data, sizeof(data));
1548+ i += sizeof(data);
1549+ buffer += sizeof(data);
1550+ }
1551+
1552+ /* Read the left bytes_remain bytes data */
1553+ if (bytes_remain) {
1554+ data = dfc_read(context, DFC_NDDB);
1555+ for (i = 0; i < bytes_remain; i++)
1556+ *buffer++ = (uint8_t)((data >> (8*i)) & 0xFF);
1557+ }
1558+
1559+ /* When read the remain bytes, we always read 4 bytes data
1560+ * to DFC. So the data_size should subtract following number.
1561+ */
1562+ data_size -= bytes_multi + (bytes_remain ? sizeof(data) : 0);
1563+
1564+ /* We need Read data_size bytes data totally */
1565+ while (data_size > 0) {
1566+ data = dfc_read(context, DFC_NDDB);
1567+ data_size -= sizeof(data);
1568+ }
1569+
1570+/*
1571+ while(i < ((uint32_t)data_size) ) {
1572+ if (i < bytes_multi) {
1573+ temp = (uint32_t *)buffer;
1574+ *temp = dfc_reg->nddb;
1575+ } else if (i == bytes_multi && bytes_remain){
1576+ uint32_t j = 0;
1577+ data = dfc_reg->nddb;
1578+ while (j++ < bytes_remain) {
1579+ *buffer++ = (uint8_t) \
1580+ ((data>>(8*j)) & 0xFF);
1581+ }
1582+ } else {
1583+ data = dfc_reg->nddb;
1584+ }
1585+ i += 4;
1586+ buffer += 4;
1587+ }
1588+*/
1589+ }
1590+ return;
1591+}
1592+
1593+/******************************************************************************
1594+ dfc_write_fifo_partial
1595+
1596+ Description:
1597+ Write to data buffer of DFC from a buffer. Bytes can be same as
1598+ data_size, also can be data_size-padding, but can¡¯t be random value,
1599+ the left will be automatically padded by WriteFIFO.
1600+ Input Parameters:
1601+ context
1602+ Pointer to DFC context structure
1603+ bytes
1604+ Indicating how much data should be read into buffer.
1605+ data_size
1606+ Specifing length of data transferred to/from DFC, which includes
1607+ padding bytes
1608+ buffer
1609+ Pointer to the data buffer where data will be taken from to be written
1610+ to DFC data buffer
1611+ Output Parameters:
1612+ None
1613+ Returns:
1614+ None
1615+*******************************************************************************/
1616+void dfc_write_fifo_partial(struct dfc_context *context, uint8_t *buffer,
1617+ int nbytes, int data_size)
1618+{
1619+ uint32_t i = 0;
1620+
1621+ uint32_t bytes_multi = (nbytes & 0xFFFFFFFC);
1622+ uint32_t bytes_remain = nbytes & 0x03;
1623+ uint32_t temp;
1624+ /*
1625+ * caller guarantee buffer contains appropriate data thereby
1626+ * it is impossible for nbytes not to be a multiple of 4 byte
1627+ */
1628+
1629+ /* Write the bytes_multi*4 bytes data */
1630+ while (i < bytes_multi) {
1631+ temp = buffer[0] | buffer[1] << 8 |
1632+ buffer[2] << 16 | buffer[3] << 24;
1633+ dfc_write(context, DFC_NDDB, temp);
1634+ buffer += 4;
1635+ i += 4;
1636+ }
1637+
1638+ /* Write the left bytes_remain bytes data */
1639+ if (bytes_remain) {
1640+ temp = 0xFFFFFFFF;
1641+ for (i = 0; i < bytes_remain; i++)
1642+ temp &= *buffer++ << i*8;
1643+
1644+ dfc_write(context, DFC_NDDB, temp);
1645+ }
1646+
1647+ /* When write the remain bytes, we always write 4 bytes data
1648+ * to DFC. So the data_size should subtract following number.
1649+ */
1650+ data_size -= bytes_multi + (bytes_remain ? sizeof(temp) : 0);
1651+
1652+ while (data_size > 0) {
1653+ dfc_write(context, DFC_NDDB, 0xFFFFFFFF);
1654+ data_size -= 4;
1655+ }
1656+
1657+/*
1658+ while (i < ((uint32_t)data_size)) {
1659+ if (i < bytes_multi) {
1660+ temp = (uint32_t *)buffer;
1661+ dfc_reg->nddb = *temp;
1662+ }
1663+ else if (i == bytes_multi && bytes_remain) {
1664+ uint32_t j = 0, data = 0xFFFFFFFF;
1665+ while (j < bytes_remain) {
1666+ data &= (uint8_t)(*buffer) << j;
1667+ buffer++;
1668+ j++;
1669+ }
1670+ dfc_reg->nddb = data;
1671+ }
1672+ else {
1673+ dfc_reg->nddb = 0xFFFFFFFF;
1674+ }
1675+ i += 4;
1676+ buffer += 4;
1677+ }
1678+*/
1679+
1680+ return;
1681+}
1682+
1683+/******************************************************************************
1684+ dfc_read_fifo
1685+ Description:
1686+ This function reads data from data buffer of DFC.Bytes can be any less
1687+ than or equal to data_size, the left is ignored by ReadFIFO though they
1688+ will be read from NDDB to clear data buffer.
1689+ Input Parameters:
1690+ context
1691+ Pointer to DFC context structure
1692+ nbytes
1693+ Indicating how much data should be read into buffer.
1694+ data_size
1695+ Specifing length of data transferred to/from DFC, which includes
1696+ padding bytes
1697+ Output Parameters:
1698+ buffer
1699+ Pointer to the data buffer where data should be placed.
1700+ Returns:
1701+ None
1702+*******************************************************************************/
1703+
1704+void dfc_read_fifo(struct dfc_context *context, uint8_t *buffer, int nbytes)
1705+{
1706+ uint32_t i = 0;
1707+
1708+ uint32_t bytes_multi = (nbytes & 0xFFFFFFFC);
1709+ uint32_t bytes_remain = nbytes & 0x03;
1710+ uint32_t temp;
1711+
1712+ /* Read the bytes_multi*4 bytes data */
1713+ while (i < bytes_multi) {
1714+ temp = dfc_read(context, DFC_NDDB);
1715+ /* FIXME: we don't know whether the buffer
1716+ * align to 4 bytes or not. Cast the buffer
1717+ * to int is not safe here. Especially under
1718+ * gcc 4.x. Used memcpy here. But the memcpy
1719+ * may be not correct on BE architecture.
1720+ * --by Yin, Fengwei
1721+ */
1722+ memcpy(buffer, &temp, sizeof(temp));
1723+ i += sizeof(temp);
1724+ buffer += sizeof(temp);
1725+ }
1726+
1727+ /* Read the left bytes_remain bytes data */
1728+ temp = dfc_read(context, DFC_NDDB);
1729+ for (i = 0; i < bytes_remain; i++) {
1730+ *buffer++ = (uint8_t)((temp >> (8*i)) & 0xFF);
1731+ }
1732+
1733+/*
1734+ while (i < bytes_multi) {
1735+ temp = (uint32_t *)buffer;
1736+ *temp = dfc_reg->nddb;
1737+ i += 4;
1738+ buffer += 4;
1739+ }
1740+
1741+ if (bytes_remain) {
1742+ data = dfc_reg->nddb;
1743+ for (i = 0; i < bytes_remain; i++) {
1744+ *buffer++ = (uint8_t)((data>>(8*i)) & 0xFF);
1745+ }
1746+ }
1747+*/
1748+
1749+ return;
1750+}
1751+
1752+/******************************************************************************
1753+ dfc_write_fifo
1754+ Description:
1755+ Write to data buffer of DFC from a buffer.Bytes can be same as data_size,
1756+ also can be data_size-padding, but can¡¯t be random value, the left will
1757+ be automatically padded by WriteFIFO.
1758+ Input Parameters:
1759+ context
1760+ Pointer to DFC context structure
1761+ nbytes
1762+ Indicating how much data should be read into buffer.
1763+ data_size
1764+ Specifing length of data transferred to/from DFC, which includes
1765+ padding bytes
1766+ buffer
1767+ Pointer to the data buffer where data will be taken from to be written to
1768+ DFC data buffer
1769+ Output Parameters:
1770+ None
1771+ Returns:
1772+ None
1773+*******************************************************************************/
1774+void dfc_write_fifo(struct dfc_context *context, uint8_t *buffer, int nbytes)
1775+{
1776+ uint32_t bytes_multi = (nbytes & 0xFFFFFFFC);
1777+ uint32_t bytes_remain = nbytes & 0x03;
1778+ uint32_t i=0;
1779+ uint32_t temp;
1780+
1781+ /* Write the bytes_multi*4 bytes data */
1782+ while (i < bytes_multi) {
1783+ temp = buffer[0] | buffer[1] << 8 |
1784+ buffer[2] << 16 | buffer[3] << 24;
1785+ dfc_write(context, DFC_NDDB, temp);
1786+ buffer += 4;
1787+ i += 4;
1788+ }
1789+
1790+ /* Write the left bytes_remain bytes data */
1791+ temp = 0xFFFFFFFF;
1792+ for (i = 0; i < bytes_remain; i++)
1793+ temp &= *buffer++ << i*8;
1794+ dfc_write(context, DFC_NDDB, temp);
1795+
1796+/*
1797+ while (i < nbytes) {
1798+ temp = (uint32_t *)buffer;
1799+ dfc_reg->nddb = *temp;
1800+ i += 4;
1801+ buffer += 4;
1802+ }
1803+*/
1804+}
1805+
1806+/******************************************************************************
1807+ dfc_read_badblock_addr
1808+
1809+ Description:
1810+ This function reads bad block address in units of block starting from 0
1811+ if bad block is detected. It takes into the account if the operation is
1812+ for CS0 or CS1 depending on settings of chip_select parameter of DFC
1813+ Mode structure.
1814+ Input Parameters:
1815+ context
1816+ Pointer to DFC context structure
1817+ Output Parameters:
1818+ pBadBlockAddr
1819+ Used to retrieve bad block address back to caller if bad block is
1820+ detected
1821+ Returns:
1822+ None
1823+*******************************************************************************/
1824+void dfc_read_badblock_addr(struct dfc_context *context, uint32_t *bbaddr)
1825+{
1826+ uint32_t ndbdr;
1827+ if (0 == context->dfc_mode->chip_select)
1828+ ndbdr = dfc_read(context, DFC_NDBDR0);
1829+ else
1830+ ndbdr = dfc_read(context, DFC_NDBDR1);
1831+
1832+ if (512 == context->flash_info->page_size) {
1833+ ndbdr = (ndbdr >> 5) & 0xFFF;
1834+ *bbaddr = ndbdr;
1835+ } else if (2048 == context->flash_info->page_size) {
1836+ /* 16 bits LB */
1837+ ndbdr = (ndbdr >> 8);
1838+ *bbaddr = ndbdr;
1839+ }
1840+ return;
1841+}
1842+
1843+/******************************************************************************
1844+ dfc_enable_int
1845+
1846+ Description:
1847+ This function is used to enable DFC interrupts. The bits in int_mask
1848+ will be used to unmask NDCR register to enable corresponding interrupts.
1849+ Input Parameters:
1850+ context
1851+ Pointer to DFC context structure
1852+ int_mask
1853+ Specifies what interrupts to enable
1854+ Output Parameters:
1855+ None
1856+ Returns:
1857+ None
1858+*******************************************************************************/
1859+void dfc_enable_int(struct dfc_context *context, uint32_t int_mask)
1860+{
1861+ uint32_t ndcr;
1862+
1863+ ndcr = dfc_read(context, DFC_NDCR);
1864+ ndcr &= ~int_mask;
1865+ dfc_write(context, DFC_NDCR, ndcr);
1866+
1867+ ndcr = dfc_read(context, DFC_NDCR);
1868+ return;
1869+}
1870+
1871+/******************************************************************************
1872+ dfc_disable_int
1873+
1874+ Description:
1875+ This function is used to disable DFC interrupts.
1876+ The bits inint_mask will be used to mask NDCR register to disable
1877+ corresponding interrupts.
1878+ Input Parameters:
1879+ context
1880+ Pointer to DFC context structure
1881+ int_mask
1882+ Specifies what interrupts to disable
1883+ Output Parameters:
1884+ None
1885+ Returns:
1886+ None
1887+*******************************************************************************/
1888+void dfc_disable_int(struct dfc_context *context, uint32_t int_mask)
1889+{
1890+ uint32_t ndcr;
1891+
1892+ ndcr = dfc_read(context, DFC_NDCR);
1893+ ndcr |= int_mask;
1894+ dfc_write(context, DFC_NDCR, ndcr);
1895+
1896+ ndcr = dfc_read(context, DFC_NDCR);
1897+ return;
1898+}
1899+
1900+/******************************************************************************
1901+ dfc_clear_int
1902+
1903+ Description:
1904+ This function is used to disable DFC interrupts.
1905+ The bits in int_mask will be used to clear corresponding interrupts
1906+ in NDCR register
1907+ Input Parameters:
1908+ context
1909+ Pointer to DFC context structure
1910+ int_mask
1911+ Specifies what interrupts to clear
1912+ Output Parameters:
1913+ None
1914+ Returns:
1915+ None
1916+*******************************************************************************/
1917+void dfc_clear_int(struct dfc_context *context, uint32_t int_mask)
1918+{
1919+ dfc_write(context, DFC_NDSR, int_mask);
1920+
1921+ dfc_read(context, DFC_NDSR);
1922+ return;
1923+}
1924+
1925+/*
1926+ * high level primitives
1927+ */
1928+
1929+/******************************************************************************
1930+ dfc_init
1931+
1932+ Description:
1933+ This function does entire DFC initialization according to the NAND
1934+ flash type currently used with platform, including setting MFP, set
1935+ flash timing, set DFC mode, configuring specified flash parameters
1936+ in DFC, clear ECC logic and page count register.
1937+ Input Parameters:
1938+ context
1939+ Pointer to DFC context structure
1940+ Output Parameters:
1941+ None
1942+ Returns:
1943+ 0
1944+ if MFPRs are set correctly
1945+ -EINVAL
1946+ if specified flash is not support by check bytes per page and pages per
1947+ block
1948+******************************************************************************/
1949+
1950+static mfp_cfg_t pxa300_nand_cfg[] = {
1951+ /* NAND */
1952+ MFP_CFG_X(DF_INT_RnB, AF0, DS10X, PULL_LOW),
1953+ MFP_CFG_X(DF_nRE_nOE, AF1, DS10X, PULL_LOW),
1954+ MFP_CFG_X(DF_nWE, AF1, DS10X, PULL_LOW),
1955+ MFP_CFG_X(DF_CLE_nOE, AF0, DS10X, PULL_LOW),
1956+ MFP_CFG_X(DF_nADV1_ALE, AF1, DS10X, PULL_LOW),
1957+ MFP_CFG_X(DF_nCS0, AF1, DS10X, PULL_LOW),
1958+ MFP_CFG_X(DF_nCS1, AF0, DS10X, PULL_LOW),
1959+ MFP_CFG_X(DF_IO0, AF1, DS08X, PULL_LOW),
1960+ MFP_CFG_X(DF_IO1, AF1, DS08X, PULL_LOW),
1961+ MFP_CFG_X(DF_IO2, AF1, DS08X, PULL_LOW),
1962+ MFP_CFG_X(DF_IO3, AF1, DS08X, PULL_LOW),
1963+ MFP_CFG_X(DF_IO4, AF1, DS08X, PULL_LOW),
1964+ MFP_CFG_X(DF_IO5, AF1, DS08X, PULL_LOW),
1965+ MFP_CFG_X(DF_IO6, AF1, DS08X, PULL_LOW),
1966+ MFP_CFG_X(DF_IO7, AF1, DS08X, PULL_LOW),
1967+ MFP_CFG_X(DF_IO8, AF1, DS08X, PULL_LOW),
1968+ MFP_CFG_X(DF_IO9, AF1, DS08X, PULL_LOW),
1969+ MFP_CFG_X(DF_IO10, AF1, DS08X, PULL_LOW),
1970+ MFP_CFG_X(DF_IO11, AF1, DS08X, PULL_LOW),
1971+ MFP_CFG_X(DF_IO12, AF1, DS08X, PULL_LOW),
1972+ MFP_CFG_X(DF_IO13, AF1, DS08X, PULL_LOW),
1973+ MFP_CFG_X(DF_IO14, AF1, DS08X, PULL_LOW),
1974+};
1975+
1976+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
1977+
1978+int dfc_init(struct dfc_context* context, int type)
1979+{
1980+ int status;
1981+ struct dfc_flash_info * flash_info;
1982+ uint32_t ndcr = 0x00000FFF; /* disable all interrupts */
1983+
1984+ status = dfc_get_flash_info(type, &flash_info);
1985+ if (status)
1986+ return status;
1987+ context->flash_info = flash_info;
1988+
1989+ pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa300_nand_cfg));
1990+ //enable_dfc_pins();
1991+
1992+ dfc_set_timing(context, &context->flash_info->timing);
1993+
1994+ if (flash_info->enable_arbiter)
1995+ ndcr |= NDCR_ND_ARB_EN;
1996+
1997+ if (64 == flash_info->page_per_block)
1998+ ndcr |= NDCR_PG_PER_BLK;
1999+ else if (32 != flash_info->page_per_block)
2000+ return -EINVAL;
2001+
2002+ if (flash_info->row_addr_start)
2003+ ndcr |= NDCR_RA_START;
2004+
2005+ ndcr |= (flash_info->read_id_bytes)<<16;
2006+
2007+ ndcr |= (flash_info->dfc_mode) << 21;
2008+
2009+ if (flash_info->ncsx)
2010+ ndcr |= NDCR_NCSX;
2011+
2012+ if (2048 == flash_info->page_size)
2013+ ndcr |= NDCR_PAGE_SZ;
2014+ else if (512 != flash_info->page_size)
2015+ return -EINVAL;
2016+
2017+ if (16 == flash_info->flash_width)
2018+ ndcr |= NDCR_DWIDTH_M;
2019+ else if (8 != flash_info->flash_width)
2020+ return -EINVAL;
2021+
2022+ if (16 == flash_info->dfc_width)
2023+ ndcr |= NDCR_DWIDTH_C;
2024+ else if (8 != flash_info->dfc_width)
2025+ return -EINVAL;
2026+
2027+ dfc_write(context, DFC_NDCR, ndcr);
2028+
2029+ dfc_set_dma(context);
2030+ dfc_set_ecc(context);
2031+ dfc_set_spare(context);
2032+
2033+ return 0;
2034+}
2035+
2036+/******************************************************************************
2037+ dfc_init_no_gpio
2038+
2039+ Description:
2040+ This function does entire DFC initialization according to the NAND
2041+ flash type currently used with platform, including set flash timing,
2042+ set DFC mode, configuring specified flash parameters in DFC, clear
2043+ ECC logic and page count register. The only difference with dfc_init
2044+ is that it does not set MFP&GPIO, very useful in OS loader
2045+ Input Parameters:
2046+ context
2047+ Pointer to DFC context structure
2048+ Output Parameters:
2049+ None
2050+ Returns:
2051+ 0
2052+ if MFPRs are set correctly
2053+ -EINVAL
2054+ if specified flash is not support by check bytes per page and pages
2055+ per block
2056+******************************************************************************/
2057+int dfc_init_no_gpio(struct dfc_context* context, int type)
2058+{
2059+ struct dfc_flash_info * flash_info;
2060+ uint32_t ndcr = 0x00000FFF; /* disable all interrupts */
2061+ int status;
2062+
2063+ status = dfc_get_flash_info(type, &flash_info);
2064+ if (status)
2065+ return status;
2066+ context->flash_info = flash_info;
2067+
2068+ dfc_set_timing(context, &context->flash_info->timing);
2069+
2070+ if (flash_info->enable_arbiter)
2071+ ndcr |= NDCR_ND_ARB_EN;
2072+
2073+ if (64 == flash_info->page_per_block)
2074+ ndcr |= NDCR_PG_PER_BLK;
2075+ else if (32 != flash_info->page_per_block)
2076+ return -EINVAL;
2077+
2078+ if (flash_info->row_addr_start)
2079+ ndcr |= NDCR_RA_START;
2080+
2081+ ndcr |= (flash_info->read_id_bytes)<<16;
2082+
2083+ ndcr |= (flash_info->dfc_mode) << 21;
2084+
2085+ if (flash_info->ncsx)
2086+ ndcr |= NDCR_NCSX;
2087+
2088+ if (2048 == flash_info->page_size)
2089+ ndcr |= NDCR_PAGE_SZ;
2090+ else if (512 != flash_info->page_size)
2091+ return -EINVAL;
2092+
2093+ if (16 == flash_info->flash_width)
2094+ ndcr |= NDCR_DWIDTH_M;
2095+ else if (8 != flash_info->flash_width)
2096+ return -EINVAL;
2097+
2098+ if (16 == flash_info->dfc_width)
2099+ ndcr |= NDCR_DWIDTH_C;
2100+ else if (8 != flash_info->dfc_width)
2101+ return -EINVAL;
2102+
2103+ dfc_write(context, DFC_NDCR, ndcr);
2104+
2105+ dfc_set_dma(context);
2106+ dfc_set_ecc(context);
2107+ dfc_set_spare(context);
2108+
2109+ return 0;
2110+}
2111+
2112+/*
2113+ * This macro will be used in following NAND operation functions.
2114+ * It is used to clear command buffer to ensure cmd buffer is empty
2115+ * in case of operation is timeout
2116+ */
2117+#define ClearCMDBuf() do { \
2118+ dfc_stop(context); \
2119+ udelay(NAND_OTHER_TIMEOUT); \
2120+ } while (0)
2121+
2122+/******************************************************************************
2123+ dfc_reset_flash
2124+
2125+ Description:
2126+ It reset the flash. The function can be called at any time when the
2127+ device is in Busy state during random read/program/erase mode and
2128+ reset operation will abort all these operations. After reset operation
2129+ the device is ready to wait for next command
2130+ Input Parameters:
2131+ context
2132+ Pointer to DFC context structure
2133+ Output Parameters:
2134+ None
2135+ Returns:
2136+ 0
2137+ execution succeeds
2138+ -ETIME
2139+ if timeout
2140+*******************************************************************************/
2141+int dfc_reset_flash(struct dfc_context *context)
2142+{
2143+ struct dfc_flash_info *flash_info = context->flash_info;
2144+ uint32_t event, event_out;
2145+ unsigned long timeo;
2146+ int status;
2147+
2148+ /* Send command */
2149+ dfc_send_cmd(context, (uint16_t)flash_info->reset, 0xFFFFFFFF, 0);
2150+
2151+ event = (context->dfc_mode->chip_select)? \
2152+ NDSR_CS1_CMDD : NDSR_CS0_CMDD;
2153+
2154+ /* Wait for CMDDM(command done successfully) */
2155+ status = dfc_wait_event(context, event, &event_out,
2156+ NAND_OTHER_TIMEOUT, 0);
2157+
2158+ if (status) {
2159+ ClearCMDBuf();
2160+ return status;
2161+ }
2162+
2163+
2164+ /* Wait until flash device is stable or timeout (10ms) */
2165+ timeo = jiffies + HZ;
2166+ do {
2167+ if (monahans_df_dev_ready(context->mtd))
2168+ break;
2169+ } while (time_before(jiffies, timeo));
2170+
2171+ return 0;
2172+}
2173+
2174+int dfc_readid(struct dfc_context *context, uint32_t *id)
2175+{
2176+ struct dfc_flash_info *flash_info = context->flash_info;
2177+ uint32_t event_out;
2178+ int status;
2179+ char tmp[DFC_DATA_SIZE_ID];
2180+
2181+ /* Send command */
2182+ status = dfc_send_cmd(context, (uint16_t)flash_info->read_id,
2183+ 0xFFFFFFFF, 0);
2184+ if (status) {
2185+ ClearCMDBuf();
2186+ return status;
2187+ }
2188+
2189+ /* Wait for CMDDM(command done successfully) */
2190+ status = dfc_wait_event(context, NDSR_RDDREQ, &event_out,
2191+ NAND_OTHER_TIMEOUT, 0);
2192+ if (status) {
2193+ ClearCMDBuf();
2194+ return status;
2195+ }
2196+ dfc_read_fifo_partial(context, (unsigned char *)tmp,
2197+ context->flash_info->read_id_bytes, DFC_DATA_SIZE_ID);
2198+
2199+ *id = tmp[0] | (tmp[1] << 8);
2200+ return 0;
2201+}
2202+
2203+#define ERR_NONE 0x0
2204+#define ERR_DMABUSERR (-0x01)
2205+#define ERR_SENDCMD (-0x02)
2206+#define ERR_DBERR (-0x03)
2207+#define ERR_BBERR (-0x04)
2208+#define ERR_BUSY (-0x05)
2209+
2210+#define STATE_CMD_SEND 0x1
2211+#define STATE_CMD_HANDLE 0x2
2212+#define STATE_DMA_TRANSFER 0x3
2213+#define STATE_DMA_DONE 0x4
2214+#define STATE_READY 0x5
2215+#define STATE_SUSPENDED 0x6
2216+#define STATE_DATA_TRANSFER 0x7
2217+
2218+#define NAND_RELOC_MAX 127
2219+#define NAND_RELOC_HEADER 0x524e
2220+#define MAX_CHIP 1
2221+#define NAND_CMD_DMA_LEN 12
2222+
2223+#define MAX_TIM_SIZE 0x1000
2224+#define MAX_BBT_SLOTS 24
2225+
2226+struct reloc_item {
2227+ unsigned short from;
2228+ unsigned short to;
2229+};
2230+
2231+struct reloc_table {
2232+ unsigned short header;
2233+ unsigned short total;
2234+ struct reloc_item reloc[NAND_RELOC_MAX];
2235+};
2236+
2237+struct monahans_dfc_info {
2238+ unsigned int state;
2239+ struct dfc_context *context;
2240+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
2241+ dma_addr_t data_buf_addr;
2242+ char *data_buf;
2243+ int data_dma;
2244+ struct pxa_dma_desc *data_desc;
2245+ dma_addr_t data_desc_addr;
2246+ dma_addr_t cmd_buf_addr;
2247+ char *cmd_buf;
2248+ int cmd_dma;
2249+ struct pxa_dma_desc *cmd_desc;
2250+ dma_addr_t cmd_desc_addr;
2251+ u64 dma_mask;
2252+#else
2253+ char *data_buf;
2254+#endif
2255+ u32 current_slot;
2256+ struct reloc_table table;
2257+ unsigned int table_init;
2258+ /* relate to the command */
2259+ unsigned int cmd;
2260+ unsigned int addr;
2261+ unsigned int column;
2262+ int retcode;
2263+ unsigned int buf_count;
2264+ struct completion cmd_complete;
2265+};
2266+
2267+static struct dfc_mode dfc_mode =
2268+{
2269+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
2270+ 1, /* enable DMA */
2271+#else
2272+ 0,
2273+#endif
2274+ 1, /* enable ECC */
2275+ 1, /* enable SPARE */
2276+ 0, /* CS0 */
2277+};
2278+
2279+
2280+struct dfc_context dfc_context =
2281+{
2282+ 0, /* Initialized at function monahans_df_init() */
2283+ &dfc_mode,
2284+ 0, /* data dma channel */
2285+ 0, /* cmd dma channel */
2286+ NULL, /* &zylonite_flashinfo */
2287+};
2288+
2289+
2290+/*
2291+ * MTD structure for Zylonite board
2292+ */
2293+static struct mtd_info *monahans_mtd = NULL;
2294+
2295+/*
2296+ * BootRom and XDB will use last 127 block, and they will keep all the status
2297+ * of the bootloader and image, so skip the first 2M size and last 2M size
2298+ */
2299+static struct mtd_partition partition_info[] = {
2300+ {
2301+ name: "Bootloader",
2302+//#ifdef CONFIG_CPU_MONAHANS_LV
2303+ size: 0x00060000,
2304+//#else
2305+// size: 0x00040000,
2306+//#endif
2307+ offset: 0,
2308+ mask_flags: MTD_WRITEABLE /* force read-only */
2309+ },{
2310+ name: "Kernel",
2311+ size: 0x00200000,
2312+//#ifdef CONFIG_CPU_MONAHANS_LV
2313+ offset: 0x00060000,
2314+//#else
2315+// offset: 0x00040000,
2316+//#endif
2317+ mask_flags: MTD_WRITEABLE /* force read-only */
2318+ },{
2319+ name: "Filesystem",
2320+ size: 0x05000000,
2321+//#ifdef CONFIG_CPU_MONAHANS_LV
2322+ offset: 0x00260000,
2323+//#else
2324+// offset: 0x00240000,
2325+//#endif
2326+ }, {
2327+ name: "MassStorage",
2328+ size: 0x0, /* It will be set at probe function */
2329+ offset: MTDPART_OFS_APPEND /* Append after fs section */
2330+ }, {
2331+ name: "BBT",
2332+ size: 0x0, /* It will be set at probe function */
2333+ offset: MTDPART_OFS_APPEND,/* Append after fs section */
2334+ mask_flags: MTD_WRITEABLE /* force read-only */
2335+ }
2336+};
2337+
2338+#define PART_NUM ARRAY_SIZE(partition_info)
2339+
2340+/* MHN_OBM_V2 is related to BBT in MOBM V2
2341+ * MHN_OBM_V3 is related to BBT in MOBM V3
2342+ */
2343+enum {
2344+ MHN_OBM_NULL = 0,
2345+ MHN_OBM_V1,
2346+ MHN_OBM_V2,
2347+ MHN_OBM_V3,
2348+ MHN_OBM_INVAL
2349+} MHN_OBM_TYPE;
2350+
2351+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
2352+static uint8_t scan_main_bbt_pattern[] = { 'p', 'x', 'a', '1' };
2353+static uint8_t scan_mirror_bbt_pattern[] = { '0', 'a', 'x', 'p' };
2354+
2355+static struct nand_bbt_descr monahans_bbt_default = {
2356+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
2357+ | NAND_BBT_2BIT | NAND_BBT_VERSION,
2358+ .maxblocks = 2,
2359+ .len = 2,
2360+ .offs = 0,
2361+ .pattern = scan_ff_pattern,
2362+};
2363+
2364+static struct nand_bbt_descr monahans_bbt_main = {
2365+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
2366+ | NAND_BBT_2BIT | NAND_BBT_VERSION,
2367+ .veroffs = 6,
2368+ .maxblocks = 2,
2369+ .offs = 2,
2370+ .len = 4,
2371+ .pattern = scan_main_bbt_pattern,
2372+};
2373+
2374+static struct nand_bbt_descr monahans_bbt_mirror = {
2375+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
2376+ | NAND_BBT_2BIT | NAND_BBT_VERSION,
2377+ .veroffs = 6,
2378+ .maxblocks = 2,
2379+ .offs = 2,
2380+ .len = 4,
2381+ .pattern = scan_mirror_bbt_pattern,
2382+};
2383+
2384+#if 0
2385+static struct nand_bbt_descr monahans_bbt_main = {
2386+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
2387+ | NAND_BBT_2BIT | NAND_BBT_VERSION,
2388+ .veroffs = 2,
2389+ .maxblocks = 2,
2390+ .offs = 0x0,
2391+ .len = 2,
2392+ .pattern = scan_ff_pattern
2393+};
2394+static struct nand_bbt_descr monahans_bbt_mirror = {
2395+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
2396+ | NAND_BBT_2BIT | NAND_BBT_VERSION,
2397+ .veroffs = 2,
2398+ .maxblocks = 2,
2399+ .offs = 0x0,
2400+ .len = 2,
2401+ .pattern = scan_ff_pattern
2402+};
2403+#endif
2404+
2405+static struct nand_ecclayout monahans_lb_nand_oob = {
2406+ .eccbytes = 24,
2407+ .eccpos = {
2408+ 40, 41, 42, 43, 44, 45, 46, 47,
2409+ 48, 49, 50, 51, 52, 53, 54, 55,
2410+ 56, 57, 58, 59, 60, 61, 62, 63},
2411+ .oobfree = { {2, 38} }
2412+};
2413+
2414+/*
2415+ * Monahans OOB size is only 8 bytes, and the rest 8 bytes is controlled by
2416+ * hardware for ECC. We construct virutal ECC buffer. Acutally, ECC is 6 bytes
2417+ * and the remain 2 bytes are reserved.
2418+ */
2419+static struct nand_ecclayout monahans_sb_nand_oob = {
2420+ .eccbytes = 6,
2421+ .eccpos = {8, 9, 10, 11, 12, 13 },
2422+ .oobfree = { {2, 6} }
2423+};
2424+
2425+
2426+static inline int is_buf_blank(u8 * buf, int size)
2427+{
2428+ int i = 0;
2429+ while(i < size) {
2430+ if (*((unsigned long *)(buf + i)) != 0xFFFFFFFF)
2431+ return 0;
2432+ i += 4;
2433+ }
2434+ if (i > size) {
2435+ i -= 4;
2436+ while( i < size) {
2437+ if(*(buf + i) != 0xFF)
2438+ return 0;
2439+ i++;
2440+ }
2441+ }
2442+ return 1;
2443+}
2444+
2445+static void print_buf(char *buf, int num)
2446+{
2447+ int i = 0;
2448+
2449+ while (i < num) {
2450+ printk(KERN_ERR "0x%08x: %02x %02x %02x %02x %02x %02x %02x"
2451+ " %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
2452+ (unsigned int) (i), buf[i], buf[i+1], buf[i+2],
2453+ buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7],
2454+ buf[i+8], buf[i+9], buf[i+10],buf[i+11], buf[i+12],
2455+ buf[i+13], buf[i+14], buf[i+15]);
2456+ i += 16;
2457+ }
2458+}
2459+
2460+static int inline enable_dfc_dma(struct dfc_context *context, int enable)
2461+{
2462+ int ret = dfc_mode.enable_dma;
2463+ unsigned long ndcr;
2464+
2465+ if (!enable) {
2466+ ndcr = dfc_read(context, DFC_NDCR);
2467+ ndcr &= ~NDCR_DMA_EN;
2468+ dfc_write(context, DFC_NDCR, ndcr);
2469+ dfc_mode.enable_dma = 0;
2470+ } else {
2471+ ndcr = dfc_read(context, DFC_NDCR);
2472+ ndcr |= NDCR_DMA_EN;
2473+ dfc_write(context, DFC_NDCR, ndcr);
2474+ dfc_mode.enable_dma = 1;
2475+ }
2476+ return ret;
2477+}
2478+
2479+
2480+static void inline dump_info(struct monahans_dfc_info *info)
2481+{
2482+ if (!info)
2483+ return;
2484+
2485+ printk(KERN_ERR "cmd:0x%x; addr:0x%x; retcode:%d; state:%d \n",
2486+ info->cmd, info->addr, info->retcode, info->state);
2487+}
2488+
2489+static void inline enable_hw_ecc(struct dfc_context* context, int enable)
2490+{
2491+ unsigned long ndcr;
2492+
2493+ if (!enable) {
2494+ ndcr = dfc_read(context, DFC_NDCR);
2495+ ndcr &= ~NDCR_ECC_EN;
2496+ dfc_write(context, DFC_NDCR, ndcr);
2497+ dfc_mode.enable_ecc = 0;
2498+ }
2499+ else {
2500+ ndcr = dfc_read(context, DFC_NDCR);
2501+ ndcr |= NDCR_ECC_EN;
2502+ dfc_write(context, DFC_NDCR, ndcr);
2503+ dfc_mode.enable_ecc = 1;
2504+ }
2505+}
2506+
2507+/*
2508+ * Now, we are not sure that the NDSR_RDY mean the flash is ready.
2509+ * Need more test.
2510+ */
2511+static int monahans_df_dev_ready(struct mtd_info *mtd)
2512+{
2513+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
2514+ (((struct nand_chip *)(mtd->priv))->priv);
2515+
2516+ struct dfc_context* context = info->context;
2517+
2518+ return ((dfc_read(context, DFC_NDSR) & NDSR_RDY));
2519+}
2520+
2521+/* each read, we can only read 4bytes from NDDB, we must buffer it */
2522+static u_char monahans_df_read_byte(struct mtd_info *mtd)
2523+{
2524+ char retval = 0xFF;
2525+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
2526+ (((struct nand_chip *)(mtd->priv))->priv);
2527+
2528+ if (info->column < info->buf_count) {
2529+ /* Has just send a new command? */
2530+ retval = info->data_buf[info->column++];
2531+ }
2532+ return retval;
2533+}
2534+
2535+static void monahans_df_write_byte(struct mtd_info *mtd, u8 byte)
2536+{
2537+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
2538+ (((struct nand_chip *)(mtd->priv))->priv);
2539+ info->data_buf[info->column++] = byte;
2540+}
2541+
2542+static u16 monahans_df_read_word(struct mtd_info *mtd)
2543+{
2544+ u16 retval = 0xFFFF;
2545+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
2546+ (((struct nand_chip *)(mtd->priv))->priv);
2547+
2548+ if (!(info->column & 0x01) && info->column < info->buf_count) {
2549+ retval = *((u16 *)(info->data_buf+info->column));
2550+ info->column += 2;
2551+ }
2552+ return retval;
2553+}
2554+
2555+static void monahans_df_write_word(struct mtd_info *mtd, u16 word)
2556+{
2557+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
2558+ (((struct nand_chip *)(mtd->priv))->priv);
2559+
2560+ if (!(info->column & 0x01) && info->column < info->buf_count) {
2561+ *((u16 *)(info->data_buf+info->column)) = word;
2562+ info->column += 2;
2563+ }
2564+}
2565+
2566+static void monahans_df_read_buf(struct mtd_info *mtd, u_char *buf, int len)
2567+{
2568+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
2569+ (((struct nand_chip *)(mtd->priv))->priv);
2570+ int real_len = min((unsigned int)len, info->buf_count - info->column);
2571+
2572+ memcpy(buf, info->data_buf + info->column, real_len);
2573+ info->column += real_len;
2574+}
2575+
2576+static void monahans_df_write_buf(struct mtd_info *mtd,
2577+ const u_char *buf, int len)
2578+{
2579+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
2580+ (((struct nand_chip *)(mtd->priv))->priv);
2581+ int real_len = min((unsigned int)len, info->buf_count - info->column);
2582+
2583+ memcpy(info->data_buf + info->column, buf, real_len);
2584+ info->column += real_len;
2585+}
2586+
2587+static int monahans_df_verify_buf(struct mtd_info *mtd,
2588+ const u_char *buf, int len)
2589+{
2590+ return 0;
2591+}
2592+
2593+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
2594+static void monahans_dfc_cmd_dma_irq(int channel, void *data,
2595+ struct pt_regs *regs)
2596+{
2597+ unsigned int dcsr;
2598+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)data;
2599+ struct dfc_context* context = info->context;
2600+ struct dfc_mode* dfc_mode = context->dfc_mode;
2601+ unsigned int intm;
2602+
2603+ dcsr = DCSR(channel);
2604+ DCSR(channel) = dcsr;
2605+
2606+ intm = (dfc_mode->chip_select) ? \
2607+ (NDSR_CS1_BBD | NDSR_CS1_CMDD) : (NDSR_CS0_BBD | NDSR_CS0_CMDD);
2608+
2609+ D1(printk("cmd dma interrupt, channel:%d, DCSR:0x%08x\n", \
2610+ channel, dcsr));
2611+
2612+ if (dcsr & DCSR_BUSERR) {
2613+ info->retcode = ERR_DMABUSERR;
2614+ complete(&info->cmd_complete);
2615+ } else {
2616+ if ((info->cmd == NAND_CMD_READ0) ||
2617+ (info->cmd == NAND_CMD_READOOB)|| \
2618+ (info->cmd == NAND_CMD_READID) || \
2619+ (info->cmd == NAND_CMD_STATUS)) {
2620+ dfc_enable_int(context, NDSR_RDDREQ | NDSR_DBERR);
2621+ } else if (info->cmd == NAND_CMD_PAGEPROG)
2622+ dfc_enable_int(context, NDSR_WRDREQ);
2623+ else if (info->cmd == NAND_CMD_ERASE1)
2624+ dfc_enable_int(context, intm);
2625+ }
2626+
2627+ return;
2628+}
2629+
2630+
2631+static void monahans_dfc_data_dma_irq(int channel, void *data,
2632+ struct pt_regs *regs)
2633+{
2634+ unsigned int dcsr, intm;
2635+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)data;
2636+ struct dfc_context* context = info->context;
2637+ struct dfc_mode* dfc_mode = context->dfc_mode;
2638+
2639+ dcsr = DCSR(channel);
2640+ DCSR(channel) = dcsr;
2641+
2642+ intm = (dfc_mode->chip_select) ? \
2643+ (NDSR_CS1_BBD | NDSR_CS1_CMDD) : (NDSR_CS0_BBD | NDSR_CS0_CMDD);
2644+
2645+ D1(printk("data dma interrupt, channel:%d, DCSR:0x%08x\n",
2646+ channel, dcsr));
2647+ if (dcsr & DCSR_BUSERR) {
2648+ info->retcode = ERR_DMABUSERR;
2649+ complete(&info->cmd_complete);
2650+ }
2651+
2652+ if (info->cmd == NAND_CMD_PAGEPROG) {
2653+ /* DMA interrupt may be interrupted by other IRQs*/
2654+ info->state = STATE_DMA_DONE;
2655+ dfc_enable_int(context, intm);
2656+ } else {
2657+ info->state = STATE_READY;
2658+ complete(&info->cmd_complete);
2659+ }
2660+
2661+}
2662+#endif
2663+
2664+static irqreturn_t monahans_dfc_irq(int irq, void *devid)
2665+{
2666+ unsigned int status, event, intm, cmd;
2667+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)devid;
2668+ struct dfc_context* context = info->context;
2669+ struct dfc_mode* dfc_mode = context->dfc_mode;
2670+
2671+ intm = (dfc_mode->chip_select) ? \
2672+ (NDSR_CS1_BBD | NDSR_CS1_CMDD) : (NDSR_CS0_BBD | NDSR_CS0_CMDD);
2673+ event = (dfc_mode->chip_select) ? \
2674+ (NDSR_CS1_BBD | NDSR_CS1_CMDD) : (NDSR_CS0_BBD | NDSR_CS0_CMDD);
2675+
2676+ status = dfc_read(context, DFC_NDSR);
2677+ D1(printk("DFC irq, NDSR:0x%x\n", status));
2678+ if (status & (NDSR_RDDREQ | NDSR_DBERR)) {
2679+ if (status & NDSR_DBERR) {
2680+ info->retcode = ERR_DBERR;
2681+ }
2682+
2683+ dfc_disable_int(context, NDSR_RDDREQ | NDSR_DBERR);
2684+ dfc_clear_int(context, NDSR_RDDREQ | NDSR_DBERR);
2685+ if (info->cmd == NAND_CMD_READID)
2686+ cmd = context->flash_info->read_id;
2687+ else if (info->cmd == NAND_CMD_STATUS)
2688+ cmd = context->flash_info->read_status;
2689+ else if (info->cmd == NAND_CMD_READ0 ||
2690+ info->cmd == NAND_CMD_READOOB)
2691+ cmd = context->flash_info->read1;
2692+ else {
2693+ printk(KERN_ERR "No according command:0x%x happens\n",
2694+ info->cmd);
2695+ goto out;
2696+ }
2697+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
2698+ info->state = STATE_DMA_TRANSFER;
2699+ dfc_start_data_dma(context,
2700+ (struct pxa_dma_desc*)info->data_desc_addr);
2701+#else
2702+ info->state = STATE_DATA_TRANSFER;
2703+ complete(&info->cmd_complete);
2704+#endif
2705+ } else if (status & NDSR_WRDREQ) {
2706+ dfc_disable_int(context, NDSR_WRDREQ);
2707+ dfc_clear_int(context, NDSR_WRDREQ);
2708+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
2709+ info->state = STATE_DMA_TRANSFER;
2710+ dfc_start_data_dma(context,
2711+ (struct pxa_dma_desc*)info->data_desc_addr);
2712+#else
2713+ info->state = STATE_DATA_TRANSFER;
2714+ complete(&info->cmd_complete);
2715+#endif
2716+ } else if (status & event) {
2717+ if (status & NDSR_CS0_BBD) {
2718+ info->retcode = ERR_BBERR;
2719+ }
2720+
2721+ dfc_disable_int(context, intm);
2722+ dfc_clear_int(context, event);
2723+ info->state = STATE_READY;
2724+ complete(&info->cmd_complete);
2725+ }
2726+out:
2727+ return IRQ_HANDLED;
2728+}
2729+
2730+static int dfc_send_command(struct mtd_info *mtd, unsigned int cmd,
2731+ unsigned int addr, unsigned int num_pages,
2732+ unsigned int event)
2733+{
2734+
2735+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
2736+ (((struct nand_chip *)(mtd->priv))->priv);
2737+ struct dfc_context* context = info->context;
2738+ int status;
2739+ int ret;
2740+
2741+ D1(printk("ready send command, cmd:0x%x, at address:0x%x,"
2742+ " num_pages:%d, wait event:0x%x\n", cmd, addr, num_pages, event));
2743+
2744+ info->state = STATE_CMD_SEND;
2745+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
2746+ status = dfc_setup_cmd_dma(context, cmd, addr, num_pages,
2747+ (uint32_t *)info->cmd_buf, info->cmd_buf_addr,
2748+ DDADR_STOP, DCMD_ENDIRQEN, info->cmd_desc);
2749+#else
2750+ status = dfc_send_cmd(context, cmd, addr, num_pages);
2751+#endif
2752+ if (status) {
2753+ info->retcode = ERR_SENDCMD;
2754+ dfc_stop(context);
2755+ udelay(20);
2756+ printk(KERN_ERR "fail send command\n");
2757+ return info->retcode;
2758+ }
2759+ info->state = STATE_CMD_HANDLE;
2760+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
2761+ dfc_setup_data_dma(context, cmd, info->data_buf_addr,
2762+ DDADR_STOP, DCMD_ENDIRQEN, info->data_desc);
2763+ dfc_start_cmd_dma(context, (struct pxa_dma_desc*)info->cmd_desc_addr);
2764+#endif
2765+#ifndef CONFIG_MTD_NAND_MONAHANS_DMA
2766+ dfc_enable_int(context, event);
2767+#endif
2768+ ret = wait_for_completion_timeout(&info->cmd_complete, 2*HZ);
2769+ if (!ret){
2770+ printk(KERN_ERR "Command time out\n");
2771+ dump_info(info);
2772+ }
2773+ D1(printk("command return, cmd:0x%x, retcode:%d\n",
2774+ info->cmd, info->retcode));
2775+ return 0;
2776+}
2777+
2778+static void monahans_df_command(struct mtd_info *mtd, unsigned command,
2779+ int column, int page_addr )
2780+{
2781+ struct nand_chip *this = (struct nand_chip *)(mtd->priv);
2782+ struct monahans_dfc_info *info =
2783+ (struct monahans_dfc_info *)(this->priv);
2784+ struct dfc_context *context = info->context;
2785+ struct dfc_flash_info * flash_info = context->flash_info;
2786+ int ret, pages_shift;
2787+ int status;
2788+#ifndef CONFIG_MTD_NAND_MONAHANS_DMA
2789+ int datasize;
2790+ int paddingsize;
2791+#endif
2792+ unsigned int to;
2793+
2794+ D1(printk("command:0x%x at address:0x%x, column:0x%x\n",
2795+ command, page_addr, column));
2796+
2797+ if (info->state != STATE_READY) {
2798+ printk(KERN_ERR "CHIP is not ready.\n");
2799+ dump_info(info);
2800+ info->retcode = ERR_BUSY;
2801+ return;
2802+ }
2803+ info->retcode = ERR_NONE;
2804+ pages_shift = this->phys_erase_shift - this->page_shift;
2805+ if (info->table_init) {
2806+ to = search_rel_block((page_addr >> pages_shift), mtd);
2807+ if (to) {
2808+ page_addr = (to << pages_shift) | (page_addr
2809+ & ((1 << pages_shift) - 1));
2810+ }
2811+ }
2812+
2813+ switch ( command ) {
2814+ case NAND_CMD_READOOB:
2815+ /*
2816+ * DFC has mark the last 8 bytes OOB data if HARDEARE_ECC is
2817+ * enabled. We must first disable the HARDWARE_ECC for getting
2818+ * all the 16 bytes OOB
2819+ */
2820+ enable_hw_ecc(context, 0);
2821+ info->buf_count = mtd->writesize + mtd->oobsize;
2822+ info->column = mtd->writesize + column;
2823+ info->cmd = command;
2824+ info->addr = page_addr << this->page_shift;
2825+ ret = dfc_send_command(mtd, flash_info->read1, info->addr,
2826+ 1, NDSR_RDDREQ | NDSR_DBERR);
2827+#ifndef CONFIG_MTD_NAND_MONAHANS_DMA
2828+ dfc_get_pattern(info->context, flash_info->read1, &datasize,
2829+ &paddingsize);
2830+ dfc_read_fifo_partial(info->context, info->data_buf,
2831+ min(info->buf_count, datasize), datasize);
2832+ info->state = STATE_READY;
2833+#endif
2834+ /* We only are OOB, so if the data has error, does not matter */
2835+ if (info->retcode == ERR_DBERR)
2836+ info->retcode = ERR_NONE;
2837+ enable_hw_ecc(context, 1);
2838+ break;
2839+
2840+ case NAND_CMD_READ0:
2841+ enable_hw_ecc(context, 1);
2842+ info->column = column;
2843+ info->cmd = command;
2844+ info->buf_count = mtd->writesize + mtd->oobsize;
2845+ memset(info->data_buf, 0xFF, info->buf_count);
2846+ info->addr = page_addr << this->page_shift;
2847+
2848+ ret = dfc_send_command(mtd, flash_info->read1, info->addr,
2849+ 1, NDSR_RDDREQ | NDSR_DBERR);
2850+#ifndef CONFIG_MTD_NAND_MONAHANS_DMA
2851+ dfc_get_pattern(info->context, flash_info->read1, &datasize,
2852+ &paddingsize);
2853+ dfc_read_fifo_partial(info->context, info->data_buf,
2854+ min(info->buf_count, datasize), datasize);
2855+ info->state = STATE_READY;
2856+#endif
2857+ /* When the data buf is blank, the DFC will report DB error */
2858+ if (info->retcode == ERR_DBERR && is_buf_blank(info->data_buf,
2859+ mtd->writesize))
2860+ info->retcode = ERR_NONE;
2861+
2862+ if (info->retcode == ERR_DBERR) {
2863+ printk(KERN_ERR "DB error at address 0x%x\n",
2864+ info->addr);
2865+ print_buf(info->data_buf, info->buf_count);
2866+ }
2867+ break;
2868+ case NAND_CMD_SEQIN:
2869+ /* Write only OOB? */
2870+
2871+ info->cmd = command;
2872+ if (column >= mtd->writesize) {
2873+ info->buf_count = mtd->writesize + mtd->oobsize;
2874+ enable_hw_ecc(context, 0);
2875+ } else {
2876+ info->buf_count = mtd->writesize + mtd->oobsize;
2877+ enable_hw_ecc(context, 1);
2878+ }
2879+ memset(info->data_buf, 0xFF, mtd->writesize + mtd->oobsize);
2880+ info->column = column;
2881+ info->addr = page_addr << this->page_shift;
2882+ break;
2883+ case NAND_CMD_PAGEPROG:
2884+ /* prevois command is NAND_CMD_SEIN ?*/
2885+ if (info->cmd != NAND_CMD_SEQIN) {
2886+ info->cmd = command;
2887+ info->retcode = ERR_SENDCMD;
2888+ printk(KERN_ERR "Monahans NAND device: "
2889+ "No NAND_CMD_SEQIN executed before.\n");
2890+ enable_hw_ecc(context, 1);
2891+ break;
2892+ }
2893+ info->cmd = command;
2894+ ret = dfc_send_command(mtd, flash_info->program, info->addr,
2895+ 1, NDSR_WRDREQ);
2896+
2897+#ifndef CONFIG_MTD_NAND_MONAHANS_DMA
2898+ if (ret != 0)
2899+ break;
2900+
2901+ dfc_get_pattern(info->context, flash_info->program, &datasize,
2902+ &paddingsize);
2903+ dfc_write_fifo_partial(info->context, info->data_buf, datasize,
2904+ datasize);
2905+
2906+ if (info->context->dfc_mode->chip_select)
2907+ dfc_enable_int(info->context,
2908+ NDSR_CS1_BBD | NDSR_CS1_CMDD);
2909+ else
2910+ dfc_enable_int(info->context,
2911+ NDSR_CS0_BBD | NDSR_CS0_CMDD);
2912+
2913+ ret = wait_for_completion_timeout(&info->cmd_complete, 2*HZ);
2914+ if (!ret){
2915+ printk(KERN_ERR "Programm Command time out\n");
2916+ dump_info(info);
2917+ }
2918+
2919+ if (info->retcode == ERR_BBERR) {
2920+ mtd->block_markbad(mtd, info->addr);
2921+ }
2922+#endif
2923+ break;
2924+ case NAND_CMD_ERASE1:
2925+ info->cmd = command;
2926+ info->addr = (page_addr >> pages_shift) << this->phys_erase_shift;
2927+
2928+ if (info->context->dfc_mode->chip_select)
2929+ ret = dfc_send_command(mtd, flash_info->erase,
2930+ info->addr, 0, NDSR_CS1_BBD | NDSR_CS1_CMDD);
2931+ else
2932+ ret = dfc_send_command(mtd, flash_info->erase,
2933+ info->addr, 0, NDSR_CS0_BBD | NDSR_CS0_CMDD);
2934+
2935+ if (info->retcode == ERR_BBERR) {
2936+ mtd->block_markbad(mtd, info->addr);
2937+ }
2938+ break;
2939+ case NAND_CMD_ERASE2:
2940+ break;
2941+ case NAND_CMD_READID:
2942+ info->cmd = command;
2943+ info->buf_count = flash_info->read_id_bytes;
2944+ info->column = 0;
2945+ info->addr = 0xFFFFFFFF;
2946+ ret = dfc_send_command(mtd, flash_info->read_id, info->addr,
2947+ 0, NDSR_RDDREQ);
2948+#ifndef CONFIG_MTD_NAND_MONAHANS_DMA
2949+ dfc_get_pattern(info->context, flash_info->read_id, &datasize,
2950+ &paddingsize);
2951+ dfc_read_fifo_partial(info->context, info->data_buf,
2952+ info->buf_count, datasize);
2953+ info->state = STATE_READY;
2954+#endif
2955+ D1(printk("ReadID, [1]:0x%x, [2]:0x%x\n",
2956+ info->data_buf[0], info->data_buf[1]));
2957+ break;
2958+ case NAND_CMD_STATUS:
2959+ info->cmd = command;
2960+ info->buf_count = 1;
2961+ info->column = 0;
2962+ info->addr = 0xFFFFFFFF;
2963+ ret = dfc_send_command(mtd, flash_info->read_status,
2964+ info->addr, 0, NDSR_RDDREQ);
2965+#ifndef CONFIG_MTD_NAND_MONAHANS_DMA
2966+ dfc_get_pattern(info->context, flash_info->read_status,
2967+ &datasize, &paddingsize);
2968+ dfc_read_fifo_partial(info->context, info->data_buf,
2969+ info->buf_count, datasize);
2970+ info->state = STATE_READY;
2971+#endif
2972+ break;
2973+
2974+ case NAND_CMD_RESET:
2975+ status = dfc_reset_flash(&dfc_context);
2976+ if (status) {
2977+ printk(KERN_WARNING "Monahans NAND device:"
2978+ "NAND_CMD_RESET error\n");
2979+ }
2980+ break;
2981+ default:
2982+ printk(KERN_WARNING "Monahans NAND device:"
2983+ "Non-support the command.\n");
2984+ break;
2985+ }
2986+
2987+ if (info->retcode != ERR_NONE)
2988+ dfc_stop(info->context);
2989+}
2990+
2991+static void monahans_df_select_chip(struct mtd_info *mtd, int chip)
2992+{
2993+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
2994+ (((struct nand_chip *)(mtd->priv))->priv);
2995+
2996+ if (chip <= MAX_CHIP)
2997+ info->context->dfc_mode->chip_select = chip;
2998+ else
2999+ printk(KERN_ERR "Monahans NAND device:"
3000+ "not select the NAND chips!\n");
3001+}
3002+
3003+static int monahans_df_waitfunc(struct mtd_info *mtd,
3004+ struct nand_chip *this)
3005+{
3006+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
3007+ (((struct nand_chip *)(mtd->priv))->priv);
3008+
3009+ /* monahans_df_send_command has waited for command complete */
3010+ if (this->state == FL_WRITING || this->state == FL_ERASING) {
3011+ if (info->retcode == ERR_NONE)
3012+ return 0;
3013+ else {
3014+ /*
3015+ * any error make it return 0x01 which will tell
3016+ * the caller the erase and write fail
3017+ */
3018+ return 0x01;
3019+ }
3020+ }
3021+
3022+ return 0;
3023+}
3024+
3025+static int monahans_df_calculate_ecc(struct mtd_info *mtd,
3026+ const u_char *dat, u_char *ecc_code)
3027+{
3028+ return 0;
3029+}
3030+
3031+static int monahans_df_correct_data(struct mtd_info *mtd,
3032+ u_char *dat, u_char *read_ecc, u_char *calc_ecc)
3033+{
3034+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
3035+ (((struct nand_chip *)(mtd->priv))->priv);
3036+
3037+ /*
3038+ * Any error include ERR_SEND_CMD, ERR_DBERR, ERR_BUSERR, we
3039+ * consider it as a ecc error which will tell the caller the
3040+ * read fail We have distinguish all the errors, but the
3041+ * nand_read_ecc only check this function return value
3042+ */
3043+ if (info->retcode != ERR_NONE)
3044+ return -1;
3045+
3046+ return 0;
3047+}
3048+
3049+static void monahans_df_enable_hwecc(struct mtd_info *mtd, int mode)
3050+{
3051+ return;
3052+}
3053+
3054+/*
3055+ * The relocation table management is different between MOBM V2 and V3.
3056+ *
3057+ * MOBM V2 is applied on chips taped out before MhnLV A0.
3058+ * MOBM V3 is applied on chips taped out after MhnLV A0. It's also applied
3059+ * on MhnLV A0.
3060+ */
3061+static int calc_obm_ver(void)
3062+{
3063+ unsigned int cpuid;
3064+ /* read CPU ID */
3065+ __asm__ (
3066+ "mrc p15, 0, %0, c0, c0, 0\n"
3067+ : "=r" (cpuid)
3068+ );
3069+ /* It's not xscale chip. */
3070+ if ((cpuid & 0xFFFF0000) != 0x69050000)
3071+ return MHN_OBM_INVAL;
3072+ /* It's MhnP Ax */
3073+ if ((cpuid & 0x0000FFF0) == 0x00006420)
3074+ return MHN_OBM_V2;
3075+ /* It's MhnP Bx */
3076+ if ((cpuid & 0x0000FFF0) == 0x00006820) {
3077+ if ((cpuid & 0x0F) <= 5)
3078+ return MHN_OBM_V2;
3079+ else
3080+ return MHN_OBM_V3;
3081+ }
3082+ /* It's MhnL Ax */
3083+ if ((cpuid & 0x0000FFF0) == 0x00006880) {
3084+ if ((cpuid & 0x0F) == 0)
3085+ return MHN_OBM_V2;
3086+ else
3087+ return MHN_OBM_V3;
3088+ }
3089+ /* It's MhnLV Ax */
3090+ if ((cpuid & 0x0000FFF0) == 0x00006890)
3091+ return MHN_OBM_V3;
3092+ return MHN_OBM_INVAL;
3093+}
3094+
3095+
3096+/*
3097+ * MOBM maintains a relocation table. It's used to replace bad blocks.
3098+ * If block A is bad, it will use block B instead.
3099+ * There're 127 relocated blocks. All of them reside in the bottom of NAND
3100+ * flash. So they're reserved and can't be calculated in mtd size and chip
3101+ * size.
3102+ */
3103+static int read_reloc_table(struct mtd_info *mtd)
3104+{
3105+ struct nand_chip *this = NULL;
3106+ struct monahans_dfc_info *info = NULL;
3107+ struct dfc_context *context = NULL;
3108+ struct reloc_table *table = NULL;
3109+ int page, maxslot;
3110+ int obm, valid;
3111+
3112+ obm = calc_obm_ver();
3113+ this = (struct nand_chip *)(mtd->priv);
3114+ info = (struct monahans_dfc_info *)(this->priv);
3115+ context = info->context;
3116+
3117+ mtd->size -= (NAND_RELOC_MAX * mtd->erasesize);
3118+ this->chipsize -= (NAND_RELOC_MAX << this->phys_erase_shift);
3119+ page = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
3120+
3121+ this->select_chip(mtd, 0);
3122+ valid = 0;
3123+ if (obm == MHN_OBM_V2) {
3124+ /* On MOBM V2, the relocation table resides in the last page
3125+ * of the first block.
3126+ */
3127+ memset(info->data_buf, 0, BUFLEN);
3128+ monahans_df_command(mtd, NAND_CMD_READ0, 0, page);
3129+ memcpy(((unsigned char *)&(info->table)), info->data_buf,
3130+ sizeof(struct reloc_table));
3131+ if (info->table.header == NAND_RELOC_HEADER)
3132+ valid = 1;
3133+ } else if (obm == MHN_OBM_V3) {
3134+ /* On MOBM V3, there're several relocation tables in the first
3135+ * block.
3136+ * When new bad blocks are found, a new relocation table will
3137+ * be generated and written back to the first block. But the
3138+ * original relocation table won't be erased. Even if the new
3139+ * relocation table is written wrong, system can still find an
3140+ * old one.
3141+ * One page contains one slot.
3142+ */
3143+ maxslot = 1 << (this->phys_erase_shift - this->page_shift);
3144+ page = maxslot - MAX_BBT_SLOTS;
3145+ for (; page < maxslot; page++) {
3146+ monahans_df_command(mtd, NAND_CMD_READ0, 0, page);
3147+ table = (struct reloc_table *)info->data_buf;
3148+ if (info->retcode == ERR_NONE) {
3149+ if (table->header != NAND_RELOC_HEADER) {
3150+ continue;
3151+ } else {
3152+ memcpy(((unsigned char *)&(info->table)),
3153+ table, sizeof(struct reloc_table));
3154+ valid = 1;
3155+ break;
3156+ }
3157+ }
3158+ }
3159+
3160+ } else {
3161+ printk(KERN_ERR "The version of MOBM isn't supported\n");
3162+ }
3163+ if (valid) {
3164+ memcpy(((unsigned char *)&(info->table)), info->data_buf,
3165+ sizeof(struct reloc_table));
3166+ printk(KERN_DEBUG "relocation table at page:%d\n", page);
3167+ PRINT_BUF((unsigned char *)&(info->table),
3168+ sizeof(struct reloc_table));
3169+ info->table_init = 1;
3170+ } else {
3171+ /* There should be a valid relocation table slot at least. */
3172+ printk(KERN_ERR "NO VALID relocation table can be \
3173+ recognized\n");
3174+ printk(KERN_ERR "CAUTION: It may cause unpredicated error\n");
3175+ printk(KERN_ERR "Please re-initialize the NAND flash.\n");
3176+ memset((unsigned char *)&(info->table), 0,
3177+ sizeof(struct reloc_table));
3178+ info->table_init = 0;
3179+ return -EINVAL;
3180+ }
3181+ return 0;
3182+}
3183+
3184+/* add the relocation entry into the relocation table
3185+ * It's valid on MOBM V3.
3186+ * If the relocated block is bad, an new entry will be added into the
3187+ * bottom of the relocation table.
3188+ */
3189+static int update_rel_table(struct mtd_info *mtd, int block)
3190+{
3191+ struct nand_chip *this = NULL;
3192+ struct monahans_dfc_info *info = NULL;
3193+ struct reloc_table *table = NULL;
3194+ int obm, reloc_block;
3195+
3196+ this = (struct nand_chip *)(mtd->priv);
3197+ info = (struct monahans_dfc_info *)(this->priv);
3198+ obm = calc_obm_ver();
3199+ if (obm == MHN_OBM_V3) {
3200+ table = &info->table;
3201+ if (info->table_init == 0) {
3202+ printk(KERN_ERR "Error: the initial relocation \
3203+ table can't be read\n");
3204+ memset(table, 0, sizeof(struct reloc_table));
3205+ table->header = NAND_RELOC_HEADER;
3206+ info->table_init = 1;
3207+ }
3208+ if (table->total == 0) {
3209+ /* Point to the first relocated block.
3210+ * It resides in the last block of flash.
3211+ * the relocation entry has calculated in
3212+ * chipsize
3213+ */
3214+ reloc_block = (this->chipsize
3215+ >> this->phys_erase_shift)
3216+ + NAND_RELOC_MAX - 1;
3217+ } else if (table->total < NAND_RELOC_MAX) {
3218+ reloc_block = table->reloc[table->total - 1].to - 1;
3219+ } else {
3220+ printk(KERN_ERR "Relocation table exceed max number, \
3221+ cannot mark block 0x%x as bad block\n", block);
3222+ return -ENOSPC;
3223+ }
3224+ /* Make sure that reloc_block is pointing to a valid block */
3225+ for (; ; reloc_block--) {
3226+ /* The relocate table is full */
3227+ if (reloc_block < (this->chipsize
3228+ >> this->phys_erase_shift))
3229+ return -ENOSPC;
3230+ this->cmdfunc(mtd, NAND_CMD_ERASE1, 0, reloc_block
3231+ << (this->phys_erase_shift
3232+ - this->page_shift));
3233+ if (info->retcode == ERR_NONE)
3234+ break;
3235+ }
3236+ /* Create the relocated block information in the table */
3237+ table->reloc[table->total].from = block;
3238+ table->reloc[table->total].to = reloc_block;
3239+ table->total++;
3240+ }
3241+ return 0;
3242+}
3243+
3244+/* Write the relocation table back to device, if there's room. */
3245+static int sync_rel_table(struct mtd_info *mtd, int *idx)
3246+{
3247+ struct nand_chip *this = NULL;
3248+ struct monahans_dfc_info *info = NULL;
3249+ int obm, start_page, len;
3250+
3251+ if (*idx >= MAX_BBT_SLOTS) {
3252+ printk(KERN_ERR "Can't write relocation table to device \
3253+ any more.\n");
3254+ return -1;
3255+ }
3256+ if (*idx < 0) {
3257+ printk(KERN_ERR "Wrong Slot is specified.\n");
3258+ return -1;
3259+ }
3260+ this = (struct nand_chip *)(mtd->priv);
3261+ info = (struct monahans_dfc_info *)(this->priv);
3262+ len = 4;
3263+ len += info->table.total << 2;
3264+ obm = calc_obm_ver();
3265+ if (obm == MHN_OBM_V3) {
3266+ /* write to device */
3267+ start_page = 1 << (this->phys_erase_shift - this->page_shift);
3268+ start_page = start_page - 1 - *idx;
3269+ memset(&(info->data_buf), 0xFF, BUFLEN);
3270+ memcpy(&(info->data_buf), &(info->table), len);
3271+
3272+ printk(KERN_DEBUG "DUMP relocation table before write. \
3273+ page:0x%x\n", start_page);
3274+ monahans_df_command(mtd, NAND_CMD_SEQIN, 0, start_page);
3275+ monahans_df_command(mtd, NAND_CMD_PAGEPROG, 0, start_page);
3276+ /* write to idx */
3277+ (*idx)++;
3278+ /* dump it */
3279+ memset(&(info->data_buf), 0, BUFLEN);
3280+ monahans_df_command(mtd, NAND_CMD_READOOB, 0, start_page);
3281+ PRINT_BUF(info->data_buf, len);
3282+ }
3283+ return 0;
3284+}
3285+
3286+
3287+/* Find the relocated block of the bad one.
3288+ * If it's a good block, return 0. Otherwise, return a relocated one.
3289+ * idx points to the next relocation entry
3290+ * If the relocated block is bad, an new entry will be added into the
3291+ * bottom of the relocation table.
3292+ */
3293+static unsigned short search_rel_block(int block, struct mtd_info *mtd)
3294+{
3295+ struct nand_chip *this = NULL;
3296+ struct monahans_dfc_info *info = NULL;
3297+ struct reloc_table *table = NULL;
3298+ int i, max, reloc_block = 0;
3299+
3300+ this = (struct nand_chip *)(mtd->priv);
3301+ info = (struct monahans_dfc_info *)(this->priv);
3302+ table = &(info->table);
3303+ if ((block <= 0) || (block > this->chipsize)
3304+ || (info->table_init == 0) || (table->total == 0))
3305+ return 0;
3306+ if (table->total > NAND_RELOC_MAX)
3307+ table->total = NAND_RELOC_MAX;
3308+ max = table->total;
3309+ for (i = 0; i < max; i++) {
3310+ if (block == table->reloc[i].from)
3311+ reloc_block = table->reloc[i].to;
3312+ }
3313+ return reloc_block;
3314+}
3315+
3316+/*
3317+ * Check whether the block is a bad one.
3318+ * At first, it will search the relocation table.
3319+ * If necessary, it will search the BBT. Because relocation table can only
3320+ * maintain limited record. If there're more bad blocks, they can't be
3321+ * recorded in relocation table. They can only be recorded in BBT.
3322+ */
3323+static int monahans_df_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
3324+{
3325+ struct nand_chip *this = NULL;
3326+ int page, block, reloc_block, chipnr, res = 0;
3327+ u16 bad;
3328+
3329+ /* At here, we only support one flash chip */
3330+ this = (struct nand_chip *)mtd->priv;
3331+ block = (int)(ofs >> this->phys_erase_shift);
3332+ /* search the block in the relocation table */
3333+ reloc_block = search_rel_block(block, mtd);
3334+ if (reloc_block) {
3335+ ofs = ((reloc_block << this->phys_erase_shift) |
3336+ (ofs & ((1 << this->phys_erase_shift) - 1)));
3337+ }
3338+
3339+ /* search BBT
3340+ * Maybe the relocation table is full, but some bad blocks aren't
3341+ * recordered in it.
3342+ * The below code are copied from nand_block_bad().
3343+ */
3344+ if (getchip) {
3345+ page = (int)(ofs >> this->page_shift);
3346+ chipnr = (int)(ofs >> this->chip_shift);
3347+
3348+ /* Select the NAND chips */
3349+ this->select_chip(mtd, chipnr);
3350+ } else
3351+ page = (int)ofs;
3352+
3353+ if (this->options & NAND_BUSWIDTH_16) {
3354+ this->cmdfunc(mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE,
3355+ page & this->pagemask);
3356+ bad = cpu_to_le16(this->read_word(mtd));
3357+ if (this->badblockpos & 0x1)
3358+ bad >>= 1;
3359+ if ((bad & 0xFF) != 0xFF)
3360+ res = 1;
3361+ } else {
3362+ this->cmdfunc(mtd, NAND_CMD_READOOB, this->badblockpos,
3363+ page & this->pagemask);
3364+ if (this->read_byte(mtd) != 0xFF)
3365+ res = 1;
3366+ }
3367+
3368+ return res;
3369+}
3370+
3371+static int monahans_df_block_markbad(struct mtd_info *mtd, loff_t ofs)
3372+{
3373+ struct nand_chip *this = NULL;
3374+ struct monahans_dfc_info *info = NULL;
3375+ unsigned char buf[2] = {0, 0};
3376+ int block, reloc_block, page, ret;
3377+
3378+ this = (struct nand_chip *)mtd->priv;
3379+ info = (struct monahans_dfc_info *)(this->priv);
3380+ /* Get block number */
3381+ block = ((int)ofs) >> this->bbt_erase_shift;
3382+ ret = update_rel_table(mtd, block);
3383+ if (!ret) {
3384+ sync_rel_table(mtd, &(info->current_slot));
3385+ return 0;
3386+ } else {
3387+ reloc_block = search_rel_block(block, mtd);
3388+ if (reloc_block)
3389+ block = reloc_block;
3390+ if (this->bbt)
3391+ this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
3392+ }
3393+
3394+ /* Do we have a flash based bad block table ? */
3395+ if (this->options & NAND_USE_FLASH_BBT)
3396+ return nand_update_bbt(mtd, ofs);
3397+
3398+ /* mark the bad block flag at the first two pages */
3399+ page = block << (this->phys_erase_shift - this->page_shift);
3400+ ofs = mtd->writesize + this->badblockpos;
3401+ this->cmdfunc(mtd, NAND_CMD_SEQIN, ofs, page);
3402+ this->write_buf(mtd, buf, 2);
3403+ this->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
3404+ page++;
3405+ this->cmdfunc(mtd, NAND_CMD_SEQIN, ofs, page);
3406+ this->write_buf(mtd, buf, 2);
3407+ this->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
3408+ return 0;
3409+}
3410+
3411+static int dump_bbt_flash(struct mtd_info *mtd)
3412+{
3413+ struct nand_chip *this = NULL;
3414+ struct monahans_dfc_info *info = NULL;
3415+ int block, page, totlen;
3416+
3417+ this = (struct nand_chip *)mtd->priv;
3418+ info = (struct monahans_dfc_info *)this->priv;
3419+ block = (this->chipsize >> this->phys_erase_shift) - 1;
3420+ totlen = (this->chipsize >> this->phys_erase_shift) >> 2;
3421+ printk(KERN_ERR "totlen:0x%x\n", totlen);
3422+ this->select_chip(mtd, 0);
3423+ if (this->bbt_td) {
3424+ printk(KERN_ERR "BBT page:0x%x\n", this->bbt_td->pages[0]);
3425+ page = this->bbt_td->pages[0];
3426+ if (this->bbt_td->pages[0] <= 0) {
3427+ page = block << (this->phys_erase_shift
3428+ - this->page_shift);
3429+ }
3430+ while (totlen > 0) {
3431+ printk(KERN_ERR "page:0x%x\n", page);
3432+ monahans_df_command(mtd, NAND_CMD_READ0, 0, page);
3433+ printk(KERN_ERR "read result:0x%x\n", info->retcode);
3434+ PRINT_BUF(info->data_buf, BUFLEN);
3435+ totlen -= (1 << this->page_shift);
3436+ page++;
3437+ }
3438+ }
3439+ if (this->bbt_md) {
3440+ printk(KERN_ERR "BBT page:0x%x\n", this->bbt_md->pages[0]);
3441+ page = this->bbt_md->pages[0];
3442+ if (this->bbt_td->pages[0] <= 0) {
3443+ page = block << (this->phys_erase_shift
3444+ - this->page_shift);
3445+ }
3446+ while (totlen > 0) {
3447+ printk(KERN_ERR "page:0x%x\n", page);
3448+ monahans_df_command(mtd, NAND_CMD_READ0, 0, page);
3449+ printk(KERN_ERR "read result:0x%x\n", info->retcode);
3450+ PRINT_BUF(info->data_buf, BUFLEN);
3451+ totlen -= (1 << this->page_shift);
3452+ page++;
3453+ }
3454+
3455+ }
3456+ return 0;
3457+}
3458+
3459+static int dump_bbt_mem(struct mtd_info *mtd)
3460+{
3461+ struct nand_chip *this = NULL;
3462+
3463+ this = (struct nand_chip *)mtd->priv;
3464+ PRINT_BUF(this->bbt, 225);
3465+ return 0;
3466+}
3467+
3468+static int monahans_df_scan_bbt(struct mtd_info *mtd)
3469+{
3470+ struct nand_chip *this = NULL;
3471+ int ret;
3472+
3473+ this = (struct nand_chip *)mtd->priv;
3474+ ret = read_reloc_table(mtd);
3475+ if (ret) {
3476+ printk(KERN_ERR "Failed to get relocation table\n");
3477+ printk(KERN_ERR "Try to build a new BBT. It may result \
3478+ unpredicated error.\n");
3479+ /* Create new memory based and flash based BBT */
3480+ }
3481+ nand_scan_bbt(mtd, &monahans_bbt_default);
3482+ //dump_bbt_flash(mtd);
3483+ dump_bbt_mem(mtd);
3484+ return 0;
3485+#if 0
3486+ /* Read flashed based BBT from device */
3487+ return (nand_scan_bbt(mtd, &monahans_bbt_main));
3488+#endif
3489+}
3490+
3491+
3492+static int monahans_df_probe(struct platform_device *pdev)
3493+{
3494+ struct nand_chip *this;
3495+ struct monahans_dfc_info *info;
3496+ int status = -1;
3497+ unsigned int data_buf_len;
3498+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
3499+ unsigned int buf_len;
3500+#endif
3501+ int i, ret = 0;
3502+
3503+ printk(KERN_ERR "Nand driver probe\n");
3504+
3505+ dfc_context.membase = ioremap_nocache(0x43100000, 0x100000);
3506+ if (!dfc_context.membase)
3507+ printk(KERN_ERR "Couldn't ioremap\n");
3508+
3509+ pxa_set_cken(CKEN_NAND, 1);
3510+
3511+ for (i = DFC_FLASH_NULL + 1; i < DFC_FLASH_END; i++)
3512+ {
3513+ uint32_t id;
3514+
3515+ status = dfc_init(&dfc_context, i);
3516+ if (status)
3517+ continue;
3518+ status = dfc_readid(&dfc_context, &id);
3519+ if (status)
3520+ continue;
3521+ printk(KERN_DEBUG "id:0x%x, chipid:0x%x\n",
3522+ id, dfc_context.flash_info->chip_id);
3523+ if (id == dfc_context.flash_info->chip_id)
3524+ break;
3525+ }
3526+
3527+ if(i == DFC_FLASH_END) {
3528+ printk(KERN_ALERT "Monahans NAND device:"
3529+ "Nand Flash initialize failure!\n");
3530+ ret = -ENXIO;
3531+ goto out;
3532+ }
3533+ flash_config = i;
3534+
3535+ monahans_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip) +
3536+ sizeof(struct monahans_dfc_info) , GFP_KERNEL);
3537+ if (!monahans_mtd) {
3538+ printk (KERN_ERR "Monahans NAND device:"
3539+ "Unable to allocate NAND MTD device structure.\n");
3540+ ret = -ENOMEM;
3541+ goto out;
3542+ }
3543+
3544+ /* Get pointer to private data */
3545+ this = (struct nand_chip *)((void *)monahans_mtd + sizeof(struct mtd_info));
3546+ info = (struct monahans_dfc_info *)((void *)this + sizeof(struct nand_chip));
3547+ dfc_context.mtd = monahans_mtd;
3548+
3549+ monahans_mtd->priv = this;
3550+ this->priv = info;
3551+ data_buf_len = dfc_context.flash_info->page_size +
3552+ dfc_context.flash_info->oob_size;
3553+ info->state = STATE_READY;
3554+ init_completion(&info->cmd_complete);
3555+ info->table_init = 0;
3556+ memset(&info->table, 0x0, sizeof(struct reloc_table));
3557+ printk(KERN_DEBUG "%s: this->controller: 0x%x, &this->controller: 0x%x\n",__func__, (unsigned int)this->controller, (unsigned int)&(this->controller));
3558+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
3559+ info->dma_mask = 0xffffffffUL;
3560+
3561+ dev->dma_mask = &info->dma_mask;
3562+ dev->coherent_dma_mask = 0xffffffffUL;
3563+
3564+ /* alloc dma data buffer for data
3565+ * buffer + 2*descriptor + command buffer
3566+ */
3567+ buf_len = ALIGN(2*sizeof(struct pxa_dma_desc), 32) +
3568+ ALIGN(data_buf_len, 32) + ALIGN(NAND_CMD_DMA_LEN, 32);
3569+
3570+ printk(KERN_INFO "Try to allocate dma buffer(len:%d)"
3571+ "for data buffer + 2*descriptor + command buffer\n", buf_len);
3572+ info->data_desc = (struct pxa_dma_desc*)dma_alloc_writecombine(dev,
3573+ buf_len, &info->data_desc_addr, GFP_KERNEL);
3574+ if (!info->data_desc) {
3575+ printk(KERN_ERR "Monahans NAND device:"
3576+ "Unable to alloc dma buffer\n");
3577+ ret = -ENOMEM;
3578+ goto free_mtd;
3579+ }
3580+
3581+ info->cmd_desc = (struct pxa_dma_desc*)((char *)info->data_desc +
3582+ sizeof(struct pxa_dma_desc));
3583+ info->cmd_desc_addr = (dma_addr_t)((char *)info->data_desc_addr +
3584+ sizeof(struct pxa_dma_desc));
3585+ info->data_buf = (char *)info->data_desc +
3586+ ALIGN(2*sizeof(struct pxa_dma_desc), 32);
3587+ info->data_buf_addr = (dma_addr_t)((char *)info->data_desc_addr +
3588+ ALIGN(2*sizeof(struct pxa_dma_desc), 32));
3589+ info->cmd_buf = (char *)info->data_buf + ALIGN(data_buf_len, 32);
3590+ info->cmd_buf_addr = (dma_addr_t)((char *)info->data_buf_addr +
3591+ ALIGN(data_buf_len, 32));
3592+
3593+ D1(printk("Get dma buffer for data dma descriptor, virt:0x%x, phys0x:%x\n",
3594+ (unsigned int)info->data_desc, info->data_desc_addr));
3595+ D1(printk("Get dma buffer for command dma descriptors, virt:0x%x,"
3596+ "phys0x:%x\n", (unsigned int)info->cmd_desc, info->cmd_desc_addr));
3597+ D1(printk("Get dma buffer for data, virt:0x%x, phys0x:%x\n",
3598+ (unsigned int)info->data_buf, info->data_buf_addr));
3599+ D1(printk("Get dma buffer for command, virt:0x%x, phys0x:%x\n",
3600+ (unsigned int)info->cmd_buf, info->cmd_buf_addr));
3601+
3602+ D1(printk("Try to allocate dma channel for data\n"));
3603+
3604+ info->data_dma = pxa_request_dma("NAND DATA", DMA_PRIO_LOW,
3605+ monahans_dfc_data_dma_irq, info);
3606+ if (info->data_dma < 0) {
3607+ printk(KERN_ERR "Monahans NAND device:"
3608+ "Unable to alloc dma channel for data\n");
3609+ ret = info->data_dma;
3610+ goto free_buf;
3611+ }
3612+ D1(printk("Get dma channel:%d for data\n", info->data_dma));
3613+
3614+ D1(printk("Try to allocate dma channel for command\n"));
3615+ info->cmd_dma = pxa_request_dma("NAND CMD", DMA_PRIO_LOW,
3616+ monahans_dfc_cmd_dma_irq, info);
3617+ if (info->cmd_dma < 0) {
3618+ printk(KERN_ERR "Monahans NAND device:"
3619+ "Unable to alloc dma channel for command\n");
3620+ ret = info->cmd_dma;
3621+ goto free_data_dma;
3622+ }
3623+ D1(printk("Get dma channel:%d for command\n", info->cmd_dma));
3624+
3625+ dfc_context.cmd_dma_ch = info->cmd_dma;
3626+ dfc_context.data_dma_ch = info->data_dma;
3627+#else
3628+ printk(KERN_DEBUG "Try to allocate data buffer(len:%d)\n", data_buf_len);
3629+ info->data_buf = kmalloc(data_buf_len, GFP_KERNEL);
3630+ if (!info->data_buf) {
3631+ printk(KERN_ERR "Monahans NAND device:"
3632+ "Unable to alloc data buffer\n");
3633+ ret = -ENOMEM;
3634+ goto free_mtd;
3635+ }
3636+#endif
3637+
3638+ D1(printk("Try to request irq:%d\n", IRQ_NAND));
3639+ ret = request_irq(IRQ_NAND, monahans_dfc_irq, 0, pdev->name, info);
3640+ if (ret < 0) {
3641+ printk(KERN_ERR "Monahans NAND device: Unable to request irq\n");
3642+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
3643+ goto free_cmd_dma;
3644+#else
3645+ goto free_buf;
3646+#endif
3647+ }
3648+
3649+ D1(printk("Success request irq\n"));
3650+
3651+ /* set address of NAND IO lines */
3652+ this->options = (dfc_context.flash_info->flash_width == 16)? \
3653+ NAND_BUSWIDTH_16: 0 | NAND_USE_FLASH_BBT;
3654+
3655+ /* this->IO_ADDR_R = this->IO_ADDR_W = NDDB */
3656+ this->waitfunc = monahans_df_waitfunc;
3657+ this->select_chip = monahans_df_select_chip;
3658+ this->dev_ready = monahans_df_dev_ready;
3659+ this->cmdfunc = monahans_df_command;
3660+ this->read_word= monahans_df_read_word;
3661+ /*this->write_word= monahans_df_write_word;*/
3662+ this->read_byte = monahans_df_read_byte;
3663+ this->read_buf = monahans_df_read_buf;
3664+ this->write_buf = monahans_df_write_buf;
3665+ this->verify_buf = monahans_df_verify_buf;
3666+ this->ecc.hwctl = monahans_df_enable_hwecc;
3667+ this->ecc.calculate = monahans_df_calculate_ecc;
3668+ this->ecc.correct = monahans_df_correct_data;
3669+ this->block_bad = monahans_df_block_bad;
3670+ this->block_markbad = monahans_df_block_markbad;
3671+ this->scan_bbt = monahans_df_scan_bbt;
3672+ this->chip_delay= 25;
3673+ this->bbt_td = &monahans_bbt_main;
3674+ this->bbt_md = &monahans_bbt_mirror;
3675+
3676+ /* If the NAND flash is small block flash, only 512-byte pagesize
3677+ * is supported.
3678+ * Adjust parameters of BBT what is depended on large block nand
3679+ * flash or small block nand flash.
3680+ */
3681+ if (dfc_context.flash_info->oob_size > 16) {
3682+ this->ecc.layout = &monahans_lb_nand_oob;
3683+ this->ecc.mode = NAND_ECC_HW;
3684+ this->ecc.size = 2048;
3685+ this->ecc.bytes = 24;
3686+ this->bbt_td->offs = 2;
3687+ this->bbt_td->veroffs = 6;
3688+ this->bbt_md->offs = 2;
3689+ this->bbt_md->veroffs = 6;
3690+ this->badblockpos = NAND_LARGE_BADBLOCK_POS;
3691+ monahans_bbt_default.offs = NAND_LARGE_BADBLOCK_POS;
3692+ monahans_bbt_default.len = 2;
3693+ /* when scan_bbt() is executed, bbt version can get */
3694+ monahans_bbt_default.veroffs = 2;
3695+ } else {
3696+ this->ecc.layout = &monahans_sb_nand_oob;
3697+ this->ecc.mode = NAND_ECC_HW;
3698+ this->ecc.size = 512;
3699+ this->ecc.bytes = 6;
3700+ this->bbt_td->offs = 8;
3701+ this->bbt_td->veroffs = 12;
3702+ this->bbt_md->offs = 8;
3703+ this->bbt_md->veroffs = 12;
3704+ this->badblockpos = NAND_SMALL_BADBLOCK_POS;
3705+ monahans_bbt_default.offs = NAND_SMALL_BADBLOCK_POS;
3706+ monahans_bbt_default.len = 1;
3707+ monahans_bbt_default.veroffs = 8;
3708+ }
3709+
3710+ info->context = &dfc_context;
3711+ /* TODO: allocate dma buffer and channel */
3712+
3713+ platform_set_drvdata(pdev, monahans_mtd);
3714+
3715+ if (nand_scan(monahans_mtd, 1)) {
3716+ printk(KERN_ERR "Nand scan failed\n");
3717+ ret = -ENXIO;
3718+ goto free_irq;
3719+ }
3720+
3721+ /* There is a potential limitation that no more partition can be
3722+ * added between MassStorage and BBT(last block).
3723+ *
3724+ * The last 127 blocks is reserved for relocation table, they aren't
3725+ * statistical data of mtd size and chip size.
3726+ *
3727+ * BBT partitions contains 4 blocks. Two blocks are used to store
3728+ * main descriptor, the other two are used to store mirror descriptor.
3729+ */
3730+ partition_info[PART_NUM - 1].size = (monahans_bbt_main.maxblocks
3731+ + monahans_bbt_mirror.maxblocks)
3732+ << this->phys_erase_shift;
3733+ partition_info[PART_NUM - 1].offset = this->chipsize
3734+ - partition_info[PART_NUM - 1].size;
3735+ partition_info[PART_NUM - 2].offset = partition_info[PART_NUM - 3].offset
3736+ + partition_info[PART_NUM - 3].size;
3737+ partition_info[PART_NUM - 2].size = this->chipsize
3738+ - partition_info[PART_NUM - 2].offset
3739+ - partition_info[PART_NUM - 1].size;
3740+ add_mtd_partitions(monahans_mtd, partition_info, PART_NUM);
3741+
3742+#ifdef CONFIG_DVFM
3743+ dvfm_notifier.client_data = info;
3744+ mhn_fv_register_notifier(&dvfm_notifier);
3745+#endif
3746+
3747+ return 0;
3748+
3749+free_irq:
3750+ free_irq(IRQ_NAND, info);
3751+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
3752+free_cmd_dma:
3753+ pxa_free_dma(info->cmd_dma);
3754+free_data_dma:
3755+ pxa_free_dma(info->data_dma);
3756+free_buf:
3757+ dma_free_writecombine(dev, buf_len, info->data_desc, info->data_desc_addr);
3758+#else
3759+free_buf:
3760+ kfree(info->data_buf);
3761+#endif
3762+free_mtd:
3763+ kfree(monahans_mtd);
3764+out:
3765+ return ret;
3766+
3767+}
3768+
3769+static int __devexit monahans_df_remove(struct platform_device *dev)
3770+{
3771+ struct mtd_info *mtd = (struct mtd_info *)platform_get_drvdata(dev);
3772+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
3773+ (((struct nand_chip *)(mtd->priv))->priv);
3774+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
3775+ unsigned int data_buf_len = dfc_context.flash_info->page_size +
3776+ dfc_context.flash_info->oob_size;
3777+ unsigned int buf_len = ALIGN(2*sizeof(struct pxa_dma_desc), 32) +
3778+ ALIGN(data_buf_len, 32) + ALIGN(NAND_CMD_DMA_LEN, 32);
3779+#endif
3780+
3781+#ifdef CONFIG_DVFM
3782+ mhn_fv_unregister_notifier(&dvfm_notifier);
3783+#endif
3784+
3785+ platform_set_drvdata(dev, NULL);
3786+
3787+ del_mtd_device(mtd);
3788+ del_mtd_partitions(mtd);
3789+ free_irq(IRQ_NAND, info);
3790+#ifdef CONFIG_MTD_NAND_MONAHANS_DMA
3791+ pxa_free_dma(info->cmd_dma);
3792+ pxa_free_dma(info->data_dma);
3793+ dma_free_writecombine(dev, buf_len, info->data_desc,
3794+ info->data_desc_addr);
3795+#else
3796+ kfree(info->data_buf);
3797+#endif
3798+ kfree(mtd);
3799+
3800+ return 0;
3801+}
3802+
3803+#ifdef CONFIG_PM
3804+static int monahans_df_suspend(struct platform_device *dev, pm_message_t state, u32 level)
3805+{
3806+ struct mtd_info *mtd = (struct mtd_info *)platform_get_drvdata(dev);
3807+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
3808+ (((struct nand_chip *)(mtd->priv))->priv);
3809+
3810+ if( SUSPEND_DISABLE == level){ /*SUSPEND_NOTIFY*/
3811+ if (info->state != STATE_READY) {
3812+ printk(KERN_ERR "current state is %d\n", info->state);
3813+ return -EAGAIN;
3814+ }
3815+ info->state = STATE_SUSPENDED;
3816+ /*
3817+ * The PM code need read the mobm from NAND.
3818+ * So the NAND clock can't be stop here.
3819+ * The PM code will cover this.
3820+ */
3821+ /* pxa_set_cken(CKEN_NAND, 0); */
3822+ }
3823+ return 0;
3824+}
3825+
3826+static int monahans_df_resume(struct platform_device *dev, u32 level)
3827+{
3828+ struct mtd_info *mtd = (struct mtd_info *)platform_get_drvdata(dev);
3829+ struct monahans_dfc_info *info = (struct monahans_dfc_info *)
3830+ (((struct nand_chip *)(mtd->priv))->priv);
3831+ int status;
3832+
3833+ if(RESUME_ENABLE == level){
3834+ if (info->state != STATE_SUSPENDED)
3835+ printk(KERN_WARNING "Error State after resume back\n");
3836+
3837+ info->state = STATE_READY;
3838+
3839+ pxa_set_cken(CKEN_NAND, 1);
3840+
3841+ status = dfc_init(&dfc_context, flash_config);
3842+ if (status) {
3843+ printk(KERN_ALERT "Monahans NAND device:"
3844+ "Nand Flash initialize failure!\n");
3845+ return -ENXIO;
3846+ }
3847+ }
3848+ return 0;
3849+}
3850+#endif
3851+
3852+#ifdef CONFIG_DVFM
3853+static int mhn_nand_dvfm_notifier(unsigned cmd, void *client_data, void *info)
3854+{
3855+ struct monahans_dfc_info *dfc_info =
3856+ (struct monahans_dfc_info *)client_data;
3857+
3858+ switch (cmd) {
3859+ case FV_NOTIFIER_QUERY_SET :
3860+ if (dfc_info->state != STATE_READY)
3861+ return -1;
3862+ break;
3863+
3864+ case FV_NOTIFIER_PRE_SET :
3865+ break;
3866+
3867+ case FV_NOTIFIER_POST_SET :
3868+ break;
3869+ }
3870+
3871+ return 0;
3872+}
3873+#endif
3874+
3875+static struct platform_driver monahans_df_driver = {
3876+ .probe = monahans_df_probe,
3877+ .remove = __devexit_p(monahans_df_remove),
3878+#ifdef CONFIG_PM
3879+ .suspend = monahans_df_suspend,
3880+ .resume = monahans_df_resume,
3881+#endif
3882+ .driver = {
3883+ .name = "monahans-nand-flash",
3884+ }
3885+};
3886+
3887+static void __exit monahans_df_cleanup(void)
3888+{
3889+ printk(KERN_ERR "Nand driver registered\n");
3890+ platform_driver_unregister(&monahans_df_driver);
3891+}
3892+
3893+static int __init monahans_df_init(void)
3894+{
3895+ return platform_driver_register(&monahans_df_driver);
3896+}
3897+
3898+module_init(monahans_df_init);
3899+module_exit(monahans_df_cleanup);
3900+
3901+MODULE_LICENSE("GPL");
3902+MODULE_AUTHOR("Jingqing.xu (jingqing.xu@intel.com)");
3903+MODULE_DESCRIPTION("Glue logic layer for NAND flash on monahans DFC");
3904+
3905+
3906Index: linux-2.6.23/arch/arm/mach-pxa/zylonite.c
3907===================================================================
3908--- linux-2.6.23.orig/arch/arm/mach-pxa/zylonite.c 2008-02-12 21:12:29.000000000 +0000
3909+++ linux-2.6.23/arch/arm/mach-pxa/zylonite.c 2008-02-13 00:50:30.000000000 +0000
3910@@ -29,6 +29,8 @@
3911 #include "generic.h"
3912
3913 int gpio_backlight;
3914+int gpio_vsync;
3915+int gpio_vsync1;
3916 int gpio_eth_irq;
3917
3918 int lcd_id;
3919@@ -54,6 +56,11 @@
3920 .resource = smc91x_resources,
3921 };
3922
3923+static struct platform_device nand_device = {
3924+ .name = "monahans-nand-flash",
3925+ .id = -1,
3926+};
3927+
3928 #if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULES)
3929 static void zylonite_backlight_power(int on)
3930 {
3931@@ -96,7 +103,7 @@
3932 };
3933
3934 static struct pxafb_mode_info sharp_ls037_modes[] = {
3935- [0] = {
3936+ [1] = {
3937 .pixclock = 158000,
3938 .xres = 240,
3939 .yres = 320,
3940@@ -109,8 +116,8 @@
3941 .lower_margin = 3,
3942 .sync = 0,
3943 },
3944- [1] = {
3945- .pixclock = 39700,
3946+ [0] = {
3947+ .pixclock = 45000,
3948 .xres = 480,
3949 .yres = 640,
3950 .bpp = 16,
3951@@ -137,6 +144,11 @@
3952 /* backlight GPIO: output, default on */
3953 gpio_direction_output(gpio_backlight, 1);
3954
3955+ gpio_direction_output(gpio_vsync, 0);
3956+ gpio_direction_output(gpio_vsync1, 0);
3957+
3958+ printk(KERN_ERR "LCD ID is %x\n", lcd_id);
3959+
3960 if (lcd_id & 0x20) {
3961 set_pxa_fb_info(&zylonite_sharp_lcd_info);
3962 return;
3963@@ -169,6 +181,8 @@
3964 smc91x_resources[1].start = gpio_to_irq(gpio_eth_irq);
3965 smc91x_resources[1].end = gpio_to_irq(gpio_eth_irq);
3966 platform_device_register(&smc91x_device);
3967+ platform_device_register(&nand_device);
3968+ printk(KERN_ERR "Nand device registered\n");
3969
3970 zylonite_init_lcd();
3971 }
3972Index: linux-2.6.23/arch/arm/mach-pxa/zylonite_pxa300.c
3973===================================================================
3974--- linux-2.6.23.orig/arch/arm/mach-pxa/zylonite_pxa300.c 2008-02-12 20:52:26.000000000 +0000
3975+++ linux-2.6.23/arch/arm/mach-pxa/zylonite_pxa300.c 2008-02-13 00:26:37.000000000 +0000
3976@@ -104,6 +104,30 @@
3977 /* Ethernet */
3978 GPIO2_nCS3,
3979 GPIO99_GPIO,
3980+
3981+ /* NAND */
3982+ MFP_CFG_X(DF_INT_RnB, AF0, DS10X, PULL_LOW),
3983+ MFP_CFG_X(DF_nRE_nOE, AF1, DS10X, PULL_LOW),
3984+ MFP_CFG_X(DF_nWE, AF1, DS10X, PULL_LOW),
3985+ MFP_CFG_X(DF_CLE_nOE, AF0, DS10X, PULL_LOW),
3986+ MFP_CFG_X(DF_nADV1_ALE, AF1, DS10X, PULL_LOW),
3987+ MFP_CFG_X(DF_nCS0, AF1, DS10X, PULL_LOW),
3988+ MFP_CFG_X(DF_nCS1, AF0, DS10X, PULL_LOW),
3989+ MFP_CFG_X(DF_IO0, AF1, DS08X, PULL_LOW),
3990+ MFP_CFG_X(DF_IO1, AF1, DS08X, PULL_LOW),
3991+ MFP_CFG_X(DF_IO2, AF1, DS08X, PULL_LOW),
3992+ MFP_CFG_X(DF_IO3, AF1, DS08X, PULL_LOW),
3993+ MFP_CFG_X(DF_IO4, AF1, DS08X, PULL_LOW),
3994+ MFP_CFG_X(DF_IO5, AF1, DS08X, PULL_LOW),
3995+ MFP_CFG_X(DF_IO6, AF1, DS08X, PULL_LOW),
3996+ MFP_CFG_X(DF_IO7, AF1, DS08X, PULL_LOW),
3997+ MFP_CFG_X(DF_IO8, AF1, DS08X, PULL_LOW),
3998+ MFP_CFG_X(DF_IO9, AF1, DS08X, PULL_LOW),
3999+ MFP_CFG_X(DF_IO10, AF1, DS08X, PULL_LOW),
4000+ MFP_CFG_X(DF_IO11, AF1, DS08X, PULL_LOW),
4001+ MFP_CFG_X(DF_IO12, AF1, DS08X, PULL_LOW),
4002+ MFP_CFG_X(DF_IO13, AF1, DS08X, PULL_LOW),
4003+ MFP_CFG_X(DF_IO14, AF1, DS08X, PULL_LOW),
4004 };
4005
4006 static mfp_cfg_t pxa310_mfp_cfg[] __initdata = {
4007@@ -163,6 +187,9 @@
4008 pxa3xx_mfp_write(lcd_detect_pins[i], mfpr_save[i]);
4009 }
4010
4011+extern int gpio_vsync;
4012+extern int gpio_vsync1;
4013+
4014 void __init zylonite_pxa300_init(void)
4015 {
4016 if (cpu_is_pxa300() || cpu_is_pxa310()) {
4017@@ -174,6 +201,8 @@
4018
4019 /* GPIO pin assignment */
4020 gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO20);
4021+ gpio_vsync = mfp_to_gpio(GPIO76_LCD_VSYNC);
4022+ gpio_vsync1 = mfp_to_gpio(GPIO71_LCD_LDD_17);
4023 }
4024
4025 if (cpu_is_pxa300()) {
4026Index: linux-2.6.23/drivers/video/pxafb.c
4027===================================================================
4028--- linux-2.6.23.orig/drivers/video/pxafb.c 2008-02-13 00:05:42.000000000 +0000
4029+++ linux-2.6.23/drivers/video/pxafb.c 2008-02-13 00:06:02.000000000 +0000
4030@@ -1543,9 +1543,9 @@
4031 if (inf->lccr0 & LCCR0_INVALID_CONFIG_MASK)
4032 dev_warn(&dev->dev, "machine LCCR0 setting contains illegal bits: %08x\n",
4033 inf->lccr0 & LCCR0_INVALID_CONFIG_MASK);
4034- if (inf->lccr3 & LCCR3_INVALID_CONFIG_MASK)
4035- dev_warn(&dev->dev, "machine LCCR3 setting contains illegal bits: %08x\n",
4036- inf->lccr3 & LCCR3_INVALID_CONFIG_MASK);
4037+ //if (inf->lccr3 & LCCR3_INVALID_CONFIG_MASK)
4038+ // dev_warn(&dev->dev, "machine LCCR3 setting contains illegal bits: %08x\n",
4039+ // inf->lccr3 & LCCR3_INVALID_CONFIG_MASK);
4040 if (inf->lccr0 & LCCR0_DPD &&
4041 ((inf->lccr0 & LCCR0_PAS) != LCCR0_Pas ||
4042 (inf->lccr0 & LCCR0_SDS) != LCCR0_Sngl ||
4043Index: linux-2.6.23/include/asm-arm/arch-pxa/mfp-pxa300.h
4044===================================================================
4045--- linux-2.6.23.orig/include/asm-arm/arch-pxa/mfp-pxa300.h 2008-02-13 00:44:38.000000000 +0000
4046+++ linux-2.6.23/include/asm-arm/arch-pxa/mfp-pxa300.h 2008-02-13 00:49:38.000000000 +0000
4047@@ -175,13 +175,13 @@
4048 #define GPIO68_LCD_LDD_14 MFP_CFG_DRV(GPIO68, AF1, DS01X)
4049 #define GPIO69_LCD_LDD_15 MFP_CFG_DRV(GPIO69, AF1, DS01X)
4050 #define GPIO70_LCD_LDD_16 MFP_CFG_DRV(GPIO70, AF1, DS01X)
4051-#define GPIO71_LCD_LDD_17 MFP_CFG_DRV(GPIO71, AF1, DS01X)
4052+#define GPIO71_LCD_LDD_17 MFP_CFG_DRV(GPIO71, AF0, DS01X)
4053 #define GPIO62_LCD_CS_N MFP_CFG_DRV(GPIO62, AF2, DS01X)
4054 #define GPIO72_LCD_FCLK MFP_CFG_DRV(GPIO72, AF1, DS01X)
4055 #define GPIO73_LCD_LCLK MFP_CFG_DRV(GPIO73, AF1, DS01X)
4056 #define GPIO74_LCD_PCLK MFP_CFG_DRV(GPIO74, AF1, DS01X)
4057 #define GPIO75_LCD_BIAS MFP_CFG_DRV(GPIO75, AF1, DS01X)
4058-#define GPIO76_LCD_VSYNC MFP_CFG_DRV(GPIO76, AF2, DS01X)
4059+#define GPIO76_LCD_VSYNC MFP_CFG_DRV(GPIO76, AF0, DS01X)
4060
4061 #define GPIO15_LCD_CS_N MFP_CFG_DRV(GPIO15, AF2, DS01X)
4062 #define GPIO127_LCD_CS_N MFP_CFG_DRV(GPIO127, AF1, DS01X)
diff --git a/meta/packages/linux/linux-rp_2.6.23.bb b/meta/packages/linux/linux-rp_2.6.23.bb
index 6c6c229f09..c9b20de485 100644
--- a/meta/packages/linux/linux-rp_2.6.23.bb
+++ b/meta/packages/linux/linux-rp_2.6.23.bb
@@ -1,6 +1,6 @@
1require linux-rp.inc 1require linux-rp.inc
2 2
3PR = "r29" 3PR = "r30"
4 4
5# Handy URLs 5# Handy URLs
6# git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git;protocol=git;tag=ef7d1b244fa6c94fb76d5f787b8629df64ea4046 6# git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git;protocol=git;tag=ef7d1b244fa6c94fb76d5f787b8629df64ea4046
@@ -138,6 +138,7 @@ SRC_URI_append_zylonite ="\
138 file://arm_pxa_20070923.patch;patch=1 \ 138 file://arm_pxa_20070923.patch;patch=1 \
139 file://pxa_fb_overlay.patch;patch=1 \ 139 file://pxa_fb_overlay.patch;patch=1 \
140 file://zylonite-boot.patch;patch=1 \ 140 file://zylonite-boot.patch;patch=1 \
141 file://zylonite_mtd-r0.patch;patch=1 \
141 " 142 "
142 143
143S = "${WORKDIR}/linux-2.6.23" 144S = "${WORKDIR}/linux-2.6.23"