1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2024-11-25 09:52:27 +02:00
openwrt-xburst/target/linux/xburst/patches-2.6.24/0004-first-pi-work-kernel.patch
Xiangfu Liu 4808ec76e8 add-2.6.24-kernel-patch
Signed-off-by: Xiangfu Liu <xiangfu.z@gmail.com>
2009-10-28 03:13:09 +08:00

3819 lines
105 KiB
Diff

From aadf2187e0236fd2ac90719f89f912f84ef87a5a Mon Sep 17 00:00:00 2001
From: xiangfu <xiangfu.z@gmail.com>
Date: Tue, 21 Apr 2009 22:18:22 +0800
Subject: [PATCH] first pi work kernel
---
arch/mips/Kconfig | 8 +
arch/mips/configs/pi_defconfig | 1297 +++++++++++++++++++
arch/mips/jz4740/Makefile | 1 +
arch/mips/jz4740/board-pi.c | 114 ++
drivers/mtd/nand/jz4740_nand.c | 2122 ++++++++++++++++---------------
drivers/video/jzlcd.c | 21 +-
drivers/video/jzlcd.h | 38 +-
include/asm-mips/mach-jz4740/board-pi.h | 68 +
include/asm-mips/mach-jz4740/jz4740.h | 4 +
9 files changed, 2623 insertions(+), 1050 deletions(-)
create mode 100644 arch/mips/configs/pi_defconfig
create mode 100644 arch/mips/jz4740/board-pi.c
create mode 100644 include/asm-mips/mach-jz4740/board-pi.h
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 3d6eddf..bdaf1ce 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -32,6 +32,14 @@ config JZ4740_PAVO
select SYS_SUPPORTS_LITTLE_ENDIAN
select SOC_JZ4740
+config JZ4740_PI
+ bool "Ingenic JZ4740 PI "
+ select DMA_NONCOHERENT
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SOC_JZ4740
+
config JZ4740_LEO
bool "Ingenic JZ4740 LEO board"
select DMA_NONCOHERENT
diff --git a/arch/mips/configs/pi_defconfig b/arch/mips/configs/pi_defconfig
new file mode 100644
index 0000000..f9451c7
--- /dev/null
+++ b/arch/mips/configs/pi_defconfig
@@ -0,0 +1,1297 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.24.3
+# Tue Apr 21 17:17:32 2009
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+# CONFIG_JZ4730_PMP is not set
+# CONFIG_JZ4740_PAVO is not set
+CONFIG_JZ4740_PI=y
+# CONFIG_JZ4740_LEO is not set
+# CONFIG_JZ4740_LYRA is not set
+# CONFIG_JZ4725_DIPPER is not set
+# CONFIG_JZ4720_VIRGO is not set
+# CONFIG_JZ4750_FUWA is not set
+# CONFIG_JZ4750D_FUWA1 is not set
+# CONFIG_JZ4750_APUS is not set
+# CONFIG_MACH_ALCHEMY is not set
+# CONFIG_BASLER_EXCITE is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_PMC_MSP is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SNI_RM is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_WR_PPMC is not set
+CONFIG_SOC_JZ4740=y
+CONFIG_JZSOC=y
+CONFIG_JZRISC=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_HOTPLUG_CPU is not set
+# CONFIG_NO_IOPORT is not set
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_LOONGSON2 is not set
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_FORCE_MAX_ZONEORDER=12
+# CONFIG_HZ_48 is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_128 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_256 is not set
+# CONFIG_HZ_1000 is not set
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=100
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
+# CONFIG_KEXEC is not set
+CONFIG_SECCOMP=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_RELAY=y
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_MMU=y
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ_JZ=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
+# CONFIG_SUSPEND is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT=y
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+CONFIG_MTD_NAND_JZ4740=y
+# CONFIG_MTD_NAND_CS2 is not set
+# CONFIG_MTD_NAND_CS3 is not set
+# CONFIG_MTD_NAND_CS4 is not set
+CONFIG_MTD_NAND_MULTI_PLANE=y
+# CONFIG_MTD_HW_HM_ECC is not set
+# CONFIG_MTD_SW_HM_ECC is not set
+CONFIG_MTD_HW_RS_ECC=y
+# CONFIG_MTD_HW_BCH_ECC is not set
+# CONFIG_MTD_MTDBLOCK_WRITE_VERIFY_ENABLE is not set
+CONFIG_MTD_OOB_COPIES=3
+CONFIG_MTD_BADBLOCK_FLAG_PAGE=127
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=m
+CONFIG_MTD_UBI_WL_THRESHOLD=256
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
+CONFIG_MTD_UBI_BLKDEVS=m
+CONFIG_MTD_UBI_BLOCK=m
+# CONFIG_PARPORT is not set
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+# CONFIG_PNPACPI is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=2
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_NET_SB1000 is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_JZCS8900=y
+# CONFIG_AX88796 is not set
+# CONFIG_DM9000 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PNP=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=2
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_RTC is not set
+# CONFIG_RTC_PCF8563 is not set
+CONFIG_RTC_JZ=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+
+#
+# JZSOC char device support
+#
+CONFIG_JZCHAR=y
+# CONFIG_JZ_CIM is not set
+# CONFIG_JZ_TPANEL_ATA2508 is not set
+CONFIG_JZ_TPANEL=y
+CONFIG_JZ_SADC=y
+# CONFIG_JZ_TPANEL_AK4182 is not set
+# CONFIG_JZ_TPANEL_UCB1400 is not set
+# CONFIG_JZ_TPANEL_WM9712 is not set
+CONFIG_JZ_UDC_HOTPLUG=y
+CONFIG_JZ_POWEROFF=y
+# CONFIG_JZ_OW is not set
+# CONFIG_JZ_TCSM is not set
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_JZ_WDT=y
+# CONFIG_SOFT_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+CONFIG_VIDEO_JZ_CIM=y
+CONFIG_VIDEO_JZ_SENSOR=y
+CONFIG_V4L_USB_DRIVERS=y
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_ZC0301 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_ZR364XX is not set
+CONFIG_RADIO_ADAPTERS=y
+# CONFIG_USB_DSBR is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+CONFIG_FB_JZSOC=y
+# CONFIG_FB_JZ4740_SLCD is not set
+CONFIG_FB_JZLCD_4730_4740=y
+CONFIG_JZLCD_FRAMEBUFFER_MAX=1
+# CONFIG_JZLCD_FRAMEBUFFER_ROTATE_SUPPORT is not set
+# CONFIG_JZLCD_SHARP_LQ035Q7 is not set
+# CONFIG_JZLCD_SAMSUNG_LTS350Q1 is not set
+# CONFIG_JZLCD_SAMSUNG_LTV350QVF04 is not set
+# CONFIG_JZLCD_SAMSUNG_LTP400WQF01 is not set
+# CONFIG_JZLCD_SAMSUNG_LTP400WQF02 is not set
+# CONFIG_JZLCD_AUO_A030FL01_V1 is not set
+# CONFIG_JZLCD_TRULY_TFTG320240DTSW is not set
+# CONFIG_JZLCD_TRULY_TFTG320240DTSW_SERIAL is not set
+# CONFIG_JZLCD_TRULY_TFTG240320UTSW_63W_E is not set
+CONFIG_JZLCD_FOXCONN_PT035TN01=y
+# CONFIG_JZLCD_INNOLUX_PT035TN01_SERIAL is not set
+# CONFIG_JZLCD_TOSHIBA_LTM084P363 is not set
+# CONFIG_JZLCD_HYNIX_HT10X21 is not set
+# CONFIG_JZLCD_INNOLUX_AT080TN42 is not set
+# CONFIG_JZLCD_CSTN_800x600 is not set
+# CONFIG_JZLCD_CSTN_320x240 is not set
+# CONFIG_JZLCD_MSTN_480x320 is not set
+# CONFIG_JZLCD_MSTN_320x240 is not set
+# CONFIG_JZLCD_MSTN_240x128 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_CURSOR_FLASH is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+# CONFIG_SND is not set
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=y
+CONFIG_OSS_OBSOLETE=y
+# CONFIG_SOUND_JZ_AC97 is not set
+CONFIG_SOUND_JZ_I2S=y
+# CONFIG_I2S_AK4642EN is not set
+CONFIG_I2S_ICODEC=y
+# CONFIG_I2S_DLV is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_PERSIST is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_SELECTED=y
+CONFIG_USB_GADGET_JZ4740=y
+CONFIG_USB_JZ4740=m
+# CONFIG_USB_GADGET_JZ4750 is not set
+# CONFIG_USB_GADGET_JZ4730 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_UDC_USE_LB_CACHE=y
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+CONFIG_MMC_JZ=y
+# CONFIG_JZ_MMC_BUS_1 is not set
+CONFIG_JZ_MMC_BUS_4=y
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
+#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_UBIFS_FS=m
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_BIND34 is not set
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+CONFIG_NLS_CODEPAGE_936=y
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Yaffs2 Filesystems
+#
+CONFIG_YAFFS_FS=y
+CONFIG_YAFFS_YAFFS1=y
+# CONFIG_YAFFS_DOES_ECC is not set
+CONFIG_YAFFS_YAFFS2=y
+CONFIG_YAFFS_ECC_RS=y
+# CONFIG_YAFFS_ECC_HAMMING is not set
+CONFIG_YAFFS_AUTO_YAFFS2=y
+# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
+# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
+CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK=y
+CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
+CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10
+CONFIG_INSTRUMENTATION=y
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SAMPLES is not set
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_ECB is not set
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_LZO=m
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=m
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
+CONFIG_REED_SOLOMON=y
+CONFIG_REED_SOLOMON_ENC8=y
+CONFIG_REED_SOLOMON_DEC8=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
index 7592f4e..dcf4d0c 100644
--- a/arch/mips/jz4740/Makefile
+++ b/arch/mips/jz4740/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_PROC_FS) += proc.o
# board specific support
obj-$(CONFIG_JZ4740_PAVO) += board-pavo.o
+obj-$(CONFIG_JZ4740_PI) += board-pi.o
obj-$(CONFIG_JZ4740_LEO) += board-leo.o
obj-$(CONFIG_JZ4740_LYRA) += board-lyra.o
obj-$(CONFIG_JZ4725_DIPPER) += board-dipper.o
diff --git a/arch/mips/jz4740/board-pi.c b/arch/mips/jz4740/board-pi.c
new file mode 100644
index 0000000..8c8544f
--- /dev/null
+++ b/arch/mips/jz4740/board-pi.c
@@ -0,0 +1,114 @@
+/*
+ * linux/arch/mips/jz4740/board-pi.c
+ *
+ * JZ4740 PI setup routines.
+ *
+ * Copyright (c) 2009 PI.
+ * Author: xiangfu <xiangfu.z@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+
+#include <asm/jzsoc.h>
+
+extern void (*jz_timer_callback)(void);
+
+static void dancing(void)
+{
+ static unsigned int count = 0;
+
+ count ++;
+ count &= 1;
+ /* if (count)
+ __gpio_set_pin(GPIO_LED_EN);
+ else
+ __gpio_clear_pin(GPIO_LED_EN); */
+}
+
+static void pi_timer_callback(void)
+{
+ static unsigned long count = 0;
+
+ if ((++count) % 50 == 0) {
+ dancing();
+ count = 0;
+ }
+}
+
+static void __init board_cpm_setup(void)
+{
+ /* Stop unused module clocks here.
+ * We have started all module clocks at arch/mips/jz4740/setup.c.
+ */
+}
+
+static void __init board_gpio_setup(void)
+{
+ /*
+ * Most of the GPIO pins should have been initialized by the boot-loader
+ */
+
+ /*
+ * Initialize MSC pins
+ */
+ /* __gpio_as_msc(); */
+
+ /*
+ * Initialize LCD pins
+ */
+ __gpio_as_lcd_18bit();
+
+ /*
+ * Initialize SSI pins
+ */
+ __gpio_as_ssi();
+
+ /*
+ * Initialize I2C pins
+ */
+ __gpio_as_i2c();
+
+ /*
+ * Initialize Other pins
+ */
+ __gpio_as_output(GPIO_SD_VCC_EN_N);
+ __gpio_clear_pin(GPIO_SD_VCC_EN_N);
+
+ __gpio_as_input(GPIO_SD_CD_N);
+ __gpio_disable_pull(GPIO_SD_CD_N);
+
+ __gpio_as_input(GPIO_SD_WP);
+ __gpio_disable_pull(GPIO_SD_WP);
+
+ __gpio_as_input(GPIO_DC_DETE_N);
+ __gpio_as_input(GPIO_CHARG_STAT_N);
+ __gpio_as_input(GPIO_USB_DETE);
+
+ __gpio_as_output(GPIO_DISP_OFF_N);
+
+ __gpio_as_output(GPIO_LED_EN);
+}
+
+void __init jz_board_setup(void)
+{
+ printk("JZ4740 PI setup\n");
+
+ board_cpm_setup();
+ board_gpio_setup();
+
+ jz_timer_callback = pavo_timer_callback;
+}
diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c
index ccd4ed6..0fe5b36 100644
--- a/drivers/mtd/nand/jz4740_nand.c
+++ b/drivers/mtd/nand/jz4740_nand.c
@@ -1,1037 +1,1085 @@
-/*
- * linux/drivers/mtd/nand/jz4740_nand.c
- *
- * Copyright (c) 2005 - 2007 Ingenic Semiconductor Inc.
- *
- * Ingenic JZ4740 NAND driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/highmem.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/io.h>
-#include <asm/jzsoc.h>
-
-#define NAND_DATA_PORT1 0xB8000000 /* read-write area in static bank 1 */
-#define NAND_DATA_PORT2 0xB4000000 /* read-write area in static bank 2 */
-#define NAND_DATA_PORT3 0xAC000000 /* read-write area in static bank 3 */
-#define NAND_DATA_PORT4 0xA8000000 /* read-write area in static bank 4 */
-
-#define PAR_SIZE 9
-
-#define __nand_enable() (REG_EMC_NFCSR |= EMC_NFCSR_NFE1 | EMC_NFCSR_NFCE1)
-#define __nand_disable() (REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE1)
-
-#define __nand_ecc_enable() (REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST )
-#define __nand_ecc_disable() (REG_EMC_NFECR &= ~EMC_NFECR_ECCE)
-
-#define __nand_select_hm_ecc() (REG_EMC_NFECR &= ~EMC_NFECR_RS )
-#define __nand_select_rs_ecc() (REG_EMC_NFECR |= EMC_NFECR_RS)
-
-#define __nand_read_hm_ecc() (REG_EMC_NFECC & 0x00ffffff)
-
-#define __nand_rs_ecc_encoding() (REG_EMC_NFECR |= EMC_NFECR_RS_ENCODING)
-#define __nand_rs_ecc_decoding() (REG_EMC_NFECR &= ~EMC_NFECR_RS_ENCODING)
-#define __nand_ecc_encode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_ENCF))
-#define __nand_ecc_decode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_DECF))
-
-/*
- * MTD structure for JzSOC board
- */
-static struct mtd_info *jz_mtd = NULL;
-extern struct mtd_info *jz_mtd1;
-extern char all_use_planes;
-extern int global_page; /* for two-plane operations */
-
-/*
- * Define partitions for flash devices
- */
-#ifdef CONFIG_JZ4740_PAVO
-static struct mtd_partition partition_info[] = {
- { name: "NAND BOOT partition",
- offset: 0 * 0x100000,
- size: 4 * 0x100000,
- use_planes: 0 },
- { name: "NAND KERNEL partition",
- offset: 4 * 0x100000,
- size: 4 * 0x100000,
- use_planes: 0 },
- { name: "NAND ROOTFS partition",
- offset: 8 * 0x100000,
- size: 120 * 0x100000,
- use_planes: 0 },
- { name: "NAND DATA1 partition",
- offset: 128 * 0x100000,
- size: 128 * 0x100000,
- use_planes: 1 },
- { name: "NAND DATA2 partition",
- offset: 256 * 0x100000,
- size: 256 * 0x100000,
- use_planes: 1 },
- { name: "NAND VFAT partition",
- offset: 512 * 0x100000,
- size: 512 * 0x100000,
- use_planes: 1 },
-};
-
-
-/* Define max reserved bad blocks for each partition.
- * This is used by the mtdblock-jz.c NAND FTL driver only.
- *
- * The NAND FTL driver reserves some good blocks which can't be
- * seen by the upper layer. When the bad block number of a partition
- * exceeds the max reserved blocks, then there is no more reserved
- * good blocks to be used by the NAND FTL driver when another bad
- * block generated.
- */
-static int partition_reserved_badblocks[] = {
- 2, /* reserved blocks of mtd0 */
- 2, /* reserved blocks of mtd1 */
- 10, /* reserved blocks of mtd2 */
- 10, /* reserved blocks of mtd3 */
- 20, /* reserved blocks of mtd4 */
- 20}; /* reserved blocks of mtd5 */
-#endif /* CONFIG_JZ4740_PAVO */
-
-#ifdef CONFIG_JZ4740_LEO
-static struct mtd_partition partition_info[] = {
- { name: "NAND BOOT partition",
- offset: 0 * 0x100000,
- size: 4 * 0x100000 },
- { name: "NAND KERNEL partition",
- offset: 4 * 0x100000,
- size: 4 * 0x100000 },
- { name: "NAND ROOTFS partition",
- offset: 8 * 0x100000,
- size: 56 * 0x100000 },
- { name: "NAND VFAT partition",
- offset: 64 * 0x100000,
- size: 64 * 0x100000 },
-};
-static int partition_reserved_badblocks[] = {
- 2, /* reserved blocks of mtd0 */
- 2, /* reserved blocks of mtd1 */
- 10, /* reserved blocks of mtd2 */
- 10}; /* reserved blocks of mtd3 */
-#endif /* CONFIG_JZ4740_LEO */
-
-#ifdef CONFIG_JZ4740_LYRA
-static struct mtd_partition partition_info[] = {
- { name: "NAND BOOT partition",
- offset: 0 * 0x100000,
- size: 4 * 0x100000 },
- { name: "NAND KERNEL partition",
- offset: 4 * 0x100000,
- size: 4 * 0x100000 },
- { name: "NAND ROOTFS partition",
- offset: 8 * 0x100000,
- size: 120 * 0x100000 },
- { name: "NAND DATA1 partition",
- offset: 128 * 0x100000,
- size: 128 * 0x100000 },
- { name: "NAND DATA2 partition",
- offset: 256 * 0x100000,
- size: 256 * 0x100000 },
- { name: "NAND VFAT partition",
- offset: 512 * 0x100000,
- size: 512 * 0x100000 },
-};
-
-/* Define max reserved bad blocks for each partition.
- * This is used by the mtdblock-jz.c NAND FTL driver only.
- *
- * The NAND FTL driver reserves some good blocks which can't be
- * seen by the upper layer. When the bad block number of a partition
- * exceeds the max reserved blocks, then there is no more reserved
- * good blocks to be used by the NAND FTL driver when another bad
- * block generated.
- */
-static int partition_reserved_badblocks[] = {
- 2, /* reserved blocks of mtd0 */
- 2, /* reserved blocks of mtd1 */
- 10, /* reserved blocks of mtd2 */
- 10, /* reserved blocks of mtd3 */
- 20, /* reserved blocks of mtd4 */
- 20}; /* reserved blocks of mtd5 */
-#endif /* CONFIG_JZ4740_LYRA */
-
-#ifdef CONFIG_JZ4725_DIPPER
-static struct mtd_partition partition_info[] = {
- { name: "NAND BOOT partition",
- offset: 0 * 0x100000,
- size: 4 * 0x100000 },
- { name: "NAND KERNEL partition",
- offset: 4 * 0x100000,
- size: 4 * 0x100000 },
- { name: "NAND ROOTFS partition",
- offset: 8 * 0x100000,
- size: 56 * 0x100000 },
- { name: "NAND VFAT partition",
- offset: 64 * 0x100000,
- size: 64 * 0x100000 },
-};
-
-/* Define max reserved bad blocks for each partition.
- * This is used by the mtdblock-jz.c NAND FTL driver only.
- *
- * The NAND FTL driver reserves some good blocks which can't be
- * seen by the upper layer. When the bad block number of a partition
- * exceeds the max reserved blocks, then there is no more reserved
- * good blocks to be used by the NAND FTL driver when another bad
- * block generated.
- */
-static int partition_reserved_badblocks[] = {
- 2, /* reserved blocks of mtd0 */
- 2, /* reserved blocks of mtd1 */
- 10, /* reserved blocks of mtd2 */
- 10}; /* reserved blocks of mtd3 */
-#endif /* CONFIG_JZ4740_DIPPER */
-
-#ifdef CONFIG_JZ4720_VIRGO
-static struct mtd_partition partition_info[] = {
- { name: "NAND BOOT partition",
- offset: 0 * 0x100000,
- size: 4 * 0x100000 },
- { name: "NAND KERNEL partition",
- offset: 4 * 0x100000,
- size: 4 * 0x100000 },
- { name: "NAND ROOTFS partition",
- offset: 8 * 0x100000,
- size: 120 * 0x100000 },
- { name: "NAND DATA1 partition",
- offset: 128 * 0x100000,
- size: 128 * 0x100000 },
- { name: "NAND DATA2 partition",
- offset: 256 * 0x100000,
- size: 256 * 0x100000 },
- { name: "NAND VFAT partition",
- offset: 512 * 0x100000,
- size: 512 * 0x100000 },
-};
-
-
-/* Define max reserved bad blocks for each partition.
- * This is used by the mtdblock-jz.c NAND FTL driver only.
- *
- * The NAND FTL driver reserves some good blocks which can't be
- * seen by the upper layer. When the bad block number of a partition
- * exceeds the max reserved blocks, then there is no more reserved
- * good blocks to be used by the NAND FTL driver when another bad
- * block generated.
- */
-static int partition_reserved_badblocks[] = {
- 2, /* reserved blocks of mtd0 */
- 2, /* reserved blocks of mtd1 */
- 10, /* reserved blocks of mtd2 */
- 10, /* reserved blocks of mtd3 */
- 20, /* reserved blocks of mtd4 */
- 20}; /* reserved blocks of mtd5 */
-#endif /* CONFIG_JZ4720_VIRGO */
-/*-------------------------------------------------------------------------
- * Following three functions are exported and used by the mtdblock-jz.c
- * NAND FTL driver only.
- */
-
-unsigned short get_mtdblock_write_verify_enable(void)
-{
-#ifdef CONFIG_MTD_MTDBLOCK_WRITE_VERIFY_ENABLE
- return 1;
-#endif
- return 0;
-}
-EXPORT_SYMBOL(get_mtdblock_write_verify_enable);
-
-unsigned short get_mtdblock_oob_copies(void)
-{
- return CONFIG_MTD_OOB_COPIES;
-}
-EXPORT_SYMBOL(get_mtdblock_oob_copies);
-
-int *get_jz_badblock_table(void)
-{
- return partition_reserved_badblocks;
-}
-EXPORT_SYMBOL(get_jz_badblock_table);
-
-/*-------------------------------------------------------------------------*/
-
-static void jz_hwcontrol(struct mtd_info *mtd, int dat,
- unsigned int ctrl)
-{
- struct nand_chip *this = (struct nand_chip *)(mtd->priv);
- unsigned int nandaddr = (unsigned int)this->IO_ADDR_W;
- extern u8 nand_nce; /* in nand_base.c, indicates which chip select is used for current nand chip */
-
- if (ctrl & NAND_CTRL_CHANGE) {
- if (ctrl & NAND_NCE) {
- switch (nand_nce) {
- case NAND_NCE1:
- this->IO_ADDR_W = this->IO_ADDR_R = (void __iomem *)NAND_DATA_PORT1;
- REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE2;
- REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE3;
- REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE4;
- REG_EMC_NFCSR |= EMC_NFCSR_NFCE1;
- break;
- case NAND_NCE2:
- this->IO_ADDR_W = this->IO_ADDR_R = (void __iomem *)NAND_DATA_PORT2;
- REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE1;
- REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE3;
- REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE4;
- REG_EMC_NFCSR |= EMC_NFCSR_NFCE2;
- break;
- case NAND_NCE3:
- this->IO_ADDR_W = this->IO_ADDR_R = (void __iomem *)NAND_DATA_PORT3;
- REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE1;
- REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE2;
- REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE4;
- REG_EMC_NFCSR |= EMC_NFCSR_NFCE3;
- break;
- case NAND_NCE4:
- this->IO_ADDR_W = this->IO_ADDR_R = (void __iomem *)NAND_DATA_PORT4;
- REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE1;
- REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE2;
- REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE3;
- REG_EMC_NFCSR |= EMC_NFCSR_NFCE4;
- break;
- default:
- printk("error: no nand_nce 0x%x\n",nand_nce);
- break;
- }
- } else {
- REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE1;
- REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE2;
- REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE3;
- REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE4;
- }
-
- if ( ctrl & NAND_ALE )
- nandaddr = (unsigned int)((unsigned long)(this->IO_ADDR_W) | 0x00010000);
- else
- nandaddr = (unsigned int)((unsigned long)(this->IO_ADDR_W) & ~0x00010000);
-
- if ( ctrl & NAND_CLE )
- nandaddr = nandaddr | 0x00008000;
- else
- nandaddr = nandaddr & ~0x00008000;
- }
-
- this->IO_ADDR_W = (void __iomem *)nandaddr;
- if (dat != NAND_CMD_NONE)
- writeb(dat, this->IO_ADDR_W);
-}
-
-static int jz_device_ready(struct mtd_info *mtd)
-{
- int ready, wait = 10;
- while (wait--);
- ready = __gpio_get_pin(94);
- return ready;
-}
-
-/*
- * EMC setup
- */
-static void jz_device_setup(void)
-{
-// PORT 0:
-// ...
-// PORT 1:
-// PIN/BIT N FUNC0 FUNC1
-// 25 CS1# -
-// 26 CS2# -
-// 27 CS3# -
-// 28 CS4# -
-#define GPIO_CS2_N (32+26)
-#define GPIO_CS3_N (32+27)
-#define GPIO_CS4_N (32+28)
-#define SMCR_VAL 0x0d221200
-
- /* Set NFE bit */
- REG_EMC_NFCSR |= EMC_NFCSR_NFE1;
- /* Read/Write timings */
- REG_EMC_SMCR1 = SMCR_VAL;
-
-#if defined(CONFIG_MTD_NAND_CS2)
- /* Set CS2# pin as function 0 */
- __gpio_as_func0(GPIO_CS2_N);
- REG_EMC_NFCSR |= EMC_NFCSR_NFE2;
- REG_EMC_SMCR2 = SMCR_VAL;
-#endif
-
-#if defined(CONFIG_MTD_NAND_CS3)
- __gpio_as_func0(GPIO_CS3_N);
- REG_EMC_NFCSR |= EMC_NFCSR_NFE3;
- REG_EMC_SMCR3 = SMCR_VAL;
-#endif
-
-#if defined(CONFIG_MTD_NAND_CS4)
- __gpio_as_func0(GPIO_CS4_N);
- REG_EMC_NFCSR |= EMC_NFCSR_NFE4;
- REG_EMC_SMCR4 = SMCR_VAL;
-#endif
-}
-
-#ifdef CONFIG_MTD_HW_HM_ECC
-
-static int jzsoc_nand_calculate_hm_ecc(struct mtd_info* mtd,
- const u_char* dat, u_char* ecc_code)
-{
- unsigned int calc_ecc;
- unsigned char *tmp;
-
- __nand_ecc_disable();
-
- calc_ecc = ~(__nand_read_hm_ecc()) | 0x00030000;
-
- tmp = (unsigned char *)&calc_ecc;
- //adjust eccbytes order for compatible with software ecc
- ecc_code[0] = tmp[1];
- ecc_code[1] = tmp[0];
- ecc_code[2] = tmp[2];
-
- return 0;
-}
-
-static void jzsoc_nand_enable_hm_hwecc(struct mtd_info* mtd, int mode)
-{
- __nand_ecc_enable();
- __nand_select_hm_ecc();
-}
-
-static int jzsoc_nand_hm_correct_data(struct mtd_info *mtd, u_char *dat,
- u_char *read_ecc, u_char *calc_ecc)
-{
- u_char a, b, c, d1, d2, d3, add, bit, i;
-
- /* Do error detection */
- d1 = calc_ecc[0] ^ read_ecc[0];
- d2 = calc_ecc[1] ^ read_ecc[1];
- d3 = calc_ecc[2] ^ read_ecc[2];
-
- if ((d1 | d2 | d3) == 0) {
- /* No errors */
- return 0;
- }
- else {
- a = (d1 ^ (d1 >> 1)) & 0x55;
- b = (d2 ^ (d2 >> 1)) & 0x55;
- c = (d3 ^ (d3 >> 1)) & 0x54;
-
- /* Found and will correct single bit error in the data */
- if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
- c = 0x80;
- add = 0;
- a = 0x80;
- for (i=0; i<4; i++) {
- if (d1 & c)
- add |= a;
- c >>= 2;
- a >>= 1;
- }
- c = 0x80;
- for (i=0; i<4; i++) {
- if (d2 & c)
- add |= a;
- c >>= 2;
- a >>= 1;
- }
- bit = 0;
- b = 0x04;
- c = 0x80;
- for (i=0; i<3; i++) {
- if (d3 & c)
- bit |= b;
- c >>= 2;
- b >>= 1;
- }
- b = 0x01;
- a = dat[add];
- a ^= (b << bit);
- dat[add] = a;
- return 0;
- }
- else {
- i = 0;
- while (d1) {
- if (d1 & 0x01)
- ++i;
- d1 >>= 1;
- }
- while (d2) {
- if (d2 & 0x01)
- ++i;
- d2 >>= 1;
- }
- while (d3) {
- if (d3 & 0x01)
- ++i;
- d3 >>= 1;
- }
- if (i == 1) {
- /* ECC Code Error Correction */
- read_ecc[0] = calc_ecc[0];
- read_ecc[1] = calc_ecc[1];
- read_ecc[2] = calc_ecc[2];
- return 0;
- }
- else {
- /* Uncorrectable Error */
- printk("NAND: uncorrectable ECC error\n");
- return -1;
- }
- }
- }
-
- /* Should never happen */
- return -1;
-}
-
-#endif /* CONFIG_MTD_HW_HM_ECC */
-
-#ifdef CONFIG_MTD_HW_RS_ECC
-
-static void jzsoc_nand_enable_rs_hwecc(struct mtd_info* mtd, int mode)
-{
- REG_EMC_NFINTS = 0x0;
- __nand_ecc_enable();
- __nand_select_rs_ecc();
-
- if (mode == NAND_ECC_READ)
- __nand_rs_ecc_decoding();
-
- if (mode == NAND_ECC_WRITE)
- __nand_rs_ecc_encoding();
-}
-
-static void jzsoc_rs_correct(unsigned char *dat, int idx, int mask)
-{
- int i;
-
- idx--;
-
- i = idx + (idx >> 3);
- if (i >= 512)
- return;
-
- mask <<= (idx & 0x7);
-
- dat[i] ^= mask & 0xff;
- if (i < 511)
- dat[i+1] ^= (mask >> 8) & 0xff;
-}
-
-/*
- * calc_ecc points to oob_buf for us
- */
-static int jzsoc_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat,
- u_char *read_ecc, u_char *calc_ecc)
-{
- volatile u8 *paraddr = (volatile u8 *)EMC_NFPAR0;
- short k;
- u32 stat;
-
- /* Set PAR values */
- for (k = 0; k < PAR_SIZE; k++) {
- *paraddr++ = read_ecc[k];
- }
-
- /* Set PRDY */
- REG_EMC_NFECR |= EMC_NFECR_PRDY;
-
- /* Wait for completion */
- __nand_ecc_decode_sync();
- __nand_ecc_disable();
-
- /* Check decoding */
- stat = REG_EMC_NFINTS;
-
- if (stat & EMC_NFINTS_ERR) {
- /* Error occurred */
- if (stat & EMC_NFINTS_UNCOR) {
- printk("NAND: Uncorrectable ECC error\n");
- return -1;
- } else {
- u32 errcnt = (stat & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT;
- switch (errcnt) {
- case 4:
- jzsoc_rs_correct(dat, (REG_EMC_NFERR3 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, (REG_EMC_NFERR3 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT);
- /* FALL-THROUGH */
- case 3:
- jzsoc_rs_correct(dat, (REG_EMC_NFERR2 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, (REG_EMC_NFERR2 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT);
- /* FALL-THROUGH */
- case 2:
- jzsoc_rs_correct(dat, (REG_EMC_NFERR1 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, (REG_EMC_NFERR1 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT);
- /* FALL-THROUGH */
- case 1:
- jzsoc_rs_correct(dat, (REG_EMC_NFERR0 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, (REG_EMC_NFERR0 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT);
- return 0;
- default:
- break;
- }
- }
- }
-
- return 0;
-}
-
-static int jzsoc_nand_calculate_rs_ecc(struct mtd_info* mtd, const u_char* dat,
- u_char* ecc_code)
-{
- volatile u8 *paraddr = (volatile u8 *)EMC_NFPAR0;
- short i;
-
- __nand_ecc_encode_sync();
- __nand_ecc_disable();
-
- for(i = 0; i < PAR_SIZE; i++) {
- ecc_code[i] = *paraddr++;
- }
-
- return 0;
-}
-
-#endif /* CONFIG_MTD_HW_RS_ECC */
-
-/* Nand optimized functions */
-static int dma_chan;
-static unsigned int dma_src_phys_addr, dma_dst_phys_addr;
-extern int jz_request_dma(int dev_id, const char *dev_str,
- irqreturn_t (*irqhandler)(int, void *),
- unsigned long irqflags, void *irq_dev_id);
-
-static void dma_setup(void)
-{
- /* Request DMA channel and setup irq handler */
- dma_chan = jz_request_dma(DMA_ID_AUTO, "auto", NULL, IRQF_DISABLED, NULL);
- if (dma_chan < 0) {
- printk("Setup irq for nand failed!\n");
- return;
- } else
- printk("Nand DMA request channel %d.\n",dma_chan);
-}
-
-static void jz4740_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
-{
- int i;
- struct nand_chip *chip = mtd->priv;
-
- if ((len <= 32) || (len & 0xf) || ((u32)buf >= (u32)high_memory))
- {
- for (i = 0; i < len; i++)
- buf[i] = readb(chip->IO_ADDR_R);
- } else {
- REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO;
- dma_src_phys_addr = CPHYSADDR(chip->IO_ADDR_R);
- dma_dst_phys_addr = CPHYSADDR(buf);
- dma_cache_inv((u32)buf, len);
- REG_DMAC_DSAR(dma_chan) = dma_src_phys_addr;
- REG_DMAC_DTAR(dma_chan) = dma_dst_phys_addr;
- REG_DMAC_DTCR(dma_chan) = len / 16;
- REG_DMAC_DCMD(dma_chan) = DMAC_DCMD_DAI | DMAC_DCMD_SWDH_8 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_16BYTE;
- REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN;
- REG_DMAC_DMACR = DMAC_DMACR_DMAE; /* global DMA enable bit */
-
- while(!(REG_DMAC_DCCSR(dma_chan) & DMAC_DCCSR_TT));
- REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */
- __dmac_channel_clear_transmit_end(dma_chan);
- }
-}
-
-static void jz4740_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
-{
- int i;
- struct nand_chip *chip = mtd->priv;
-
- if ((len <= 32) || (len & 0xf) || ((u32)buf >= (u32)high_memory))
- {
- for (i = 0; i < len; i++)
- writeb(buf[i], chip->IO_ADDR_W);
- } else {
- REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO;
- dma_dst_phys_addr = CPHYSADDR(chip->IO_ADDR_R);
- dma_src_phys_addr = CPHYSADDR(buf);
- dma_cache_wback((unsigned long)buf, len);
- REG_DMAC_DSAR(dma_chan) = dma_src_phys_addr;
- REG_DMAC_DTAR(dma_chan) = dma_dst_phys_addr;
- REG_DMAC_DTCR(dma_chan) = len / 16;
- REG_DMAC_DCMD(dma_chan) = DMAC_DCMD_SAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_8 | DMAC_DCMD_DS_16BYTE ;
- REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN;
- REG_DMAC_DMACR = DMAC_DMACR_DMAE; /* global DMA enable bit */
-
- while(!(REG_DMAC_DCCSR(dma_chan) & DMAC_DCCSR_TT));
- REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */
- __dmac_channel_clear_transmit_end(dma_chan);
- }
-}
-
-static int nand_read_page_hwecc_rs_planes(struct mtd_info *mtd, struct nand_chip *chip,
- uint8_t *buf)
-{
- int i, eccsize = chip->ecc.size;
- int eccbytes = chip->ecc.bytes;
- int eccsteps = chip->ecc.steps >> 1;
- uint8_t *p;
- uint8_t *ecc_calc = chip->buffers->ecccalc;
- uint8_t *ecc_code = chip->buffers->ecccode;
- uint32_t *eccpos = chip->ecc.layout->eccpos;
- uint32_t page;
- uint8_t flag = 0;
- int oobsize = mtd->oobsize >> 1;
- int ppb = mtd->erasesize / mtd->writesize;
- int ecctotal = chip->ecc.total >> 1;
-
- page = (global_page / ppb) * ppb + global_page; /* = global_page%ppb + (global_page/ppb)*ppb*2 */
-
- /* Read first page */
- chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
- chip->read_buf(mtd, chip->oob_poi, oobsize);
- for (i = 0; i < ecctotal; i++) {
- ecc_code[i] = chip->oob_poi[eccpos[i]];
- if (ecc_code[i] != 0xff) flag = 1;
- }
-
- p = buf;
- chip->cmdfunc(mtd, NAND_CMD_RNDOUT, 0x00, -1);
- for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
- int stat;
- if (flag) {
- chip->ecc.hwctl(mtd, NAND_ECC_READ);
- chip->read_buf(mtd, p, eccsize);
- stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
- if (stat < 0)
- mtd->ecc_stats.failed++;
- else
- mtd->ecc_stats.corrected += stat;
- }
- else {
- chip->ecc.hwctl(mtd, NAND_ECC_READ);
- chip->read_buf(mtd, p, eccsize);
- }
- }
- /* Read second page */
- page += ppb;
- flag = 0;
- chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
- chip->read_buf(mtd, chip->oob_poi + oobsize, oobsize);
- for (i = 0; i < ecctotal; i++) {
- ecc_code[i] = chip->oob_poi[oobsize + eccpos[i]];
- if (ecc_code[i] != 0xff) flag = 1;
- }
-
- chip->cmdfunc(mtd, NAND_CMD_RNDOUT, 0x00, -1);
- eccsteps = chip->ecc.steps >> 1;
- for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
- int stat;
- if (flag) {
- chip->ecc.hwctl(mtd, NAND_ECC_READ);
- chip->read_buf(mtd, p, eccsize);
- stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
- if (stat < 0)
- mtd->ecc_stats.failed++;
- else
- mtd->ecc_stats.corrected += stat;
- }
- else {
- chip->ecc.hwctl(mtd, NAND_ECC_READ);
- chip->read_buf(mtd, p, eccsize);
- }
- }
-
- return 0;
-}
-
-static int nand_read_oob_std_planes(struct mtd_info *mtd, struct nand_chip *chip,
- int global_page, int sndcmd)
-{
- int page;
- int oobsize = mtd->oobsize >> 1;
- int ppb = mtd->erasesize / mtd->writesize;
-
- page = (global_page / ppb) * ppb + global_page; /* = global_page%ppb + (global_page/ppb)*ppb*2 */
-
- /* Read first page OOB */
- if (sndcmd) {
- chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
- }
- chip->read_buf(mtd, chip->oob_poi, oobsize);
- /* Read second page OOB */
- page += ppb;
- if (sndcmd) {
- chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
- sndcmd = 0;
- }
- chip->read_buf(mtd, chip->oob_poi+oobsize, oobsize);
- return 0;
-}
-
-static int nand_write_oob_std_planes(struct mtd_info *mtd, struct nand_chip *chip,
- int global_page)
-{
- int status = 0,page;
- int pagesize = mtd->writesize >> 1;
- int oobsize = mtd->oobsize >> 1;
- int ppb = mtd->erasesize / mtd->writesize;
- const uint8_t *buf = chip->oob_poi;
-
- page = (global_page / ppb) * ppb + global_page; /* = global_page%ppb + (global_page/ppb)*ppb*2 */
-
- /* send cmd 0x80, the MSB should be valid if realplane is 4 */
- if (chip->realplanenum == 2)
- chip->cmdfunc(mtd, 0x80, pagesize, 0x00);
- else
- chip->cmdfunc(mtd, 0x80, pagesize, page & (1 << (chip->chip_shift - chip->page_shift)));
-
- chip->write_buf(mtd, buf, oobsize);
- /* Send first command to program the OOB data */
- chip->cmdfunc(mtd, 0x11, -1, -1);
- ndelay(100);
- status = chip->waitfunc(mtd, chip);
-
- page += ppb;
- buf += oobsize;
- chip->cmdfunc(mtd, 0x81, pagesize, page);
- chip->write_buf(mtd, buf, oobsize);
- /* Send command to program the OOB data */
- chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
- /* Wait long R/B */
- ndelay(100);
- status = chip->waitfunc(mtd, chip);
-
- return status & NAND_STATUS_FAIL ? -EIO : 0;
-}
-
-static void nand_write_page_hwecc_planes(struct mtd_info *mtd, struct nand_chip *chip,
- const uint8_t *buf)
-{
- int i, eccsize = chip->ecc.size;
- int eccbytes = chip->ecc.bytes;
- int eccsteps = chip->ecc.steps >> 1;
- uint8_t *ecc_calc = chip->buffers->ecccalc;
- uint8_t *p = (uint8_t *)buf;
- uint32_t *eccpos = chip->ecc.layout->eccpos;
- int oobsize = mtd->oobsize >> 1;
- int ppb = mtd->erasesize / mtd->writesize;
- int ecctotal = chip->ecc.total >> 1;
- int page;
-
- page = (global_page / ppb) * ppb + global_page; /* = global_page%ppb + (global_page/ppb)*ppb*2 */
-
- /* send cmd 0x80, the MSB should be valid if realplane is 4 */
- if (chip->realplanenum == 2)
- chip->cmdfunc(mtd, 0x80, 0x00, 0x00);
- else
- chip->cmdfunc(mtd, 0x80, 0x00, page & (1 << (chip->chip_shift - chip->page_shift)));
-
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
- chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
- chip->write_buf(mtd, p, eccsize);
- chip->ecc.calculate(mtd, p, &ecc_calc[i]);
- }
- for (i = 0; i < ecctotal; i++)
- chip->oob_poi[eccpos[i]] = ecc_calc[i];
-
- chip->write_buf(mtd, chip->oob_poi, oobsize);
-
- chip->cmdfunc(mtd, 0x11, -1, -1); /* send cmd 0x11 */
- ndelay(100);
- while(!chip->dev_ready(mtd));
-
- page += ppb;
- chip->cmdfunc(mtd, 0x81, 0x00, page); /* send cmd 0x81 */
- eccsteps = chip->ecc.steps >> 1;
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
- chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
- chip->write_buf(mtd, p, eccsize);
- chip->ecc.calculate(mtd, p, &ecc_calc[i]);
- }
-
- for (i = 0; i < ecctotal; i++)
- chip->oob_poi[eccpos[i]] = ecc_calc[i];
-
- chip->write_buf(mtd, chip->oob_poi, oobsize);
-}
-
-static void single_erase_cmd_planes(struct mtd_info *mtd, int global_page)
-{
- struct nand_chip *chip = mtd->priv;
-
- /* Send commands to erase a block */
- int page;
- int ppb = mtd->erasesize / mtd->writesize;
-
- page = (global_page / ppb) * ppb + global_page; /* = global_page%ppb + (global_page/ppb)*ppb*2 */
-
- /* send cmd 0x60, the MSB should be valid if realplane is 4 */
- if (chip->realplanenum == 2)
- chip->cmdfunc(mtd, 0x60, -1, 0x00);
- else
- chip->cmdfunc(mtd, 0x60, -1, page & (1 << (chip->chip_shift - chip->page_shift)));
-
- page += ppb;
- chip->cmdfunc(mtd, 0x60, -1, page & (~(ppb-1))); /* send cmd 0x60 */
-
- chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1); /* send cmd 0xd0 */
- /* Do not need wait R/B or check status */
-}
-
-/*
- * Main initialization routine
- */
-int __init jznand_init(void)
-{
- struct nand_chip *this;
- int nr_partitions, ret, i;
-
- /* Allocate memory for MTD device structure and private data */
- jz_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
- GFP_KERNEL);
- if (!jz_mtd) {
- printk ("Unable to allocate JzSOC NAND MTD device structure.\n");
- return -ENOMEM;
- }
-
- jz_mtd1 = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
- GFP_KERNEL);
- if (!jz_mtd1) {
- printk ("Unable to allocate JzSOC NAND MTD device structure 1.\n");
- kfree(jz_mtd);
- return -ENOMEM;
- }
-
- /* Get pointer to private data */
- this = (struct nand_chip *) (&jz_mtd[1]);
-
- /* Initialize structures */
- memset((char *) jz_mtd, 0, sizeof(struct mtd_info));
- memset((char *) this, 0, sizeof(struct nand_chip));
-
- /* Link the private data with the MTD structure */
- jz_mtd->priv = this;
-
- /* Set & initialize NAND Flash controller */
- jz_device_setup();
-
- /* Set address of NAND IO lines */
- this->IO_ADDR_R = (void __iomem *) NAND_DATA_PORT1;
- this->IO_ADDR_W = (void __iomem *) NAND_DATA_PORT1;
- this->cmd_ctrl = jz_hwcontrol;
- this->dev_ready = jz_device_ready;
-
-#ifdef CONFIG_MTD_HW_HM_ECC
- this->ecc.calculate = jzsoc_nand_calculate_hm_ecc;
- this->ecc.correct = jzsoc_nand_hm_correct_data;
- this->ecc.hwctl = jzsoc_nand_enable_hm_hwecc;
- this->ecc.mode = NAND_ECC_HW;
- this->ecc.size = 256;
- this->ecc.bytes = 3;
-
-#endif
-
-#ifdef CONFIG_MTD_HW_RS_ECC
- this->ecc.calculate = jzsoc_nand_calculate_rs_ecc;
- this->ecc.correct = jzsoc_nand_rs_correct_data;
- this->ecc.hwctl = jzsoc_nand_enable_rs_hwecc;
- this->ecc.mode = NAND_ECC_HW;
- this->ecc.size = 512;
- this->ecc.bytes = 9;
-#endif
-
-#ifdef CONFIG_MTD_SW_HM_ECC
- this->ecc.mode = NAND_ECC_SOFT;
-#endif
- /* 20 us command delay time */
- this->chip_delay = 20;
-
- dma_setup();
-
- /* Scan to find existance of the device */
- ret = nand_scan_ident(jz_mtd, NAND_MAX_CHIPS);
- if (!ret) {
- if (this->planenum == 2) {
- /* reset nand functions */
- this->erase_cmd = single_erase_cmd_planes;
- this->ecc.read_page = nand_read_page_hwecc_rs_planes; //Muti planes read
- this->ecc.write_page = nand_write_page_hwecc_planes;
- this->ecc.read_oob = nand_read_oob_std_planes;
- this->ecc.write_oob = nand_write_oob_std_planes;
- this->write_buf = jz4740_nand_write_buf;
- this->read_buf = jz4740_nand_read_buf;
-
- printk(KERN_INFO "Nand using two-plane mode, "
- "and resized to writesize:%d oobsize:%d blocksize:0x%x \n",
- jz_mtd->writesize, jz_mtd->oobsize, jz_mtd->erasesize);
- } else
- return -ENXIO;
- }
-
- /* Determine whether all the partitions will use multiple planes if supported */
- nr_partitions = sizeof(partition_info) / sizeof(struct mtd_partition);
- all_use_planes = 1;
- for (i = 0; i < nr_partitions; i++) {
- all_use_planes &= partition_info[i].use_planes;
- }
-
- if (!ret)
- ret = nand_scan_tail(jz_mtd);
-
- if (ret){
- kfree (jz_mtd1);
- kfree (jz_mtd);
- return -ENXIO;
- }
-
- /* Register the partitions */
- printk (KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nr_partitions, jz_mtd->name);
-
- if ((this->planenum == 2) && !all_use_planes) {
- for (i = 0; i < nr_partitions; i++) {
- if (partition_info[i].use_planes)
- add_mtd_partitions(jz_mtd, &partition_info[i], 1);
- else
- add_mtd_partitions(jz_mtd1, &partition_info[i], 1);
- }
- } else {
- kfree(jz_mtd1);
- add_mtd_partitions(jz_mtd, partition_info, nr_partitions);
- }
- return 0;
-}
-module_init(jznand_init);
-
-/*
- * Clean up routine
- */
-#ifdef MODULE
-static void __exit jznand_cleanup(void)
-{
- struct nand_chip *this = (struct nand_chip *) &jz_mtd[1];
-
- /* Unregister partitions */
- del_mtd_partitions(jz_mtd);
-
- /* Unregister the device */
- del_mtd_device (jz_mtd);
-
- /* Free internal data buffers */
- kfree (this->data_buf);
-
- /* Free the MTD device structure */
- if ((this->planenum == 2) && !all_use_planes)
- kfree (jz_mtd1);
- kfree (jz_mtd);
-}
-module_exit(jznand_cleanup);
-#endif
+/*
+ * linux/drivers/mtd/nand/jz4740_nand.c
+ *
+ * Copyright (c) 2005 - 2007 Ingenic Semiconductor Inc.
+ *
+ * Ingenic JZ4740 NAND driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/highmem.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/io.h>
+#include <asm/jzsoc.h>
+
+#define NAND_DATA_PORT1 0xB8000000 /* read-write area in static bank 1 */
+#define NAND_DATA_PORT2 0xB4000000 /* read-write area in static bank 2 */
+#define NAND_DATA_PORT3 0xAC000000 /* read-write area in static bank 3 */
+#define NAND_DATA_PORT4 0xA8000000 /* read-write area in static bank 4 */
+
+#define PAR_SIZE 9
+
+#define __nand_enable() (REG_EMC_NFCSR |= EMC_NFCSR_NFE1 | EMC_NFCSR_NFCE1)
+#define __nand_disable() (REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE1)
+
+#define __nand_ecc_enable() (REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST )
+#define __nand_ecc_disable() (REG_EMC_NFECR &= ~EMC_NFECR_ECCE)
+
+#define __nand_select_hm_ecc() (REG_EMC_NFECR &= ~EMC_NFECR_RS )
+#define __nand_select_rs_ecc() (REG_EMC_NFECR |= EMC_NFECR_RS)
+
+#define __nand_read_hm_ecc() (REG_EMC_NFECC & 0x00ffffff)
+
+#define __nand_rs_ecc_encoding() (REG_EMC_NFECR |= EMC_NFECR_RS_ENCODING)
+#define __nand_rs_ecc_decoding() (REG_EMC_NFECR &= ~EMC_NFECR_RS_ENCODING)
+#define __nand_ecc_encode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_ENCF))
+#define __nand_ecc_decode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_DECF))
+
+/*
+ * MTD structure for JzSOC board
+ */
+static struct mtd_info *jz_mtd = NULL;
+extern struct mtd_info *jz_mtd1;
+extern char all_use_planes;
+extern int global_page; /* for two-plane operations */
+
+/*
+ * Define partitions for flash devices
+ */
+#ifdef CONFIG_JZ4740_PAVO
+static struct mtd_partition partition_info[] = {
+ { name: "NAND BOOT partition",
+ offset: 0 * 0x100000,
+ size: 4 * 0x100000,
+ use_planes: 0 },
+ { name: "NAND KERNEL partition",
+ offset: 4 * 0x100000,
+ size: 4 * 0x100000,
+ use_planes: 0 },
+ { name: "NAND ROOTFS partition",
+ offset: 8 * 0x100000,
+ size: 120 * 0x100000,
+ use_planes: 0 },
+ { name: "NAND DATA1 partition",
+ offset: 128 * 0x100000,
+ size: 128 * 0x100000,
+ use_planes: 1 },
+ { name: "NAND DATA2 partition",
+ offset: 256 * 0x100000,
+ size: 256 * 0x100000,
+ use_planes: 1 },
+ { name: "NAND VFAT partition",
+ offset: 512 * 0x100000,
+ size: 512 * 0x100000,
+ use_planes: 1 },
+};
+
+
+/* Define max reserved bad blocks for each partition.
+ * This is used by the mtdblock-jz.c NAND FTL driver only.
+ *
+ * The NAND FTL driver reserves some good blocks which can't be
+ * seen by the upper layer. When the bad block number of a partition
+ * exceeds the max reserved blocks, then there is no more reserved
+ * good blocks to be used by the NAND FTL driver when another bad
+ * block generated.
+ */
+static int partition_reserved_badblocks[] = {
+ 2, /* reserved blocks of mtd0 */
+ 2, /* reserved blocks of mtd1 */
+ 10, /* reserved blocks of mtd2 */
+ 10, /* reserved blocks of mtd3 */
+ 20, /* reserved blocks of mtd4 */
+ 20}; /* reserved blocks of mtd5 */
+#endif /* CONFIG_JZ4740_PAVO */
+
+#ifdef CONFIG_JZ4740_PI
+static struct mtd_partition partition_info[] = {
+ { name: "NAND BOOT partition",
+ offset: 0 * 0x100000,
+ size: 4 * 0x100000,
+ use_planes: 0 },
+ { name: "NAND KERNEL partition",
+ offset: 4 * 0x100000,
+ size: 4 * 0x100000,
+ use_planes: 0 },
+ { name: "NAND ROOTFS partition",
+ offset: 8 * 0x100000,
+ size: 120 * 0x100000,
+ use_planes: 0 },
+ { name: "NAND DATA1 partition",
+ offset: 128 * 0x100000,
+ size: 128 * 0x100000,
+ use_planes: 1 },
+ { name: "NAND DATA2 partition",
+ offset: 256 * 0x100000,
+ size: 256 * 0x100000,
+ use_planes: 1 },
+ { name: "NAND VFAT partition",
+ offset: 512 * 0x100000,
+ size: 512 * 0x100000,
+ use_planes: 1 },
+};
+
+
+/* Define max reserved bad blocks for each partition.
+ * This is used by the mtdblock-jz.c NAND FTL driver only.
+ *
+ * The NAND FTL driver reserves some good blocks which can't be
+ * seen by the upper layer. When the bad block number of a partition
+ * exceeds the max reserved blocks, then there is no more reserved
+ * good blocks to be used by the NAND FTL driver when another bad
+ * block generated.
+ */
+static int partition_reserved_badblocks[] = {
+ 2, /* reserved blocks of mtd0 */
+ 2, /* reserved blocks of mtd1 */
+ 10, /* reserved blocks of mtd2 */
+ 10, /* reserved blocks of mtd3 */
+ 20, /* reserved blocks of mtd4 */
+ 20}; /* reserved blocks of mtd5 */
+#endif /* CONFIG_JZ4740_PI */
+
+
+#ifdef CONFIG_JZ4740_LEO
+static struct mtd_partition partition_info[] = {
+ { name: "NAND BOOT partition",
+ offset: 0 * 0x100000,
+ size: 4 * 0x100000 },
+ { name: "NAND KERNEL partition",
+ offset: 4 * 0x100000,
+ size: 4 * 0x100000 },
+ { name: "NAND ROOTFS partition",
+ offset: 8 * 0x100000,
+ size: 56 * 0x100000 },
+ { name: "NAND VFAT partition",
+ offset: 64 * 0x100000,
+ size: 64 * 0x100000 },
+};
+static int partition_reserved_badblocks[] = {
+ 2, /* reserved blocks of mtd0 */
+ 2, /* reserved blocks of mtd1 */
+ 10, /* reserved blocks of mtd2 */
+ 10}; /* reserved blocks of mtd3 */
+#endif /* CONFIG_JZ4740_LEO */
+
+#ifdef CONFIG_JZ4740_LYRA
+static struct mtd_partition partition_info[] = {
+ { name: "NAND BOOT partition",
+ offset: 0 * 0x100000,
+ size: 4 * 0x100000 },
+ { name: "NAND KERNEL partition",
+ offset: 4 * 0x100000,
+ size: 4 * 0x100000 },
+ { name: "NAND ROOTFS partition",
+ offset: 8 * 0x100000,
+ size: 120 * 0x100000 },
+ { name: "NAND DATA1 partition",
+ offset: 128 * 0x100000,
+ size: 128 * 0x100000 },
+ { name: "NAND DATA2 partition",
+ offset: 256 * 0x100000,
+ size: 256 * 0x100000 },
+ { name: "NAND VFAT partition",
+ offset: 512 * 0x100000,
+ size: 512 * 0x100000 },
+};
+
+/* Define max reserved bad blocks for each partition.
+ * This is used by the mtdblock-jz.c NAND FTL driver only.
+ *
+ * The NAND FTL driver reserves some good blocks which can't be
+ * seen by the upper layer. When the bad block number of a partition
+ * exceeds the max reserved blocks, then there is no more reserved
+ * good blocks to be used by the NAND FTL driver when another bad
+ * block generated.
+ */
+static int partition_reserved_badblocks[] = {
+ 2, /* reserved blocks of mtd0 */
+ 2, /* reserved blocks of mtd1 */
+ 10, /* reserved blocks of mtd2 */
+ 10, /* reserved blocks of mtd3 */
+ 20, /* reserved blocks of mtd4 */
+ 20}; /* reserved blocks of mtd5 */
+#endif /* CONFIG_JZ4740_LYRA */
+
+#ifdef CONFIG_JZ4725_DIPPER
+static struct mtd_partition partition_info[] = {
+ { name: "NAND BOOT partition",
+ offset: 0 * 0x100000,
+ size: 4 * 0x100000 },
+ { name: "NAND KERNEL partition",
+ offset: 4 * 0x100000,
+ size: 4 * 0x100000 },
+ { name: "NAND ROOTFS partition",
+ offset: 8 * 0x100000,
+ size: 56 * 0x100000 },
+ { name: "NAND VFAT partition",
+ offset: 64 * 0x100000,
+ size: 64 * 0x100000 },
+};
+
+/* Define max reserved bad blocks for each partition.
+ * This is used by the mtdblock-jz.c NAND FTL driver only.
+ *
+ * The NAND FTL driver reserves some good blocks which can't be
+ * seen by the upper layer. When the bad block number of a partition
+ * exceeds the max reserved blocks, then there is no more reserved
+ * good blocks to be used by the NAND FTL driver when another bad
+ * block generated.
+ */
+static int partition_reserved_badblocks[] = {
+ 2, /* reserved blocks of mtd0 */
+ 2, /* reserved blocks of mtd1 */
+ 10, /* reserved blocks of mtd2 */
+ 10}; /* reserved blocks of mtd3 */
+#endif /* CONFIG_JZ4740_DIPPER */
+
+#ifdef CONFIG_JZ4720_VIRGO
+static struct mtd_partition partition_info[] = {
+ { name: "NAND BOOT partition",
+ offset: 0 * 0x100000,
+ size: 4 * 0x100000 },
+ { name: "NAND KERNEL partition",
+ offset: 4 * 0x100000,
+ size: 4 * 0x100000 },
+ { name: "NAND ROOTFS partition",
+ offset: 8 * 0x100000,
+ size: 120 * 0x100000 },
+ { name: "NAND DATA1 partition",
+ offset: 128 * 0x100000,
+ size: 128 * 0x100000 },
+ { name: "NAND DATA2 partition",
+ offset: 256 * 0x100000,
+ size: 256 * 0x100000 },
+ { name: "NAND VFAT partition",
+ offset: 512 * 0x100000,
+ size: 512 * 0x100000 },
+};
+
+
+/* Define max reserved bad blocks for each partition.
+ * This is used by the mtdblock-jz.c NAND FTL driver only.
+ *
+ * The NAND FTL driver reserves some good blocks which can't be
+ * seen by the upper layer. When the bad block number of a partition
+ * exceeds the max reserved blocks, then there is no more reserved
+ * good blocks to be used by the NAND FTL driver when another bad
+ * block generated.
+ */
+static int partition_reserved_badblocks[] = {
+ 2, /* reserved blocks of mtd0 */
+ 2, /* reserved blocks of mtd1 */
+ 10, /* reserved blocks of mtd2 */
+ 10, /* reserved blocks of mtd3 */
+ 20, /* reserved blocks of mtd4 */
+ 20}; /* reserved blocks of mtd5 */
+#endif /* CONFIG_JZ4720_VIRGO */
+/*-------------------------------------------------------------------------
+ * Following three functions are exported and used by the mtdblock-jz.c
+ * NAND FTL driver only.
+ */
+
+unsigned short get_mtdblock_write_verify_enable(void)
+{
+#ifdef CONFIG_MTD_MTDBLOCK_WRITE_VERIFY_ENABLE
+ return 1;
+#endif
+ return 0;
+}
+EXPORT_SYMBOL(get_mtdblock_write_verify_enable);
+
+unsigned short get_mtdblock_oob_copies(void)
+{
+ return CONFIG_MTD_OOB_COPIES;
+}
+EXPORT_SYMBOL(get_mtdblock_oob_copies);
+
+int *get_jz_badblock_table(void)
+{
+ return partition_reserved_badblocks;
+}
+EXPORT_SYMBOL(get_jz_badblock_table);
+
+/*-------------------------------------------------------------------------*/
+
+static void jz_hwcontrol(struct mtd_info *mtd, int dat,
+ unsigned int ctrl)
+{
+ struct nand_chip *this = (struct nand_chip *)(mtd->priv);
+ unsigned int nandaddr = (unsigned int)this->IO_ADDR_W;
+ extern u8 nand_nce; /* in nand_base.c, indicates which chip select is used for current nand chip */
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ if (ctrl & NAND_NCE) {
+ switch (nand_nce) {
+ case NAND_NCE1:
+ this->IO_ADDR_W = this->IO_ADDR_R = (void __iomem *)NAND_DATA_PORT1;
+ REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE2;
+ REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE3;
+ REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE4;
+ REG_EMC_NFCSR |= EMC_NFCSR_NFCE1;
+ break;
+ case NAND_NCE2:
+ this->IO_ADDR_W = this->IO_ADDR_R = (void __iomem *)NAND_DATA_PORT2;
+ REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE1;
+ REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE3;
+ REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE4;
+ REG_EMC_NFCSR |= EMC_NFCSR_NFCE2;
+ break;
+ case NAND_NCE3:
+ this->IO_ADDR_W = this->IO_ADDR_R = (void __iomem *)NAND_DATA_PORT3;
+ REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE1;
+ REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE2;
+ REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE4;
+ REG_EMC_NFCSR |= EMC_NFCSR_NFCE3;
+ break;
+ case NAND_NCE4:
+ this->IO_ADDR_W = this->IO_ADDR_R = (void __iomem *)NAND_DATA_PORT4;
+ REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE1;
+ REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE2;
+ REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE3;
+ REG_EMC_NFCSR |= EMC_NFCSR_NFCE4;
+ break;
+ default:
+ printk("error: no nand_nce 0x%x\n",nand_nce);
+ break;
+ }
+ } else {
+ REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE1;
+ REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE2;
+ REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE3;
+ REG_EMC_NFCSR &= ~EMC_NFCSR_NFCE4;
+ }
+
+ if ( ctrl & NAND_ALE )
+ nandaddr = (unsigned int)((unsigned long)(this->IO_ADDR_W) | 0x00010000);
+ else
+ nandaddr = (unsigned int)((unsigned long)(this->IO_ADDR_W) & ~0x00010000);
+
+ if ( ctrl & NAND_CLE )
+ nandaddr = nandaddr | 0x00008000;
+ else
+ nandaddr = nandaddr & ~0x00008000;
+ }
+
+ this->IO_ADDR_W = (void __iomem *)nandaddr;
+ if (dat != NAND_CMD_NONE)
+ writeb(dat, this->IO_ADDR_W);
+}
+
+static int jz_device_ready(struct mtd_info *mtd)
+{
+ int ready, wait = 10;
+ while (wait--);
+ ready = __gpio_get_pin(94);
+ return ready;
+}
+
+/*
+ * EMC setup
+ */
+static void jz_device_setup(void)
+{
+// PORT 0:
+// ...
+// PORT 1:
+// PIN/BIT N FUNC0 FUNC1
+// 25 CS1# -
+// 26 CS2# -
+// 27 CS3# -
+// 28 CS4# -
+#define GPIO_CS2_N (32+26)
+#define GPIO_CS3_N (32+27)
+#define GPIO_CS4_N (32+28)
+#define SMCR_VAL 0x0d221200
+
+ /* Set NFE bit */
+ REG_EMC_NFCSR |= EMC_NFCSR_NFE1;
+ /* Read/Write timings */
+ REG_EMC_SMCR1 = SMCR_VAL;
+
+#if defined(CONFIG_MTD_NAND_CS2)
+ /* Set CS2# pin as function 0 */
+ __gpio_as_func0(GPIO_CS2_N);
+ REG_EMC_NFCSR |= EMC_NFCSR_NFE2;
+ REG_EMC_SMCR2 = SMCR_VAL;
+#endif
+
+#if defined(CONFIG_MTD_NAND_CS3)
+ __gpio_as_func0(GPIO_CS3_N);
+ REG_EMC_NFCSR |= EMC_NFCSR_NFE3;
+ REG_EMC_SMCR3 = SMCR_VAL;
+#endif
+
+#if defined(CONFIG_MTD_NAND_CS4)
+ __gpio_as_func0(GPIO_CS4_N);
+ REG_EMC_NFCSR |= EMC_NFCSR_NFE4;
+ REG_EMC_SMCR4 = SMCR_VAL;
+#endif
+}
+
+#ifdef CONFIG_MTD_HW_HM_ECC
+
+static int jzsoc_nand_calculate_hm_ecc(struct mtd_info* mtd,
+ const u_char* dat, u_char* ecc_code)
+{
+ unsigned int calc_ecc;
+ unsigned char *tmp;
+
+ __nand_ecc_disable();
+
+ calc_ecc = ~(__nand_read_hm_ecc()) | 0x00030000;
+
+ tmp = (unsigned char *)&calc_ecc;
+ //adjust eccbytes order for compatible with software ecc
+ ecc_code[0] = tmp[1];
+ ecc_code[1] = tmp[0];
+ ecc_code[2] = tmp[2];
+
+ return 0;
+}
+
+static void jzsoc_nand_enable_hm_hwecc(struct mtd_info* mtd, int mode)
+{
+ __nand_ecc_enable();
+ __nand_select_hm_ecc();
+}
+
+static int jzsoc_nand_hm_correct_data(struct mtd_info *mtd, u_char *dat,
+ u_char *read_ecc, u_char *calc_ecc)
+{
+ u_char a, b, c, d1, d2, d3, add, bit, i;
+
+ /* Do error detection */
+ d1 = calc_ecc[0] ^ read_ecc[0];
+ d2 = calc_ecc[1] ^ read_ecc[1];
+ d3 = calc_ecc[2] ^ read_ecc[2];
+
+ if ((d1 | d2 | d3) == 0) {
+ /* No errors */
+ return 0;
+ }
+ else {
+ a = (d1 ^ (d1 >> 1)) & 0x55;
+ b = (d2 ^ (d2 >> 1)) & 0x55;
+ c = (d3 ^ (d3 >> 1)) & 0x54;
+
+ /* Found and will correct single bit error in the data */
+ if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
+ c = 0x80;
+ add = 0;
+ a = 0x80;
+ for (i=0; i<4; i++) {
+ if (d1 & c)
+ add |= a;
+ c >>= 2;
+ a >>= 1;
+ }
+ c = 0x80;
+ for (i=0; i<4; i++) {
+ if (d2 & c)
+ add |= a;
+ c >>= 2;
+ a >>= 1;
+ }
+ bit = 0;
+ b = 0x04;
+ c = 0x80;
+ for (i=0; i<3; i++) {
+ if (d3 & c)
+ bit |= b;
+ c >>= 2;
+ b >>= 1;
+ }
+ b = 0x01;
+ a = dat[add];
+ a ^= (b << bit);
+ dat[add] = a;
+ return 0;
+ }
+ else {
+ i = 0;
+ while (d1) {
+ if (d1 & 0x01)
+ ++i;
+ d1 >>= 1;
+ }
+ while (d2) {
+ if (d2 & 0x01)
+ ++i;
+ d2 >>= 1;
+ }
+ while (d3) {
+ if (d3 & 0x01)
+ ++i;
+ d3 >>= 1;
+ }
+ if (i == 1) {
+ /* ECC Code Error Correction */
+ read_ecc[0] = calc_ecc[0];
+ read_ecc[1] = calc_ecc[1];
+ read_ecc[2] = calc_ecc[2];
+ return 0;
+ }
+ else {
+ /* Uncorrectable Error */
+ printk("NAND: uncorrectable ECC error\n");
+ return -1;
+ }
+ }
+ }
+
+ /* Should never happen */
+ return -1;
+}
+
+#endif /* CONFIG_MTD_HW_HM_ECC */
+
+#ifdef CONFIG_MTD_HW_RS_ECC
+
+static void jzsoc_nand_enable_rs_hwecc(struct mtd_info* mtd, int mode)
+{
+ REG_EMC_NFINTS = 0x0;
+ __nand_ecc_enable();
+ __nand_select_rs_ecc();
+
+ if (mode == NAND_ECC_READ)
+ __nand_rs_ecc_decoding();
+
+ if (mode == NAND_ECC_WRITE)
+ __nand_rs_ecc_encoding();
+}
+
+static void jzsoc_rs_correct(unsigned char *dat, int idx, int mask)
+{
+ int i;
+
+ idx--;
+
+ i = idx + (idx >> 3);
+ if (i >= 512)
+ return;
+
+ mask <<= (idx & 0x7);
+
+ dat[i] ^= mask & 0xff;
+ if (i < 511)
+ dat[i+1] ^= (mask >> 8) & 0xff;
+}
+
+/*
+ * calc_ecc points to oob_buf for us
+ */
+static int jzsoc_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat,
+ u_char *read_ecc, u_char *calc_ecc)
+{
+ volatile u8 *paraddr = (volatile u8 *)EMC_NFPAR0;
+ short k;
+ u32 stat;
+
+ /* Set PAR values */
+ for (k = 0; k < PAR_SIZE; k++) {
+ *paraddr++ = read_ecc[k];
+ }
+
+ /* Set PRDY */
+ REG_EMC_NFECR |= EMC_NFECR_PRDY;
+
+ /* Wait for completion */
+ __nand_ecc_decode_sync();
+ __nand_ecc_disable();
+
+ /* Check decoding */
+ stat = REG_EMC_NFINTS;
+
+ if (stat & EMC_NFINTS_ERR) {
+ /* Error occurred */
+ if (stat & EMC_NFINTS_UNCOR) {
+ printk("NAND: Uncorrectable ECC error\n");
+ return -1;
+ } else {
+ u32 errcnt = (stat & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT;
+ switch (errcnt) {
+ case 4:
+ jzsoc_rs_correct(dat, (REG_EMC_NFERR3 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, (REG_EMC_NFERR3 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT);
+ /* FALL-THROUGH */
+ case 3:
+ jzsoc_rs_correct(dat, (REG_EMC_NFERR2 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, (REG_EMC_NFERR2 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT);
+ /* FALL-THROUGH */
+ case 2:
+ jzsoc_rs_correct(dat, (REG_EMC_NFERR1 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, (REG_EMC_NFERR1 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT);
+ /* FALL-THROUGH */
+ case 1:
+ jzsoc_rs_correct(dat, (REG_EMC_NFERR0 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, (REG_EMC_NFERR0 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT);
+ return 0;
+ default:
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int jzsoc_nand_calculate_rs_ecc(struct mtd_info* mtd, const u_char* dat,
+ u_char* ecc_code)
+{
+ volatile u8 *paraddr = (volatile u8 *)EMC_NFPAR0;
+ short i;
+
+ __nand_ecc_encode_sync();
+ __nand_ecc_disable();
+
+ for(i = 0; i < PAR_SIZE; i++) {
+ ecc_code[i] = *paraddr++;
+ }
+
+ return 0;
+}
+
+#endif /* CONFIG_MTD_HW_RS_ECC */
+
+/* Nand optimized functions */
+static int dma_chan;
+static unsigned int dma_src_phys_addr, dma_dst_phys_addr;
+extern int jz_request_dma(int dev_id, const char *dev_str,
+ irqreturn_t (*irqhandler)(int, void *),
+ unsigned long irqflags, void *irq_dev_id);
+
+static void dma_setup(void)
+{
+ /* Request DMA channel and setup irq handler */
+ dma_chan = jz_request_dma(DMA_ID_AUTO, "auto", NULL, IRQF_DISABLED, NULL);
+ if (dma_chan < 0) {
+ printk("Setup irq for nand failed!\n");
+ return;
+ } else
+ printk("Nand DMA request channel %d.\n",dma_chan);
+}
+
+static void jz4740_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+ int i;
+ struct nand_chip *chip = mtd->priv;
+
+ if ((len <= 32) || (len & 0xf) || ((u32)buf >= (u32)high_memory))
+ {
+ for (i = 0; i < len; i++)
+ buf[i] = readb(chip->IO_ADDR_R);
+ } else {
+ REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO;
+ dma_src_phys_addr = CPHYSADDR(chip->IO_ADDR_R);
+ dma_dst_phys_addr = CPHYSADDR(buf);
+ dma_cache_inv((u32)buf, len);
+ REG_DMAC_DSAR(dma_chan) = dma_src_phys_addr;
+ REG_DMAC_DTAR(dma_chan) = dma_dst_phys_addr;
+ REG_DMAC_DTCR(dma_chan) = len / 16;
+ REG_DMAC_DCMD(dma_chan) = DMAC_DCMD_DAI | DMAC_DCMD_SWDH_8 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_16BYTE;
+ REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN;
+ REG_DMAC_DMACR = DMAC_DMACR_DMAE; /* global DMA enable bit */
+
+ while(!(REG_DMAC_DCCSR(dma_chan) & DMAC_DCCSR_TT));
+ REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */
+ __dmac_channel_clear_transmit_end(dma_chan);
+ }
+}
+
+static void jz4740_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+ int i;
+ struct nand_chip *chip = mtd->priv;
+
+ if ((len <= 32) || (len & 0xf) || ((u32)buf >= (u32)high_memory))
+ {
+ for (i = 0; i < len; i++)
+ writeb(buf[i], chip->IO_ADDR_W);
+ } else {
+ REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO;
+ dma_dst_phys_addr = CPHYSADDR(chip->IO_ADDR_R);
+ dma_src_phys_addr = CPHYSADDR(buf);
+ dma_cache_wback((unsigned long)buf, len);
+ REG_DMAC_DSAR(dma_chan) = dma_src_phys_addr;
+ REG_DMAC_DTAR(dma_chan) = dma_dst_phys_addr;
+ REG_DMAC_DTCR(dma_chan) = len / 16;
+ REG_DMAC_DCMD(dma_chan) = DMAC_DCMD_SAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_8 | DMAC_DCMD_DS_16BYTE ;
+ REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN;
+ REG_DMAC_DMACR = DMAC_DMACR_DMAE; /* global DMA enable bit */
+
+ while(!(REG_DMAC_DCCSR(dma_chan) & DMAC_DCCSR_TT));
+ REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */
+ __dmac_channel_clear_transmit_end(dma_chan);
+ }
+}
+
+static int nand_read_page_hwecc_rs_planes(struct mtd_info *mtd, struct nand_chip *chip,
+ uint8_t *buf)
+{
+ int i, eccsize = chip->ecc.size;
+ int eccbytes = chip->ecc.bytes;
+ int eccsteps = chip->ecc.steps >> 1;
+ uint8_t *p;
+ uint8_t *ecc_calc = chip->buffers->ecccalc;
+ uint8_t *ecc_code = chip->buffers->ecccode;
+ uint32_t *eccpos = chip->ecc.layout->eccpos;
+ uint32_t page;
+ uint8_t flag = 0;
+ int oobsize = mtd->oobsize >> 1;
+ int ppb = mtd->erasesize / mtd->writesize;
+ int ecctotal = chip->ecc.total >> 1;
+
+ page = (global_page / ppb) * ppb + global_page; /* = global_page%ppb + (global_page/ppb)*ppb*2 */
+
+ /* Read first page */
+ chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
+ chip->read_buf(mtd, chip->oob_poi, oobsize);
+ for (i = 0; i < ecctotal; i++) {
+ ecc_code[i] = chip->oob_poi[eccpos[i]];
+ if (ecc_code[i] != 0xff) flag = 1;
+ }
+
+ p = buf;
+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, 0x00, -1);
+ for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+ int stat;
+ if (flag) {
+ chip->ecc.hwctl(mtd, NAND_ECC_READ);
+ chip->read_buf(mtd, p, eccsize);
+ stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
+ if (stat < 0)
+ mtd->ecc_stats.failed++;
+ else
+ mtd->ecc_stats.corrected += stat;
+ }
+ else {
+ chip->ecc.hwctl(mtd, NAND_ECC_READ);
+ chip->read_buf(mtd, p, eccsize);
+ }
+ }
+ /* Read second page */
+ page += ppb;
+ flag = 0;
+ chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
+ chip->read_buf(mtd, chip->oob_poi + oobsize, oobsize);
+ for (i = 0; i < ecctotal; i++) {
+ ecc_code[i] = chip->oob_poi[oobsize + eccpos[i]];
+ if (ecc_code[i] != 0xff) flag = 1;
+ }
+
+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, 0x00, -1);
+ eccsteps = chip->ecc.steps >> 1;
+ for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+ int stat;
+ if (flag) {
+ chip->ecc.hwctl(mtd, NAND_ECC_READ);
+ chip->read_buf(mtd, p, eccsize);
+ stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
+ if (stat < 0)
+ mtd->ecc_stats.failed++;
+ else
+ mtd->ecc_stats.corrected += stat;
+ }
+ else {
+ chip->ecc.hwctl(mtd, NAND_ECC_READ);
+ chip->read_buf(mtd, p, eccsize);
+ }
+ }
+
+ return 0;
+}
+
+static int nand_read_oob_std_planes(struct mtd_info *mtd, struct nand_chip *chip,
+ int global_page, int sndcmd)
+{
+ int page;
+ int oobsize = mtd->oobsize >> 1;
+ int ppb = mtd->erasesize / mtd->writesize;
+
+ page = (global_page / ppb) * ppb + global_page; /* = global_page%ppb + (global_page/ppb)*ppb*2 */
+
+ /* Read first page OOB */
+ if (sndcmd) {
+ chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
+ }
+ chip->read_buf(mtd, chip->oob_poi, oobsize);
+ /* Read second page OOB */
+ page += ppb;
+ if (sndcmd) {
+ chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
+ sndcmd = 0;
+ }
+ chip->read_buf(mtd, chip->oob_poi+oobsize, oobsize);
+ return 0;
+}
+
+static int nand_write_oob_std_planes(struct mtd_info *mtd, struct nand_chip *chip,
+ int global_page)
+{
+ int status = 0,page;
+ int pagesize = mtd->writesize >> 1;
+ int oobsize = mtd->oobsize >> 1;
+ int ppb = mtd->erasesize / mtd->writesize;
+ const uint8_t *buf = chip->oob_poi;
+
+ page = (global_page / ppb) * ppb + global_page; /* = global_page%ppb + (global_page/ppb)*ppb*2 */
+
+ /* send cmd 0x80, the MSB should be valid if realplane is 4 */
+ if (chip->realplanenum == 2)
+ chip->cmdfunc(mtd, 0x80, pagesize, 0x00);
+ else
+ chip->cmdfunc(mtd, 0x80, pagesize, page & (1 << (chip->chip_shift - chip->page_shift)));
+
+ chip->write_buf(mtd, buf, oobsize);
+ /* Send first command to program the OOB data */
+ chip->cmdfunc(mtd, 0x11, -1, -1);
+ ndelay(100);
+ status = chip->waitfunc(mtd, chip);
+
+ page += ppb;
+ buf += oobsize;
+ chip->cmdfunc(mtd, 0x81, pagesize, page);
+ chip->write_buf(mtd, buf, oobsize);
+ /* Send command to program the OOB data */
+ chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
+ /* Wait long R/B */
+ ndelay(100);
+ status = chip->waitfunc(mtd, chip);
+
+ return status & NAND_STATUS_FAIL ? -EIO : 0;
+}
+
+static void nand_write_page_hwecc_planes(struct mtd_info *mtd, struct nand_chip *chip,
+ const uint8_t *buf)
+{
+ int i, eccsize = chip->ecc.size;
+ int eccbytes = chip->ecc.bytes;
+ int eccsteps = chip->ecc.steps >> 1;
+ uint8_t *ecc_calc = chip->buffers->ecccalc;
+ uint8_t *p = (uint8_t *)buf;
+ uint32_t *eccpos = chip->ecc.layout->eccpos;
+ int oobsize = mtd->oobsize >> 1;
+ int ppb = mtd->erasesize / mtd->writesize;
+ int ecctotal = chip->ecc.total >> 1;
+ int page;
+
+ page = (global_page / ppb) * ppb + global_page; /* = global_page%ppb + (global_page/ppb)*ppb*2 */
+
+ /* send cmd 0x80, the MSB should be valid if realplane is 4 */
+ if (chip->realplanenum == 2)
+ chip->cmdfunc(mtd, 0x80, 0x00, 0x00);
+ else
+ chip->cmdfunc(mtd, 0x80, 0x00, page & (1 << (chip->chip_shift - chip->page_shift)));
+
+ for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+ chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
+ chip->write_buf(mtd, p, eccsize);
+ chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+ }
+ for (i = 0; i < ecctotal; i++)
+ chip->oob_poi[eccpos[i]] = ecc_calc[i];
+
+ chip->write_buf(mtd, chip->oob_poi, oobsize);
+
+ chip->cmdfunc(mtd, 0x11, -1, -1); /* send cmd 0x11 */
+ ndelay(100);
+ while(!chip->dev_ready(mtd));
+
+ page += ppb;
+ chip->cmdfunc(mtd, 0x81, 0x00, page); /* send cmd 0x81 */
+ eccsteps = chip->ecc.steps >> 1;
+ for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+ chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
+ chip->write_buf(mtd, p, eccsize);
+ chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+ }
+
+ for (i = 0; i < ecctotal; i++)
+ chip->oob_poi[eccpos[i]] = ecc_calc[i];
+
+ chip->write_buf(mtd, chip->oob_poi, oobsize);
+}
+
+static void single_erase_cmd_planes(struct mtd_info *mtd, int global_page)
+{
+ struct nand_chip *chip = mtd->priv;
+
+ /* Send commands to erase a block */
+ int page;
+ int ppb = mtd->erasesize / mtd->writesize;
+
+ page = (global_page / ppb) * ppb + global_page; /* = global_page%ppb + (global_page/ppb)*ppb*2 */
+
+ /* send cmd 0x60, the MSB should be valid if realplane is 4 */
+ if (chip->realplanenum == 2)
+ chip->cmdfunc(mtd, 0x60, -1, 0x00);
+ else
+ chip->cmdfunc(mtd, 0x60, -1, page & (1 << (chip->chip_shift - chip->page_shift)));
+
+ page += ppb;
+ chip->cmdfunc(mtd, 0x60, -1, page & (~(ppb-1))); /* send cmd 0x60 */
+
+ chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1); /* send cmd 0xd0 */
+ /* Do not need wait R/B or check status */
+}
+
+/*
+ * Main initialization routine
+ */
+int __init jznand_init(void)
+{
+ struct nand_chip *this;
+ int nr_partitions, ret, i;
+
+ /* Allocate memory for MTD device structure and private data */
+ jz_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
+ GFP_KERNEL);
+ if (!jz_mtd) {
+ printk ("Unable to allocate JzSOC NAND MTD device structure.\n");
+ return -ENOMEM;
+ }
+
+ jz_mtd1 = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
+ GFP_KERNEL);
+ if (!jz_mtd1) {
+ printk ("Unable to allocate JzSOC NAND MTD device structure 1.\n");
+ kfree(jz_mtd);
+ return -ENOMEM;
+ }
+
+ /* Get pointer to private data */
+ this = (struct nand_chip *) (&jz_mtd[1]);
+
+ /* Initialize structures */
+ memset((char *) jz_mtd, 0, sizeof(struct mtd_info));
+ memset((char *) this, 0, sizeof(struct nand_chip));
+
+ /* Link the private data with the MTD structure */
+ jz_mtd->priv = this;
+
+ /* Set & initialize NAND Flash controller */
+ jz_device_setup();
+
+ /* Set address of NAND IO lines */
+ this->IO_ADDR_R = (void __iomem *) NAND_DATA_PORT1;
+ this->IO_ADDR_W = (void __iomem *) NAND_DATA_PORT1;
+ this->cmd_ctrl = jz_hwcontrol;
+ this->dev_ready = jz_device_ready;
+
+#ifdef CONFIG_MTD_HW_HM_ECC
+ this->ecc.calculate = jzsoc_nand_calculate_hm_ecc;
+ this->ecc.correct = jzsoc_nand_hm_correct_data;
+ this->ecc.hwctl = jzsoc_nand_enable_hm_hwecc;
+ this->ecc.mode = NAND_ECC_HW;
+ this->ecc.size = 256;
+ this->ecc.bytes = 3;
+
+#endif
+
+#ifdef CONFIG_MTD_HW_RS_ECC
+ this->ecc.calculate = jzsoc_nand_calculate_rs_ecc;
+ this->ecc.correct = jzsoc_nand_rs_correct_data;
+ this->ecc.hwctl = jzsoc_nand_enable_rs_hwecc;
+ this->ecc.mode = NAND_ECC_HW;
+ this->ecc.size = 512;
+ this->ecc.bytes = 9;
+#endif
+
+#ifdef CONFIG_MTD_SW_HM_ECC
+ this->ecc.mode = NAND_ECC_SOFT;
+#endif
+ /* 20 us command delay time */
+ this->chip_delay = 20;
+
+ dma_setup();
+
+ /* Scan to find existance of the device */
+ ret = nand_scan_ident(jz_mtd, NAND_MAX_CHIPS);
+ if (!ret) {
+ if (this->planenum == 2) {
+ /* reset nand functions */
+ this->erase_cmd = single_erase_cmd_planes;
+ this->ecc.read_page = nand_read_page_hwecc_rs_planes; //Muti planes read
+ this->ecc.write_page = nand_write_page_hwecc_planes;
+ this->ecc.read_oob = nand_read_oob_std_planes;
+ this->ecc.write_oob = nand_write_oob_std_planes;
+ this->write_buf = jz4740_nand_write_buf;
+ this->read_buf = jz4740_nand_read_buf;
+
+ printk(KERN_INFO "Nand using two-plane mode, "
+ "and resized to writesize:%d oobsize:%d blocksize:0x%x \n",
+ jz_mtd->writesize, jz_mtd->oobsize, jz_mtd->erasesize);
+ } else
+ return -ENXIO;
+ }
+
+ /* Determine whether all the partitions will use multiple planes if supported */
+ nr_partitions = sizeof(partition_info) / sizeof(struct mtd_partition);
+ all_use_planes = 1;
+ for (i = 0; i < nr_partitions; i++) {
+ all_use_planes &= partition_info[i].use_planes;
+ }
+
+ if (!ret)
+ ret = nand_scan_tail(jz_mtd);
+
+ if (ret){
+ kfree (jz_mtd1);
+ kfree (jz_mtd);
+ return -ENXIO;
+ }
+
+ /* Register the partitions */
+ printk (KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nr_partitions, jz_mtd->name);
+
+ if ((this->planenum == 2) && !all_use_planes) {
+ for (i = 0; i < nr_partitions; i++) {
+ if (partition_info[i].use_planes)
+ add_mtd_partitions(jz_mtd, &partition_info[i], 1);
+ else
+ add_mtd_partitions(jz_mtd1, &partition_info[i], 1);
+ }
+ } else {
+ kfree(jz_mtd1);
+ add_mtd_partitions(jz_mtd, partition_info, nr_partitions);
+ }
+ return 0;
+}
+module_init(jznand_init);
+
+/*
+ * Clean up routine
+ */
+#ifdef MODULE
+static void __exit jznand_cleanup(void)
+{
+ struct nand_chip *this = (struct nand_chip *) &jz_mtd[1];
+
+ /* Unregister partitions */
+ del_mtd_partitions(jz_mtd);
+
+ /* Unregister the device */
+ del_mtd_device (jz_mtd);
+
+ /* Free internal data buffers */
+ kfree (this->data_buf);
+
+ /* Free the MTD device structure */
+ if ((this->planenum == 2) && !all_use_planes)
+ kfree (jz_mtd1);
+ kfree (jz_mtd);
+}
+module_exit(jznand_cleanup);
+#endif
diff --git a/drivers/video/jzlcd.c b/drivers/video/jzlcd.c
index bb461fd..93b9e6f 100644
--- a/drivers/video/jzlcd.c
+++ b/drivers/video/jzlcd.c
@@ -126,15 +126,18 @@ static struct jzfb_info jzfb = {
MODE_TFT_GEN | HSYNC_N | VSYNC_N | PCLK_N | DE_N,
320, 240, 16, 60, 3, 3, 3, 3, 3, 85 /* 320x240 */
#endif
-#if defined(CONFIG_JZLCD_FOXCONN_PT035TN01) && defined(CONFIG_JZ4740_PAVO)
- MODE_TFT_GEN | HSYNC_N | VSYNC_N | MODE_TFT_18BIT | PCLK_N,
-// 320, 240, 18, 110, 1, 1, 10, 50, 10, 13
- 320, 240, 18, 80, 1, 1, 10, 50, 10, 13
-#endif
-#if defined(CONFIG_JZLCD_FOXCONN_PT035TN01) && !(defined(CONFIG_JZ4740_PAVO))
- MODE_TFT_GEN | HSYNC_N | VSYNC_N | PCLK_N,
- 320, 240, 16, 110, 1, 1, 10, 50, 10, 13
-#endif
+#if defined(CONFIG_JZLCD_FOXCONN_PT035TN01)
+ #if defined(CONFIG_JZ4740_PAVO)
+ MODE_TFT_GEN | HSYNC_N | VSYNC_N | MODE_TFT_18BIT | PCLK_N,
+ 320, 240, 18, 80, 1, 1, 10, 50, 10, 13
+ #elif defined(CONFIG_JZ4740_PI)
+ MODE_8BIT_SERIAL_TFT | PCLK_N | HSYNC_N | VSYNC_N,
+ 320, 240, 32, 70, 1, 1, 273, 140, 1, 20
+ #else
+ MODE_TFT_GEN | HSYNC_N | VSYNC_N | PCLK_N,
+ 320, 240, 16, 110, 1, 1, 10, 50, 10, 13
+ #endif
+#endif /* CONFIG_JZLCD_FOXCONN_PT035TN01 */
#if defined(CONFIG_JZLCD_INNOLUX_PT035TN01_SERIAL)
MODE_8BIT_SERIAL_TFT | PCLK_N | HSYNC_N | VSYNC_N,
320, 240, 32, 60, 1, 1, 10, 50, 10, 13
diff --git a/drivers/video/jzlcd.h b/drivers/video/jzlcd.h
index 3676b9b..d441d97 100644
--- a/drivers/video/jzlcd.h
+++ b/drivers/video/jzlcd.h
@@ -359,12 +359,16 @@ do { \
#endif /* CONFIG_JZLCD_AUO_A030FL01_V1 */
-//#if defined(CONFIG_JZLCD_FOXCONN_PT035TN01)
#if defined(CONFIG_JZLCD_FOXCONN_PT035TN01) || defined(CONFIG_JZLCD_INNOLUX_PT035TN01_SERIAL)
#if defined(CONFIG_JZLCD_FOXCONN_PT035TN01) /* board pmp */
+#if defined(CONFIG_JZ4740_PI)
+#define MODE 0xc9
+#else
#define MODE 0xcd /* 24bit parellel RGB */
#endif
+#endif
+
#if defined(CONFIG_JZLCD_INNOLUX_PT035TN01_SERIAL)
#define MODE 0xc9 /* 8bit serial RGB */
#endif
@@ -384,6 +388,11 @@ do { \
#define SPCK (32*1+17) //LCD_CLS
#define SPDA (32*2+12) //LCD_D12
#define LCD_RET (32*2+23) //LCD_REV, GPC23
+#elif defined(CONFIG_JZ4740_PI)
+ #define SPEN (32*2+21) //LCD_SPL
+ #define SPCK (32*2+23) //LCD_CLS
+ #define SPDA (32*2+22) //LCD_D12
+ #define LCD_RET (32*3+27)
#if 0 /*old driver*/
#define SPEN (32*1+18) //LCD_SPL
#define SPCK (32*1+17) //LCD_CLS
@@ -653,7 +662,6 @@ do { \
#endif /* CONFIG_JZ4730_PMP */
-/*#if defined(CONFIG_JZ4740_LEO) || defined(CONFIG_JZ4740_PAVO)*/
#if defined(CONFIG_SOC_JZ4740)
#if defined(CONFIG_JZ4740_PAVO) || defined(CONFIG_JZ4740_LYRA)
#define GPIO_PWM 123 /* GP_D27 */
@@ -708,11 +716,32 @@ __gpio_as_output(GPIO_PWM); \
__gpio_clear_pin(GPIO_PWM); \
} while (0)
+#elif defined(CONFIG_JZ4740_PI)
+#define GPIO_PWM 123 /* GP_D27 */
+#define PWM_CHN 4 /* pwm channel */
+#define PWM_FULL 101
+#define __lcd_set_backlight_level(n)\
+do { \
+__gpio_as_output(32*3+27); \
+__gpio_set_pin(32*3+27); \
+} while (0)
+
+#define __lcd_close_backlight() \
+do { \
+__gpio_as_output(GPIO_PWM); \
+__gpio_clear_pin(GPIO_PWM); \
+} while (0)
+#define __lcd_display_pin_init() \
+do { \
+ __gpio_as_output(GPIO_DISP_OFF_N); \
+ __cpm_start_tcu(); \
+ __lcd_special_pin_init(); \
+} while (0) /* CONFIG_MIPS_JZ4740_PI) */
#else
#define __lcd_set_backlight_level(n)
#define __lcd_close_backlight()
-#endif /* #if defined(CONFIG_MIPS_JZ4740_PAVO) */
+#endif
#define __lcd_display_pin_init() \
do { \
@@ -735,7 +764,7 @@ do { \
__gpio_clear_pin(GPIO_DISP_OFF_N); \
} while (0)
-#endif /* CONFIG_MIPS_JZ4740_LEO */
+#endif /* (CONFIG_SOC_JZ4740) */
#if defined(CONFIG_JZLCD_MSTN_240x128)
@@ -772,6 +801,7 @@ static void vsync_irq(int irq, void *dev_id, struct pt_regs *reg)
/* We uses AC BIAs pin to generate VCOM signal, so above code should be removed.
*/
#endif
+
/*****************************************************************************
* LCD display pin dummy macros
*****************************************************************************/
diff --git a/include/asm-mips/mach-jz4740/board-pi.h b/include/asm-mips/mach-jz4740/board-pi.h
new file mode 100644
index 0000000..54a7c95
--- /dev/null
+++ b/include/asm-mips/mach-jz4740/board-pi.h
@@ -0,0 +1,68 @@
+/*
+ * linux/include/asm-mips/mach-jz4740/board-pi.h
+ *
+ * JZ4730-based PI ver 2.x definition.
+ *
+ * Copyright (c) 2009 PI.
+ * Author: xiangfu <xiangfu.z@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_JZ4740_PI_H__
+#define __ASM_JZ4740_PI_H__
+
+/*======================================================================
+ * Frequencies of on-board oscillators
+ */
+#define JZ_EXTAL 12000000 /* Main extal freq: 12 MHz */
+#define JZ_EXTAL2 32768 /* RTC extal freq: 32.768 KHz */
+
+/*======================================================================
+ * GPIO
+ */
+#define GPIO_SD_VCC_EN_N 98 /* GPD2 */
+#define GPIO_SD_CD_N 96 /* GPD0 */
+#define GPIO_SD_WP 112 /* GPD16 */
+#define GPIO_USB_DETE 124 /* GPD28 */
+#define GPIO_DISP_OFF_N 117 /* GPD21 */
+#define GPIO_LED_EN 124
+#define GPIO_DC_DETE_N 100
+#define GPIO_CHARG_STAT_N 91 /* GPC27 */
+
+#define GPIO_UDC_HOTPLUG GPIO_USB_DETE
+/*======================================================================
+ * MMC/SD
+ */
+
+#define MSC_WP_PIN GPIO_SD_WP
+#define MSC_HOTPLUG_PIN GPIO_SD_CD_N
+#define MSC_HOTPLUG_IRQ (IRQ_GPIO_0 + GPIO_SD_CD_N)
+
+#define __msc_init_io() \
+do { \
+ __gpio_as_output(GPIO_SD_VCC_EN_N); \
+ __gpio_as_input(GPIO_SD_CD_N); \
+} while (0)
+
+#define __msc_enable_power() \
+do { \
+ __gpio_clear_pin(GPIO_SD_VCC_EN_N); \
+} while (0)
+
+#define __msc_disable_power() \
+do { \
+ __gpio_set_pin(GPIO_SD_VCC_EN_N); \
+} while (0)
+
+#define __msc_card_detected(s) \
+({ \
+ int detected = 1; \
+ if (__gpio_get_pin(GPIO_SD_CD_N)) \
+ detected = 0; \
+ detected; \
+})
+
+#endif /* __ASM_JZ4740_PI_H__ */
diff --git a/include/asm-mips/mach-jz4740/jz4740.h b/include/asm-mips/mach-jz4740/jz4740.h
index 437caf4..b2c3872 100644
--- a/include/asm-mips/mach-jz4740/jz4740.h
+++ b/include/asm-mips/mach-jz4740/jz4740.h
@@ -27,6 +27,10 @@
#include <asm/mach-jz4740/board-pavo.h>
#endif
+#ifdef CONFIG_JZ4740_PI
+#include <asm/mach-jz4740/board-pi.h>
+#endif
+
#ifdef CONFIG_JZ4740_LEO
#include <asm/mach-jz4740/board-leo.h>
#endif
--
1.6.0.4