mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-11-25 05:30:37 +02:00
4808ec76e8
Signed-off-by: Xiangfu Liu <xiangfu.z@gmail.com>
3819 lines
105 KiB
Diff
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
|
|
|