From aadf2187e0236fd2ac90719f89f912f84ef87a5a Mon Sep 17 00:00:00 2001 From: xiangfu 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 + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +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 -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#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 +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#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 + * + * 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 #endif +#ifdef CONFIG_JZ4740_PI +#include +#endif + #ifdef CONFIG_JZ4740_LEO #include #endif -- 1.6.0.4