diff options
author | Quinn Jensen <quinn.jensen@freescale.com> | 2007-10-24 21:18:22 -0600 |
---|---|---|
committer | Quinn Jensen <quinn.jensen@freescale.com> | 2007-10-24 21:18:22 -0600 |
commit | 6824c6b6dd3e9f962de0e6d731c663d9a2dd283a (patch) | |
tree | 4d35238b19ed0e94b81a6bdf9797f771e6c89ca8 | |
parent | cfd242cdfcfe168bf16b7b63bdc9e7fbfc6f81e7 (diff) |
This patch adds MX27-specific files to the linux 2.6.22 kernel.
http://www.bitshrine.org/gpp/linux-2.6.22-mx-mach_mx27.patch
-rw-r--r-- | arch/arm/configs/imx27ads_defconfig | 1583 | ||||
-rw-r--r-- | arch/arm/mach-mx27/Kconfig | 36 | ||||
-rw-r--r-- | arch/arm/mach-mx27/Makefile | 12 | ||||
-rw-r--r-- | arch/arm/mach-mx27/Makefile.boot | 3 | ||||
-rw-r--r-- | arch/arm/mach-mx27/board-mx27ads.h | 385 | ||||
-rw-r--r-- | arch/arm/mach-mx27/clock.c | 1549 | ||||
-rw-r--r-- | arch/arm/mach-mx27/cpu.c | 33 | ||||
-rw-r--r-- | arch/arm/mach-mx27/crm_regs.h | 283 | ||||
-rw-r--r-- | arch/arm/mach-mx27/devices.c | 600 | ||||
-rw-r--r-- | arch/arm/mach-mx27/dma.c | 553 | ||||
-rw-r--r-- | arch/arm/mach-mx27/dpm.c | 405 | ||||
-rw-r--r-- | arch/arm/mach-mx27/dptc.c | 49 | ||||
-rw-r--r-- | arch/arm/mach-mx27/gpio_mux.c | 308 | ||||
-rw-r--r-- | arch/arm/mach-mx27/gpio_mux.h | 76 | ||||
-rw-r--r-- | arch/arm/mach-mx27/mm.c | 62 | ||||
-rw-r--r-- | arch/arm/mach-mx27/mx27ads.c | 758 | ||||
-rw-r--r-- | arch/arm/mach-mx27/mx27ads_gpio.c | 1182 | ||||
-rw-r--r-- | arch/arm/mach-mx27/mxc_pm.c | 458 | ||||
-rw-r--r-- | arch/arm/mach-mx27/pm.c | 105 | ||||
-rw-r--r-- | arch/arm/mach-mx27/serial.c | 275 | ||||
-rw-r--r-- | arch/arm/mach-mx27/serial.h | 170 | ||||
-rw-r--r-- | arch/arm/mach-mx27/system.c | 60 | ||||
-rw-r--r-- | arch/arm/mach-mx27/time.c | 195 | ||||
-rw-r--r-- | arch/arm/mach-mx27/usb.c | 343 |
24 files changed, 9483 insertions, 0 deletions
diff --git a/arch/arm/configs/imx27ads_defconfig b/arch/arm/configs/imx27ads_defconfig new file mode 100644 index 000000000000..21ea7daf92ed --- /dev/null +++ b/arch/arm/configs/imx27ads_defconfig @@ -0,0 +1,1583 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.22.6 +# Thu Sep 27 12:13:29 2007 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +# CONFIG_GENERIC_GPIO is not set +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA=y +CONFIG_ARCH_MTD_XIP=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=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_TIMERFD=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_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +CONFIG_ARCH_MXC=y +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set + +# +# Freescale MXC Implementations +# +# CONFIG_ARCH_MX3 is not set +CONFIG_ARCH_MX27=y + +# +# MX27 Options +# +CONFIG_MACH_MX27ADS=y +CONFIG_ARCH_MXC_HAS_NFC_V1=y + +# +# Device options +# +CONFIG_I2C_MXC_SELECT1=y +# CONFIG_I2C_MXC_SELECT2 is not set +CONFIG_MXC_EMMA=y +CONFIG_ISP1301_MXC=y +CONFIG_MXC_USB_SU6=y +# CONFIG_MXC_USB_SB3 is not set +# CONFIG_MXC_USB_DU6 is not set +# CONFIG_MXC_USB_DB4 is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +# CONFIG_CPU_V6 is not set +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# +CONFIG_ISA=y +# CONFIG_ARCH_SUPPORTS_MSI is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +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_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="noinitrd console=ttymxc0 root=/dev/mtdblock2 rw ip=off" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_LEGACY is not set +# CONFIG_PM_DEBUG is not set +# CONFIG_PM_SYSFS_DEPRECATED is not set +# CONFIG_APM_EMULATION is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# 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_IP_MROUTE 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=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# 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 + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +# CONFIG_DONGLE is not set +# CONFIG_KINGSUN_DONGLE is not set + +# +# Old SIR device drivers +# +# CONFIG_IRPORT_SIR is not set + +# +# Old Serial dongle support +# + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_SIGMATEL_FIR is not set +# CONFIG_MCS_FIR is not set +# CONFIG_MXC_FIR 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=y +# CONFIG_IEEE80211_DEBUG is not set +# CONFIG_IEEE80211_CRYPT_WEP is not set +# CONFIG_IEEE80211_CRYPT_CCMP is not set +# CONFIG_IEEE80211_CRYPT_TKIP is not set +# CONFIG_IEEE80211_SOFTMAC is not set +# CONFIG_RFKILL is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_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 + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set +# 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 is not set +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_RAM=y +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_PLATRAM is not set +CONFIG_MTD_MXC=y + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# 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_MXC=y +# CONFIG_MTD_NAND_MXC_SWECC is not set +# CONFIG_MTD_NAND_MXC_FORCE_CE is not set +# CONFIG_MTD_NAND_MXC_ECC_CORRECTION_OPTION2 is not set +# CONFIG_MXC_NAND_LOW_LEVEL_ERASE is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set +# CONFIG_PNPACPI is not set + +# +# Block devices +# +# 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=16 +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_IDE=m +CONFIG_IDE_MAX_HWIFS=4 +CONFIG_BLK_DEV_IDE=m + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=m +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +# CONFIG_IDE_ARM is not set +CONFIG_BLK_DEV_IDE_MXC=m +# CONFIG_IDE_CHIPSETS is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=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=y +# 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_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ARCNET is not set +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +CONFIG_CS89x0=y +# CONFIG_FEC is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_TR 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=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET_MII=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_MCS7830 is not set +# CONFIG_USB_NET_RNDIS_HOST is not set +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_WAN is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPP_MPPE is not set +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set +CONFIG_SLHC=m +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN 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 is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +CONFIG_KEYBOARD_MXC=y +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +CONFIG_TOUCHSCREEN_MXC=y +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO 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 is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_MXC=y +CONFIG_SERIAL_MXC_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_MXC_WATCHDOG=y + +# +# ISA-based Watchdog Cards +# +# CONFIG_PCWATCHDOG is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_WDT is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_NVRAM is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ELEKTOR is not set +CONFIG_I2C_MXC=y +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_TINY_USB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BITBANG=y +CONFIG_SPI_MXC=y +# CONFIG_SPI_MXC_TEST_LOOPBACK is not set +CONFIG_SPI_MXC_SELECT1=y +CONFIG_SPI_MXC_SELECT2=y +# CONFIG_SPI_MXC_SELECT3 is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_AT25 is not set +# CONFIG_SPI_SPIDEV is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set +# CONFIG_HWMON is not set + +# +# Misc devices +# + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# 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_PMS is not set +CONFIG_VIDEO_MXC_CAMERA=y + +# +# MXC Camera/V4L2 PRP Features support +# +CONFIG_VIDEO_MXC_EMMA_CAMERA=y +# CONFIG_VIDEO_MXC_CSI_DMA is not set +# CONFIG_MXC_CAMERA_MICRON111 is not set +# CONFIG_MXC_CAMERA_MC521DA is not set +CONFIG_MXC_CAMERA_OV2640=y +CONFIG_VIDEO_MXC_OUTPUT=y +CONFIG_VIDEO_MXC_EMMA_OUTPUT=y +CONFIG_VIDEO_MXC_OUTPUT_FBSYNC=y +CONFIG_VIDEO_MXC_OPL=y +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_USBVISION is not set +# 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_VIDEO_OVCAMCHIP is not set +# CONFIG_USB_W9968CF 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_RADIO_CADET is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_ZOLTRIX is not set +# CONFIG_USB_DSBR is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE 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_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_MXC=y +CONFIG_FB_MXC_SYNC_PANEL=y +CONFIG_FB_MXC_TVOUT=y +# CONFIG_FB_MXC_ASYNC_PANEL is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_LOGO_MX27ADS_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +# CONFIG_SND_SEQUENCER is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# ALSA ARM devices +# +CONFIG_SND_MXC_PMIC=y + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_CAIAQ is not set + +# +# System on Chip audio support +# +# CONFIG_SND_SOC is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# HID Devices +# +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=m +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ARC=y +CONFIG_USB_EHCI_ARC_H1=y +CONFIG_USB_EHCI_ARC_OTG=y +# CONFIG_USB_EHCI_FSL_MC13783 is not set +CONFIG_USB_EHCI_FSL_1301=y +# CONFIG_USB_EHCI_FSL_1504 is not set +# CONFIG_USB_EHCI_SPLIT_ISO is not set +CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_SL811_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_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 is not set + +# +# 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_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST 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_SELECTED=y +# 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_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +CONFIG_USB_GADGET_ARC=y +CONFIG_USB_ARC=m +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_DUALSPEED is not set +CONFIG_USB_GADGET_ARC_OTG=y +# CONFIG_USB_GADGET_FSL_MC13783 is not set +CONFIG_USB_GADGET_FSL_1301=y +# CONFIG_USB_GADGET_FSL_1504 is not set +# CONFIG_USB_ZERO is not set +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m +# 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_MXC=y + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_MAX6902 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_MXC=y + +# +# MXC support drivers +# + +# +# MXC IPU +# + +# +# MXC SSI support +# +CONFIG_MXC_SSI=y + +# +# MXC Digital Audio Multiplexer support +# +CONFIG_MXC_DAM=y + +# +# MXC PMIC support +# +CONFIG_MXC_SPI_PMIC_CORE=y +CONFIG_MXC_PMIC=y +CONFIG_MXC_PMIC_CHARDEV=y + +# +# MXC PMIC Client Drivers +# +CONFIG_MXC_PMIC_MC13783=y +CONFIG_MXC_MC13783_ADC=y +CONFIG_MXC_MC13783_AUDIO=y +CONFIG_MXC_MC13783_RTC=y +CONFIG_MXC_MC13783_LIGHT=y +CONFIG_MXC_MC13783_BATTERY=y +CONFIG_MXC_MC13783_CONNECTIVITY=y +CONFIG_MXC_MC13783_POWER=y + +# +# Advanced Power Management devices +# +CONFIG_MX27_DPTC=y + +# +# MXC Security Drivers +# +CONFIG_MXC_SECURITY_SCC=y +# CONFIG_SCC_DEBUG is not set +CONFIG_MXC_SECURITY_RTIC=y +# CONFIG_MXC_RTIC_TEST_DEBUG is not set +CONFIG_MXC_SECURITY_CORE=y + +# +# SAHARA2 Security Hardware Support +# +CONFIG_MXC_SAHARA=y +CONFIG_MXC_SAHARA_USER_MODE=y +# CONFIG_MXC_SAHARA_POLL_MODE is not set + +# +# MXC MPEG4 Encoder Kernel module support +# + +# +# MXC VPU(Video Processing Unit) support +# +CONFIG_MXC_VPU=y +# CONFIG_MXC_VPU_DEBUG is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# 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=m +# 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_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# 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_YAFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# CONFIG_CRAMFS_LINEAR 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 + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# 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 +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +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 is not set +# 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=m +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=m + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set + +# +# CodeTEST setup +# +# CONFIG_CODETEST is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_CRC_CCITT=m +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/arm/mach-mx27/Kconfig b/arch/arm/mach-mx27/Kconfig new file mode 100644 index 000000000000..062dd2940845 --- /dev/null +++ b/arch/arm/mach-mx27/Kconfig @@ -0,0 +1,36 @@ +menu "MX27 Options" + depends on ARCH_MX27 + +config MACH_MX27ADS + bool "Support MX27ADS platforms" + default y + help + Include support for MX27ADS platform. This includes specific + configurations for the board and its peripherals. + +config ARCH_MXC_HAS_NFC_V1 + bool "MXC NFC Hardware Version 1" + default y + help + This selects the Freescale MXC Nand Flash Controller Hardware Version 1 + If unsure, say N. + +menu "Device options" + +config I2C_MXC_SELECT1 + bool "Enable I2C1 module" + default y + depends on I2C_MXC + help + Enable MX31 I2C1 module. + +config I2C_MXC_SELECT2 + bool "Enable I2C2 module" + default n + depends on I2C_MXC + help + Enable MX31 I2C2 module. + +endmenu + +endmenu diff --git a/arch/arm/mach-mx27/Makefile b/arch/arm/mach-mx27/Makefile new file mode 100644 index 000000000000..56322326e7e0 --- /dev/null +++ b/arch/arm/mach-mx27/Makefile @@ -0,0 +1,12 @@ +# +# Makefile for the linux kernel. +# + +# Object file lists. + +obj-y := mm.o time.o dma.o gpio_mux.o clock.o devices.o serial.o system.o usb.o cpu.o +obj-$(CONFIG_MACH_MX27ADS) += mx27ads.o mx27ads_gpio.o + +# power management +obj-$(CONFIG_PM) += pm.o mxc_pm.o +obj-$(CONFIG_DPM) += dpm.o diff --git a/arch/arm/mach-mx27/Makefile.boot b/arch/arm/mach-mx27/Makefile.boot new file mode 100644 index 000000000000..696831dcd485 --- /dev/null +++ b/arch/arm/mach-mx27/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0xA0008000 +params_phys-y := 0xA0000100 +initrd_phys-y := 0xA0800000 diff --git a/arch/arm/mach-mx27/board-mx27ads.h b/arch/arm/mach-mx27/board-mx27ads.h new file mode 100644 index 000000000000..1730c452b9c1 --- /dev/null +++ b/arch/arm/mach-mx27/board-mx27ads.h @@ -0,0 +1,385 @@ +/* + * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef __ASM_ARCH_MXC_BOARD_MX27ADS_H__ +#define __ASM_ARCH_MXC_BOARD_MX27ADS_H__ + +/*! + * @defgroup BRDCFG_MX27 Board Configuration Options + * @ingroup MSL_MX27 + */ + +/*! + * @file mach-mx27/board-mx27ads.h + * + * @brief This file contains all the board level configuration options. + * + * It currently hold the options defined for MX27 ADS Platform. + * + * @ingroup BRDCFG_MX27 + */ + +/* + * Include Files + */ +#include <asm/arch/mxc_uart.h> + +/*! + * @name MXC UART EVB board level configurations + */ +/*! @{ */ +/*! + * Specifies if the Irda transmit path is inverting + */ +#define MXC_IRDA_TX_INV 0 +/*! + * Specifies if the Irda receive path is inverting + */ +#define MXC_IRDA_RX_INV 0 +/* UART 1 configuration */ +/*! + * This define specifies if the UART port is configured to be in DTE or + * DCE mode. There exists a define like this for each UART port. Valid + * values that can be used are \b MODE_DTE or \b MODE_DCE. + */ +#define UART1_MODE MODE_DCE +/*! + * This define specifies if the UART is to be used for IRDA. There exists a + * define like this for each UART port. Valid values that can be used are + * \b IRDA or \b NO_IRDA. + */ +#define UART1_IR NO_IRDA +/*! + * This define is used to enable or disable a particular UART port. If + * disabled, the UART will not be registered in the file system and the user + * will not be able to access it. There exists a define like this for each UART + * port. Specify a value of 1 to enable the UART and 0 to disable it. + */ +#define UART1_ENABLED 1 +/*! @} */ +/* UART 2 configuration */ +#define UART2_MODE MODE_DCE +#define UART2_IR NO_IRDA +#define UART2_ENABLED 1 +/* UART 3 configuration */ +#define UART3_MODE MODE_DCE +#define UART3_IR IRDA +#define UART3_ENABLED 1 +/* UART 4 configuration */ +#define UART4_MODE MODE_DTE +#define UART4_IR NO_IRDA +#define UART4_ENABLED 0 /* Disable UART 4 as its pins are shared with ATA */ +/* UART 5 configuration */ +#define UART5_MODE MODE_DTE +#define UART5_IR NO_IRDA +#define UART5_ENABLED 1 +/* UART 6 configuration */ +#define UART6_MODE MODE_DTE +#define UART6_IR NO_IRDA +#define UART6_ENABLED 1 + +#define MXC_LL_EXTUART_PADDR (CS4_BASE_ADDR + 0x20000) +#define MXC_LL_EXTUART_VADDR (CS4_BASE_ADDR_VIRT + 0x20000) +#define MXC_LL_EXTUART_16BIT_BUS + +#define MXC_LL_UART_PADDR UART1_BASE_ADDR +#define MXC_LL_UART_VADDR AIPI_IO_ADDRESS(UART1_BASE_ADDR) + +/*! + * @name PBC Controller parameters + */ +/*! @{ */ +/*! + * Base address of PBC controller, CS4 + */ +#define PBC_BASE_ADDRESS IO_ADDRESS(CS4_BASE_ADDR) +#define PBC_REG_ADDR(offset) (PBC_BASE_ADDRESS + (offset)) + +/*! + * PBC Interupt name definitions + */ +#define PBC_GPIO1_0 0 +#define PBC_GPIO1_1 1 +#define PBC_GPIO1_2 2 +#define PBC_GPIO1_3 3 +#define PBC_GPIO1_4 4 +#define PBC_GPIO1_5 5 + +#define PBC_INTR_MAX_NUM 6 +#define PBC_INTR_SHARED_MAX_NUM 8 + +/* When the PBC address connection is fixed in h/w, defined as 1 */ +#define PBC_ADDR_SH 0 + +/* Offsets for the PBC Controller register */ +/*! + * PBC Board version register offset + */ +#define PBC_VERSION_REG PBC_REG_ADDR(0x00000 >> PBC_ADDR_SH) +/*! + * PBC Board control register 1 set address. + */ +#define PBC_BCTRL1_SET_REG PBC_REG_ADDR(0x00008 >> PBC_ADDR_SH) +/*! + * PBC Board control register 1 clear address. + */ +#define PBC_BCTRL1_CLEAR_REG PBC_REG_ADDR(0x0000C >> PBC_ADDR_SH) +/*! + * PBC Board control register 2 set address. + */ +#define PBC_BCTRL2_SET_REG PBC_REG_ADDR(0x00010 >> PBC_ADDR_SH) +/*! + * PBC Board control register 2 clear address. + */ +#define PBC_BCTRL2_CLEAR_REG PBC_REG_ADDR(0x00014 >> PBC_ADDR_SH) +/*! + * PBC Board control register 3 set address. + */ +#define PBC_BCTRL3_SET_REG PBC_REG_ADDR(0x00018 >> PBC_ADDR_SH) +/*! + * PBC Board control register 3 clear address. + */ +#define PBC_BCTRL3_CLEAR_REG PBC_REG_ADDR(0x0001C >> PBC_ADDR_SH) +/*! + * PBC Board control register 3 set address. + */ +#define PBC_BCTRL4_SET_REG PBC_REG_ADDR(0x00020 >> PBC_ADDR_SH) +/*! + * PBC Board control register 4 clear address. + */ +#define PBC_BCTRL4_CLEAR_REG PBC_REG_ADDR(0x00024 >> PBC_ADDR_SH) +/*!PBC_ADDR_SH + * PBC Board status register 1. + */ +#define PBC_BSTAT1_REG PBC_REG_ADDR(0x00028 >> PBC_ADDR_SH) +/*! + * PBC Board interrupt status register. + */ +#define PBC_INTSTATUS_REG PBC_REG_ADDR(0x0002C >> PBC_ADDR_SH) +/*! + * PBC Board interrupt current status register. + */ +#define PBC_INTCURR_STATUS_REG PBC_REG_ADDR(0x00034 >> PBC_ADDR_SH) +/*! + * PBC Interrupt mask register set address. + */ +#define PBC_INTMASK_SET_REG PBC_REG_ADDR(0x00038 >> PBC_ADDR_SH) +/*! + * PBC Interrupt mask register clear address. + */ +#define PBC_INTMASK_CLEAR_REG PBC_REG_ADDR(0x0003C >> PBC_ADDR_SH) +/*! + * External UART A. + */ +#define PBC_SC16C652_UARTA_REG PBC_REG_ADDR(0x20000 >> PBC_ADDR_SH) +/*! + * UART 4 Expanding Signal Status. + */ +#define PBC_UART_STATUS_REG PBC_REG_ADDR(0x22000 >> PBC_ADDR_SH) +/*! + * UART 4 Expanding Signal Control Set. + */ +#define PBC_UCTRL_SET_REG PBC_REG_ADDR(0x24000 >> PBC_ADDR_SH) +/*! + * UART 4 Expanding Signal Control Clear. + */ +#define PBC_UCTRL_CLR_REG PBC_REG_ADDR(0x26000 >> PBC_ADDR_SH) +/*! + * Ethernet Controller IO base address. + */ +#define PBC_CS8900A_IOBASE_REG PBC_REG_ADDR(0x40000 >> PBC_ADDR_SH) +/*! + * Ethernet Controller Memory base address. + */ +#define PBC_CS8900A_MEMBASE_REG PBC_REG_ADDR(0x42000 >> PBC_ADDR_SH) +/*! + * Ethernet Controller DMA base address. + */ +#define PBC_CS8900A_DMABASE_REG PBC_REG_ADDR(0x44000 >> PBC_ADDR_SH) + +/* PBC Board Version Register bit definition */ +#define PBC_VERSION_ADS 0x8000 /* Bit15=1 means version for ads */ +#define PBC_VERSION_EVB_REVB 0x4000 /* BIT14=1 means version for evb revb */ + +/* PBC Board Control Register 1 bit definitions */ +#define PBC_BCTRL1_ERST 0x0001 /* Ethernet Reset */ +#define PBC_BCTRL1_URST 0x0002 /* Reset External UART controller */ +#define PBC_BCTRL1_FRST 0x0004 /* FEC Reset */ +#define PBC_BCTRL1_ESLEEP 0x0010 /* Enable ethernet Sleep */ +#define PBC_BCTRL1_LCDON 0x0800 /* Enable the LCD */ + +/* PBC Board Control Register 2 bit definitions */ +#define PBC_BCTRL2_VCC_EN 0x0004 /* Enable VCC */ +#define PBC_BCTRL2_VPP_EN 0x0008 /* Enable Vpp */ +#define PBC_BCTRL2_ATAFEC_EN 0X0010 +#define PBC_BCTRL2_ATAFEC_SEL 0X0020 +#define PBC_BCTRL2_ATA_EN 0X0040 +#define PBC_BCTRL2_IRDA_SD 0X0080 +#define PBC_BCTRL2_IRDA_EN 0X0100 +#define PBC_BCTRL2_CCTL10 0X0200 +#define PBC_BCTRL2_CCTL11 0X0400 + +/* PBC Board Control Register 3 bit definitions */ +#define PBC_BCTRL3_HSH_EN 0X0020 +#define PBC_BCTRL3_FSH_MOD 0X0040 +#define PBC_BCTRL3_OTG_HS_EN 0X0080 +#define PBC_BCTRL3_OTG_VBUS_EN 0X0100 +#define PBC_BCTRL3_FSH_VBUS_EN 0X0200 +#define PBC_BCTRL3_USB_OTG_ON 0X0800 +#define PBC_BCTRL3_USB_FSH_ON 0X1000 + +/* PBC Board Control Register 4 bit definitions */ +#define PBC_BCTRL4_REGEN_SEL 0X0001 +#define PBC_BCTRL4_USER_OFF 0X0002 +#define PBC_BCTRL4_VIB_EN 0X0004 +#define PBC_BCTRL4_PWRGT1_EN 0X0008 +#define PBC_BCTRL4_PWRGT2_EN 0X0010 +#define PBC_BCTRL4_STDBY_PRI 0X0020 + +#ifndef __ASSEMBLY__ +/*! + * Enumerations for SD cards and memory stick card. This corresponds to + * the card EN bits in the IMR: SD1_EN | MS_EN | SD3_EN | SD2_EN. + */ +enum mxc_card_no { + MXC_CARD_SD2 = 0, + MXC_CARD_SD3, + MXC_CARD_MS, + MXC_CARD_SD1, + MXC_CARD_MIN = MXC_CARD_SD2, + MXC_CARD_MAX = MXC_CARD_SD1, +}; +#endif + +#define MXC_CPLD_VER_1_50 0x01 + +/*! + * PBC BSTAT Register bit definitions + */ +#define PBC_BSTAT_PRI_INT 0X0001 +#define PBC_BSTAT_USB_BYP 0X0002 +#define PBC_BSTAT_ATA_IOCS16 0X0004 +#define PBC_BSTAT_ATA_CBLID 0X0008 +#define PBC_BSTAT_ATA_DASP 0X0010 +#define PBC_BSTAT_PWR_RDY 0X0020 +#define PBC_BSTAT_SD3_WP 0X0100 +#define PBC_BSTAT_SD2_WP 0X0200 +#define PBC_BSTAT_SD1_WP 0X0400 +#define PBC_BSTAT_SD3_DET 0X0800 +#define PBC_BSTAT_SD2_DET 0X1000 +#define PBC_BSTAT_SD1_DET 0X2000 +#define PBC_BSTAT_MS_DET 0X4000 +#define PBC_BSTAT_SD3_DET_BIT 11 +#define PBC_BSTAT_SD2_DET_BIT 12 +#define PBC_BSTAT_SD1_DET_BIT 13 +#define PBC_BSTAT_MS_DET_BIT 14 +#define MXC_BSTAT_BIT(n) ((n == MXC_CARD_SD2) ? PBC_BSTAT_SD2_DET : \ + ((n == MXC_CARD_SD3) ? PBC_BSTAT_SD3_DET : \ + ((n == MXC_CARD_SD1) ? PBC_BSTAT_SD1_DET : \ + ((n == MXC_CARD_MS) ? PBC_BSTAT_MS_DET : 0x0)))) + +/*! + * PBC UART Control Register bit definitions + */ +#define PBC_UCTRL_DCE_DCD 0X0001 +#define PBC_UCTRL_DCE_DSR 0X0002 +#define PBC_UCTRL_DCE_RI 0X0004 +#define PBC_UCTRL_DTE_DTR 0X0100 + +/*! + * PBC UART Status Register bit definitions + */ +#define PBC_USTAT_DTE_DCD 0X0001 +#define PBC_USTAT_DTE_DSR 0X0002 +#define PBC_USTAT_DTE_RI 0X0004 +#define PBC_USTAT_DCE_DTR 0X0100 + +/*! + * PBC Interupt mask register bit definitions + */ +#define PBC_INTR_SD3_R_EN_BIT 4 +#define PBC_INTR_SD2_R_EN_BIT 0 +#define PBC_INTR_SD1_R_EN_BIT 6 +#define PBC_INTR_MS_R_EN_BIT 5 +#define PBC_INTR_SD3_EN_BIT 13 +#define PBC_INTR_SD2_EN_BIT 12 +#define PBC_INTR_MS_EN_BIT 14 +#define PBC_INTR_SD1_EN_BIT 15 + +#define PBC_INTR_SD2_R_EN 0x0001 +#define PBC_INTR_LOW_BAT 0X0002 +#define PBC_INTR_OTG_FSOVER 0X0004 +#define PBC_INTR_FSH_OVER 0X0008 +#define PBC_INTR_SD3_R_EN 0x0010 +#define PBC_INTR_MS_R_EN 0x0020 +#define PBC_INTR_SD1_R_EN 0x0040 +#define PBC_INTR_FEC_INT 0X0080 +#define PBC_INTR_ENET_INT 0X0100 +#define PBC_INTR_OTGFS_INT 0X0200 +#define PBC_INTR_XUART_INT 0X0400 +#define PBC_INTR_CCTL12 0X0800 +#define PBC_INTR_SD2_EN 0x1000 +#define PBC_INTR_SD3_EN 0x2000 +#define PBC_INTR_MS_EN 0x4000 +#define PBC_INTR_SD1_EN 0x8000 + +/*! @} */ + +#define CKIH_27MHZ_BIT_SET (1 << 3) + +/* For interrupts like xuart, enet etc */ +#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX27_PIN_TIN) + +/* + * This corresponds to PBC_INTMASK_SET_REG at offset 0x38. + * + */ +#define EXPIO_INT_LOW_BAT (MXC_EXP_IO_BASE + 1) +#define EXPIO_INT_OTG_FS_OVR (MXC_EXP_IO_BASE + 2) +#define EXPIO_INT_FSH_OVR (MXC_EXP_IO_BASE + 3) +#define EXPIO_INT_RES4 (MXC_EXP_IO_BASE + 4) +#define EXPIO_INT_RES5 (MXC_EXP_IO_BASE + 5) +#define EXPIO_INT_RES6 (MXC_EXP_IO_BASE + 6) +#define EXPIO_INT_FEC (MXC_EXP_IO_BASE + 7) +#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8) +#define EXPIO_INT_OTG_FS_INT (MXC_EXP_IO_BASE + 9) +#define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10) +#define EXPIO_INT_CCTL12_INT (MXC_EXP_IO_BASE + 11) +#define EXPIO_INT_SD2_EN (MXC_EXP_IO_BASE + 12) +#define EXPIO_INT_SD3_EN (MXC_EXP_IO_BASE + 13) +#define EXPIO_INT_MS_EN (MXC_EXP_IO_BASE + 14) +#define EXPIO_INT_SD1_EN (MXC_EXP_IO_BASE + 15) + +/*! This is System IRQ used by CS8900A for interrupt generation taken from platform.h */ +#define CS8900AIRQ EXPIO_INT_ENET_INT +/*! This is I/O Base address used to access registers of CS8900A on MXC ADS */ +#define CS8900A_BASE_ADDRESS (PBC_CS8900A_IOBASE_REG + 0x300) + +#define MXC_PMIC_INT_LINE IOMUX_TO_IRQ(MX27_PIN_TOUT) + +/*! +* This is used to detect if the CPLD version is for mx27 evb board rev-a +*/ +#define PBC_CPLD_VERSION_IS_REVA() \ + ((__raw_readw(PBC_VERSION_REG) & \ + (PBC_VERSION_ADS | PBC_VERSION_EVB_REVB))\ + == 0) + +#define MXC_BD_LED1 (1 << 5) +#define MXC_BD_LED2 (1 << 6) +#define MXC_BD_LED_ON(led) \ + __raw_writew(led, PBC_BCTRL1_SET_REG) +#define MXC_BD_LED_OFF(led) \ + __raw_writew(led, PBC_BCTRL1_CLEAR_REG) + +#endif /* __ASM_ARCH_MXC_BOARD_MX27ADS_H__ */ diff --git a/arch/arm/mach-mx27/clock.c b/arch/arm/mach-mx27/clock.c new file mode 100644 index 000000000000..ff3ec8d517d8 --- /dev/null +++ b/arch/arm/mach-mx27/clock.c @@ -0,0 +1,1549 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/module.h> +#include <linux/spinlock.h> +#include <linux/clk.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include "crm_regs.h" + +#define CKIH_CLK_FREQ 26000000 /* 26M reference clk */ +#define CKIH_CLK_FREQ_27MHZ 27000000 +#define CKIL_CLK_FREQ 32768 /* 32.768k oscillator in */ + +static struct clk ckil_clk; +static struct clk mpll_clk; +static struct clk mpll_main_clk[]; +static struct clk spll_clk; + +static int _clk_enable(struct clk *clk) +{ + unsigned long reg; + + reg = __raw_readl(clk->enable_reg); + reg |= 1 << clk->enable_shift; + __raw_writel(reg, clk->enable_reg); + + return 0; +} + +static void _clk_disable(struct clk *clk) +{ + unsigned long reg; + + reg = __raw_readl(clk->enable_reg); + reg &= ~(1 << clk->enable_shift); + __raw_writel(reg, clk->enable_reg); +} + +static int _clk_spll_enable(struct clk *clk) +{ + unsigned long reg; + + reg = __raw_readl(CCM_CSCR); + reg |= CCM_CSCR_SPEN; + __raw_writel(reg, CCM_CSCR); + + while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0) ; + + return 0; +} + +static void _clk_spll_disable(struct clk *clk) +{ + unsigned long reg; + + reg = __raw_readl(CCM_CSCR); + reg &= ~CCM_CSCR_SPEN; + __raw_writel(reg, CCM_CSCR); +} + +static void _clk_pccr01_enable(unsigned long mask0, unsigned long mask1) +{ + unsigned long reg; + + reg = __raw_readl(CCM_PCCR0); + reg |= mask0; + __raw_writel(reg, CCM_PCCR0); + + reg = __raw_readl(CCM_PCCR1); + reg |= mask1; + __raw_writel(reg, CCM_PCCR1); + +} + +static void _clk_pccr01_disable(unsigned long mask0, unsigned long mask1) +{ + unsigned long reg; + + reg = __raw_readl(CCM_PCCR0); + reg &= ~mask0; + __raw_writel(reg, CCM_PCCR0); + + reg = __raw_readl(CCM_PCCR1); + reg &= ~mask1; + __raw_writel(reg, CCM_PCCR1); +} + +static void _clk_pccr10_enable(unsigned long mask1, unsigned long mask0) +{ + unsigned long reg; + + reg = __raw_readl(CCM_PCCR1); + reg |= mask1; + __raw_writel(reg, CCM_PCCR1); + + reg = __raw_readl(CCM_PCCR0); + reg |= mask0; + __raw_writel(reg, CCM_PCCR0); +} + +static void _clk_pccr10_disable(unsigned long mask1, unsigned long mask0) +{ + unsigned long reg; + + reg = __raw_readl(CCM_PCCR1); + reg &= ~mask1; + __raw_writel(reg, CCM_PCCR1); + + reg = __raw_readl(CCM_PCCR0); + reg &= ~mask0; + __raw_writel(reg, CCM_PCCR0); +} + +static int _clk_dma_enable(struct clk *clk) +{ + _clk_pccr01_enable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK); + + return 0; +} + +static void _clk_dma_disable(struct clk *clk) +{ + _clk_pccr01_disable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK); +} + +static int _clk_rtic_enable(struct clk *clk) +{ + _clk_pccr01_enable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK); + + return 0; +} + +static void _clk_rtic_disable(struct clk *clk) +{ + _clk_pccr01_disable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK); +} + +static int _clk_emma_enable(struct clk *clk) +{ + _clk_pccr01_enable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK); + + return 0; +} + +static void _clk_emma_disable(struct clk *clk) +{ + _clk_pccr01_disable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK); +} + +static int _clk_slcdc_enable(struct clk *clk) +{ + _clk_pccr01_enable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK); + + return 0; +} + +static void _clk_slcdc_disable(struct clk *clk) +{ + _clk_pccr01_disable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK); +} + +static int _clk_fec_enable(struct clk *clk) +{ + _clk_pccr01_enable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK); + + return 0; +} + +static void _clk_fec_disable(struct clk *clk) +{ + _clk_pccr01_disable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK); +} + +static int _clk_vpu_enable(struct clk *clk) +{ + unsigned long reg; + + reg = __raw_readl(CCM_PCCR1); + reg |= CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK; + __raw_writel(reg, CCM_PCCR1); + + return 0; +} + +static void _clk_vpu_disable(struct clk *clk) +{ + unsigned long reg; + + reg = __raw_readl(CCM_PCCR1); + reg &= ~(CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK); + __raw_writel(reg, CCM_PCCR1); +} + +static int _clk_sahara2_enable(struct clk *clk) +{ + _clk_pccr01_enable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK); + + return 0; +} + +static void _clk_sahara2_disable(struct clk *clk) +{ + _clk_pccr01_disable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK); +} + +static int _clk_mstick1_enable(struct clk *clk) +{ + _clk_pccr10_enable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK); + + return 0; +} + +static void _clk_mstick1_disable(struct clk *clk) +{ + _clk_pccr10_disable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK); +} + +#define CSCR() (__raw_readl(CCM_CSCR)) +#define PCDR0() (__raw_readl(CCM_PCDR0)) +#define PCDR1() (__raw_readl(CCM_PCDR1)) + +static void _clk_pll_recalc(struct clk *clk) +{ + unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0; + unsigned long ref_clk; + unsigned long reg; + unsigned long long temp; + + ref_clk = clk->parent->rate; + if (clk->parent == &ckil_clk) { + ref_clk *= 1024; + } + + if (clk == &mpll_clk) { + reg = __raw_readl(CCM_MPCTL0); + pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET; + mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET; + mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET; + mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET; + } else if (clk == &spll_clk) { + reg = __raw_readl(CCM_SPCTL0); + /*TODO: This is TO2 Bug */ + if (cpu_is_mx27_rev(CHIP_REV_2_0) == 1) { + __raw_writel(reg, CCM_SPCTL0); + } + pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET; + mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET; + mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET; + mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET; + } else { + BUG(); /* oops */ + } + + mfi = (mfi <= 5) ? 5 : mfi; + temp = 2LL * ref_clk * mfn; + do_div(temp, mfd + 1); + temp = 2LL * ref_clk * mfi + temp; + do_div(temp, pdf + 1); + + clk->rate = temp; +} + +static void _clk_mpll_main_recalc(struct clk *clk) +{ + /* i.MX27 TO2: + * clk->id == 0: arm clock source path 1 which is from 2*MPLL/DIV_2 + * clk->id == 1: arm clock source path 2 which is from 2*MPLL/DIV_3 + */ + switch (clk->id) { + case 0: + clk->rate = clk->parent->rate; + break; + case 1: + clk->rate = 2 * clk->parent->rate / 3; + } +} + +static int _clk_cpu_set_parent(struct clk *clk, struct clk *parent) +{ + int cscr = CSCR(); + + if (clk->parent == parent) + return 0; + + if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) { + if (parent == &mpll_main_clk[0]) { + cscr |= CCM_CSCR_ARM_SRC; + } else { + if (parent == &mpll_main_clk[1]) { + cscr &= ~CCM_CSCR_ARM_SRC; + } else { + return -EINVAL; + } + } + __raw_writel(CCM_CSCR, cscr); + } else { + return -ENODEV; + } + clk->parent = parent; + return 0; +} + +static unsigned long _clk_cpu_round_rate(struct clk *clk, unsigned long rate) +{ + int div; + div = clk->parent->rate / rate; + if (clk->parent->rate % rate) { + div++; + } + + if (div > 4) { + div = 4; + } + return clk->parent->rate / div; +} + +static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate) +{ + int div, reg; + div = clk->parent->rate / rate; + + if (div > 4 || div < 1 || ((clk->parent->rate / div) != rate)) { + return -EINVAL; + } + div--; + + reg = (CSCR() & ~CCM_CSCR_ARM_MASK) | (div << CCM_CSCR_ARM_OFFSET); + __raw_writel(CCM_CSCR, reg); + clk->rate = rate; + return 0; +} + +static void _clk_cpu_recalc(struct clk *clk) +{ + unsigned long div; + + if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) { + div = (CSCR() & CCM_CSCR_ARM_MASK) >> CCM_CSCR_ARM_OFFSET; + } else { + div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET; + } + + clk->rate = clk->parent->rate / (div + 1); +} + +static void _clk_ahb_recalc(struct clk *clk) +{ + unsigned long bclk_pdf; + + if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) { + bclk_pdf = (CSCR() & CCM_CSCR_AHB_MASK) >> CCM_CSCR_AHB_OFFSET; + } else { + bclk_pdf = + (CSCR() & CCM_CSCR_BCLK_MASK) >> CCM_CSCR_BCLK_OFFSET; + } + clk->rate = clk->parent->rate / (bclk_pdf + 1); +} + +static void _clk_perclkx_recalc(struct clk *clk) +{ + unsigned long perclk_pdf; + + if (clk->id < 0 || clk->id > 3) + return; + + perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK; + + clk->rate = clk->parent->rate / (perclk_pdf + 1); +} + +static unsigned long _clk_perclkx_round_rate(struct clk *clk, + unsigned long rate) +{ + u32 div; + + div = clk->parent->rate / rate; + if (clk->parent->rate % rate) + div++; + + if (div > 64) { + div = 64; + } + + return clk->parent->rate / div; +} + +static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg; + u32 div; + + if (clk->id < 0 || clk->id > 3) + return -EINVAL; + + div = clk->parent->rate / rate; + if (div > 64 || div < 1 || ((clk->parent->rate / div) != rate)) { + return -EINVAL; + } + div--; + + reg = + __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK << + (clk->id << 3)); + reg |= div << (clk->id << 3); + __raw_writel(reg, CCM_PCDR1); + + clk->rate = rate; + + return 0; +} + +static void _clk_usb_recalc(struct clk *clk) +{ + unsigned long usb_pdf; + + usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET; + + clk->rate = clk->parent->rate / (usb_pdf + 1); +} + +static void _clk_ssi1_recalc(struct clk *clk) +{ + unsigned long ssi1_pdf; + + ssi1_pdf = (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK) >> + CCM_PCDR0_SSI1BAUDDIV_OFFSET; + + if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) { + ssi1_pdf += 4; + } else { + ssi1_pdf = (ssi1_pdf < 2) ? 124 : ssi1_pdf; + } + + clk->rate = 2 * clk->parent->rate / ssi1_pdf; +} + +static void _clk_ssi2_recalc(struct clk *clk) +{ + unsigned long ssi2_pdf; + + ssi2_pdf = (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >> + CCM_PCDR0_SSI2BAUDDIV_OFFSET; + + if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) { + ssi2_pdf += 4; + } else { + ssi2_pdf = (ssi2_pdf < 2) ? 124 : ssi2_pdf; + } + + clk->rate = 2 * clk->parent->rate / ssi2_pdf; +} + +static void _clk_nfc_recalc(struct clk *clk) +{ + unsigned long nfc_pdf; + + if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) { + nfc_pdf = + (PCDR0() & CCM_PCDR0_NFCDIV2_MASK) >> + CCM_PCDR0_NFCDIV2_OFFSET; + } else { + nfc_pdf = + (PCDR0() & CCM_PCDR0_NFCDIV_MASK) >> + CCM_PCDR0_NFCDIV_OFFSET; + } + + clk->rate = clk->parent->rate / (nfc_pdf + 1); +} + +static void _clk_vpu_recalc(struct clk *clk) +{ + unsigned long vpu_pdf; + + if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) { + vpu_pdf = + (PCDR0() & CCM_PCDR0_VPUDIV2_MASK) >> + CCM_PCDR0_VPUDIV2_OFFSET; + vpu_pdf += 4; + } else { + vpu_pdf = + (PCDR0() & CCM_PCDR0_VPUDIV_MASK) >> + CCM_PCDR0_VPUDIV_OFFSET; + vpu_pdf = (vpu_pdf < 2) ? 124 : vpu_pdf; + } + clk->rate = 2 * clk->parent->rate / vpu_pdf; +} + +static void _clk_ipg_recalc(struct clk *clk) +{ + unsigned long ipg_pdf; + + if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) { + ipg_pdf = 1; + } else { + ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET; + } + + clk->rate = clk->parent->rate / (ipg_pdf + 1); +} + +static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate) +{ + return clk->parent->round_rate(clk->parent, rate); +} + +static int _clk_parent_set_rate(struct clk *clk, unsigned long rate) +{ + int ret; + if ((ret = clk->parent->set_rate(clk->parent, rate)) == 0) + clk->rate = rate; + return ret; +} + +static struct clk ckih_clk = { + .name = "ckih", + .rate = 0, /* determined at boot time (26 or 27 MHz) */ + .flags = RATE_PROPAGATES, +}; + +static struct clk ckil_clk = { + .name = "ckil", + .rate = CKIL_CLK_FREQ, + .flags = RATE_PROPAGATES, +}; + +static struct clk mpll_clk = { + .name = "mpll", + .parent = &ckih_clk, + .recalc = _clk_pll_recalc, + .flags = RATE_PROPAGATES, +}; + +static struct clk mpll_main_clk[] = { + { + /* For i.MX27 TO2, it is the MPLL path 1 of ARM core + * It provide the clock source whose rate is same as MPLL + */ + .name = "mpll_main", + .id = 0, + .parent = &mpll_clk, + .recalc = _clk_mpll_main_recalc,}, + { + /* For i.MX27 TO2, it is the MPLL path 1 of ARM core + * It provide the clock source whose rate is same as MPLL + */ + .name = "mpll_main", + .id = 1, + .parent = &mpll_clk, + .recalc = _clk_mpll_main_recalc,} +}; + +static struct clk spll_clk = { + .name = "spll", + .parent = &ckih_clk, + .recalc = _clk_pll_recalc, + .enable = _clk_spll_enable, + .disable = _clk_spll_disable, + .flags = RATE_PROPAGATES, +}; + +static struct clk cpu_clk = { + .name = "cpu_clk", + .parent = &mpll_main_clk[1], + .set_parent = _clk_cpu_set_parent, + .round_rate = _clk_cpu_round_rate, + .set_rate = _clk_cpu_set_rate, + .recalc = _clk_cpu_recalc, + .flags = RATE_PROPAGATES, +}; + +static struct clk ahb_clk = { + .name = "ahb_clk", + .parent = &mpll_main_clk[1], + .recalc = _clk_ahb_recalc, + .flags = RATE_PROPAGATES, +}; + +static struct clk ipg_clk = { + .name = "ipg_clk", + .parent = &ahb_clk, + .recalc = _clk_ipg_recalc, + .flags = RATE_PROPAGATES, +}; + +static struct clk per_clk[] = { + { + .name = "per_clk", + .id = 0, + .parent = &mpll_main_clk[1], + .recalc = _clk_perclkx_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_PERCLK1_OFFSET, + .disable = _clk_disable, + .flags = RATE_PROPAGATES,}, + { + .name = "per_clk", + .id = 1, + .parent = &mpll_main_clk[1], + .recalc = _clk_perclkx_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_PERCLK2_OFFSET, + .disable = _clk_disable, + .flags = RATE_PROPAGATES,}, + { + .name = "per_clk", + .id = 2, + .parent = &mpll_main_clk[1], + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .recalc = _clk_perclkx_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_PERCLK3_OFFSET, + .disable = _clk_disable, + .flags = RATE_PROPAGATES,}, + { + .name = "per_clk", + .id = 3, + .parent = &mpll_main_clk[1], + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .recalc = _clk_perclkx_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_PERCLK4_OFFSET, + .disable = _clk_disable, + .flags = RATE_PROPAGATES,}, +}; + +struct clk uart1_clk[] = { + { + .name = "uart_clk", + .id = 0, + .parent = &per_clk[0], + .secondary = &uart1_clk[1],}, + { + .name = "uart_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_UART1_OFFSET, + .disable = _clk_disable,}, +}; + +struct clk uart2_clk[] = { + { + .name = "uart_clk", + .id = 1, + .parent = &per_clk[0], + .secondary = &uart2_clk[1],}, + { + .name = "uart_ipg_clk", + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_UART2_OFFSET, + .disable = _clk_disable,}, +}; + +struct clk uart3_clk[] = { + { + .name = "uart_clk", + .id = 2, + .parent = &per_clk[0], + .secondary = &uart3_clk[1],}, + { + .name = "uart_ipg_clk", + .id = 2, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_UART3_OFFSET, + .disable = _clk_disable,}, +}; + +struct clk uart4_clk[] = { + { + .name = "uart_clk", + .id = 3, + .parent = &per_clk[0], + .secondary = &uart4_clk[1],}, + { + .name = "uart_ipg_clk", + .id = 3, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_UART4_OFFSET, + .disable = _clk_disable,}, +}; + +struct clk uart5_clk[] = { + { + .name = "uart_clk", + .id = 4, + .parent = &per_clk[0], + .secondary = &uart5_clk[1],}, + { + .name = "uart_ipg_clk", + .id = 4, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_UART5_OFFSET, + .disable = _clk_disable,}, +}; + +struct clk uart6_clk[] = { + { + .name = "uart_clk", + .id = 5, + .parent = &per_clk[0], + .secondary = &uart6_clk[1],}, + { + .name = "uart_ipg_clk", + .id = 5, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_UART6_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk gpt1_clk[] = { + { + .name = "gpt_clk", + .id = 0, + .parent = &per_clk[0], + .secondary = &gpt1_clk[1],}, + { + .name = "gpt_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_GPT1_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk gpt2_clk[] = { + { + .name = "gpt_clk", + .id = 1, + .parent = &per_clk[0], + .secondary = &gpt2_clk[1],}, + { + .name = "gpt_ipg_clk", + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_GPT2_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk gpt3_clk[] = { + { + .name = "gpt_clk", + .id = 2, + .parent = &per_clk[0], + .secondary = &gpt3_clk[1],}, + { + .name = "gpt_ipg_clk", + .id = 2, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_GPT3_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk gpt4_clk[] = { + { + .name = "gpt_clk", + .id = 3, + .parent = &per_clk[0], + .secondary = &gpt4_clk[1],}, + { + .name = "gpt_ipg_clk", + .id = 3, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_GPT4_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk gpt5_clk[] = { + { + .name = "gpt_clk", + .id = 4, + .parent = &per_clk[0], + .secondary = &gpt5_clk[1],}, + { + .name = "gpt_ipg_clk", + .id = 4, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_GPT5_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk gpt6_clk[] = { + { + .name = "gpt_clk", + .id = 5, + .parent = &per_clk[0], + .secondary = &gpt6_clk[1],}, + { + .name = "gpt_ipg_clk", + .id = 5, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_GPT6_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk pwm_clk[] = { + { + .name = "pwm_clk", + .parent = &per_clk[0], + .secondary = &pwm_clk[1],}, + { + .name = "pwm_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_PWM_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk sdhc1_clk[] = { + { + .name = "sdhc_clk", + .id = 0, + .parent = &per_clk[1], + .secondary = &sdhc1_clk[1],}, + { + .name = "sdhc_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_SDHC1_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk sdhc2_clk[] = { + { + .name = "sdhc_clk", + .id = 1, + .parent = &per_clk[1], + .secondary = &sdhc2_clk[1],}, + { + .name = "sdhc_ipg_clk", + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_SDHC2_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk sdhc3_clk[] = { + { + .name = "sdhc_clk", + .id = 2, + .parent = &per_clk[1], + .secondary = &sdhc3_clk[1],}, + { + .name = "sdhc_ipg_clk", + .id = 2, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_SDHC3_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk cspi1_clk[] = { + { + .name = "cspi_clk", + .id = 0, + .parent = &per_clk[1], + .secondary = &cspi1_clk[1],}, + { + .name = "cspi_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_CSPI1_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk cspi2_clk[] = { + { + .name = "cspi_clk", + .id = 1, + .parent = &per_clk[1], + .secondary = &cspi2_clk[1],}, + { + .name = "cspi_ipg_clk", + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_CSPI2_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk cspi3_clk[] = { + { + .name = "cspi_clk", + .id = 2, + .parent = &per_clk[1], + .secondary = &cspi3_clk[1],}, + { + .name = "cspi_ipg_clk", + .id = 2, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_CSPI3_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk lcdc_clk[] = { + { + .name = "lcdc_clk", + .parent = &per_clk[2], + .secondary = &lcdc_clk[1], + .round_rate = _clk_parent_round_rate, + .set_rate = _clk_parent_set_rate,}, + { + .name = "lcdc_ipg_clk", + .parent = &ipg_clk, + .secondary = &lcdc_clk[2], + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_LCDC_OFFSET, + .disable = _clk_disable,}, + { + .name = "lcdc_ahb_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_HCLK_LCDC_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk csi_clk[] = { + { + .name = "csi_perclk", + .parent = &per_clk[3], + .secondary = &csi_clk[1], + .round_rate = _clk_parent_round_rate, + .set_rate = _clk_parent_set_rate,}, + { + .name = "csi_ahb_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_HCLK_CSI_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk usb_clk[] = { + { + .name = "usb_clk", + .parent = &spll_clk, + .recalc = _clk_usb_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_USBOTG_OFFSET, + .disable = _clk_disable,}, + { + .name = "usb_ahb_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_HCLK_USBOTG_OFFSET, + .disable = _clk_disable,} +}; + +static struct clk ssi1_clk[] = { + { + .name = "ssi_clk", + .id = 0, + .parent = &mpll_main_clk[1], + .secondary = &ssi1_clk[1], + .recalc = _clk_ssi1_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_SSI1_BAUD_OFFSET, + .disable = _clk_disable,}, + { + .name = "ssi_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_SSI1_IPG_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk ssi2_clk[] = { + { + .name = "ssi_clk", + .id = 1, + .parent = &mpll_main_clk[1], + .secondary = &ssi2_clk[1], + .recalc = _clk_ssi2_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_SSI2_BAUD_OFFSET, + .disable = _clk_disable,}, + { + .name = "ssi_ipg_clk", + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_SSI2_IPG_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk nfc_clk = { + .name = "nfc_clk", + .parent = &cpu_clk, + .recalc = _clk_nfc_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_NFC_BAUD_OFFSET, + .disable = _clk_disable, +}; + +static struct clk vpu_clk = { + .name = "vpu_clk", + .parent = &mpll_main_clk[1], + .recalc = _clk_vpu_recalc, + .enable = _clk_vpu_enable, + .disable = _clk_vpu_disable, +}; + +static struct clk dma_clk = { + .name = "dma_clk", + .parent = &ahb_clk, + .enable = _clk_dma_enable, + .disable = _clk_dma_disable, +}; + +static struct clk rtic_clk = { + .name = "rtic_clk", + .parent = &ahb_clk, + .enable = _clk_rtic_enable, + .disable = _clk_rtic_disable, +}; + +static struct clk brom_clk = { + .name = "brom_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_HCLK_BROM_OFFSET, + .disable = _clk_disable, +}; + +static struct clk emma_clk = { + .name = "emma_clk", + .parent = &ahb_clk, + .enable = _clk_emma_enable, + .disable = _clk_emma_disable, +}; + +static struct clk slcdc_clk = { + .name = "slcdc_clk", + .parent = &ahb_clk, + .enable = _clk_slcdc_enable, + .disable = _clk_slcdc_disable, +}; + +static struct clk fec_clk = { + .name = "fec_clk", + .parent = &ahb_clk, + .enable = _clk_fec_enable, + .disable = _clk_fec_disable, +}; + +static struct clk emi_clk = { + .name = "emi_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_HCLK_EMI_OFFSET, + .disable = _clk_disable, +}; + +static struct clk sahara2_clk = { + .name = "sahara_clk", + .parent = &ahb_clk, + .enable = _clk_sahara2_enable, + .disable = _clk_sahara2_disable, +}; + +static struct clk ata_clk = { + .name = "ata_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_HCLK_ATA_OFFSET, + .disable = _clk_disable, +}; + +static struct clk mstick1_clk = { + .name = "mstick1_clk", + .parent = &ipg_clk, + .enable = _clk_mstick1_enable, + .disable = _clk_mstick1_disable, +}; + +static struct clk wdog_clk = { + .name = "wdog_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR1_WDT_OFFSET, + .disable = _clk_disable, +}; + +static struct clk gpio_clk = { + .name = "gpio_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR1, + .enable_shift = CCM_PCCR0_GPIO_OFFSET, + .disable = _clk_disable, +}; + +static struct clk i2c_clk[] = { + { + .name = "i2c_clk", + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_I2C1_OFFSET, + .disable = _clk_disable,}, + { + .name = "i2c_clk", + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_I2C2_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk iim_clk = { + .name = "iim_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_IIM_OFFSET, + .disable = _clk_disable, +}; + +static struct clk kpp_clk = { + .name = "kpp_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_KPP_OFFSET, + .disable = _clk_disable, +}; + +static struct clk owire_clk = { + .name = "owire_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_OWIRE_OFFSET, + .disable = _clk_disable, +}; + +static struct clk rtc_clk = { + .name = "rtc_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_RTC_OFFSET, + .disable = _clk_disable, +}; + +static struct clk scc_clk = { + .name = "scc_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR0, + .enable_shift = CCM_PCCR0_SCC_OFFSET, + .disable = _clk_disable, +}; + +static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate) +{ + u32 div; + + div = clk->parent->rate / rate; + if (clk->parent->rate % rate) + div++; + + if (div > 8) { + div = 8; + } + + return clk->parent->rate / div; +} + +static int _clk_clko_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg; + u32 div; + + div = clk->parent->rate / rate; + + if (div > 8 || div < 1 || ((clk->parent->rate / div) != rate)) { + return -EINVAL; + } + div--; + + reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKODIV_MASK; + reg |= div << CCM_PCDR0_CLKODIV_OFFSET; + __raw_writel(reg, CCM_PCDR0); + + clk->rate = rate; + + return 0; +} + +static void _clk_clko_recalc(struct clk *clk) +{ + u32 div; + + div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_CLKODIV_MASK >> + CCM_PCDR0_CLKODIV_OFFSET; + div++; + + clk->rate = clk->parent->rate / div; +} + +static int _clk_clko_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK; + + if (parent == &ckil_clk) { + reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET; + } else if (parent == &ckih_clk) { + reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET; + } else if (parent == mpll_clk.parent) { + reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET; + } else if (parent == spll_clk.parent) { + reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET; + } else if (parent == &mpll_clk) { + reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET; + } else if (parent == &spll_clk) { + reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET; + } else if (parent == &cpu_clk) { + reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET; + } else if (parent == &ahb_clk) { + reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET; + } else if (parent == &ipg_clk) { + reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET; + } else if (parent == &per_clk[0]) { + reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET; + } else if (parent == &per_clk[1]) { + reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET; + } else if (parent == &per_clk[2]) { + reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET; + } else if (parent == &per_clk[3]) { + reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET; + } else if (parent == &ssi1_clk[0]) { + reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET; + } else if (parent == &ssi2_clk[0]) { + reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET; + } else if (parent == &nfc_clk) { + reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET; + } else if (parent == &mstick1_clk) { + reg |= 0x11 << CCM_CCSR_CLKOSEL_OFFSET; + } else if (parent == &vpu_clk) { + reg |= 0x12 << CCM_CCSR_CLKOSEL_OFFSET; + } else if (parent == &usb_clk[0]) { + reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET; + } else { + return -EINVAL; + } + + __raw_writel(reg, CCM_CCSR); + + return 0; +} + +static int _clk_clko_enable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(CCM_PCDR0) | CCM_PCDR0_CLKO_EN; + __raw_writel(reg, CCM_PCDR0); + + return 0; +} + +static void _clk_clko_disable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKO_EN; + __raw_writel(reg, CCM_PCDR0); +} + +static struct clk clko_clk = { + .name = "clko_clk", + .recalc = _clk_clko_recalc, + .set_rate = _clk_clko_set_rate, + .round_rate = _clk_clko_round_rate, + .set_parent = _clk_clko_set_parent, + .enable = _clk_clko_enable, + .disable = _clk_clko_disable, +}; + +static struct clk *mxc_clks[] = { + &ckih_clk, + &ckil_clk, + &mpll_clk, + &mpll_main_clk[0], + &mpll_main_clk[1], + &spll_clk, + &cpu_clk, + &ahb_clk, + &ipg_clk, + &per_clk[0], + &per_clk[1], + &per_clk[2], + &per_clk[3], + &clko_clk, + &uart1_clk[0], + &uart1_clk[1], + &uart2_clk[0], + &uart2_clk[1], + &uart3_clk[0], + &uart3_clk[1], + &uart4_clk[0], + &uart4_clk[1], + &uart5_clk[0], + &uart5_clk[1], + &uart6_clk[0], + &uart6_clk[1], + &gpt1_clk[0], + &gpt1_clk[1], + &gpt2_clk[0], + &gpt2_clk[1], + &gpt3_clk[0], + &gpt3_clk[1], + &gpt4_clk[0], + &gpt4_clk[1], + &gpt5_clk[0], + &gpt5_clk[1], + &gpt6_clk[0], + &gpt6_clk[1], + &pwm_clk[0], + &pwm_clk[1], + &sdhc1_clk[0], + &sdhc1_clk[1], + &sdhc2_clk[0], + &sdhc2_clk[1], + &sdhc3_clk[0], + &sdhc3_clk[1], + &cspi1_clk[0], + &cspi1_clk[1], + &cspi2_clk[0], + &cspi2_clk[1], + &cspi3_clk[0], + &cspi3_clk[1], + &lcdc_clk[0], + &lcdc_clk[1], + &lcdc_clk[2], + &csi_clk[0], + &csi_clk[1], + &usb_clk[0], + &usb_clk[1], + &ssi1_clk[0], + &ssi1_clk[1], + &ssi2_clk[0], + &ssi2_clk[1], + &nfc_clk, + &vpu_clk, + &dma_clk, + &rtic_clk, + &brom_clk, + &emma_clk, + &slcdc_clk, + &fec_clk, + &emi_clk, + &sahara2_clk, + &ata_clk, + &mstick1_clk, + &wdog_clk, + &gpio_clk, + &i2c_clk[0], + &i2c_clk[1], + &iim_clk, + &kpp_clk, + &owire_clk, + &rtc_clk, + &scc_clk, +}; + +static void probe_mxc_clocks(void) +{ + int i; + + if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) { + if (CSCR() & 0x8000) { + cpu_clk.parent = &mpll_main_clk[0]; + } + + if (!(CSCR() & 0x00800000)) { + ssi2_clk[0].parent = &spll_clk; + } + + if (!(CSCR() & 0x00400000)) { + ssi1_clk[0].parent = &spll_clk; + } + + if (!(CSCR() & 0x00200000)) { + vpu_clk.parent = &spll_clk; + } + } else { + cpu_clk.parent = &mpll_clk; + cpu_clk.set_parent = NULL; + cpu_clk.round_rate = NULL; + cpu_clk.set_rate = NULL; + ahb_clk.parent = &mpll_clk; + + for (i = 0; i < sizeof(per_clk) / sizeof(per_clk[0]); i++) { + per_clk[i].parent = &mpll_clk; + } + + ssi1_clk[0].parent = &mpll_clk; + ssi2_clk[0].parent = &mpll_clk; + + vpu_clk.parent = &mpll_clk; + } +} + +/*! + * Function to get timer clock rate early in boot process before clock tree is + * initialized. + * + * @return Clock rate for timer + */ +unsigned long __init clk_early_get_timer_rate(void) +{ + if (CSCR() & CCM_CSCR_MCU) { + mpll_clk.parent = &ckih_clk; + } else { + mpll_clk.parent = &ckil_clk; + } + + /* Determine which high frequency clock source is coming in */ + ckih_clk.rate = board_get_ckih_rate(); + + probe_mxc_clocks(); + + mpll_clk.recalc(&mpll_clk); + if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) { + mpll_main_clk[0].recalc(&mpll_main_clk[0]); + mpll_main_clk[1].recalc(&mpll_main_clk[1]); + } + per_clk[0].recalc(&per_clk[0]); + per_clk[0].enable(&per_clk[0]); + gpt1_clk[1].enable(&gpt1_clk[1]); + return per_clk[0].rate; +} + +extern void propagate_rate(struct clk *tclk); + +int __init mxc_clocks_init(void) +{ + u32 cscr; + struct clk **clkp; + + for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++) { + if (*clkp == &mpll_main_clk[0] || *clkp == &mpll_main_clk[1]) { + if (cpu_is_mx27_rev(CHIP_REV_1_0) == 1) + continue; + } + clk_register(*clkp); + } + + /* Turn off all possible clocks */ + __raw_writel(CCM_PCCR0_GPT1_MASK, CCM_PCCR0); + __raw_writel(CCM_PCCR1_PERCLK1_MASK | CCM_PCCR1_HCLK_EMI_MASK, + CCM_PCCR1); + spll_clk.disable(&spll_clk); + + cscr = CSCR(); + if (cscr & CCM_CSCR_MCU) { + mpll_clk.parent = &ckih_clk; + } else { + mpll_clk.parent = &ckil_clk; + } + if (cscr & CCM_CSCR_SP) { + spll_clk.parent = &ckih_clk; + } else { + spll_clk.parent = &ckil_clk; + } + + pr_info("Clock input source is %ld\n", ckih_clk.rate); + + /* This will propagate to all children and init all the clock rates */ + propagate_rate(&ckih_clk); + propagate_rate(&ckil_clk); + + clk_enable(&emi_clk); + clk_enable(&gpio_clk); + clk_enable(&iim_clk); + clk_enable(&gpt1_clk[0]); + + return 0; +} diff --git a/arch/arm/mach-mx27/cpu.c b/arch/arm/mach-mx27/cpu.c new file mode 100644 index 000000000000..5c8909f68916 --- /dev/null +++ b/arch/arm/mach-mx27/cpu.c @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2001 Deep Blue Solutions Ltd. + * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. + * + * + * 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. + * + */ + +/*! + * @file mach-mx27/cpu.c + * + * @brief This file contains the CPU initialization code. + * + * @ingroup MSL_MX27 + */ + +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <asm/hardware.h> + +/*! + * CPU initialization. It is called by fixup_mxc_board() + */ +void __init mxc_cpu_init(void) +{ + if (!system_rev) { + mxc_set_system_rev(0x27, CHIP_REV_2_0); + } +} diff --git a/arch/arm/mach-mx27/crm_regs.h b/arch/arm/mach-mx27/crm_regs.h new file mode 100644 index 000000000000..5512aae40015 --- /dev/null +++ b/arch/arm/mach-mx27/crm_regs.h @@ -0,0 +1,283 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef __ARCH_ARM_MACH_MX27_CRM_REGS_H__ +#define __ARCH_ARM_MACH_MX27_CRM_REGS_H__ + +#include <asm/arch/hardware.h> + +#define SYSCTRL_BASE IO_ADDRESS(SYSCTRL_BASE_ADDR) + +/* Register offsets */ +#define CCM_CSCR (IO_ADDRESS(CCM_BASE_ADDR) + 0x0) +#define CCM_MPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x4) +#define CCM_MPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x8) +#define CCM_SPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0xC) +#define CCM_SPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x10) +#define CCM_OSC26MCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x14) +#define CCM_PCDR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x18) +#define CCM_PCDR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x1c) +#define CCM_PCCR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x20) +#define CCM_PCCR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x24) +#define CCM_CCSR (IO_ADDRESS(CCM_BASE_ADDR) + 0x28) +#define CCM_PMCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x2c) +#define CCM_PMCOUNT (IO_ADDRESS(CCM_BASE_ADDR) + 0x30) +#define CCM_WKGDCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x34) +#define MXC_CCM_PMCR0 SYSCTRL_BASE + 0x60 +#define MXC_CCM_DCVR0 SYSCTRL_BASE + 0x64) +#define MXC_CCM_DCVR1 SYSCTRL_BASE + 0x68) +#define MXC_CCM_DCVR2 SYSCTRL_BASE + 0x72) +#define MXC_CCM_DCVR3 SYSCTRL_BASE + 0x76) +#define MXC_CCM_PMCR0_DPTEN 0x00000001 +#define MXC_CCM_DIE 0x00000002 +#define MXC_CCM_DIM 0x0000000C +#define MXC_CCM_DCR 0x00000200 +#define MXC_CCM_PMCR0_DRCE0 0x00000010 +#define MXC_CCM_PMCR0_DRCE1 0x00000020 +#define MXC_CCM_PMCR0_DRCE2 0x00000040 +#define MXC_CCM_PMCR0_DRCE3 0x00000080 +#define MXC_CCM_PMCR0_PTVAIM MXC_CCM_DIM + +#define CCM_CSCR_USB_OFFSET 28 +#define CCM_CSCR_USB_MASK (0x7 << 28) +#define CCM_CSCR_SD_OFFSET 24 +#define CCM_CSCR_SD_MASK (0x3 << 24) +#define CCM_CSCR_SSI2 (1 << 23) +#define CCM_CSCR_SSI2_OFFSET 23 +#define CCM_CSCR_SSI1 (1 << 22) +#define CCM_CSCR_SSI1_OFFSET 22 +#define CCM_CSCR_VPU (1 << 21) +#define CCM_CSCR_VPU_OFFSET 21 +#define CCM_CSCR_MSHC (1 << 20) +#define CCM_CSCR_SPLLRES (1 << 19) +#define CCM_CSCR_MPLLRES (1 << 18) +#define CCM_CSCR_SP (1 << 17) +#define CCM_CSCR_MCU (1 << 16) +/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/ +#define CCM_CSCR_ARM_SRC (1 << 15) +#define CCM_CSCR_ARM_OFFSET 12 +#define CCM_CSCR_ARM_MASK (0x3 << 12) +/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/ +#define CCM_CSCR_PRESC_OFFSET 13 +#define CCM_CSCR_PRESC_MASK (0x7 << 13) +#define CCM_CSCR_BCLK_OFFSET 9 +#define CCM_CSCR_BCLK_MASK (0xf << 9) +#define CCM_CSCR_IPDIV_OFFSET 8 +#define CCM_CSCR_IPDIV (1 << 8) +/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/ +#define CCM_CSCR_AHB_OFFSET 8 +#define CCM_CSCR_AHB_MASK (0x3 << 8) +/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/ +#define CCM_CSCR_OSC26MDIV (1 << 4) +#define CCM_CSCR_OSC26M (1 << 3) +#define CCM_CSCR_FPM (1 << 2) +#define CCM_CSCR_SPEN (1 << 1) +#define CCM_CSCR_MPEN 1 + +#define CCM_MPCTL0_CPLM (1 << 31) +#define CCM_MPCTL0_PD_OFFSET 26 +#define CCM_MPCTL0_PD_MASK (0xf << 26) +#define CCM_MPCTL0_MFD_OFFSET 16 +#define CCM_MPCTL0_MFD_MASK (0x3ff << 16) +#define CCM_MPCTL0_MFI_OFFSET 10 +#define CCM_MPCTL0_MFI_MASK (0xf << 10) +#define CCM_MPCTL0_MFN_OFFSET 0 +#define CCM_MPCTL0_MFN_MASK 0x3ff + +#define CCM_MPCTL1_LF (1 << 15) +#define CCM_MPCTL1_BRMO (1 << 6) + +#define CCM_SPCTL0_CPLM (1 << 31) +#define CCM_SPCTL0_PD_OFFSET 26 +#define CCM_SPCTL0_PD_MASK (0xf << 26) +#define CCM_SPCTL0_MFD_OFFSET 16 +#define CCM_SPCTL0_MFD_MASK (0x3ff << 16) +#define CCM_SPCTL0_MFI_OFFSET 10 +#define CCM_SPCTL0_MFI_MASK (0xf << 10) +#define CCM_SPCTL0_MFN_OFFSET 0 +#define CCM_SPCTL0_MFN_MASK 0x3ff + +#define CCM_SPCTL1_LF (1 << 15) +#define CCM_SPCTL1_BRMO (1 << 6) + +#define CCM_OSC26MCTL_PEAK_OFFSET 16 +#define CCM_OSC26MCTL_PEAK_MASK (0x3 << 16) +#define CCM_OSC26MCTL_AGC_OFFSET 8 +#define CCM_OSC26MCTL_AGC_MASK (0x3f << 8) +#define CCM_OSC26MCTL_ANATEST_OFFSET 0 +#define CCM_OSC26MCTL_ANATEST_MASK 0x3f + +#define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26 +#define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26) +#define CCM_PCDR0_CLKO_EN 25 +#define CCM_PCDR0_CLKODIV_OFFSET 22 +#define CCM_PCDR0_CLKODIV_MASK (0x7 << 22) +#define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16 +#define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16) +/*The difinition for i.MX27 TO2*/ +#define CCM_PCDR0_VPUDIV2_OFFSET 10 +#define CCM_PCDR0_VPUDIV2_MASK (0x3f << 10) +#define CCM_PCDR0_NFCDIV2_OFFSET 6 +#define CCM_PCDR0_NFCDIV2_MASK (0xf << 6) +#define CCM_PCDR0_MSHCDIV2_MASK 0x3f +/*The difinition for i.MX27 TO2*/ +#define CCM_PCDR0_NFCDIV_OFFSET 12 +#define CCM_PCDR0_NFCDIV_MASK (0xf << 12) +#define CCM_PCDR0_VPUDIV_OFFSET 8 +#define CCM_PCDR0_VPUDIV_MASK (0xf << 8) +#define CCM_PCDR0_MSHCDIV_OFFSET 0 +#define CCM_PCDR0_MSHCDIV_MASK 0x1f + +#define CCM_PCDR1_PERDIV4_OFFSET 24 +#define CCM_PCDR1_PERDIV4_MASK (0x3f << 24) +#define CCM_PCDR1_PERDIV3_OFFSET 16 +#define CCM_PCDR1_PERDIV3_MASK (0x3f << 16) +#define CCM_PCDR1_PERDIV2_OFFSET 8 +#define CCM_PCDR1_PERDIV2_MASK (0x3f << 8) +#define CCM_PCDR1_PERDIV1_OFFSET 0 +#define CCM_PCDR1_PERDIV1_MASK 0x3f + +#define CCM_PCCR0_CSPI1_OFFSET 31 +#define CCM_PCCR0_CSPI1_MASK (1 << 31) +#define CCM_PCCR0_CSPI2_OFFSET 30 +#define CCM_PCCR0_CSPI2_MASK (1 << 30) +#define CCM_PCCR0_CSPI3_OFFSET 29 +#define CCM_PCCR0_CSPI3_MASK (1 << 29) +#define CCM_PCCR0_DMA_OFFSET 28 +#define CCM_PCCR0_DMA_MASK (1 << 28) +#define CCM_PCCR0_EMMA_OFFSET 27 +#define CCM_PCCR0_EMMA_MASK (1 << 27) +#define CCM_PCCR0_FEC_OFFSET 26 +#define CCM_PCCR0_FEC_MASK (1 << 26) +#define CCM_PCCR0_GPIO_OFFSET 25 +#define CCM_PCCR0_GPIO_MASK (1 << 25) +#define CCM_PCCR0_GPT1_OFFSET 24 +#define CCM_PCCR0_GPT1_MASK (1 << 24) +#define CCM_PCCR0_GPT2_OFFSET 23 +#define CCM_PCCR0_GPT2_MASK (1 << 23) +#define CCM_PCCR0_GPT3_OFFSET 22 +#define CCM_PCCR0_GPT3_MASK (1 << 22) +#define CCM_PCCR0_GPT4_OFFSET 21 +#define CCM_PCCR0_GPT4_MASK (1 << 21) +#define CCM_PCCR0_GPT5_OFFSET 20 +#define CCM_PCCR0_GPT5_MASK (1 << 20) +#define CCM_PCCR0_GPT6_OFFSET 19 +#define CCM_PCCR0_GPT6_MASK (1 << 19) +#define CCM_PCCR0_I2C1_OFFSET 18 +#define CCM_PCCR0_I2C1_MASK (1 << 18) +#define CCM_PCCR0_I2C2_OFFSET 17 +#define CCM_PCCR0_I2C2_MASK (1 << 17) +#define CCM_PCCR0_IIM_OFFSET 16 +#define CCM_PCCR0_IIM_MASK (1 << 16) +#define CCM_PCCR0_KPP_OFFSET 15 +#define CCM_PCCR0_KPP_MASK (1 << 15) +#define CCM_PCCR0_LCDC_OFFSET 14 +#define CCM_PCCR0_LCDC_MASK (1 << 14) +#define CCM_PCCR0_MSHC_OFFSET 13 +#define CCM_PCCR0_MSHC_MASK (1 << 13) +#define CCM_PCCR0_OWIRE_OFFSET 12 +#define CCM_PCCR0_OWIRE_MASK (1 << 12) +#define CCM_PCCR0_PWM_OFFSET 11 +#define CCM_PCCR0_PWM_MASK (1 << 11) +#define CCM_PCCR0_RTC_OFFSET 9 +#define CCM_PCCR0_RTC_MASK (1 << 9) +#define CCM_PCCR0_RTIC_OFFSET 8 +#define CCM_PCCR0_RTIC_MASK (1 << 8) +#define CCM_PCCR0_SAHARA_OFFSET 7 +#define CCM_PCCR0_SAHARA_MASK (1 << 7) +#define CCM_PCCR0_SCC_OFFSET 6 +#define CCM_PCCR0_SCC_MASK (1 << 6) +#define CCM_PCCR0_SDHC1_OFFSET 5 +#define CCM_PCCR0_SDHC1_MASK (1 << 5) +#define CCM_PCCR0_SDHC2_OFFSET 4 +#define CCM_PCCR0_SDHC2_MASK (1 << 4) +#define CCM_PCCR0_SDHC3_OFFSET 3 +#define CCM_PCCR0_SDHC3_MASK (1 << 3) +#define CCM_PCCR0_SLCDC_OFFSET 2 +#define CCM_PCCR0_SLCDC_MASK (1 << 2) +#define CCM_PCCR0_SSI1_IPG_OFFSET 1 +#define CCM_PCCR0_SSI1_IPG_MASK (1 << 1) +#define CCM_PCCR0_SSI2_IPG_OFFSET 0 +#define CCM_PCCR0_SSI2_IPG_MASK (1 << 0) + +#define CCM_PCCR1_UART1_OFFSET 31 +#define CCM_PCCR1_UART1_MASK (1 << 31) +#define CCM_PCCR1_UART2_OFFSET 30 +#define CCM_PCCR1_UART2_MASK (1 << 30) +#define CCM_PCCR1_UART3_OFFSET 29 +#define CCM_PCCR1_UART3_MASK (1 << 29) +#define CCM_PCCR1_UART4_OFFSET 28 +#define CCM_PCCR1_UART4_MASK (1 << 28) +#define CCM_PCCR1_UART5_OFFSET 27 +#define CCM_PCCR1_UART5_MASK (1 << 27) +#define CCM_PCCR1_UART6_OFFSET 26 +#define CCM_PCCR1_UART6_MASK (1 << 26) +#define CCM_PCCR1_USBOTG_OFFSET 25 +#define CCM_PCCR1_USBOTG_MASK (1 << 25) +#define CCM_PCCR1_WDT_OFFSET 24 +#define CCM_PCCR1_WDT_MASK (1 << 24) +#define CCM_PCCR1_HCLK_ATA_OFFSET 23 +#define CCM_PCCR1_HCLK_ATA_MASK (1 << 23) +#define CCM_PCCR1_HCLK_BROM_OFFSET 22 +#define CCM_PCCR1_HCLK_BROM_MASK (1 << 22) +#define CCM_PCCR1_HCLK_CSI_OFFSET 21 +#define CCM_PCCR1_HCLK_CSI_MASK (1 << 21) +#define CCM_PCCR1_HCLK_DMA_OFFSET 20 +#define CCM_PCCR1_HCLK_DMA_MASK (1 << 20) +#define CCM_PCCR1_HCLK_EMI_OFFSET 19 +#define CCM_PCCR1_HCLK_EMI_MASK (1 << 19) +#define CCM_PCCR1_HCLK_EMMA_OFFSET 18 +#define CCM_PCCR1_HCLK_EMMA_MASK (1 << 18) +#define CCM_PCCR1_HCLK_FEC_OFFSET 17 +#define CCM_PCCR1_HCLK_FEC_MASK (1 << 17) +#define CCM_PCCR1_HCLK_VPU_OFFSET 16 +#define CCM_PCCR1_HCLK_VPU_MASK (1 << 16) +#define CCM_PCCR1_HCLK_LCDC_OFFSET 15 +#define CCM_PCCR1_HCLK_LCDC_MASK (1 << 15) +#define CCM_PCCR1_HCLK_RTIC_OFFSET 14 +#define CCM_PCCR1_HCLK_RTIC_MASK (1 << 14) +#define CCM_PCCR1_HCLK_SAHARA_OFFSET 13 +#define CCM_PCCR1_HCLK_SAHARA_MASK (1 << 13) +#define CCM_PCCR1_HCLK_SLCDC_OFFSET 12 +#define CCM_PCCR1_HCLK_SLCDC_MASK (1 << 12) +#define CCM_PCCR1_HCLK_USBOTG_OFFSET 11 +#define CCM_PCCR1_HCLK_USBOTG_MASK (1 << 11) +#define CCM_PCCR1_PERCLK1_OFFSET 10 +#define CCM_PCCR1_PERCLK1_MASK (1 << 10) +#define CCM_PCCR1_PERCLK2_OFFSET 9 +#define CCM_PCCR1_PERCLK2_MASK (1 << 9) +#define CCM_PCCR1_PERCLK3_OFFSET 8 +#define CCM_PCCR1_PERCLK3_MASK (1 << 8) +#define CCM_PCCR1_PERCLK4_OFFSET 7 +#define CCM_PCCR1_PERCLK4_MASK (1 << 7) +#define CCM_PCCR1_VPU_BAUD_OFFSET 6 +#define CCM_PCCR1_VPU_BAUD_MASK (1 << 6) +#define CCM_PCCR1_SSI1_BAUD_OFFSET 5 +#define CCM_PCCR1_SSI1_BAUD_MASK (1 << 5) +#define CCM_PCCR1_SSI2_BAUD_OFFSET 4 +#define CCM_PCCR1_SSI2_BAUD_MASK (1 << 4) +#define CCM_PCCR1_NFC_BAUD_OFFSET 3 +#define CCM_PCCR1_NFC_BAUD_MASK (1 << 3) +#define CCM_PCCR1_MSHC_BAUD_OFFSET 2 +#define CCM_PCCR1_MSHC_BAUD_MASK (1 << 2) + +#define CCM_CCSR_32KSR (1 << 15) +#define CCM_CCSR_CLKMODE1 (1 << 9) +#define CCM_CCSR_CLKMODE0 (1 << 8) +#define CCM_CCSR_CLKOSEL_OFFSET 0 +#define CCM_CCSR_CLKOSEL_MASK 0x1f + +#define SYS_FMCR 0x14 /* Functional Muxing Control Reg */ +#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */ + +#endif /* __ARCH_ARM_MACH_MX27_CRM_REGS_H__ */ diff --git a/arch/arm/mach-mx27/devices.c b/arch/arm/mach-mx27/devices.c new file mode 100644 index 000000000000..e22020206c83 --- /dev/null +++ b/arch/arm/mach-mx27/devices.c @@ -0,0 +1,600 @@ +/* + * Author: MontaVista Software, Inc. + * <source@mvista.com> + * + * Based on the OMAP devices.c + * + * 2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is + * licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> + +#include <linux/spi/spi.h> + +#include <asm/hardware.h> +#include <asm/arch/pmic_external.h> +#include <asm/arch/pmic_power.h> +#include <asm/arch/mmc.h> + + /*! + * @file mach-mx27/devices.c + * @brief device configurations including nor/nand/watchdog for mx27. + * + * @ingroup MSL_MX27 + */ + +#ifndef CONFIG_MX27_DPTC +extern struct dptc_wp dptc_wp_allfreq[DPTC_WP_SUPPORTED]; +#endif + +static void mxc_nop_release(struct device *dev) +{ + /* Nothing */ +} + +#if defined(CONFIG_W1_MASTER_MXC) || defined(CONFIG_W1_MASTER_MXC_MODULE) +static struct mxc_w1_config mxc_w1_data = { + .search_rom_accelerator = 0, +}; + +static struct platform_device mxc_w1_devices = { + .name = "mxc_w1", + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_w1_data, + }, + .id = 0 +}; + +static void mxc_init_owire(void) +{ + (void)platform_device_register(&mxc_w1_devices); +} +#else +static inline void mxc_init_owire(void) +{ +} +#endif + +#if defined(CONFIG_RTC_MXC) || defined(CONFIG_RTC_MXC_MODULE) +static struct resource rtc_resources[] = { + { + .start = RTC_BASE_ADDR, + .end = RTC_BASE_ADDR + 0x30, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_RTC, + .flags = IORESOURCE_IRQ, + }, +}; +static struct platform_device mxc_rtc_device = { + .name = "mxc_rtc", + .id = 0, + .dev = { + .release = mxc_nop_release, + }, + .num_resources = ARRAY_SIZE(rtc_resources), + .resource = rtc_resources, +}; +static void mxc_init_rtc(void) +{ + (void)platform_device_register(&mxc_rtc_device); +} +#else +static inline void mxc_init_rtc(void) +{ +} +#endif +#if defined(CONFIG_MXC_WATCHDOG) || defined(CONFIG_MXC_WATCHDOG_MODULE) + +static struct resource wdt_resources[] = { + { + .start = WDOG1_BASE_ADDR, + .end = WDOG1_BASE_ADDR + 0x30, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mxc_wdt_device = { + .name = "mxc_wdt", + .id = 0, + .dev = { + .release = mxc_nop_release, + }, + .num_resources = ARRAY_SIZE(wdt_resources), + .resource = wdt_resources, +}; + +static void mxc_init_wdt(void) +{ + (void)platform_device_register(&mxc_wdt_device); +} +#else +static inline void mxc_init_wdt(void) +{ +} +#endif + +/* MMC device data */ + +#if defined(CONFIG_MMC_MXC) || defined(CONFIG_MMC_MXC_MODULE) + +extern unsigned int sdhc_get_card_det_status(struct device *dev); +extern int sdhc_init_card_det(int id); + +static struct mxc_mmc_platform_data mmc_data = { + .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30, + .min_clk = 150000, + .max_clk = 25000000, + .card_inserted_state = 0, + .status = sdhc_get_card_det_status, +}; + +/*! + * Resource definition for the SDHC1 + */ +static struct resource mxcsdhc1_resources[] = { + [0] = { + .start = SDHC1_BASE_ADDR, + .end = SDHC1_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = INT_SDHC1, + .end = INT_SDHC1, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = 0, + .end = 0, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = MXC_SDIO1_CARD_IRQ, + .end = MXC_SDIO1_CARD_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! + * Resource definition for the SDHC2 + */ +static struct resource mxcsdhc2_resources[] = { + [0] = { + .start = SDHC2_BASE_ADDR, + .end = SDHC2_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = INT_SDHC2, + .end = INT_SDHC2, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = 0, + .end = 0, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = MXC_SDIO2_CARD_IRQ, + .end = MXC_SDIO2_CARD_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Device Definition for MXC SDHC1 */ +static struct platform_device mxcsdhc1_device = { + .name = "mxcmci", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mmc_data, + }, + .num_resources = ARRAY_SIZE(mxcsdhc1_resources), + .resource = mxcsdhc1_resources, +}; + +/*! Device Definition for MXC SDHC2 */ +static struct platform_device mxcsdhc2_device = { + .name = "mxcmci", + .id = 1, + .dev = { + .release = mxc_nop_release, + .platform_data = &mmc_data, + }, + .num_resources = ARRAY_SIZE(mxcsdhc2_resources), + .resource = mxcsdhc2_resources, +}; + +#ifdef CONFIG_MXC_SDHC3 +/*! + * Resource definition for the SDHC3 + */ +static struct resource mxcsdhc3_resources[] = { + [0] = { + .start = SDHC3_BASE_ADDR, + .end = SDHC3_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = INT_SDHC3, + .end = INT_SDHC3, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = 0, + .end = 0, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = MXC_SDIO3_CARD_IRQ, + .end = MXC_SDIO3_CARD_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Device Definition for MXC SDHC3 */ +static struct platform_device mxcsdhc3_device = { + .name = "mxcmci", + .id = 2, + .dev = { + .release = mxc_nop_release, + .platform_data = &mmc_data, + }, + .num_resources = ARRAY_SIZE(mxcsdhc3_resources), + .resource = mxcsdhc3_resources, +}; +#endif + +static inline void mxc_init_mmc(void) +{ + int cd_irq; + + cd_irq = sdhc_init_card_det(0); + if (cd_irq) { + mxcsdhc1_device.resource[2].start = cd_irq; + mxcsdhc1_device.resource[2].end = cd_irq; + } + cd_irq = sdhc_init_card_det(1); + if (cd_irq) { + mxcsdhc2_device.resource[2].start = cd_irq; + mxcsdhc2_device.resource[2].end = cd_irq; + } + + (void)platform_device_register(&mxcsdhc1_device); + (void)platform_device_register(&mxcsdhc2_device); +#ifdef CONFIG_MXC_SDHC3 + (void)platform_device_register(&mxcsdhc3_device); +#endif +} +#else +static inline void mxc_init_mmc(void) +{ +} +#endif + +/* SPI controller and device data */ +#if defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE) + +#ifdef CONFIG_SPI_MXC_SELECT1 +/*! + * Resource definition for the CSPI1 + */ +static struct resource mxcspi1_resources[] = { + [0] = { + .start = CSPI1_BASE_ADDR, + .end = CSPI1_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = INT_CSPI1, + .end = INT_CSPI1, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Platform Data for MXC CSPI1 */ +static struct mxc_spi_master mxcspi1_data = { + .maxchipselect = 4, + .spi_version = 0, +}; + +/*! Device Definition for MXC CSPI1 */ +static struct platform_device mxcspi1_device = { + .name = "mxc_spi", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxcspi1_data, + }, + .num_resources = ARRAY_SIZE(mxcspi1_resources), + .resource = mxcspi1_resources, +}; + +#endif /* CONFIG_SPI_MXC_SELECT1 */ + +#ifdef CONFIG_SPI_MXC_SELECT2 +/*! + * Resource definition for the CSPI2 + */ +static struct resource mxcspi2_resources[] = { + [0] = { + .start = CSPI2_BASE_ADDR, + .end = CSPI2_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = INT_CSPI2, + .end = INT_CSPI2, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Platform Data for MXC CSPI2 */ +static struct mxc_spi_master mxcspi2_data = { + .maxchipselect = 4, + .spi_version = 0, +}; + +/*! Device Definition for MXC CSPI2 */ +static struct platform_device mxcspi2_device = { + .name = "mxc_spi", + .id = 1, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxcspi2_data, + }, + .num_resources = ARRAY_SIZE(mxcspi2_resources), + .resource = mxcspi2_resources, +}; +#endif /* CONFIG_SPI_MXC_SELECT2 */ + +#ifdef CONFIG_SPI_MXC_SELECT3 +/*! + * Resource definition for the CSPI3 + */ +static struct resource mxcspi3_resources[] = { + [0] = { + .start = CSPI3_BASE_ADDR, + .end = CSPI3_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = INT_CSPI3, + .end = INT_CSPI3, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Platform Data for MXC CSPI3 */ +static struct mxc_spi_master mxcspi3_data = { + .maxchipselect = 4, + .spi_version = 0, +}; + +/*! Device Definition for MXC CSPI3 */ +static struct platform_device mxcspi3_device = { + .name = "mxc_spi", + .id = 2, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxcspi3_data, + }, + .num_resources = ARRAY_SIZE(mxcspi3_resources), + .resource = mxcspi3_resources, +}; +#endif /* CONFIG_SPI_MXC_SELECT3 */ + +static inline void mxc_init_spi(void) +{ +#ifdef CONFIG_SPI_MXC_SELECT1 + if (platform_device_register(&mxcspi1_device) < 0) + printk(KERN_ERR "Registering the SPI Controller_1\n"); +#endif /* CONFIG_SPI_MXC_SELECT1 */ +#ifdef CONFIG_SPI_MXC_SELECT2 + if (platform_device_register(&mxcspi2_device) < 0) + printk(KERN_ERR "Registering the SPI Controller_2\n"); +#endif /* CONFIG_SPI_MXC_SELECT2 */ +#ifdef CONFIG_SPI_MXC_SELECT3 + if (platform_device_register(&mxcspi3_device) < 0) + printk(KERN_ERR "Registering the SPI Controller_3\n"); +#endif /* CONFIG_SPI_MXC_SELECT3 */ +} +#else +static inline void mxc_init_spi(void) +{ +} +#endif + +/* I2C controller and device data */ +#if defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE) + +#ifdef CONFIG_I2C_MXC_SELECT1 +/*! + * Resource definition for the I2C1 + */ +static struct resource mxci2c1_resources[] = { + [0] = { + .start = I2C_BASE_ADDR, + .end = I2C_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = INT_I2C, + .end = INT_I2C, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Platform Data for MXC I2C */ +static struct mxc_i2c_platform_data mxci2c1_data = { + .i2c_clk = 100000, +}; +#endif + +#ifdef CONFIG_I2C_MXC_SELECT2 +/*! + * Resource definition for the I2C2 + */ +static struct resource mxci2c2_resources[] = { + [0] = { + .start = I2C2_BASE_ADDR, + .end = I2C2_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = INT_I2C2, + .end = INT_I2C2, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Platform Data for MXC I2C */ +static struct mxc_i2c_platform_data mxci2c2_data = { + .i2c_clk = 100000, +}; +#endif + +/*! Device Definition for MXC I2C */ +static struct platform_device mxci2c_devices[] = { +#ifdef CONFIG_I2C_MXC_SELECT1 + { + .name = "mxc_i2c", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxci2c1_data, + }, + .num_resources = ARRAY_SIZE(mxci2c1_resources), + .resource = mxci2c1_resources,}, +#endif +#ifdef CONFIG_I2C_MXC_SELECT2 + { + .name = "mxc_i2c", + .id = 1, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxci2c2_data, + }, + .num_resources = ARRAY_SIZE(mxci2c2_resources), + .resource = mxci2c2_resources,}, +#endif +}; + +static inline void mxc_init_i2c(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(mxci2c_devices); i++) { + if (platform_device_register(&mxci2c_devices[i]) < 0) + dev_err(&mxci2c_devices[i].dev, + "Unable to register I2C device\n"); + } +} +#else +static inline void mxc_init_i2c(void) +{ +} +#endif + +#ifdef CONFIG_MXC_VPU +/*! Platform Data for MXC VPU */ +static struct platform_device mxcvpu_device = { + .name = "mxc_vpu", + .dev = { + .release = mxc_nop_release, + }, + .id = 0, +}; + +static inline void mxc_init_vpu(void) +{ + if (platform_device_register(&mxcvpu_device) < 0) + printk(KERN_ERR "Error: Registering the VPU.\n"); +} +#else +static inline void mxc_init_vpu(void) +{ +} +#endif + +struct mxc_gpio_port mxc_gpio_ports[GPIO_PORT_NUM] = { + { + .num = 0, + .base = IO_ADDRESS(GPIO_BASE_ADDR), + .irq = INT_GPIO, + .virtual_irq_start = MXC_GPIO_BASE, + }, + { + .num = 1, + .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x100, + .irq = INT_GPIO, + .virtual_irq_start = MXC_GPIO_BASE + GPIO_NUM_PIN, + }, + { + .num = 2, + .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x200, + .irq = INT_GPIO, + .virtual_irq_start = MXC_GPIO_BASE + GPIO_NUM_PIN * 2, + }, + { + .num = 3, + .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x300, + .irq = INT_GPIO, + .virtual_irq_start = MXC_GPIO_BASE + GPIO_NUM_PIN * 3, + }, + { + .num = 4, + .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x400, + .irq = INT_GPIO, + .virtual_irq_start = MXC_GPIO_BASE + GPIO_NUM_PIN * 4, + }, + { + .num = 5, + .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x500, + .irq = INT_GPIO, + .virtual_irq_start = MXC_GPIO_BASE + GPIO_NUM_PIN * 5, + }, +}; + +#ifndef CONFIG_MX27_DPTC +/*! Device Definition for DPTC */ +static struct platform_device mxc_dptc_device = { + .name = "mxc_dptc", + .dev = { + .release = mxc_nop_release, + .platform_data = &dptc_wp_allfreq, + }, +}; + +static inline void mxc_init_dptc(void) +{ + (void)platform_device_register(&mxc_dptc_device); +} +#endif + +static int __init mxc_init_devices(void) +{ + mxc_init_wdt(); + mxc_init_mmc(); + mxc_init_spi(); + mxc_init_i2c(); + mxc_init_rtc(); + mxc_init_owire(); + mxc_init_vpu(); +#ifndef CONFIG_MX27_DPTC + mxc_init_dptc(); +#endif + + return 0; +} + +arch_initcall(mxc_init_devices); diff --git a/arch/arm/mach-mx27/dma.c b/arch/arm/mach-mx27/dma.c new file mode 100644 index 000000000000..e47acb8cc055 --- /dev/null +++ b/arch/arm/mach-mx27/dma.c @@ -0,0 +1,553 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/*! + *@file mach-mx27/dma.c + *@brief This file contains the dma parameter which is depend on the platform . + * @ingroup DMA_MX27 + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <asm/dma.h> + +#define MXC_SOUND_PLAYBACK_CHAIN_DMA 1 +#define MXC_SOUND_CAPTURE_CHAIN_DMA 1 + +/*! + * @brief the structure stored device_id and dma_info pointer + */ +typedef struct dma_info_entry_s { + mxc_dma_device_t device; + /* if there are two dma_info , first is for reading, another is for writing */ + mx2_dma_info_t *info; +} dma_info_entry_t; + +/*! + * @brief dma_info from memory to memory for dma testing + */ +static mx2_dma_info_t ram2ram_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 0, + .burstLength = 4,.request = 0,.busuntils = 0, + .sourceType = DMA_TYPE_LINEAR,.sourcePort = TRANSFER_32BIT, + .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_32BIT, + .M2D_Valid = 0 +}; + +/*! + * @brief dma_info from 2D memory to 2D memory for dma testing + */ +static mx2_dma_info_t ram2d2ram2d_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 0, + .dir = 0, + .rto_en = 0, + .dma_chaining = 0,.ren = 0, + .burstLength = 4,.request = 0,.busuntils = 0, + .sourceType = DMA_TYPE_2D,.sourcePort = TRANSFER_32BIT, + .destType = DMA_TYPE_2D,.destPort = TRANSFER_32BIT, + .M2D_Valid = 1,.msel = 0,.W = 0x80,.X = 0x40,.Y = 0x10 +}; + +/*! + * @brief dma_info from memory to 2D memory for dma testing + */ +static mx2_dma_info_t ram2ram2d_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 0, + .burstLength = 4,.request = 0,.busuntils = 0, + .sourceType = DMA_TYPE_LINEAR,.sourcePort = TRANSFER_32BIT, + .destType = DMA_TYPE_2D,.destPort = TRANSFER_32BIT, + .M2D_Valid = 1,.msel = 0,.W = 0x100,.X = 0x80,.Y = 0x10 +}; + +/*! + * @brief dma_info from 2D memory to memory for dma testing + */ +static mx2_dma_info_t ram2d2ram_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 0, + .burstLength = 4,.request = 0,.busuntils = 0, + .sourceType = DMA_TYPE_2D,.sourcePort = TRANSFER_32BIT, + .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_32BIT, + .M2D_Valid = 1,.msel = 0,.W = 0x100,.X = 0x100,.Y = 0x10 +}; + +/*! + * @brief dma_info with dma chaining feature for dma testing + */ +static mx2_dma_info_t hw_chaining_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 0, + .dir = 0, + .dma_chaining = 1,.ren = 0, + .burstLength = 4,.request = 0,.busuntils = 0, + .sourceType = DMA_TYPE_LINEAR,.sourcePort = TRANSFER_32BIT, + .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_32BIT, + .M2D_Valid = 0, +}; + +/*! + * @brief dma_info without dma chaining feature for dma testing + */ +static mx2_dma_info_t sw_chaining_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 0, + .burstLength = 4,.request = 0,.busuntils = 0, + .sourceType = DMA_TYPE_LINEAR,.sourcePort = TRANSFER_32BIT, + .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_32BIT, + .M2D_Valid = 0, +}; + +/*! + * @brief dma_info for ATA recieveing + */ +static mx2_dma_info_t ata_rx_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 1, + .burstLength = 32,.request = 29,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_32BIT, + .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_32BIT, + .per_address = (ATA_BASE_ADDR + 0x18), + .M2D_Valid = 0, +}; + +/*! + * @brief: dma_info for ATA transmitting + */ +static mx2_dma_info_t ata_tx_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 1, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 1, + .burstLength = 32,.request = 28,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_32BIT, + .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_32BIT, + .per_address = (ATA_BASE_ADDR + 0x18), + .M2D_Valid = 0, +}; + +/*! + * @brief dma_info for UART1 recieveing + */ +static mx2_dma_info_t uart1_rx_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 1, + .dir = 0, + .dma_chaining = 0,.ren = 1, + .burstLength = 1,.request = 26,.busuntils = 8, + .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT, + .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT, + .per_address = (UART1_BASE_ADDR), + .M2D_Valid = 0, +}; + +/*! + * @brief: dma_info for UART1 transmitting + */ +static mx2_dma_info_t uart1_tx_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 1, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 1, + .burstLength = 1,.request = 27,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT, + .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT, + .per_address = (UART1_BASE_ADDR + 0x40), + .M2D_Valid = 0, +}; + +/*! + * @brief dma_info for UART2 recieveing + */ +static mx2_dma_info_t uart2_rx_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 1, + .burstLength = 1,.request = 24,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT, + .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT, + .per_address = (UART2_BASE_ADDR), + .M2D_Valid = 0, +}; + +/*! + * @brief: dma_info for UART2 transmitting + */ +static mx2_dma_info_t uart2_tx_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 1, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 1, + .burstLength = 1,.request = 25,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT, + .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT, + .per_address = (UART2_BASE_ADDR + 0x40), + .M2D_Valid = 0, +}; + +/*! + * @brief dma_info for UART3 recieveing + */ +static mx2_dma_info_t uart3_rx_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 1, + .burstLength = 1,.request = 22,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT, + .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT, + .per_address = (UART3_BASE_ADDR), + .M2D_Valid = 0, +}; + +/*! + * @brief: dma_info for UART3 transmitting + */ +static mx2_dma_info_t uart3_tx_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 1, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 1, + .burstLength = 1,.request = 23,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT, + .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT, + .per_address = (UART3_BASE_ADDR + 0x40), + .M2D_Valid = 0, +}; + +/*! + * @brief dma_info for UART4 recieveing + */ +static mx2_dma_info_t uart4_rx_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 1, + .burstLength = 1,.request = 20,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT, + .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT, + .per_address = (UART4_BASE_ADDR), + .M2D_Valid = 0, +}; + +/*! + * @brief: dma_info for UART4transmitting + */ +static mx2_dma_info_t uart4_tx_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 1, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 1, + .burstLength = 1,.request = 21,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT, + .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT, + .per_address = (UART4_BASE_ADDR + 0x40), + .M2D_Valid = 0, +}; + +/*! + * @brief dma_info for UART5 recieveing + */ +static mx2_dma_info_t uart5_rx_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 1, + .burstLength = 1,.request = 32,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT, + .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT, + .per_address = (UART5_BASE_ADDR), + .M2D_Valid = 0, +}; + +/*! + * @brief: dma_info for UART5 transmitting + */ +static mx2_dma_info_t uart5_tx_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 1, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 1, + .burstLength = 1,.request = 33,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT, + .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT, + .per_address = (UART5_BASE_ADDR + 0x40), + .M2D_Valid = 0, +}; + +/*! + * @brief dma_info for UART6 recieveing + */ +static mx2_dma_info_t uart6_rx_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 1, + .burstLength = 1,.request = 34,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT, + .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT, + .per_address = (UART6_BASE_ADDR), + .M2D_Valid = 0, +}; + +/*! + * @brief: dma_info for UART6 transmitting + */ +static mx2_dma_info_t uart6_tx_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 1, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 1, + .burstLength = 1,.request = 35,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT, + .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT, + .per_address = (UART6_BASE_ADDR + 0x40), + .M2D_Valid = 0, +}; + +static mx2_dma_info_t ssi1_16bit_rx0_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 0, + .dir = 0, + .dma_chaining = MXC_SOUND_CAPTURE_CHAIN_DMA,.ren = 1, + .burstLength = 8,.request = DMA_REQ_SSI1_RX0,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = DMA_MEM_SIZE_16, + .destType = DMA_TYPE_LINEAR,.destPort = DMA_MEM_SIZE_32, + .per_address = (SSI1_BASE_ADDR + 0x08), + .M2D_Valid = 0, +}; + +static mx2_dma_info_t ssi1_16bit_tx0_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 1, + .rto_en = 0, + .dir = 0, + .dma_chaining = MXC_SOUND_PLAYBACK_CHAIN_DMA,.ren = 1, + .burstLength = 8,.request = DMA_REQ_SSI1_TX0,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = DMA_MEM_SIZE_16, + .destType = DMA_TYPE_LINEAR,.destPort = DMA_MEM_SIZE_32, + .per_address = (SSI1_BASE_ADDR), + .M2D_Valid = 0, +}; + +static mx2_dma_info_t ssi2_16bit_rx0_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 0, + .dir = 0, + .dma_chaining = MXC_SOUND_CAPTURE_CHAIN_DMA,.ren = 1, + .burstLength = 8,.request = DMA_REQ_SSI2_RX0,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = DMA_MEM_SIZE_16, + .destType = DMA_TYPE_LINEAR,.destPort = DMA_MEM_SIZE_32, + .per_address = (SSI2_BASE_ADDR + 0x08), + .M2D_Valid = 0, +}; + +static mx2_dma_info_t ssi2_16bit_tx0_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 1, + .rto_en = 0, + .dir = 0, + .dma_chaining = MXC_SOUND_PLAYBACK_CHAIN_DMA,.ren = 1, + .burstLength = 8,.request = DMA_REQ_SSI2_TX0,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = DMA_MEM_SIZE_16, + .destType = DMA_TYPE_LINEAR,.destPort = DMA_MEM_SIZE_32, + .per_address = (SSI2_BASE_ADDR), + .M2D_Valid = 0, +}; + +static mx2_dma_info_t mmc1_width1_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 1, + .burstLength = 16,.request = DMA_REQ_SDHC1,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = DMA_MEM_SIZE_32, + .destType = DMA_TYPE_LINEAR,.destPort = DMA_MEM_SIZE_32, + .per_address = (SDHC1_BASE_ADDR + 0x38), + .M2D_Valid = 0, +}; + +static mx2_dma_info_t mmc1_width4_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 1, + .burstLength = 0,.request = DMA_REQ_SDHC1,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = DMA_MEM_SIZE_32, + .destType = DMA_TYPE_LINEAR,.destPort = DMA_MEM_SIZE_32, + .per_address = (SDHC1_BASE_ADDR + 0x38), + .M2D_Valid = 0, +}; + +static mx2_dma_info_t mmc2_width1_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 1, + .burstLength = 16,.request = DMA_REQ_SDHC2,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = DMA_MEM_SIZE_32, + .destType = DMA_TYPE_LINEAR,.destPort = DMA_MEM_SIZE_32, + .per_address = (SDHC2_BASE_ADDR + 0x38), + .M2D_Valid = 0, +}; + +static mx2_dma_info_t mmc2_width4_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 0, + .dir = 0, + .dma_chaining = 0,.ren = 1, + .burstLength = 0,.request = DMA_REQ_SDHC2,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = DMA_MEM_SIZE_32, + .destType = DMA_TYPE_LINEAR,.destPort = DMA_MEM_SIZE_32, + .per_address = (SDHC2_BASE_ADDR + 0x38), + .M2D_Valid = 0, +}; + +static mx2_dma_info_t csi_rx_dma_info = { + .dma_chan = MXC_DMA_DYNAMIC_CHANNEL, + .mode = 0, + .rto_en = 0, + .dir = 0, + .dma_chaining = 1,.ren = 1, + .burstLength = 64,.request = DMA_REQ_CSI_RX,.busuntils = 0, + .sourceType = DMA_TYPE_FIFO,.sourcePort = DMA_MEM_SIZE_32, + .destType = DMA_TYPE_LINEAR,.destPort = DMA_MEM_SIZE_32, + .per_address = (CSI_BASE_ADDR + 0x10), + .M2D_Valid = 0, +}; + +/*! + * @brief dma info array which is actived + * DEVICE_ID RX/(RX&TX) TX + */ +static dma_info_entry_t active_dma_info[] = { + {MXC_DMA_TEST_RAM2RAM, &ram2ram_dma_info}, + {MXC_DMA_TEST_RAM2D2RAM2D, &ram2d2ram2d_dma_info}, + {MXC_DMA_TEST_RAM2RAM2D, &ram2ram2d_dma_info}, + {MXC_DMA_TEST_RAM2D2RAM, &ram2d2ram_dma_info}, + {MXC_DMA_TEST_HW_CHAINING, &hw_chaining_dma_info}, + {MXC_DMA_TEST_SW_CHAINING, &sw_chaining_dma_info}, + {MXC_DMA_ATA_RX, &ata_rx_dma_info}, + {MXC_DMA_ATA_TX, &ata_tx_dma_info}, + {MXC_DMA_UART1_RX, &uart1_rx_dma_info}, + {MXC_DMA_UART1_TX, &uart1_tx_dma_info}, + {MXC_DMA_UART2_RX, &uart2_rx_dma_info}, + {MXC_DMA_UART2_TX, &uart2_tx_dma_info}, + {MXC_DMA_UART3_RX, &uart3_rx_dma_info}, + {MXC_DMA_UART3_TX, &uart3_tx_dma_info}, + {MXC_DMA_UART4_RX, &uart4_rx_dma_info}, + {MXC_DMA_UART4_TX, &uart4_tx_dma_info}, + {MXC_DMA_UART5_RX, &uart5_rx_dma_info}, + {MXC_DMA_UART5_TX, &uart5_tx_dma_info}, + {MXC_DMA_UART6_RX, &uart6_rx_dma_info}, + {MXC_DMA_UART6_TX, &uart6_tx_dma_info}, + {MXC_DMA_SSI1_16BIT_RX0, &ssi1_16bit_rx0_dma_info}, + {MXC_DMA_SSI1_16BIT_TX0, &ssi1_16bit_tx0_dma_info}, + {MXC_DMA_SSI2_16BIT_RX0, &ssi2_16bit_rx0_dma_info}, + {MXC_DMA_SSI2_16BIT_TX0, &ssi2_16bit_tx0_dma_info}, + {MXC_DMA_MMC1_WIDTH_1, &mmc1_width1_dma_info}, + {MXC_DMA_MMC1_WIDTH_4, &mmc1_width4_dma_info}, + {MXC_DMA_MMC2_WIDTH_1, &mmc2_width1_dma_info}, + {MXC_DMA_MMC2_WIDTH_4, &mmc2_width4_dma_info}, + {MXC_DMA_CSI_RX, &csi_rx_dma_info}, +}; + +/*! + * @brief the number of actived dma info + */ +static int dma_info_entrys = + sizeof(active_dma_info) / sizeof(active_dma_info[0]); + +/*! + * @brief get the dma info by channel_id + */ +mx2_dma_info_t *mxc_dma_get_info(mxc_dma_device_t channel_id) +{ + dma_info_entry_t *p = active_dma_info; + int i; + for (i = 0; i < dma_info_entrys; i++, p++) { + if (p->device == channel_id) + return p->info; + } + return NULL; +} + +/*! + * @brief: scan dma parameter list . And collect information about which channels are dynamic . + */ +void mxc_dma_load_info(mxc_dma_channel_t * dma) +{ + int i, idx; + dma_info_entry_t *p = active_dma_info; + + BUG_ON(dma == NULL); + BUG_ON(p == NULL); + + for (i = 0; i < MXC_DMA_CHANNELS; i++) { + dma[i].dynamic = 1; + } + + for (i = 0; i < dma_info_entrys; i++, p++) { + BUG_ON((p->info == NULL)); + + idx = p->info->dma_chan; + + BUG_ON(((idx >= MAX_DMA_CHANNELS) + && (idx != MXC_DMA_DYNAMIC_CHANNEL))); + if ((idx < 0) || (idx == MXC_DMA_DYNAMIC_CHANNEL)) + continue; + dma[idx].dynamic = 0; + } +} + +EXPORT_SYMBOL(mxc_dma_get_info); +EXPORT_SYMBOL(mxc_dma_load_info); diff --git a/arch/arm/mach-mx27/dpm.c b/arch/arm/mach-mx27/dpm.c new file mode 100644 index 000000000000..9aacfcbdd347 --- /dev/null +++ b/arch/arm/mach-mx27/dpm.c @@ -0,0 +1,405 @@ +/* REVISIT Doxygen fixups */ +/* + * DPM support for Freescale i.MX27 + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Copyright (C) 2002, 2004 MontaVista Software <source@mvista.com>. + * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. + * + * Based on code by Matthew Locke, Dmitry Chigirev, and Bishop Brock. + */ + +/*! + * @file mach-mx27/dpm.c + * + * @brief This file provides DPM support hooks for the Freescale i.MX27 + * + * @ingroup DPM_MX27 + */ + +#include <linux/dpm.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/kmod.h> +#include <linux/module.h> +#include <linux/proc_fs.h> +#include <linux/stat.h> +#include <linux/string.h> +#include <linux/device.h> +#include <linux/pm.h> +#include <linux/delay.h> + +#include <asm/hardirq.h> +#include <asm/page.h> +#include <asm/processor.h> +#include <asm/uaccess.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/arch/mxc_pm.h> +#include <asm/arch/clock.h> + +static unsigned saved_cpu_freq; +static unsigned long saved_loops_per_jiffy; +static unsigned int curr_mode = DPM_MODE_RUN; + +extern void (*pm_idle) (void); + +static int mxc_dpm_set_opt(struct dpm_opt *cur, struct dpm_opt *new) +{ + struct dpm_md_opt *md_cur, *md_new; + unsigned long flags; + + md_cur = &cur->md_opt; + md_new = &new->md_opt; + + if (md_new->cpu == -1) + md_new->cpu = md_cur->cpu; + if (md_new->ahb == -1) + md_new->ahb = md_cur->ahb; + if (md_new->ip == -1) + md_new->ip = md_cur->ip; + if (md_new->mode == -1) + md_new->mode = md_cur->mode; + + if (md_new->cpu == 0 || md_new->mode == DPM_MODE_SLEEP) { + +#ifdef CONFIG_PM + pm_suspend(PM_SUSPEND_MEM); + + /* Here when we wake up. Recursive call to switch back to + * to task state. + */ + dpm_set_os(DPM_TASK_STATE); +#endif + return 0; + } + + if (md_new->mode == DPM_MODE_WAIT) { +#ifdef CONFIG_PM + pm_suspend(PM_SUSPEND_STANDBY); + + /* Here when we wake up. Recursive call to switch back to + * to task state. + */ + dpm_set_os(DPM_TASK_STATE); +#endif + return 0; + } + + if (md_new->mode == DPM_MODE_STOP) { +#ifdef CONFIG_PM + pm_suspend(PM_SUSPEND_STOP); + + /* Here when we wake up. Recursive call to switch back to + * to task state. + */ + dpm_set_os(DPM_TASK_STATE); +#endif + return 0; + } + + local_irq_save(flags); + + if (md_new->cpu) { + loops_per_jiffy = + dpm_compute_lpj(saved_loops_per_jiffy, saved_cpu_freq, + md_new->cpu / 1000); + } +#ifdef CONFIG_PM + mxc_pm_dvfs(md_new->cpu, md_new->ahb, md_new->ip); + curr_mode = md_new->mode; +#endif + + local_irq_restore(flags); + return 0; +} + +static int mxc_dpm_init_opt(struct dpm_opt *opt) +{ + int core = opt->pp[DPM_CORE_FREQ]; + int ahb = opt->pp[DPM_AHB_FREQ]; + int ip = opt->pp[DPM_IP_FREQ]; + int mode = opt->pp[DPM_MODE]; + struct dpm_md_opt *md_opt = &opt->md_opt; + + if (mode != DPM_MODE_SLEEP && + mode != DPM_MODE_RUN && + mode != DPM_MODE_WAIT && mode != DPM_MODE_STOP && mode != -1) { + printk(KERN_ERR "MXC DPM Error: " + "MCU mode is out of range. " + "Possible settings: 0 - sleep, 1 - run, 2 - wait, 3 - stop\n"); + return -EINVAL; + } + + if (mode == DPM_MODE_SLEEP || core == 0) { + md_opt->cpu = 0; + md_opt->ahb = 0; + md_opt->ip = 0; + md_opt->mode = mode; + return 0; + } + + if (ahb != -1 && (ahb > AHB_MAX || ahb < AHB_MIN)) { + printk(KERN_ERR "MXC DPM Error: " + "AHB frequency setting %u is out of range for opt " + "named %s. Possible settings: %d .. %d.\n", + ahb, opt->name, AHB_MIN, AHB_MAX); + return -EINVAL; + } + + if (ahb != -1 && ahb % AHB_MIN != 0) { + printk(KERN_ERR "MXC DPM Error: " + "AHB frequency setting %u is out of range for opt " + "named %s. AHB frequency should be multiple of %d.\n", + ahb, opt->name, AHB_MIN); + return -EINVAL; + } + + if (ip != -1 && (ip > IPG_MAX || ip < IPG_MIN)) { + printk(KERN_ERR "MXC DPM Error: " + "IPG frequency setting %u is out of range for opt " + "named %s. Possible settings: %d .. %d.\n", + ip, opt->name, IPG_MIN, IPG_MAX); + return -EINVAL; + } + + if (ip != -1 && ip % IPG_MIN != 0) { + printk(KERN_ERR "MXC DPM Error: " + "IP frequency setting %u is out of range for opt " + "named %s. IP frequency should be multiple of %d.\n", + ip, opt->name, IPG_MIN); + return -EINVAL; + } + + if (core != -1 && (core > ARM_MAX || core < ARM_MIN) && core != 0) { + printk(KERN_ERR "MXC DPM Error: " + "ARM frequency setting %u is out of range for opt " + "named %s. Possible settings: %d .. %d.\n", + core, opt->name, ARM_MIN, ARM_MAX); + return -EINVAL; + } +#if 0 + if (core != -1 && core % ARM_MIN != 0) { + printk(KERN_ERR "MXC DPM Error: " + "ARM frequency setting %u is out of range for opt " + "named %s. ARM frequency should be multiple of %d.\n", + core, opt->name, ARM_MIN); + return -EINVAL; + } +#endif + md_opt->cpu = core; + md_opt->ahb = ahb; + md_opt->ip = ip; + md_opt->mode = mode; + return 0; +} + +/*! + * Fully determine the current machine-dependent operating point, and fill in a + * structure presented by the caller. This should only be called when the + * dpm_sem is held. This call can return an error if the system is currently at + * an operating point that could not be constructed by dpm_md_init_opt(). + */ +static int mxc_dpm_get_opt(struct dpm_opt *opt) +{ + struct dpm_md_opt *md_opt; + + md_opt = &opt->md_opt; + + md_opt->cpu = mxc_get_clocks(CPU_CLK); + md_opt->ahb = mxc_get_clocks(AHB_CLK); + md_opt->ip = mxc_get_clocks(IPG_CLK); + md_opt->mode = curr_mode; + + return 0; +} + +/**************************************************************************** + * Machine-dependent /proc/driver/dpm/md entries + ****************************************************************************/ + +static inline int p5d(char *buf, unsigned mhz) +{ + return sprintf(buf, "%5d", mhz); /* Round */ +} + +int dpm_proc_print_opt(char *buf, struct dpm_opt *opt) +{ + int len = 0; + struct dpm_md_opt *md_opt; + + md_opt = &opt->md_opt; + + len += sprintf(buf + len, "%12s %9lu", opt->name, opt->stats.count); + len += sprintf(buf + len, "\t%d\t%d\t%d\n", + md_opt->cpu, md_opt->ahb, md_opt->ip); + /* Add MODE string later */ + return len; +} + +int +read_proc_dpm_md_opts(char *page, char **start, off_t offset, + int count, int *eof, void *data) +{ + int len = 0; + int limit = offset + count; + struct dpm_opt *opt; + struct list_head *opt_list; + + /* FIXME: For now we assume that the complete table, + * formatted, fits within one page */ + if (offset >= PAGE_SIZE) + return 0; + + if (dpm_lock_interruptible()) + return -ERESTARTSYS; + + if (!dpm_initialized) + len += sprintf(page + len, "DPM is not initialized\n"); + else if (!dpm_enabled) + len += sprintf(page + len, "DPM is disabled\n"); + else { + len += sprintf(page + len, + "The active DPM policy is \"%s\"\n", + dpm_active_policy->name); + len += sprintf(page + len, + "The current operating point is \"%s\"\n", + dpm_active_opt->name); + } + + if (dpm_initialized) { + len += sprintf(page + len, + "Table of all defined operating points, " + "frequencies in MHz:\n"); + + len += sprintf(page + len, + " Name Count DPLL CPU TC PER DSP DSPMMU LCD\n"); + + list_for_each(opt_list, &dpm_opts) { + opt = list_entry(opt_list, struct dpm_opt, list); + if (len >= PAGE_SIZE) + BUG(); + if (len >= limit) + break; + len += dpm_proc_print_opt(page + len, opt); + } + } + dpm_unlock(); + *eof = 1; + if (offset >= len) + return 0; + *start = page + offset; + return min(count, len - (int)offset); +} + +/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * /proc/driver/dpm/md/cmd (Write-only) + * + * This is a catch-all, simple command processor for the MX27 DPM + * implementation. These commands are for experimentation and development + * _only_, and may leave the system in an unstable state. + * + * No commands defined now. + * + ****************************************************************************/ + +int +write_proc_dpm_md_cmd(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + char *buf, *tok, *s; + static const char *whitespace = " \t\r\n"; + int ret = 0; + + if (current->uid != 0) + return -EACCES; + if (count == 0) + return 0; + if (!(buf = kmalloc(count + 1, GFP_KERNEL))) + return -ENOMEM; + if (copy_from_user(buf, buffer, count)) { + kfree(buf); + return -EFAULT; + } + buf[count] = '\0'; + s = buf + strspn(buf, whitespace); + tok = strsep(&s, whitespace); + + if (strcmp(tok, "define-me") == 0) { + ; + } else { + ret = -EINVAL; + } + kfree(buf); + if (ret == 0) + return count; + else + return ret; +} + +/**************************************************************************** + * DPM Idle Handler + ****************************************************************************/ + +static void (*orig_idle) (void); + +static void mxc_dpm_idle(void) +{ + extern void default_idle(void); + + if (orig_idle) + orig_idle(); + else + default_idle(); +} + +/**************************************************************************** + * Initialization/Exit + ****************************************************************************/ + +static void mxc_dpm_startup(void) +{ + if (!saved_loops_per_jiffy) { + saved_loops_per_jiffy = loops_per_jiffy; + saved_cpu_freq = mxc_get_clocks(CPU_CLK) / 1000; + } + orig_idle = pm_idle; + pm_idle = dpm_idle; +} + +static void mxc_dpm_cleanup(void) +{ + pm_idle = orig_idle; +} + +static int __init mxc_dpm_init(void) +{ + printk(KERN_INFO "Freescale i.MX27 Dynamic Power Management.\n"); + + dpm_md.init_opt = mxc_dpm_init_opt; + dpm_md.set_opt = mxc_dpm_set_opt; + dpm_md.get_opt = mxc_dpm_get_opt; + dpm_md.check_constraint = dpm_default_check_constraint; + dpm_md.idle = mxc_dpm_idle; + dpm_md.startup = mxc_dpm_startup; + dpm_md.cleanup = mxc_dpm_cleanup; + + return 0; +} + +__initcall(mxc_dpm_init); diff --git a/arch/arm/mach-mx27/dptc.c b/arch/arm/mach-mx27/dptc.c new file mode 100644 index 000000000000..5edc1cb733d1 --- /dev/null +++ b/arch/arm/mach-mx27/dptc.c @@ -0,0 +1,49 @@ +/* + * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/*! + * @file dptc.c + * + * @brief DPTC table for the Freescale Semiconductor MXC DPTC module. + * + * @ingroup PM + */ + +#include <asm/arch/pmic_power.h> +#include <asm/arch/hardware.h> + +struct dptc_wp dptc_wp_allfreq[DPTC_WP_SUPPORTED] = { + /* 532MHz */ + /* dcvr0 dcvr1 dcvr2 dcvr3 regulator voltage */ + /* wp0 */ + {0xffe00000, 0x18e2e85b, 0xffe00000, 0x25c4688a, SW_SW1A, SW1A_1_6V}, + {0xffe00000, 0x18e2e85b, 0xffe00000, 0x25c4688a, SW_SW1A, SW1A_1_575V}, + {0xffe00000, 0x1902e85b, 0xffe00000, 0x25e4688a, SW_SW1A, SW1A_1_55V}, + {0xffe00000, 0x1922e85b, 0xffe00000, 0x25e4688a, SW_SW1A, SW1A_1_525V}, + {0xffe00000, 0x1942ec5b, 0xffe00000, 0x2604688a, SW_SW1A, SW1A_1_5V}, + /* wp5 */ + {0xffe00000, 0x1942ec5b, 0xffe00000, 0x26646c8a, SW_SW1A, SW1A_1_475V}, + {0xffe00000, 0x1962ec5b, 0xffe00000, 0x26c4708b, SW_SW1A, SW1A_1_45V}, + {0xffe00000, 0x1962ec5b, 0xffe00000, 0x26e4708b, SW_SW1A, SW1A_1_425V}, + {0xffe00000, 0x1982f05c, 0xffe00000, 0x2704748b, SW_SW1A, SW1A_1_4V}, + {0xffe00000, 0x19c2f05c, 0xffe00000, 0x2744748b, SW_SW1A, SW1A_1_375V}, + /* wp10 */ + {0xffe00000, 0x1a02f45c, 0xffe00000, 0x2784788b, SW_SW1A, SW1A_1_35V}, + {0xffe00000, 0x1a42f45c, 0xffe00000, 0x27c47c8b, SW_SW1A, SW1A_1_325V}, + {0xffe00000, 0x1a82f85c, 0xffe00000, 0x2824808c, SW_SW1A, SW1A_1_3V}, + {0xffe00000, 0x1aa2f85c, 0xffe00000, 0x2884848c, SW_SW1A, SW1A_1_275V}, + {0xffe00000, 0x1ac2fc5c, 0xffe00000, 0x28e4888c, SW_SW1A, SW1A_1_25V}, + /* wp15 */ + {0xffe00000, 0x1ae2fc5c, 0xffe00000, 0x2924888c, SW_SW1A, SW1A_1_225V}, + {0xffe00000, 0x1b23005d, 0xffe00000, 0x29648c8c, SW_SW1A, SW1A_1_2V}, +}; diff --git a/arch/arm/mach-mx27/gpio_mux.c b/arch/arm/mach-mx27/gpio_mux.c new file mode 100644 index 000000000000..0d83383036ab --- /dev/null +++ b/arch/arm/mach-mx27/gpio_mux.c @@ -0,0 +1,308 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/*! + * @defgroup GPIO_MX27 Board GPIO and Muxing Setup + * @ingroup MSL_MX27 + */ +/*! + * @file mach-mx27/gpio_mux.c + * + * @brief I/O Muxing control functions + * + * @ingroup GPIO_MX27 + */ + +#include <linux/kernel.h> +#include <linux/cache.h> +#include <linux/spinlock.h> + +#include <asm/io.h> +#include <asm/hardware.h> +#include <asm/arch/gpio.h> +#include "gpio_mux.h" + +/*! + * This structure defines the offset of registers in gpio module. + */ +enum gpio_reg { + GPIO_GIUS = 0x20, + GPIO_GPR = 0x38, + GPIO_PUEN = 0x40, + GPIO_DDIR = 0x00, + GPIO_OCR1 = 0x04, + GPIO_OCR2 = 0x08, + GPIO_ICONFA1 = 0x0C, + GPIO_ICONFA2 = 0x10, + GPIO_ICONFB1 = 0x14, + GPIO_ICONFB2 = 0x18, +}; + +/*! + * This enumeration data type defines the configuration for input mode. + */ +typedef enum { + GPIO_INPUT_GPIO = 0x00, + GPIO_INPUT_INTR = 0x01, + GPIO_INPUT_LOW = 0x02, + GPIO_INPUT_HIGH = 0x03 +} gpio_input_cfg_t; + +/*! + * This enumeration data type defines the configuration for output mode. + */ +typedef enum { + GPIO_OUTPUT_A = 0x00, + GPIO_OUTPUT_B = 0x01, + GPIO_OUTPUT_C = 0x02, + GPIO_OUTPUT_DR = 0x03 +} gpio_output_cfg_t; + +extern struct mxc_gpio_port mxc_gpio_ports[]; + +/*! + * defines a spinlock to protected the accessing to gpio pin. + */ +DEFINE_SPINLOCK(gpio_mux_lock); + +/*! + * This function enable or disable the pullup feature to the pin. + * @param port a pointer of gpio port + * @param index the index of the pin in the port + * @param en 0 if disable pullup, otherwise enable it. + * @return none + */ +static inline void _gpio_set_puen(struct mxc_gpio_port *port, u32 index, + bool en) +{ + u32 reg; + + reg = __raw_readl(port->base + GPIO_PUEN); + if (en) { + reg |= 1 << index; + } else { + reg &= ~(1 << index); + } + __raw_writel(reg, port->base + GPIO_PUEN); +} + +/*! + * This function set the input configuration A. + * @param port a pointer of gpio port + * @param index the index of the pin in the port + * @param config a mode as define in \b #gpio_input_cfg_t + * @return none + */ +static inline void _gpio_set_iconfa(struct mxc_gpio_port *port, u32 index, + gpio_input_cfg_t config) +{ + u32 reg, val; + u32 mask; + + mask = 0x3 << ((index % 16) << 1); + + if (index >= 16) { + reg = port->base + GPIO_ICONFA2; + val = config << ((index - 16) * 2); + } else { + reg = port->base + GPIO_ICONFA1; + val = config << (index * 2); + } + val |= __raw_readl(reg) & ~(mask); + __raw_writel(val, reg); +} + +/*! + * This function set the input configuration B. + * @param port a pointer of gpio port + * @param index the index of the pin in the port + * @param config a mode as define in \b #gpio_input_cfg_t + * @return none + */ +static inline void _gpio_set_iconfb(struct mxc_gpio_port *port, u32 index, + gpio_input_cfg_t config) +{ + u32 reg, val; + u32 mask; + + mask = 0x3 << ((index % 16) << 1); + + if (index >= 16) { + reg = port->base + GPIO_ICONFB2; + val = config << ((index - 16) * 2); + } else { + reg = port->base + GPIO_ICONFB1; + val = config << (index * 2); + } + val |= __raw_readl(reg) & (~mask); + __raw_writel(val, reg); +} + +/*! + * This function set the output configuration. + * @param port a pointer of gpio port + * @param index the index of the pin in the port + * @param config a mode as define in \b #gpio_output_cfg_t + * @return none + */ +static inline void _gpio_set_ocr(struct mxc_gpio_port *port, u32 index, + gpio_output_cfg_t config) +{ + u32 reg, val; + u32 mask; + + mask = 0x3 << ((index % 16) << 1); + if (index >= 16) { + reg = port->base + GPIO_OCR2; + val = config << ((index - 16) * 2); + } else { + reg = port->base + GPIO_OCR1; + val = config << (index * 2); + } + val |= __raw_readl(reg) & (~mask); + __raw_writel(val, reg); +} + +/*! + *@brief gpio_config_mux - just configure the mode of the gpio pin. + *@param pin a pin number as defined in \b #iomux_pin_name_t + *@param mode a module as define in \b #gpio_mux_mode_t; + * GPIO_MUX_PRIMARY set pin to work as primary function. + * GPIO_MUX_ALT set pin to work as alternate function. + * GPIO_MUX_GPIO set pin to work as output function based the data register + * GPIO_MUX_INPUT1 set pin to work as input function connected with A_OUT + * GPIO_MUX_INPUT2 set pin to work as input function connected with B_OUT + * GPIO_MUX_OUTPUT1 set pin to work as output function connected with A_IN + * GPIO_MUX_OUTPUT2 set pin to work as output function connected with B_IN + * GPIO_MUX_OUTPUT3 set pin to work as output function connected with C_IN + *@return 0 if successful, Non-zero otherwise + */ + +int gpio_config_mux(iomux_pin_name_t pin, gpio_mux_mode_t mode) +{ + unsigned long lock_flags; + u32 gius_reg, gpr_reg; + struct mxc_gpio_port *port; + u32 index, gpio = IOMUX_TO_GPIO(pin); + + port = &(mxc_gpio_ports[GPIO_TO_PORT(gpio)]); + index = GPIO_TO_INDEX(gpio); + + pr_debug("%s: Configuring PORT %c, bit %d\n", + __FUNCTION__, port->num + 'A', index); + + spin_lock_irqsave(&gpio_mux_lock, lock_flags); + + gius_reg = __raw_readl(port->base + GPIO_GIUS); + gpr_reg = __raw_readl(port->base + GPIO_GPR); + + switch (mode) { + case GPIO_MUX_PRIMARY: + gius_reg &= ~(1L << index); + gpr_reg &= ~(1L << index); + break; + case GPIO_MUX_ALT: + gius_reg &= ~(1L << index); + gpr_reg |= (1L << index); + break; + case GPIO_MUX_GPIO: + gius_reg |= (1L << index); + _gpio_set_ocr(port, index, GPIO_OUTPUT_DR); + break; + case GPIO_MUX_INPUT1: + gius_reg |= (1L << index); + _gpio_set_iconfa(port, index, GPIO_INPUT_GPIO); + break; + case GPIO_MUX_INPUT2: + gius_reg |= (1L << index); + _gpio_set_iconfb(port, index, GPIO_INPUT_GPIO); + break; + case GPIO_MUX_OUTPUT1: + gius_reg |= (1L << index); + _gpio_set_ocr(port, index, GPIO_OUTPUT_A); + break; + case GPIO_MUX_OUTPUT2: + gius_reg |= (1L << index); + _gpio_set_ocr(port, index, GPIO_OUTPUT_B); + break; + case GPIO_MUX_OUTPUT3: + gius_reg |= (1L << index); + _gpio_set_ocr(port, index, GPIO_OUTPUT_C); + break; + default: + spin_unlock_irqrestore(&gpio_mux_lock, lock_flags); + return -1; + } + + __raw_writel(gius_reg, port->base + GPIO_GIUS); + __raw_writel(gpr_reg, port->base + GPIO_GPR); + + spin_unlock_irqrestore(&gpio_mux_lock, lock_flags); + return 0; +} + +/*! + * This function is just used to enable or disable the pull up feature . + * @param pin a pin number as defined in \b #iomux_pin_name_t + * @param en 0 if disable, Non-zero enable + * @return 0 if successful, Non-zero otherwise + */ +int gpio_set_puen(iomux_pin_name_t pin, bool en) +{ + unsigned long lock_flags; + + struct mxc_gpio_port *port; + u32 index, gpio = IOMUX_TO_GPIO(pin); + + port = &(mxc_gpio_ports[GPIO_TO_PORT(gpio)]); + index = GPIO_TO_INDEX(gpio); + + pr_debug("%s: Configuring output mode of PORT %c, bit %d\n", + __FUNCTION__, port->num + 'A', index); + + spin_lock_irqsave(&gpio_mux_lock, lock_flags); + + _gpio_set_puen(port, index, en); + spin_unlock_irqrestore(&gpio_mux_lock, lock_flags); + return 0; + +} + +/*! + * This function is just used to request a pin and configure it. + * @param pin a pin number as defined in \b #iomux_pin_name_t + * @param mode a module as define in \b #gpio_mux_mode_t; + * @return 0 if successful, Non-zero otherwise + */ +int gpio_request_mux(iomux_pin_name_t pin, gpio_mux_mode_t mode) +{ + int ret; + ret = mxc_request_gpio(pin); + if (ret == 0) { + ret = gpio_config_mux(pin, mode); + if (ret) { + mxc_free_gpio(pin); + } + } + return ret; +} + +/*! + * This function is just used to release a pin. + * @param pin a pin number as defined in \b #iomux_pin_name_t + * @return none + */ +void gpio_free_mux(iomux_pin_name_t pin) +{ + mxc_free_gpio(pin); +} diff --git a/arch/arm/mach-mx27/gpio_mux.h b/arch/arm/mach-mx27/gpio_mux.h new file mode 100644 index 000000000000..cb31a25f3032 --- /dev/null +++ b/arch/arm/mach-mx27/gpio_mux.h @@ -0,0 +1,76 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/*! + *@file mach-mx27/gpio_mux.h + *@brief This file contains the private definition . + * @ingroup GPIO_MX27 + */ + +#ifndef __ARCH_ARM_MACH_MX27_GPIO_MUX_H__ +#define __ARCH_ARM_MACH_MX27_GPIO_MUX_H__ + +/*! + * This enumeration data type defines the modes of the pin . + * GPIO_MUX_PRIMARY is the primary mode. + * GPIO_MUX_ALT is the alternate mode. + * GPIO_MUX_GPIO is the output mode and the signal source is data register. + * GPIO_MUX_INPUT1 is the input mode and the signal destination is A_OUT. + * GPIO_MUX_INPUT2 is the input mode and the signal destination is B_OUT. + * GPIO_MUX_OUTPUT1 is the output mode and the signal destination is A_IN. + * GPIO_MUX_OUTPUT2 is the output mode and the signal destination is B_IN. + * GPIO_MUX_OUTPUT3 is the output mode and the signal destination is C_IN. + */ +typedef enum { + GPIO_MUX_PRIMARY, + GPIO_MUX_ALT, + GPIO_MUX_GPIO, + GPIO_MUX_INPUT1, + GPIO_MUX_INPUT2, + GPIO_MUX_OUTPUT1, + GPIO_MUX_OUTPUT2, + GPIO_MUX_OUTPUT3, +} gpio_mux_mode_t; + +/*! + * This function is just used to request a pin and configure it. + * @param pin a pin number as defined in \b #iomux_pin_name_t + * @param mode a module as define in \b #gpio_mux_mode_t; + * @return 0 if successful, Non-zero otherwise + */ +extern int gpio_request_mux(iomux_pin_name_t pin, gpio_mux_mode_t mode); + +/*! + * This function is just used to configure a pin . + * @param pin a pin number as defined in \b #iomux_pin_name_t + * @param mode a module as define in \b #gpio_mux_mode_t; + * @return 0 if successful, Non-zero otherwise + */ +extern int gpio_config_mux(iomux_pin_name_t pin, gpio_mux_mode_t mode); + +/*! + * This function is just used to enable or disable the pull up feature . + * @param pin a pin number as defined in \b #iomux_pin_name_t + * @param en 0 if disable, Non-zero enable + * @return 0 if successful, Non-zero otherwise + */ +extern int gpio_set_puen(iomux_pin_name_t pin, bool en); + +/*! + * This function is just used to release a pin. + * @param pin a pin number as defined in \b #iomux_pin_name_t + * @return none + */ +extern void gpio_free_mux(iomux_pin_name_t pin); + +#endif /* __ARCH_ARM_MACH_MX27_GPIO_MUX_H__ */ diff --git a/arch/arm/mach-mx27/mm.c b/arch/arm/mach-mx27/mm.c new file mode 100644 index 000000000000..cbddcf2fdf61 --- /dev/null +++ b/arch/arm/mach-mx27/mm.c @@ -0,0 +1,62 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/mm.h> +#include <linux/init.h> +#include <asm/hardware.h> +#include <asm/pgtable.h> +#include <asm/mach/map.h> + +/*! + * @file mach-mx27/mm.c + * + * @brief This file creates static mapping between physical to virtual memory. + * + * @ingroup Memory_MX27 + */ + +/*! + * This structure defines the MX27 memory map. + */ +static struct map_desc mxc_io_desc[] __initdata = { + { + .virtual = AIPI_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(AIPI_BASE_ADDR), + .length = AIPI_SIZE, + .type = MT_DEVICE}, + { + .virtual = SAHB1_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(SAHB1_BASE_ADDR), + .length = SAHB1_SIZE, + .type = MT_DEVICE}, + { + .virtual = X_MEMC_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(X_MEMC_BASE_ADDR), + .length = X_MEMC_SIZE, + .type = MT_DEVICE}, + { + .virtual = CS4_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(CS4_BASE_ADDR), + .length = CS4_SIZE, + .type = MT_DEVICE} +}; + +/*! + * This function initializes the memory map. It is called during the + * system startup to create static physical to virtual memory map for + * the IO modules. + */ +void __init mxc_map_io(void) +{ + iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); +} diff --git a/arch/arm/mach-mx27/mx27ads.c b/arch/arm/mach-mx27/mx27ads.c new file mode 100644 index 000000000000..8ee9804cb1bd --- /dev/null +++ b/arch/arm/mach-mx27/mx27ads.c @@ -0,0 +1,758 @@ +/* + * Copyright (C) 2000 Deep Blue Solutions Ltd + * Copyright (C) 2002 Shane Nay (shane@minirl.com) + * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/device.h> +#include <linux/input.h> +#include <linux/nodemask.h> +#include <linux/clk.h> +#include <linux/spi/spi.h> +#include <linux/serial_8250.h> +#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE) +#include <linux/mtd/mtd.h> +#include <linux/mtd/map.h> +#include <linux/mtd/partitions.h> + +#include <asm/mach/flash.h> +#endif + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/irq.h> +#include <asm/arch/memory.h> +#include <asm/arch/gpio.h> +#include <asm/mach/keypad.h> +#include "gpio_mux.h" +#include "board-mx27ads.h" + +/*! + * @file mach-mx27/mx27ads.c + * @brief This file contains the board specific initialization routines. + * + * @ingroup MSL_MX27 + */ + +extern void mxc_map_io(void); +extern void mxc_init_irq(void); +extern void mxc_cpu_init(void) __init; +extern void mxc_clocks_init(void); +extern void mxc_cpu_common_init(void); +extern struct sys_timer mxc_timer; +extern void __init early_console_setup(char *); + +static char command_line[COMMAND_LINE_SIZE]; +static int mxc_card_status; +int mxc_board_is_ads = 1; + +static void mxc_nop_release(struct device *dev) +{ + /* Nothing */ +} + +unsigned long board_get_ckih_rate(void) +{ + if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0) { + return 27000000; + } + return 26000000; +} + +#if defined(CONFIG_CS89x0) || defined(CONFIG_CS89x0_MODULE) +/*! Null terminated portlist used to probe for the CS8900A device on ISA Bus + * Add 3 to reset the page window before probing (fixes eth probe when deployed + * using nand_boot) + */ +unsigned int netcard_portlist[] = { CS8900A_BASE_ADDRESS + 3, 0 }; + +EXPORT_SYMBOL(netcard_portlist); +/*! + * The CS8900A has 4 IRQ pins, which is software selectable, CS8900A interrupt + * pin 0 is used for interrupt generation. + */ +unsigned int cs8900_irq_map[] = { CS8900AIRQ, 0, 0, 0 }; + +EXPORT_SYMBOL(cs8900_irq_map); +#endif + +#if defined(CONFIG_FEC) || defined(CONFIG_FEC_MODULE) +unsigned int expio_intr_fec = MXC_EXP_IO_BASE + 7; + +EXPORT_SYMBOL(expio_intr_fec); +#endif + +#if defined(CONFIG_KEYBOARD_MXC) || defined(CONFIG_KEYBOARD_MXC_MODULE) + +/*! + * This array is used for mapping mx27 ADS keypad scancodes to input keyboard + * keycodes. + */ +static u16 mxckpd_keycodes[] = { + KEY_KP9, KEY_LEFTSHIFT, KEY_0, KEY_KPASTERISK, KEY_RECORD, KEY_POWER, + KEY_KP8, KEY_9, KEY_8, KEY_7, KEY_KP5, KEY_VOLUMEDOWN, + KEY_KP7, KEY_6, KEY_5, KEY_4, KEY_KP4, KEY_VOLUMEUP, + KEY_KP6, KEY_3, KEY_2, KEY_1, KEY_KP3, KEY_DOWN, + KEY_BACK, KEY_RIGHT, KEY_ENTER, KEY_LEFT, KEY_HOME, KEY_KP2, + KEY_END, KEY_F2, KEY_UP, KEY_F1, KEY_F4, KEY_KP1, +}; + +static struct keypad_data evb_6_by_6_keypad = { + .rowmax = 6, + .colmax = 6, + .irq = INT_KPP, + .learning = 0, + .delay = 2, + .matrix = mxckpd_keycodes, +}; + +static struct resource mxc_kpp_resources[] = { + [0] = { + .start = INT_KPP, + .end = INT_KPP, + .flags = IORESOURCE_IRQ, + } +}; + +/* mxc keypad driver */ +static struct platform_device mxc_keypad_device = { + .name = "mxc_keypad", + .id = 0, + .num_resources = ARRAY_SIZE(mxc_kpp_resources), + .resource = mxc_kpp_resources, + .dev = { + .release = mxc_nop_release, + .platform_data = &evb_6_by_6_keypad, + }, +}; + +static void mxc_init_keypad(void) +{ + (void)platform_device_register(&mxc_keypad_device); +} +#else +static inline void mxc_init_keypad(void) +{ +} +#endif + +/* MTD NOR flash */ + +#if defined(CONFIG_MTD_MXC) || defined(CONFIG_MTD_MXC_MODULE) + +static struct mtd_partition mxc_nor_partitions[] = { + { + .name = "Bootloader", + .size = 512 * 1024, + .offset = 0x00000000, + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .name = "nor.Kernel", + .size = 2 * 1024 * 1024, + .offset = MTDPART_OFS_APPEND, + .mask_flags = 0}, + { + .name = "nor.userfs", + .size = 14 * 1024 * 1024, + .offset = MTDPART_OFS_APPEND, + .mask_flags = 0}, + { + .name = "nor.rootfs", + .size = 12 * 1024 * 1024, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE}, + { + .name = "FIS directory", + .size = 12 * 1024, + .offset = 0x01FE0000, + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .name = "Redboot config", + .size = MTDPART_SIZ_FULL, + .offset = 0x01FFF000, + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, +}; + +static struct flash_platform_data mxc_flash_data = { + .map_name = "cfi_probe", + .width = 2, + .parts = mxc_nor_partitions, + .nr_parts = ARRAY_SIZE(mxc_nor_partitions), +}; + +static struct resource mxc_flash_resource = { + .start = 0xc0000000, + .end = 0xc0000000 + 0x02000000 - 1, + .flags = IORESOURCE_MEM, + +}; + +static struct platform_device mxc_nor_mtd_device = { + .name = "mxc_nor_flash", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_flash_data, + }, + .num_resources = 1, + .resource = &mxc_flash_resource, +}; + +static void mxc_init_nor_mtd(void) +{ + (void)platform_device_register(&mxc_nor_mtd_device); +} +#else +static void mxc_init_nor_mtd(void) +{ +} +#endif + +/* MTD NAND flash */ + +#if defined(CONFIG_MTD_NAND_MXC) || defined(CONFIG_MTD_NAND_MXC_MODULE) + +static struct mtd_partition mxc_nand_partitions[4] = { + { + .name = "IPL-SPL", + .offset = 0, + .size = 128 * 1024}, + { + .name = "nand.kernel", + .offset = MTDPART_OFS_APPEND, + .size = 4 * 1024 * 1024}, + { + .name = "nand.rootfs", + .offset = MTDPART_OFS_APPEND, + .size = 22 * 1024 * 1024}, + { + .name = "nand.userfs", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL}, +}; + +static struct flash_platform_data mxc_nand_data = { + .parts = mxc_nand_partitions, + .nr_parts = ARRAY_SIZE(mxc_nand_partitions), + .width = 1, +}; + +static struct platform_device mxc_nand_mtd_device = { + .name = "mxc_nand_flash", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_nand_data, + }, +}; + +static void mxc_init_nand_mtd(void) +{ + (void)platform_device_register(&mxc_nand_mtd_device); +} +#else +static inline void mxc_init_nand_mtd(void) +{ +} +#endif + +#if defined(CONFIG_FB_MXC_SYNC_PANEL) || defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE) +static const char fb_default_mode[] = "Sharp-QVGA"; + +/* mxc lcd driver */ +static struct platform_device mxc_fb_device = { + .name = "mxc_sdc_fb", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &fb_default_mode, + .coherent_dma_mask = 0xFFFFFFFF, + }, +}; + +static void mxc_init_fb(void) +{ + (void)platform_device_register(&mxc_fb_device); +} +#else +static inline void mxc_init_fb(void) +{ +} +#endif + +static struct spi_board_info mxc_spi_board_info[] __initdata = { + { + .modalias = "pmic_spi", + .irq = IOMUX_TO_IRQ(MX27_PIN_TOUT), + .max_speed_hz = 4000000, + .bus_num = 1, + .chip_select = 0, + }, +}; + +#if 0 +#define MXC_CARD_DEBUG +#endif + +static const int pbc_card_bit[4][3] = { + /* BSTAT IMR enable IMR removal */ + {PBC_BSTAT_SD2_DET, PBC_INTR_SD2_EN, PBC_INTR_SD2_R_EN}, + {PBC_BSTAT_SD3_DET, PBC_INTR_SD3_EN, PBC_INTR_SD3_R_EN}, + {PBC_BSTAT_MS_DET, PBC_INTR_MS_EN, PBC_INTR_MS_R_EN}, + {PBC_BSTAT_SD1_DET, PBC_INTR_SD1_EN, PBC_INTR_SD1_R_EN}, +}; + +/*! + * Check if a SD card has been inserted or not. + * + * @param num a card number as defined in \b enum \b mxc_card_no + * @return 0 if a card is not present; non-zero otherwise. + */ +int mxc_card_detected(enum mxc_card_no num) +{ + u32 status; + + status = __raw_readw(PBC_BSTAT1_REG); + return ((status & MXC_BSTAT_BIT(num)) == 0); +} + +/* + * Check if there is any state change by reading the IMR register and the + * previous and current states of the board status register (offset 0x28). + * A state change is defined to be card insertion OR removal. So the driver + * may have to call the mxc_card_detected() function to see if it is card + * insertion or removal. + * + * @param mask current IMR value + * @param s0 previous status register value (offset 0x28) + * @param s1 current status register value (offset 0x28) + * + * @return 0 if no card status change OR the corresponding bits in the IMR + * (passed in as 'mask') is NOT set. + * A non-zero value indicates some card state changes. For example, + * 0b0001 means SD3 has a card state change (bit0 is set) AND its + * associated insertion or removal bits in IMR is SET. + * 0b0100 means SD1 has a card state change (bit2 is set) AND its + * associated insertion or removal bits in IMR is SET. + * 0b1001 means both MS and SD3 have state changes + */ +static u32 mxc_card_state_changed(u32 mask, u32 s0, u32 s1) +{ + u32 i, retval = 0; + u32 stat = (s0 ^ s1) & 0x7800; + + if (stat == 0) + return 0; + + for (i = MXC_CARD_MIN; i <= MXC_CARD_MAX; i++) { + if ((stat & pbc_card_bit[i][0]) != 0 && + (mask & (pbc_card_bit[i][1] | pbc_card_bit[i][2])) != 0) { + retval |= 1 << i; + } + } +#ifdef MXC_CARD_DEBUG + printk(KERN_INFO "\nmask=%x, s0=%x, s1=%x\n", mask, s0, s1); + printk(KERN_INFO "retval=%x, stat=%x\n", retval, stat); +#endif + return retval; +} + +/*! + * Interrupt handler for the expio (CPLD) to deal with interrupts from + * FEC, external UART, CS8900 Ethernet and SD cards, etc. + */ +static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc) +{ + u32 imr, card_int, i; + u32 int_valid; + u32 expio_irq; + u32 stat = __raw_readw(PBC_BSTAT1_REG); + + desc->chip->mask(irq); /* irq = gpio irq number */ + + imr = __raw_readw(PBC_INTMASK_SET_REG); + + card_int = mxc_card_state_changed(imr, mxc_card_status, stat); + mxc_card_status = stat; + + if (card_int != 0) { + for (i = MXC_CARD_MIN; i <= MXC_CARD_MAX - 1; i++) { + if ((card_int & (1 << i)) != 0) { + pr_info("card no %d state changed\n", i); + } + } + } + + /* Bits defined in PBC_INTSTATUS_REG at 0x2C */ + int_valid = __raw_readw(PBC_INTSTATUS_REG) & imr; + /* combined with the card interrupt valid information */ + int_valid = (int_valid & 0x0F8E) | (card_int << PBC_INTR_SD2_EN_BIT); + + if (unlikely(!int_valid)) { + printk(KERN_ERR "\nEXPIO: Spurious interrupt:0x%0x\n\n", + int_valid); + pr_info("CPLD IMR(0x38)=0x%x, BSTAT1(0x28)=0x%x\n", imr, stat); + goto out; + } + + expio_irq = MXC_EXP_IO_BASE; + for (; int_valid != 0; int_valid >>= 1, expio_irq++) { + struct irq_desc *d; + if ((int_valid & 1) == 0) + continue; + d = irq_desc + expio_irq; + if (unlikely(!(d->handle_irq))) { + printk(KERN_ERR "\nEXPIO irq: %d unhandeled\n", + expio_irq); + BUG(); /* oops */ + } + d->handle_irq(expio_irq, d); + } + + out: + desc->chip->ack(irq); + desc->chip->unmask(irq); +} + +#ifdef MXC_CARD_DEBUG + +static irqreturn_t mxc_sd_test_handler(int irq, void *desc) +{ + int s = -1; + + printk(KERN_INFO "%s(irq=%d) for ", __FUNCTION__, irq); + if (irq == EXPIO_INT_SD1_EN) { + printk(KERN_INFO "SD1"); + s = MXC_CARD_SD1; + } else if (irq == EXPIO_INT_SD2_EN) { + printk(KERN_INFO "SD2"); + s = MXC_CARD_SD2; + } else if (irq == EXPIO_INT_SD3_EN) { + printk(KERN_INFO "SD3"); + s = MXC_CARD_SD3; + } else if (irq == EXPIO_INT_MS_EN) { + printk(KERN_INFO "MS"); + s = MXC_CARD_MS; + } else { + printk(KERN_INFO "None!!!!"); + } + if (mxc_card_detected(s)) { + printk(KERN_INFO " inserted\n"); + } else { + printk(KERN_INFO " removed\n"); + } + + return IRQ_HANDLED; +} +#endif /* MXC_CARD_DEBUG */ + +/* + * Disable an expio pin's interrupt by setting the bit in the imr. + * @param irq an expio virtual irq number + */ +static void expio_mask_irq(u32 irq) +{ + u32 expio = MXC_IRQ_TO_EXPIO(irq); + + /* mask the interrupt */ + if (irq < EXPIO_INT_SD2_EN) { + __raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG); + } else { + irq -= EXPIO_INT_SD2_EN; + /* clear both SDx_EN and SDx_R_EN bits */ + __raw_writew((pbc_card_bit[irq][1] | pbc_card_bit[irq][2]), + PBC_INTMASK_CLEAR_REG); + } +} + +/* + * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr. + * @param irq an expanded io virtual irq number + */ +static void expio_ack_irq(u32 irq) +{ + u32 expio = MXC_IRQ_TO_EXPIO(irq); + /* clear the interrupt status */ + __raw_writew(1 << expio, PBC_INTSTATUS_REG); + /* mask the interrupt */ + expio_mask_irq(irq); +} + +/* + * Enable a expio pin's interrupt by clearing the bit in the imr. + * @param irq an expio virtual irq number + */ +static void expio_unmask_irq(u32 irq) +{ + u32 expio = MXC_IRQ_TO_EXPIO(irq); + + /* unmask the interrupt */ + if (irq < EXPIO_INT_SD2_EN) { + if (irq == EXPIO_INT_XUART_INTA) { + /* Set 8250 MCR register bit 3 - Forces the INT (A-B + * outputs to the active mode and sets OP2 to logic 0. + * This is needed to avoid spurious int caused by the + * internal CPLD pull-up for the interrupt pin. + */ + u16 val = __raw_readw(MXC_LL_EXTUART_VADDR + 8); + __raw_writew(val | 0x8, MXC_LL_EXTUART_VADDR + 8); + } + __raw_writew(1 << expio, PBC_INTMASK_SET_REG); + } else { + irq -= EXPIO_INT_SD2_EN; + + if (mxc_card_detected(irq)) { + __raw_writew(pbc_card_bit[irq][2], PBC_INTMASK_SET_REG); + } else { + __raw_writew(pbc_card_bit[irq][1], PBC_INTMASK_SET_REG); + } + } +} + +static struct irq_chip expio_irq_chip = { + .ack = expio_ack_irq, + .mask = expio_mask_irq, + .unmask = expio_unmask_irq, +}; + +static int __init mxc_expio_init(void) +{ + int i, ver; + + ver = (__raw_readw(PBC_VERSION_REG) >> 8) & 0xFF; + if ((ver & 0x80) != 0) { + pr_info("MX27 ADS EXPIO(CPLD) hardware\n"); + pr_info("CPLD version: 0x%x\n", ver); + } else { + mxc_board_is_ads = 0; + ver &= 0x0F; + pr_info("MX27 EVB EXPIO(CPLD) hardware\n"); + if (ver == 0xF || ver <= MXC_CPLD_VER_1_50) + pr_info("Wrong CPLD version: %d\n", ver); + else { + pr_info("CPLD version: %d\n", ver); + } + } + + mxc_card_status = __raw_readw(PBC_BSTAT1_REG); + +#ifdef MXC_CARD_DEBUG + for (i = MXC_CARD_MIN; i <= MXC_CARD_MAX; i++) { + if (mxc_card_detected(i)) { + pr_info("Card %d is detected\n", 3 - i); + } + } +#endif + /* + * Configure INT line as GPIO input + */ + gpio_config_mux(MX27_PIN_TIN, GPIO_MUX_GPIO); + mxc_set_gpio_direction(MX27_PIN_TIN, 1); + + /* disable the interrupt and clear the status */ + __raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG); + __raw_writew(0xFFFF, PBC_INTSTATUS_REG); + + for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES); + i++) { + set_irq_chip(i, &expio_irq_chip); + set_irq_handler(i, handle_level_irq); + set_irq_flags(i, IRQF_VALID); + } + set_irq_type(EXPIO_PARENT_INT, IRQT_HIGH); + set_irq_chained_handler(EXPIO_PARENT_INT, mxc_expio_irq_handler); + + return 0; +} + +#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) + +/*! + * The serial port definition structure. The fields contain: + * {UART, CLK, PORT, IRQ, FLAGS} + */ +static struct plat_serial8250_port serial_platform_data[] = { + { + .membase = (void __iomem *)(CS4_BASE_ADDR_VIRT + 0x20000), + .mapbase = (unsigned long)(CS4_BASE_ADDR + 0x20000), + .irq = EXPIO_INT_XUART_INTA, + .uartclk = 3686400, + .regshift = 1, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ, + /*.pm = serial_platform_pm, */ + }, + {}, +}; + +/*! + * REVISIT: document me + */ +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = &serial_platform_data[0], + }, +}; + +/*! + * REVISIT: document me + */ +static int __init mxc_init_extuart(void) +{ + int value; + /*reset ext uart in cpld */ + __raw_writew(PBC_BCTRL1_URST, PBC_BCTRL1_SET_REG); + /*delay some time for reset finish */ + for (value = 0; value < 1000; value++) ; + __raw_writew(PBC_BCTRL1_URST, PBC_BCTRL1_CLEAR_REG); + return platform_device_register(&serial_device); +} +#else +static inline int mxc_init_extuart(void) +{ + return 0; +} +#endif + +#if defined(CONFIG_MXC_PMIC_MC13783) && defined(CONFIG_SND_MXC_PMIC) +extern void gpio_ssi_active(int ssi_num); + +static void __init mxc_init_pmic_audio(void) +{ + struct clk *ssi_clk; + struct clk *ckih_clk; + struct clk *cko_clk; + + /* Enable 26 mhz clock on CKO1 for PMIC audio */ + ckih_clk = clk_get(NULL, "ckih"); + cko_clk = clk_get(NULL, "clko_clk"); + if (IS_ERR(ckih_clk) || IS_ERR(cko_clk)) { + printk(KERN_ERR "Unable to set CLKO output to CKIH\n"); + } else { + clk_set_parent(cko_clk, ckih_clk); + clk_set_rate(cko_clk, clk_get_rate(ckih_clk)); + clk_enable(cko_clk); + } + clk_put(ckih_clk); + clk_put(cko_clk); + + ssi_clk = clk_get(NULL, "ssi_clk.0"); + clk_enable(ssi_clk); + clk_put(ssi_clk); + ssi_clk = clk_get(NULL, "ssi_clk.1"); + clk_enable(ssi_clk); + clk_put(ssi_clk); + + gpio_ssi_active(0); + gpio_ssi_active(1); +} +#else +static void __inline mxc_init_pmic_audio(void) +{ +} +#endif + +static __init void mxc_board_init(void) +{ + pr_info("AIPI VA base: 0x%x\n", IO_ADDRESS(AIPI_BASE_ADDR)); + mxc_cpu_common_init(); + mxc_clocks_init(); + early_console_setup(saved_command_line); + mxc_gpio_init(); + mxc_expio_init(); + mxc_init_keypad(); + mxc_init_nor_mtd(); + mxc_init_nand_mtd(); + mxc_init_extuart(); + mxc_init_pmic_audio(); +#ifdef MXC_CARD_DEBUG + request_irq(EXPIO_INT_SD1_EN, mxc_sd_test_handler, 0, "SD_card1", NULL); + request_irq(EXPIO_INT_SD2_EN, mxc_sd_test_handler, 0, "SD_card2", NULL); + request_irq(EXPIO_INT_SD3_EN, mxc_sd_test_handler, 0, "SD_card3", NULL); + request_irq(EXPIO_INT_MS_EN, mxc_sd_test_handler, 0, "MS_card", NULL); +#endif + + spi_register_board_info(mxc_spi_board_info, + ARRAY_SIZE(mxc_spi_board_info)); + + mxc_init_fb(); +} + +static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ +#ifdef CONFIG_KGDB_8250 + int i; + for (i = 0; + i < + (sizeof(serial_platform_data) / sizeof(serial_platform_data[0])); + i += 1) + kgdb8250_add_platform_port(i, &serial_platform_data[i]); +#endif + + mxc_cpu_init(); + /* Store command line for use on mxc_board_init */ + strcpy(command_line, *cmdline); + +#ifdef CONFIG_DISCONTIGMEM + do { + int nid; + mi->nr_banks = MXC_NUMNODES; + for (nid = 0; nid < mi->nr_banks; nid++) { + SET_NODE(mi, nid); + } + } while (0); +#endif +} + +EXPORT_SYMBOL(mxc_card_detected); +EXPORT_SYMBOL(mxc_board_is_ads); + +/* + * The following uses standard kernel macros define in arch.h in order to + * initialize __mach_desc_MX27ADS data structure. + */ +/* *INDENT-OFF* */ +MACHINE_START(MX27ADS, "Freescale i.MX27ADS") + /* maintainer: Freescale Semiconductor, Inc. */ +#ifdef CONFIG_SERIAL_8250_CONSOLE + .phys_io = CS4_BASE_ADDR, + .io_pg_offst = ((CS4_BASE_ADDR_VIRT) >> 18) & 0xfffc, +#else + .phys_io = AIPI_BASE_ADDR, + .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, +#endif + .boot_params = PHYS_OFFSET + 0x100, + .fixup = fixup_mxc_board, + .map_io = mxc_map_io, + .init_irq = mxc_init_irq, + .init_machine = mxc_board_init, + .timer = &mxc_timer, +MACHINE_END diff --git a/arch/arm/mach-mx27/mx27ads_gpio.c b/arch/arm/mach-mx27/mx27ads_gpio.c new file mode 100644 index 000000000000..871b4724fc85 --- /dev/null +++ b/arch/arm/mach-mx27/mx27ads_gpio.c @@ -0,0 +1,1182 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/errno.h> +#include <linux/module.h> +#include <linux/device.h> +#include <asm/io.h> +#include <asm/hardware.h> +#include <asm/arch/gpio.h> + +#include "board-mx27ads.h" +#include "gpio_mux.h" +#include "crm_regs.h" + +static int g_uart_activated[MXC_UART_NR] = { 0, 0, 0, 0, 0, 0 }; + +/*! + * @file mach-mx27/mx27ads_gpio.c + * + * @brief This file contains all the GPIO setup functions for the board. + * + * @ingroup GPIO_MX27 + */ + +/*! + * Setup GPIO for a UART port to be active + * + * @param port a UART port + * @param no_irda indicates if the port is used for SIR + */ +void gpio_uart_active(int port, int no_irda) +{ + if (port < 0 || port >= MXC_UART_NR) { + pr_info("Wrong port number: %d\n", port); + BUG(); + } + + if (g_uart_activated[port]) { + pr_info("UART %d has been activated multi-times\n", port + 1); + return; + } + g_uart_activated[port] = 1; + + switch (port) { + case 0: + gpio_request_mux(MX27_PIN_UART1_TXD, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_UART1_RXD, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_UART1_CTS, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_UART1_RTS, GPIO_MUX_PRIMARY); + break; + case 1: + gpio_request_mux(MX27_PIN_UART2_TXD, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_UART2_RXD, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_UART2_CTS, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_UART2_RTS, GPIO_MUX_PRIMARY); + break; + case 2: + gpio_request_mux(MX27_PIN_UART3_TXD, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_UART3_RXD, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_UART3_CTS, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_UART3_RTS, GPIO_MUX_PRIMARY); + + /* Enable IRDA in CPLD */ + __raw_writew(PBC_BCTRL2_IRDA_EN, PBC_BCTRL2_CLEAR_REG); + break; + case 3: + gpio_request_mux(MX27_PIN_USBH1_TXDM, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_USBH1_RXDP, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_USBH1_TXDP, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_USBH1_FS, GPIO_MUX_ALT); + break; + case 4: + gpio_request_mux(MX27_PIN_CSI_D6, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_CSI_D7, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_CSI_VSYNC, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_CSI_HSYNC, GPIO_MUX_ALT); + break; + case 5: + gpio_request_mux(MX27_PIN_CSI_D0, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_CSI_D1, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_CSI_D2, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_CSI_D3, GPIO_MUX_ALT); + break; + default: + break; + } +} + +/*! + * Setup GPIO for a UART port to be inactive + * + * @param port a UART port + * @param no_irda indicates if the port is used for SIR + */ +void gpio_uart_inactive(int port, int no_irda) +{ + if (port < 0 || port >= MXC_UART_NR) { + pr_info("Wrong port number: %d\n", port); + BUG(); + } + + if (g_uart_activated[port] == 0) { + pr_info("UART %d has not been activated \n", port + 1); + return; + } + g_uart_activated[port] = 0; + + switch (port) { + case 0: + gpio_free_mux(MX27_PIN_UART1_TXD); + gpio_free_mux(MX27_PIN_UART1_RXD); + gpio_free_mux(MX27_PIN_UART1_CTS); + gpio_free_mux(MX27_PIN_UART1_RTS); + break; + case 1: + gpio_free_mux(MX27_PIN_UART2_TXD); + gpio_free_mux(MX27_PIN_UART2_RXD); + gpio_free_mux(MX27_PIN_UART2_CTS); + gpio_free_mux(MX27_PIN_UART2_RTS); + break; + case 2: + gpio_free_mux(MX27_PIN_UART3_TXD); + gpio_free_mux(MX27_PIN_UART3_RXD); + gpio_free_mux(MX27_PIN_UART3_CTS); + gpio_free_mux(MX27_PIN_UART3_RTS); + + /* Disable IRDA in CPLD */ + __raw_writew(PBC_BCTRL2_IRDA_EN, PBC_BCTRL2_SET_REG); + break; + case 3: + gpio_free_mux(MX27_PIN_USBH1_TXDM); + gpio_free_mux(MX27_PIN_USBH1_RXDP); + gpio_free_mux(MX27_PIN_USBH1_TXDP); + gpio_free_mux(MX27_PIN_USBH1_FS); + break; + case 4: + gpio_free_mux(MX27_PIN_CSI_D6); + gpio_free_mux(MX27_PIN_CSI_D7); + gpio_free_mux(MX27_PIN_CSI_VSYNC); + gpio_free_mux(MX27_PIN_CSI_HSYNC); + break; + case 5: + gpio_free_mux(MX27_PIN_CSI_D0); + gpio_free_mux(MX27_PIN_CSI_D1); + gpio_free_mux(MX27_PIN_CSI_D2); + gpio_free_mux(MX27_PIN_CSI_D3); + break; + default: + break; + } +} + +/*! + * Configure the IOMUX GPR register to receive shared SDMA UART events + * + * @param port a UART port + */ +void config_uartdma_event(int port) +{ + return; +} + +/*! + * Setup GPIO for USB, Total 34 signals + * PIN Configuration for USBOTG: High/Full speed OTG + * PE2,PE1,PE0,PE24,PE25 -- PRIMARY + PC7 - PC13 -- PRIMARY + PB23,PB24 -- PRIMARY + + * PIN Configuration for USBH2: : High/Full/Low speed host + * PA0 - PA4 -- PRIMARY + PD19, PD20,PD21,PD22,PD23,PD24,PD26 --Alternate (SECONDARY) + + * PIN Configuration for USBH1: Full/low speed host + * PB25 - PB31 -- PRIMARY + PB22 -- PRIMARY + */ +void gpio_usbh1_active(void) +{ + gpio_request_mux(MX27_PIN_USBH1_SUSP, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBH1_RCV, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBH1_FS, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBH1_OE_B, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBH1_TXDM, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBH1_TXDP, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBH1_RXDM, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBH1_RXDP, GPIO_MUX_PRIMARY); + + __raw_writew(PBC_BCTRL3_FSH_MOD, PBC_BCTRL3_CLEAR_REG); + __raw_writew(PBC_BCTRL3_FSH_VBUS_EN, PBC_BCTRL3_CLEAR_REG); +} +void gpio_usbh1_inactive(void) +{ + gpio_free_mux(MX27_PIN_USBH1_SUSP); + gpio_free_mux(MX27_PIN_USBH1_RCV); + gpio_free_mux(MX27_PIN_USBH1_FS); + gpio_free_mux(MX27_PIN_USBH1_OE_B); + gpio_free_mux(MX27_PIN_USBH1_TXDM); + gpio_free_mux(MX27_PIN_USBH1_TXDP); + gpio_free_mux(MX27_PIN_USBH1_RXDM); + gpio_free_mux(MX27_PIN_USBH1_RXDP); + __raw_writew(PBC_BCTRL3_FSH_VBUS_EN, PBC_BCTRL3_SET_REG); +} + +/* + * conflicts with CSPI1 (MC13783) and CSPI2 (Connector) + */ +void gpio_usbh2_active(void) +{ + gpio_set_puen(MX27_PIN_USBH2_CLK, 0); + gpio_set_puen(MX27_PIN_USBH2_DIR, 0); + gpio_set_puen(MX27_PIN_USBH2_DATA7, 0); + gpio_set_puen(MX27_PIN_USBH2_NXT, 0); + gpio_set_puen(MX27_PIN_USBH2_STP, 0); + gpio_set_puen(MX27_PIN_CSPI2_SS2, 0); + gpio_set_puen(MX27_PIN_CSPI2_SS1, 0); + gpio_set_puen(MX27_PIN_CSPI2_SS0, 0); + gpio_set_puen(MX27_PIN_CSPI2_SCLK, 0); + gpio_set_puen(MX27_PIN_CSPI2_MISO, 0); + gpio_set_puen(MX27_PIN_CSPI2_MOSI, 0); + gpio_set_puen(MX27_PIN_CSPI1_SS2, 0); + + gpio_request_mux(MX27_PIN_USBH2_CLK, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBH2_DIR, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBH2_DATA7, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBH2_NXT, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBH2_STP, GPIO_MUX_PRIMARY); + + gpio_request_mux(MX27_PIN_CSPI2_SS2, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_CSPI2_SS1, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_CSPI2_SS0, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_CSPI2_SCLK, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_CSPI2_MISO, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_CSPI2_MOSI, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_CSPI1_SS2, GPIO_MUX_ALT); + __raw_writew(PBC_BCTRL3_HSH_EN, PBC_BCTRL3_CLEAR_REG); +} +void gpio_usbh2_inactive(void) +{ + gpio_free_mux(MX27_PIN_USBH2_CLK); + gpio_free_mux(MX27_PIN_USBH2_DIR); + gpio_free_mux(MX27_PIN_USBH2_DATA7); + gpio_free_mux(MX27_PIN_USBH2_NXT); + gpio_free_mux(MX27_PIN_USBH2_STP); + + gpio_free_mux(MX27_PIN_CSPI2_SS2); + gpio_free_mux(MX27_PIN_CSPI2_SS1); + gpio_free_mux(MX27_PIN_CSPI2_SS0); + gpio_free_mux(MX27_PIN_CSPI2_SCLK); + gpio_free_mux(MX27_PIN_CSPI2_MISO); + gpio_free_mux(MX27_PIN_CSPI2_MOSI); + gpio_free_mux(MX27_PIN_CSPI1_SS2); + + gpio_set_puen(MX27_PIN_USBH2_CLK, 1); + gpio_set_puen(MX27_PIN_USBH2_DIR, 1); + gpio_set_puen(MX27_PIN_USBH2_DATA7, 1); + gpio_set_puen(MX27_PIN_USBH2_NXT, 1); + gpio_set_puen(MX27_PIN_USBH2_STP, 1); + gpio_set_puen(MX27_PIN_CSPI2_SS2, 1); + gpio_set_puen(MX27_PIN_CSPI2_SS1, 1); + gpio_set_puen(MX27_PIN_CSPI2_SS0, 1); + gpio_set_puen(MX27_PIN_CSPI2_SCLK, 1); + gpio_set_puen(MX27_PIN_CSPI2_MISO, 1); + gpio_set_puen(MX27_PIN_CSPI2_MOSI, 1); + gpio_set_puen(MX27_PIN_CSPI1_SS2, 1); + __raw_writew(PBC_BCTRL3_HSH_EN, PBC_BCTRL3_SET_REG); +} + +int gpio_usbotg_hs_active(void) +{ + gpio_request_mux(MX27_PIN_USBOTG_DATA5, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBOTG_DATA6, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBOTG_DATA0, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBOTG_DATA2, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBOTG_DATA1, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBOTG_DATA3, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBOTG_DATA4, GPIO_MUX_PRIMARY); + + gpio_request_mux(MX27_PIN_USBOTG_DIR, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBOTG_STP, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBOTG_NXT, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBOTG_CLK, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USBOTG_DATA7, GPIO_MUX_PRIMARY); + + gpio_request_mux(MX27_PIN_USB_OC_B, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_USB_PWR, GPIO_MUX_PRIMARY); + __raw_writew(PBC_BCTRL3_OTG_HS_EN, PBC_BCTRL3_CLEAR_REG); + return 0; +} + +void gpio_usbotg_hs_inactive(void) +{ + gpio_free_mux(MX27_PIN_USBOTG_DATA5); + gpio_free_mux(MX27_PIN_USBOTG_DATA6); + gpio_free_mux(MX27_PIN_USBOTG_DATA0); + gpio_free_mux(MX27_PIN_USBOTG_DATA2); + gpio_free_mux(MX27_PIN_USBOTG_DATA1); + gpio_free_mux(MX27_PIN_USBOTG_DATA3); + gpio_free_mux(MX27_PIN_USBOTG_DATA4); + + gpio_free_mux(MX27_PIN_USBOTG_DIR); + gpio_free_mux(MX27_PIN_USBOTG_STP); + gpio_free_mux(MX27_PIN_USBOTG_NXT); + gpio_free_mux(MX27_PIN_USBOTG_CLK); + gpio_free_mux(MX27_PIN_USBOTG_DATA7); + + gpio_free_mux(MX27_PIN_USB_OC_B); + gpio_free_mux(MX27_PIN_USB_PWR); + __raw_writew(PBC_BCTRL3_OTG_HS_EN, PBC_BCTRL3_SET_REG); +} + +int gpio_usbotg_fs_active(void) +{ + return gpio_usbotg_hs_active(); +} + +void gpio_usbotg_fs_inactive(void) +{ + return gpio_usbotg_hs_inactive(); +} + +/*! + * end Setup GPIO for USB + * + */ + +/************************************************************************/ +/* for i2c gpio */ +/* I2C1: PD17,PD18 -- Primary */ +/* I2C2: PC5,PC6 -- Primary */ +/************************************************************************/ +/*! +* Setup GPIO for an I2C device to be active +* +* @param i2c_num an I2C device +*/ +void gpio_i2c_active(int i2c_num) +{ + switch (i2c_num) { + case 0: + gpio_request_mux(MX27_PIN_I2C_CLK, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_I2C_DATA, GPIO_MUX_PRIMARY); + break; + case 1: + gpio_request_mux(MX27_PIN_I2C2_SCL, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_I2C2_SDA, GPIO_MUX_PRIMARY); + break; + default: + printk(KERN_ERR "gpio_i2c_active no compatible I2C adapter\n"); + break; + } +} + +/*! + * * Setup GPIO for an I2C device to be inactive + * * + * * @param i2c_num an I2C device + */ +void gpio_i2c_inactive(int i2c_num) +{ + switch (i2c_num) { + case 0: + gpio_free_mux(MX27_PIN_I2C_CLK); + gpio_free_mux(MX27_PIN_I2C_DATA); + break; + case 1: + gpio_free_mux(MX27_PIN_I2C2_SCL); + gpio_free_mux(MX27_PIN_I2C2_SDA); + break; + default: + break; + } +} + +/*! + * Setup GPIO for a CSPI device to be active + * + * @param cspi_mod an CSPI device + */ +void gpio_spi_active(int cspi_mod) +{ + switch (cspi_mod) { + case 0: + /* SPI1 */ + gpio_request_mux(MX27_PIN_CSPI1_MOSI, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSPI1_MISO, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSPI1_SCLK, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSPI1_RDY, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSPI1_SS0, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSPI1_SS1, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSPI1_SS2, GPIO_MUX_PRIMARY); + break; + case 1: + /*SPI2 */ + gpio_request_mux(MX27_PIN_CSPI2_MOSI, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSPI2_MISO, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSPI2_SCLK, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSPI2_SS0, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSPI2_SS1, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSPI2_SS2, GPIO_MUX_PRIMARY); + break; + case 2: + /*SPI3 */ + gpio_request_mux(MX27_PIN_SD1_D0, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_SD1_CMD, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_SD1_CLK, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_SD1_D3, GPIO_MUX_ALT); + break; + + default: + break; + } +} + +/*! + * Setup GPIO for a CSPI device to be inactive + * + * @param cspi_mod a CSPI device + */ +void gpio_spi_inactive(int cspi_mod) +{ + switch (cspi_mod) { + case 0: + /* SPI1 */ + gpio_free_mux(MX27_PIN_CSPI1_MOSI); + gpio_free_mux(MX27_PIN_CSPI1_MISO); + gpio_free_mux(MX27_PIN_CSPI1_SCLK); + gpio_free_mux(MX27_PIN_CSPI1_RDY); + gpio_free_mux(MX27_PIN_CSPI1_SS0); + gpio_free_mux(MX27_PIN_CSPI1_SS1); + gpio_free_mux(MX27_PIN_CSPI1_SS2); + break; + case 1: + /*SPI2 */ + gpio_free_mux(MX27_PIN_CSPI2_MOSI); + gpio_free_mux(MX27_PIN_CSPI2_MISO); + gpio_free_mux(MX27_PIN_CSPI2_SCLK); + gpio_free_mux(MX27_PIN_CSPI2_SS0); + gpio_free_mux(MX27_PIN_CSPI2_SS1); + gpio_free_mux(MX27_PIN_CSPI2_SS2); + break; + case 2: + /*SPI3 */ + gpio_free_mux(MX27_PIN_SD1_D0); + gpio_free_mux(MX27_PIN_SD1_CMD); + gpio_free_mux(MX27_PIN_SD1_CLK); + gpio_free_mux(MX27_PIN_SD1_D3); + break; + + default: + break; + } +} + +/*! + * Setup GPIO for a nand flash device to be active + * + */ +void gpio_nand_active(void) +{ + unsigned long reg; + reg = __raw_readl(IO_ADDRESS(SYSCTRL_BASE_ADDR) + SYS_FMCR); + reg &= ~(1 << 4); + __raw_writel(reg, IO_ADDRESS(SYSCTRL_BASE_ADDR) + SYS_FMCR); + + gpio_request_mux(MX27_PIN_NFRB, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_NFCE_B, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_NFWP_B, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_NFCLE, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_NFALE, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_NFRE_B, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_NFWE_B, GPIO_MUX_PRIMARY); +} + +/*! + * Setup GPIO for a nand flash device to be inactive + * + */ +void gpio_nand_inactive(void) +{ + gpio_free_mux(MX27_PIN_NFRB); + gpio_free_mux(MX27_PIN_NFCE_B); + gpio_free_mux(MX27_PIN_NFWP_B); + gpio_free_mux(MX27_PIN_NFCLE); + gpio_free_mux(MX27_PIN_NFALE); + gpio_free_mux(MX27_PIN_NFRE_B); + gpio_free_mux(MX27_PIN_NFWE_B); +} + +/*! + * Setup GPIO for CSI device to be active + * + */ +void gpio_sensor_active(void) +{ + gpio_request_mux(MX27_PIN_CSI_D0, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSI_D1, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSI_D2, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSI_D3, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSI_D4, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSI_MCLK, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSI_PIXCLK, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSI_D5, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSI_D6, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSI_D7, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSI_VSYNC, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSI_HSYNC, GPIO_MUX_PRIMARY); + +#ifdef CONFIG_MXC_CAMERA_MC521DA + __raw_writew(0x100, PBC_BCTRL2_SET_REG); +#else + __raw_writew(0x400, PBC_BCTRL2_SET_REG); +#endif +} + +void gpio_sensor_inactive(void) +{ + gpio_free_mux(MX27_PIN_CSI_D0); + gpio_free_mux(MX27_PIN_CSI_D1); + gpio_free_mux(MX27_PIN_CSI_D2); + gpio_free_mux(MX27_PIN_CSI_D3); + gpio_free_mux(MX27_PIN_CSI_D4); + gpio_free_mux(MX27_PIN_CSI_MCLK); + gpio_free_mux(MX27_PIN_CSI_PIXCLK); + gpio_free_mux(MX27_PIN_CSI_D5); + gpio_free_mux(MX27_PIN_CSI_D6); + gpio_free_mux(MX27_PIN_CSI_D7); + gpio_free_mux(MX27_PIN_CSI_VSYNC); + gpio_free_mux(MX27_PIN_CSI_HSYNC); + +#ifdef CONFIG_MXC_CAMERA_MC521DA + __raw_writew(0x100, PBC_BCTRL2_CLEAR_REG); +#else + __raw_writew(0x400, PBC_BCTRL2_CLEAR_REG); +#endif +} + +void gpio_sensor_reset(bool flag) +{ + u16 temp; + + if (flag) { + temp = 0x200; + __raw_writew(temp, PBC_BCTRL2_CLEAR_REG); + } else { + temp = 0x200; + __raw_writew(temp, PBC_BCTRL2_SET_REG); + } +} + +/*! + * Setup GPIO for LCDC device to be active + * + */ +void gpio_lcdc_active(void) +{ + gpio_request_mux(MX27_PIN_LSCLK, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_LD0, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_LD1, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_LD2, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_LD3, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_LD4, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_LD5, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_LD6, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_LD7, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_LD8, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_LD9, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_LD10, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_LD11, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_LD12, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_LD13, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_LD14, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_LD15, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_LD16, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_LD17, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_REV, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CLS, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_PS, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_SPL_SPR, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_HSYNC, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_VSYNC, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CONTRAST, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_OE_ACD, GPIO_MUX_PRIMARY); +} + +/*! + * Setup GPIO for LCDC device to be inactive + * + */ +void gpio_lcdc_inactive(void) +{ + gpio_free_mux(MX27_PIN_LSCLK); + gpio_free_mux(MX27_PIN_LD0); + gpio_free_mux(MX27_PIN_LD1); + gpio_free_mux(MX27_PIN_LD2); + gpio_free_mux(MX27_PIN_LD3); + gpio_free_mux(MX27_PIN_LD4); + gpio_free_mux(MX27_PIN_LD5); + gpio_free_mux(MX27_PIN_LD6); + gpio_free_mux(MX27_PIN_LD7); + gpio_free_mux(MX27_PIN_LD8); + gpio_free_mux(MX27_PIN_LD9); + gpio_free_mux(MX27_PIN_LD10); + gpio_free_mux(MX27_PIN_LD11); + gpio_free_mux(MX27_PIN_LD12); + gpio_free_mux(MX27_PIN_LD13); + gpio_free_mux(MX27_PIN_LD14); + gpio_free_mux(MX27_PIN_LD15); + gpio_free_mux(MX27_PIN_LD16); + gpio_free_mux(MX27_PIN_LD17); + gpio_free_mux(MX27_PIN_REV); + gpio_free_mux(MX27_PIN_CLS); + gpio_free_mux(MX27_PIN_PS); + gpio_free_mux(MX27_PIN_SPL_SPR); + gpio_free_mux(MX27_PIN_HSYNC); + gpio_free_mux(MX27_PIN_VSYNC); + gpio_free_mux(MX27_PIN_CONTRAST); + gpio_free_mux(MX27_PIN_OE_ACD); +} + +/*! + * Setup GPIO PA25 low to start hard reset FS453 TV encoder + * + */ +void gpio_fs453_reset_low(void) +{ + gpio_free_mux(MX27_PIN_CLS); + if (gpio_request_mux(MX27_PIN_CLS, GPIO_MUX_GPIO)) { + printk(KERN_ERR "bug: request GPIO PA25 failed.\n"); + return; + } + + /* PA25 (CLS) as output */ + mxc_set_gpio_direction(MX27_PIN_CLS, 0); + gpio_config_mux(MX27_PIN_CLS, GPIO_MUX_GPIO); + mxc_set_gpio_dataout(MX27_PIN_CLS, 0); +} + +/*! + * Setup GPIO PA25 high to end hard reset FS453 TV encoder + * + */ +void gpio_fs453_reset_high(void) +{ + gpio_free_mux(MX27_PIN_CLS); + if (gpio_request_mux(MX27_PIN_CLS, GPIO_MUX_GPIO)) { + printk(KERN_ERR "bug: request GPIO PA25 failed.\n"); + return; + } + + /* PA25 (CLS) as output */ + mxc_set_gpio_direction(MX27_PIN_CLS, 0); + gpio_config_mux(MX27_PIN_CLS, GPIO_MUX_GPIO); + mxc_set_gpio_dataout(MX27_PIN_CLS, 1); +} + +/*! + * This function configures the IOMux block for PMIC standard operations. + * + */ +void gpio_pmic_active(void) +{ + gpio_config_mux(MX27_PIN_TOUT, GPIO_MUX_GPIO); + mxc_set_gpio_direction(MX27_PIN_TOUT, 1); +} + +/*! + * GPIO settings not required for keypad + * + */ +void gpio_keypad_active(void) +{ +} + +/*! + * GPIO settings not required for keypad + * + */ +void gpio_keypad_inactive(void) +{ +} + +/*! + * Setup GPIO for ATA device to be active + * + */ +void gpio_ata_active(void) +{ + gpio_request_mux(MX27_PIN_ATA_DATA0, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_ATA_DATA1, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_ATA_DATA2, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_ATA_DATA3, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_ATA_DATA4, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_ATA_DATA5, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_ATA_DATA6, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_ATA_DATA7, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_ATA_DATA8, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_ATA_DATA9, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_ATA_DATA10, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_ATA_DATA11, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_ATA_DATA12, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_ATA_DATA13, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_ATA_DATA14, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_ATA_DATA15, GPIO_MUX_PRIMARY); + + gpio_request_mux(MX27_PIN_PC_CD1_B, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_PC_CD2_B, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_PC_WAIT_B, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_PC_READY, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_PC_PWRON, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_PC_VS1, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_PC_VS2, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_PC_BVD1, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_PC_BVD2, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_PC_RST, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_IOIS16, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_PC_RW_B, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_PC_POE, GPIO_MUX_ALT); + + __raw_writew(PBC_BCTRL2_ATAFEC_EN | PBC_BCTRL2_ATAFEC_SEL | + PBC_BCTRL2_ATA_EN, PBC_BCTRL2_CLEAR_REG); +} + +/*! + * Setup GPIO for ATA device to be inactive + * + */ +void gpio_ata_inactive(void) +{ + __raw_writew(PBC_BCTRL2_ATAFEC_EN | PBC_BCTRL2_ATAFEC_SEL | + PBC_BCTRL2_ATA_EN, PBC_BCTRL2_SET_REG); + + gpio_free_mux(MX27_PIN_ATA_DATA0); + gpio_free_mux(MX27_PIN_ATA_DATA1); + gpio_free_mux(MX27_PIN_ATA_DATA2); + gpio_free_mux(MX27_PIN_ATA_DATA3); + gpio_free_mux(MX27_PIN_ATA_DATA4); + gpio_free_mux(MX27_PIN_ATA_DATA5); + gpio_free_mux(MX27_PIN_ATA_DATA6); + gpio_free_mux(MX27_PIN_ATA_DATA7); + gpio_free_mux(MX27_PIN_ATA_DATA8); + gpio_free_mux(MX27_PIN_ATA_DATA9); + gpio_free_mux(MX27_PIN_ATA_DATA10); + gpio_free_mux(MX27_PIN_ATA_DATA11); + gpio_free_mux(MX27_PIN_ATA_DATA12); + gpio_free_mux(MX27_PIN_ATA_DATA13); + gpio_free_mux(MX27_PIN_ATA_DATA14); + gpio_free_mux(MX27_PIN_ATA_DATA15); + + gpio_free_mux(MX27_PIN_PC_CD1_B); + gpio_free_mux(MX27_PIN_PC_CD2_B); + gpio_free_mux(MX27_PIN_PC_WAIT_B); + gpio_free_mux(MX27_PIN_PC_READY); + gpio_free_mux(MX27_PIN_PC_PWRON); + gpio_free_mux(MX27_PIN_PC_VS1); + gpio_free_mux(MX27_PIN_PC_VS2); + gpio_free_mux(MX27_PIN_PC_BVD1); + gpio_free_mux(MX27_PIN_PC_BVD2); + gpio_free_mux(MX27_PIN_PC_RST); + gpio_free_mux(MX27_PIN_IOIS16); + gpio_free_mux(MX27_PIN_PC_RW_B); + gpio_free_mux(MX27_PIN_PC_POE); +} + +/*! + * Setup GPIO for FEC device to be active + * + */ +void gpio_fec_active(void) +{ + gpio_request_mux(MX27_PIN_ATA_DATA15, GPIO_MUX_OUTPUT1); + mxc_set_gpio_direction(MX27_PIN_ATA_DATA15, 0); + gpio_request_mux(MX27_PIN_ATA_DATA14, GPIO_MUX_OUTPUT1); + mxc_set_gpio_direction(MX27_PIN_ATA_DATA14, 0); + gpio_request_mux(MX27_PIN_ATA_DATA13, GPIO_MUX_INPUT1); + mxc_set_gpio_direction(MX27_PIN_ATA_DATA13, 1); + gpio_request_mux(MX27_PIN_ATA_DATA12, GPIO_MUX_INPUT1); + mxc_set_gpio_direction(MX27_PIN_ATA_DATA12, 1); + gpio_request_mux(MX27_PIN_ATA_DATA11, GPIO_MUX_INPUT1); + mxc_set_gpio_direction(MX27_PIN_ATA_DATA11, 1); + gpio_request_mux(MX27_PIN_ATA_DATA10, GPIO_MUX_INPUT1); + mxc_set_gpio_direction(MX27_PIN_ATA_DATA10, 1); + gpio_request_mux(MX27_PIN_ATA_DATA9, GPIO_MUX_INPUT1); + mxc_set_gpio_direction(MX27_PIN_ATA_DATA9, 1); + gpio_request_mux(MX27_PIN_ATA_DATA8, GPIO_MUX_INPUT1); + mxc_set_gpio_direction(MX27_PIN_ATA_DATA8, 1); + gpio_request_mux(MX27_PIN_ATA_DATA7, GPIO_MUX_OUTPUT1); + mxc_set_gpio_direction(MX27_PIN_ATA_DATA7, 0); + + gpio_request_mux(MX27_PIN_ATA_DATA6, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_ATA_DATA5, GPIO_MUX_INPUT1); + mxc_set_gpio_direction(MX27_PIN_ATA_DATA5, 1); + gpio_request_mux(MX27_PIN_ATA_DATA4, GPIO_MUX_INPUT1); + mxc_set_gpio_direction(MX27_PIN_ATA_DATA4, 1); + gpio_request_mux(MX27_PIN_ATA_DATA3, GPIO_MUX_INPUT1); + mxc_set_gpio_direction(MX27_PIN_ATA_DATA3, 1); + gpio_request_mux(MX27_PIN_ATA_DATA2, GPIO_MUX_INPUT1); + mxc_set_gpio_direction(MX27_PIN_ATA_DATA2, 1); + gpio_request_mux(MX27_PIN_ATA_DATA1, GPIO_MUX_OUTPUT1); + mxc_set_gpio_direction(MX27_PIN_ATA_DATA1, 0); + gpio_request_mux(MX27_PIN_ATA_DATA0, GPIO_MUX_OUTPUT1); + mxc_set_gpio_direction(MX27_PIN_ATA_DATA0, 0); + gpio_request_mux(MX27_PIN_SD3_CLK, GPIO_MUX_OUTPUT1); + mxc_set_gpio_direction(MX27_PIN_SD3_CLK, 0); + gpio_request_mux(MX27_PIN_SD3_CMD, GPIO_MUX_OUTPUT1); + mxc_set_gpio_direction(MX27_PIN_SD3_CMD, 0); + + __raw_writew(PBC_BCTRL2_ATAFEC_EN, PBC_BCTRL2_CLEAR_REG); + __raw_writew(PBC_BCTRL2_ATAFEC_SEL, PBC_BCTRL2_SET_REG); +} + +/*! + * Setup GPIO for FEC device to be inactive + * + */ +void gpio_fec_inactive(void) +{ + gpio_free_mux(MX27_PIN_ATA_DATA0); + gpio_free_mux(MX27_PIN_ATA_DATA1); + gpio_free_mux(MX27_PIN_ATA_DATA2); + gpio_free_mux(MX27_PIN_ATA_DATA3); + gpio_free_mux(MX27_PIN_ATA_DATA4); + gpio_free_mux(MX27_PIN_ATA_DATA5); + gpio_free_mux(MX27_PIN_ATA_DATA6); + gpio_free_mux(MX27_PIN_ATA_DATA7); + gpio_free_mux(MX27_PIN_ATA_DATA8); + gpio_free_mux(MX27_PIN_ATA_DATA9); + gpio_free_mux(MX27_PIN_ATA_DATA10); + gpio_free_mux(MX27_PIN_ATA_DATA11); + gpio_free_mux(MX27_PIN_ATA_DATA12); + gpio_free_mux(MX27_PIN_ATA_DATA13); + gpio_free_mux(MX27_PIN_ATA_DATA14); + gpio_free_mux(MX27_PIN_ATA_DATA15); + + gpio_free_mux(MX27_PIN_SD3_CMD); + gpio_free_mux(MX27_PIN_SD3_CLK); +} + +/*! + * Setup GPIO for SLCDC device to be active + * + */ +void gpio_slcdc_active(int type) +{ + switch (type) { + case 0: + gpio_request_mux(MX27_PIN_SSI3_CLK, GPIO_MUX_ALT); /* CLK */ + gpio_request_mux(MX27_PIN_SSI3_TXDAT, GPIO_MUX_ALT); /* CS */ + gpio_request_mux(MX27_PIN_SSI3_RXDAT, GPIO_MUX_ALT); /* RS */ + gpio_request_mux(MX27_PIN_SSI3_FS, GPIO_MUX_ALT); /* D0 */ + break; + + case 1: + gpio_request_mux(MX27_PIN_SD2_D1, GPIO_MUX_GPIO); /* CLK */ + gpio_request_mux(MX27_PIN_SD2_D2, GPIO_MUX_GPIO); /* D0 */ + gpio_request_mux(MX27_PIN_SD2_D3, GPIO_MUX_GPIO); /* RS */ + gpio_request_mux(MX27_PIN_SD2_CMD, GPIO_MUX_GPIO); /* CS */ + break; + + case 2: + gpio_request_mux(MX27_PIN_LD0, GPIO_MUX_GPIO); + gpio_request_mux(MX27_PIN_LD1, GPIO_MUX_GPIO); + gpio_request_mux(MX27_PIN_LD2, GPIO_MUX_GPIO); + gpio_request_mux(MX27_PIN_LD3, GPIO_MUX_GPIO); + gpio_request_mux(MX27_PIN_LD4, GPIO_MUX_GPIO); + gpio_request_mux(MX27_PIN_LD5, GPIO_MUX_GPIO); + gpio_request_mux(MX27_PIN_LD6, GPIO_MUX_GPIO); + gpio_request_mux(MX27_PIN_LD7, GPIO_MUX_GPIO); + gpio_request_mux(MX27_PIN_LD8, GPIO_MUX_GPIO); + gpio_request_mux(MX27_PIN_LD9, GPIO_MUX_GPIO); + gpio_request_mux(MX27_PIN_LD10, GPIO_MUX_GPIO); + gpio_request_mux(MX27_PIN_LD11, GPIO_MUX_GPIO); + gpio_request_mux(MX27_PIN_LD12, GPIO_MUX_GPIO); + gpio_request_mux(MX27_PIN_LD13, GPIO_MUX_GPIO); + gpio_request_mux(MX27_PIN_LD14, GPIO_MUX_GPIO); + gpio_request_mux(MX27_PIN_LD15, GPIO_MUX_GPIO); + break; + + default: + break; + } + + return; +} + +/*! + * Setup GPIO for SLCDC device to be inactive + * + */ +void gpio_slcdc_inactive(int type) +{ + switch (type) { + case 0: + gpio_free_mux(MX27_PIN_SSI3_CLK); /* CLK */ + gpio_free_mux(MX27_PIN_SSI3_TXDAT); /* CS */ + gpio_free_mux(MX27_PIN_SSI3_RXDAT); /* RS */ + gpio_free_mux(MX27_PIN_SSI3_FS); /* D0 */ + break; + + case 1: + gpio_free_mux(MX27_PIN_SD2_D1); /* CLK */ + gpio_free_mux(MX27_PIN_SD2_D2); /* D0 */ + gpio_free_mux(MX27_PIN_SD2_D3); /* RS */ + gpio_free_mux(MX27_PIN_SD2_CMD); /* CS */ + break; + + case 2: + gpio_free_mux(MX27_PIN_LD0); + gpio_free_mux(MX27_PIN_LD1); + gpio_free_mux(MX27_PIN_LD2); + gpio_free_mux(MX27_PIN_LD3); + gpio_free_mux(MX27_PIN_LD4); + gpio_free_mux(MX27_PIN_LD5); + gpio_free_mux(MX27_PIN_LD6); + gpio_free_mux(MX27_PIN_LD7); + gpio_free_mux(MX27_PIN_LD8); + gpio_free_mux(MX27_PIN_LD9); + gpio_free_mux(MX27_PIN_LD10); + gpio_free_mux(MX27_PIN_LD11); + gpio_free_mux(MX27_PIN_LD12); + gpio_free_mux(MX27_PIN_LD13); + gpio_free_mux(MX27_PIN_LD14); + gpio_free_mux(MX27_PIN_LD15); + break; + + default: + break; + } + + return; +} + +void gpio_ssi_active(int ssi_num) +{ + switch (ssi_num) { + case 0: + gpio_request_mux(MX27_PIN_SSI1_FS, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_SSI1_RXDAT, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_SSI1_TXDAT, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_SSI1_CLK, GPIO_MUX_PRIMARY); + gpio_set_puen(MX27_PIN_SSI1_FS, 0); + gpio_set_puen(MX27_PIN_SSI1_RXDAT, 0); + gpio_set_puen(MX27_PIN_SSI1_TXDAT, 0); + gpio_set_puen(MX27_PIN_SSI1_CLK, 0); + break; + case 1: + gpio_request_mux(MX27_PIN_SSI2_FS, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_SSI2_RXDAT, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_SSI2_TXDAT, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_SSI2_CLK, GPIO_MUX_PRIMARY); + gpio_set_puen(MX27_PIN_SSI2_FS, 0); + gpio_set_puen(MX27_PIN_SSI2_RXDAT, 0); + gpio_set_puen(MX27_PIN_SSI2_TXDAT, 0); + gpio_set_puen(MX27_PIN_SSI2_CLK, 0); + break; + default: + break; + } + return; +} + +/*! + * * Setup GPIO for a SSI port to be inactive + * * + * * @param ssi_num an SSI port num + */ + +void gpio_ssi_inactive(int ssi_num) +{ + switch (ssi_num) { + case 0: + gpio_free_mux(MX27_PIN_SSI1_FS); + gpio_free_mux(MX27_PIN_SSI1_RXDAT); + gpio_free_mux(MX27_PIN_SSI1_TXDAT); + gpio_free_mux(MX27_PIN_SSI1_CLK); + break; + case 1: + gpio_free_mux(MX27_PIN_SSI2_FS); + gpio_free_mux(MX27_PIN_SSI2_RXDAT); + gpio_free_mux(MX27_PIN_SSI2_TXDAT); + gpio_free_mux(MX27_PIN_SSI2_CLK); + break; + default: + break; + } + return; +} + +/*! + * Setup GPIO for SDHC to be active + * + * @param module SDHC module number + */ +void gpio_sdhc_active(int module) +{ + u16 data; + switch (module) { + case 0: + gpio_request_mux(MX27_PIN_SD1_CLK, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_SD1_CMD, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_SD1_D0, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_SD1_D1, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_SD1_D2, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_SD1_D3, GPIO_MUX_PRIMARY); + /* 22k pull up for sd1 dat3 pins */ + data = __raw_readw(IO_ADDRESS(SYSCTRL_BASE_ADDR + 0x54)); + data |= 0x0c; + __raw_writew(data, IO_ADDRESS(SYSCTRL_BASE_ADDR + 0x54)); + /*mxc_clks_enable(SDHC1_CLK); + mxc_clks_enable(PERCLK2); */ + break; + case 1: + gpio_request_mux(MX27_PIN_SD2_CLK, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_SD2_CMD, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_SD2_D0, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_SD2_D1, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_SD2_D2, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_SD2_D3, GPIO_MUX_PRIMARY); + /* 22k pull up for sd2 pins */ + data = __raw_readw(IO_ADDRESS(SYSCTRL_BASE_ADDR + 0x54)); + data &= ~0xfff0; + data |= 0xfff0; + __raw_writew(data, IO_ADDRESS(SYSCTRL_BASE_ADDR + 0x54)); + /*mxc_clks_enable(SDHC2_CLK); + mxc_clks_enable(PERCLK2); */ + break; + case 2: + gpio_request_mux(MX27_PIN_SD3_CLK, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_SD3_CMD, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_ATA_DATA0, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_ATA_DATA1, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_ATA_DATA2, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_ATA_DATA3, GPIO_MUX_ALT); + /*mxc_clks_enable(SDHC3_CLK); + mxc_clks_enable(PERCLK2); */ + break; + default: + break; + } +} + +/*! + * Setup GPIO for SDHC1 to be inactive + * + * @param module SDHC module number + */ +void gpio_sdhc_inactive(int module) +{ + switch (module) { + case 0: + gpio_free_mux(MX27_PIN_SD1_CLK); + gpio_free_mux(MX27_PIN_SD1_CMD); + gpio_free_mux(MX27_PIN_SD1_D0); + gpio_free_mux(MX27_PIN_SD1_D1); + gpio_free_mux(MX27_PIN_SD1_D2); + gpio_free_mux(MX27_PIN_SD1_D3); + /*mxc_clks_disable(SDHC1_CLK); */ + break; + case 1: + gpio_free_mux(MX27_PIN_SD2_CLK); + gpio_free_mux(MX27_PIN_SD2_CMD); + gpio_free_mux(MX27_PIN_SD2_D0); + gpio_free_mux(MX27_PIN_SD2_D1); + gpio_free_mux(MX27_PIN_SD2_D2); + gpio_free_mux(MX27_PIN_SD2_D3); + /*mxc_clks_disable(SDHC2_CLK); */ + break; + case 2: + gpio_free_mux(MX27_PIN_SD3_CLK); + gpio_free_mux(MX27_PIN_SD3_CMD); + gpio_free_mux(MX27_PIN_ATA_DATA0); + gpio_free_mux(MX27_PIN_ATA_DATA1); + gpio_free_mux(MX27_PIN_ATA_DATA2); + gpio_free_mux(MX27_PIN_ATA_DATA3); + /*mxc_clks_disable(SDHC3_CLK); */ + break; + default: + break; + } +} + +/* + * Probe for the card. If present the GPIO data would be set. + */ +int sdhc_get_card_det_status(struct device *dev) +{ + return 0; +} + +/* + * Return the card detect pin. + */ +int sdhc_init_card_det(int id) +{ + int ret = 0; + switch (id) { + case 0: + ret = EXPIO_INT_SD1_EN; + break; + case 1: + ret = EXPIO_INT_SD2_EN; + break; + default: + ret = 0; + break; + } + return ret; +} + +/* + * Power on/off Sharp QVGA panel. + */ +void board_power_lcd(int on) +{ + if (on) + __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG); + else + __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG); +} + +void gpio_owire_active(void) +{ + gpio_request_mux(MX27_PIN_RTCK, GPIO_MUX_ALT); +} + +void gpio_owire_inactive(void) +{ + gpio_request_mux(MX27_PIN_RTCK, GPIO_MUX_PRIMARY); +} + +EXPORT_SYMBOL(gpio_uart_active); +EXPORT_SYMBOL(gpio_uart_inactive); +EXPORT_SYMBOL(config_uartdma_event); +EXPORT_SYMBOL(gpio_usbh1_active); +EXPORT_SYMBOL(gpio_usbh1_inactive); +EXPORT_SYMBOL(gpio_usbh2_active); +EXPORT_SYMBOL(gpio_usbh2_inactive); +EXPORT_SYMBOL(gpio_usbotg_hs_active); +EXPORT_SYMBOL(gpio_usbotg_hs_inactive); +EXPORT_SYMBOL(gpio_usbotg_fs_active); +EXPORT_SYMBOL(gpio_usbotg_fs_inactive); +EXPORT_SYMBOL(gpio_i2c_active); +EXPORT_SYMBOL(gpio_i2c_inactive); +EXPORT_SYMBOL(gpio_spi_active); +EXPORT_SYMBOL(gpio_spi_inactive); +EXPORT_SYMBOL(gpio_nand_active); +EXPORT_SYMBOL(gpio_nand_inactive); +EXPORT_SYMBOL(gpio_sensor_active); +EXPORT_SYMBOL(gpio_sensor_inactive); +EXPORT_SYMBOL(gpio_sensor_reset); +EXPORT_SYMBOL(gpio_lcdc_active); +EXPORT_SYMBOL(gpio_lcdc_inactive); +EXPORT_SYMBOL(gpio_fs453_reset_low); +EXPORT_SYMBOL(gpio_fs453_reset_high); +EXPORT_SYMBOL(gpio_pmic_active); +EXPORT_SYMBOL(gpio_keypad_active); +EXPORT_SYMBOL(gpio_keypad_inactive); +EXPORT_SYMBOL(gpio_ata_active); +EXPORT_SYMBOL(gpio_ata_inactive); +EXPORT_SYMBOL(gpio_fec_active); +EXPORT_SYMBOL(gpio_fec_inactive); +EXPORT_SYMBOL(gpio_slcdc_active); +EXPORT_SYMBOL(gpio_slcdc_inactive); +EXPORT_SYMBOL(gpio_ssi_active); +EXPORT_SYMBOL(gpio_ssi_inactive); +EXPORT_SYMBOL(gpio_sdhc_active); +EXPORT_SYMBOL(gpio_sdhc_inactive); +EXPORT_SYMBOL(sdhc_get_card_det_status); +EXPORT_SYMBOL(sdhc_init_card_det); +EXPORT_SYMBOL(board_power_lcd); +EXPORT_SYMBOL(gpio_owire_active); +EXPORT_SYMBOL(gpio_owire_inactive); diff --git a/arch/arm/mach-mx27/mxc_pm.c b/arch/arm/mach-mx27/mxc_pm.c new file mode 100644 index 000000000000..9fd0830b9d75 --- /dev/null +++ b/arch/arm/mach-mx27/mxc_pm.c @@ -0,0 +1,458 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/*! + * @defgroup DPM_MX27 Power Management + * @ingroup MSL_MX27 + */ +/*! + * @file mach-mx27/mxc_pm.c + * + * @brief This file contains the implementation of the Low-level power + * management driver. It modifies the registers of the PLL and clock module + * of the i.MX27. + * + * @ingroup DPM_MX27 + */ + +/* + * Include Files + */ +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <asm/arch/mxc_pm.h> +#include <asm/arch/mxc.h> +#include <asm/arch/system.h> +#include <asm/irq.h> +#include "crm_regs.h" + +/* Local defines */ +#define MAX_ARM_FREQ 400000000 +#define MAX_AHB_FREQ 133000000 +#define MAX_IPG_FREQ 66500000 +#define FREQ_COMP_TOLERANCE 100 /* tolerance percentage times 100 */ +#define MX27_LLPM_DEBUG 0 + +/* + * Global variables + */ +#if 0 +/*! + * These variables hold the various clock values when the module is loaded. + * This is needed because these clocks are derived from MPLL and when MPLL + * output changes, these clocks need to be adjusted. + */ +static u32 perclk1, perclk2, perclk3, perclk4, nfcclk, cpuclk; + +/*! + * Compare two frequences using allowable tolerance + * + * The MX27 PLL can generate many frequencies. This function + * compares the generated frequency to the requested frequency + * and determines it they are within and acceptable tolerance. + * + * @param freq1 desired frequency + * @param freq2 generated frequency + * + * @return Returns 0 is frequencies are within talerance + * and non-zero is they are not. + */ +static s32 freq_equal(u32 freq1, u32 freq2) +{ + if (freq1 > freq2) { + return (freq1 - freq2) <= (freq1 / FREQ_COMP_TOLERANCE); + } + return (freq2 - freq1) <= (freq1 / FREQ_COMP_TOLERANCE); +} + +/*! + * Select the PLL frequency based on the desired ARM frequency. + * + * The MPLL will be configured to output three frequencies, 400/333/266 MHz. + * + * @param armfreq Desired ARM frequency + * + * @return Returns one of the selected PLL frequency (400/333/266 MHz). + * Returns -1 on error. + * + */ +static s32 select_freq_pll(u32 armfreq) +{ + u32 div; + + div = 266000000 / armfreq; + if ((div == 0) || (!freq_equal(armfreq, 266000000 / div))) { + div = 400000000 / armfreq; + if ((div == 0) || (!freq_equal(armfreq, 400000000 / div))) { + return -1; + } + + return 400000000; + } + + return 266000000; +} + +/*! + * Check whether the desired ARM and AHB frequencies are valid. + * + * @param armfreq Desired ARM frequency + * @param ahbfreq Desired AHB frequency + * + * @return Returns 0 on success + * Return -1 on error + */ +static s32 mx27_pm_check_parameters(u32 armfreq, u32 ahbfreq) +{ + u32 ahbdiv; + + /* No idea about minimum frequencies.. just a guess! */ + if ((armfreq < 1000000) || (ahbfreq < 1000000)) { + printk("arm or ahb frequencies are less\n"); + return -1; + } + + if ((armfreq > MAX_ARM_FREQ) || (ahbfreq > MAX_AHB_FREQ)) { + printk("arm or ahb freq. are too much\n"); + return -1; + } + + /* AHB divider value is restricted to less than 8 */ + ahbdiv = armfreq / ahbfreq; + if ((ahbdiv == 0) || (ahbdiv > 8)) { + printk("Invalid ahb frequency\n"); + return -1; + } + + return 0; +} + +/*! + * Integer clock scaling + * + * Change the main ARM clock frequencies without changing the MPLL. + * The integer dividers (PRESC and BCLKDIV) are changed to obtain the + * desired frequency. Since NFC clock is derived from ARM frequency, + * NFCDIV is also adjusted. + * + * @param arm_freq Desired ARM frequency + * @param ahb_freq Desired AHB frequency + * @param pll_freq Current PLL frequency + * + * @return Returns 0 + */ +static s32 mx27_pm_intscale(u32 arm_freq, u32 ahb_freq, s32 pll_freq) +{ + u32 pre_div, bclk_div, nfc_div; + + /* Calculate ARM divider */ + pre_div = pll_freq / arm_freq; + if (pre_div == 0) + pre_div = 1; + + /* Calculate AHB divider */ + bclk_div = arm_freq / ahb_freq; + if (bclk_div == 0) + bclk_div = 1; + + if ((arm_freq / bclk_div) > ahb_freq) + bclk_div++; + + /* NFC clock is dependent on ARM clock */ + nfc_div = arm_freq / nfcclk; + if ((arm_freq / nfc_div) > nfcclk) + nfc_div++; + + /* Adjust NFC divider */ + mxc_set_clocks_div(NFC_CLK, nfc_div); + +#if MX27_LLPM_DEBUG + printk("DIVIDERS: PreDiv = %d BCLKDIV = %d \n", pre_div, bclk_div); + printk("Integer scaling\n"); + printk("PLL = %d : ARM = %d: AHB = %d\n", pll_freq, arm_freq, ahb_freq); +#endif + + /* + * This part is tricky. What to adjust first (PRESC or BCLKDIV)? + * After trial and error, if current ARM frequency is greater than + * desired ARM frequency, then adjust PRESC first, else if current + * ARM frequency is less than desired ARM frequency, then adjust + * BCLKDIV first. + */ + if (cpuclk > arm_freq) { + mxc_set_clocks_div(CPU_CLK, pre_div); + mxc_set_clocks_div(AHB_CLK, bclk_div); + } else { + mxc_set_clocks_div(AHB_CLK, bclk_div); + mxc_set_clocks_div(CPU_CLK, pre_div); + } + + cpuclk = arm_freq; + mdelay(50); + return 0; +} + +/*! + * Set dividers for various peripheral clocks. + * + * PERCLK1, PERCLK2, PERCLK3 and PERCLK4 are adjusted based on the MPLL + * output frequency. + * + * @param pll_freq Desired MPLL output frequency + */ +static void mx27_set_dividers(u32 pll_freq) +{ + s32 perdiv1, perdiv2, perdiv3, perdiv4; + + perdiv1 = pll_freq / perclk1; + if ((pll_freq / perdiv1) > perclk1) + perdiv1++; + + perdiv2 = pll_freq / perclk2; + if ((pll_freq / perdiv2) > perclk2) + perdiv2++; + + perdiv3 = pll_freq / perclk3; + if ((pll_freq / perdiv3) > perclk3) + perdiv3++; + + perdiv4 = pll_freq / perclk4; + if ((pll_freq / perdiv4) > perclk4) + perdiv4++; + + mxc_set_clocks_div(PERCLK1, perdiv1); + mxc_set_clocks_div(PERCLK2, perdiv2); + mxc_set_clocks_div(PERCLK3, perdiv3); + mxc_set_clocks_div(PERCLK4, perdiv4); +} + +/*! + * Change MPLL output frequency and adjust derived clocks to produce the + * desired frequencies. + * + * @param arm_freq Desired ARM frequency + * @param ahb_freq Desired AHB frequency + * @param org_pll Current PLL frequency + * + * @return Returns 0 on success + * Returns -1 on error + */ +static s32 mx27_pm_pllscale(u32 arm_freq, u32 ahb_freq, s32 org_pll) +{ + u32 mfi, mfn, mfd, pd = 1, cscr; + s32 pll_freq; + + /* Obtain the PLL frequency for the desired ARM frequency */ + pll_freq = select_freq_pll(arm_freq); + if (pll_freq == -1) { + return -1; + } + + /* The MPCTL0 register values are programmed based on the oscillator */ + cscr = __raw_readl(IO_ADDRESS(CCM_BASE_ADDR) + CCM_CSCR); + if ((cscr & CCM_CSCR_OSC26M) == 0) { + /* MPCTL0 register values are programmed for 400/266 MHz */ + switch (pll_freq) { + case 400000000: + mfi = 7; + mfn = 9; + mfd = 12; + pd = 0; + break; + + case 266000000: + mfi = 10; + mfn = 6; + mfd = 25; + break; + + default: + return -1; + } + } else { + /* MPCTL0 register values are programmed for 400/266 MHz */ + switch (pll_freq) { + case 400000000: + mfi = 12; + mfn = 2; + mfd = 3; + break; + + case 266000000: + mfi = 8; + mfn = 10; + mfd = 31; + break; + + default: + return -1; + } + } + +#if MX27_LLPM_DEBUG + printk("PLL scaling\n"); + printk("PLL = %d : ARM = %d: AHB = %d\n", pll_freq, arm_freq, ahb_freq); +#endif + + /* Adjust the peripheral clock dividers for new PLL frequency */ + mx27_set_dividers(pll_freq); + + if (pll_freq > org_pll) { + /* Set the dividers first */ + mx27_pm_intscale(arm_freq, ahb_freq, pll_freq); + + /* Set the PLL */ + mxc_pll_set(MCUPLL, mfi, pd, mfd, mfn); + mdelay(50); + } else { + /* Set the PLL first */ + mxc_pll_set(MCUPLL, mfi, pd, mfd, mfn); + mdelay(50); + + /* Set the dividers later */ + mx27_pm_intscale(arm_freq, ahb_freq, pll_freq); + } + + return 0; +} +#endif +/*! + * Implement steps required to transition to low-power modes. + * + * @param mode The desired low-power mode. Possible values are, + * DOZE_MODE + * WAIT_MODE + * STOP_MODE + * DSM_MODE + */ +void mxc_pm_lowpower(s32 mode) +{ + u32 cscr; + + local_irq_disable(); + + /* WAIT and DOZE execute WFI only */ + switch (mode) { + case STOP_MODE: + case DSM_MODE: + /* Clear MPEN and SPEN to disable MPLL/SPLL */ + cscr = __raw_readl(CCM_CSCR); + cscr &= 0xFFFFFFFC; + __raw_writel(cscr, CCM_CSCR); + break; + } + + /* Executes WFI */ + arch_idle(); + + local_irq_enable(); +} + +#if 0 +/*! + * Called to change the core frequency. This function internally decides + * whether to do integer scaling or pll scaling. + * + * @param arm_freq Desired ARM frequency + * @param ahb_freq Desired AHB frequency + * @param ipg_freq Desired IP frequency, constant AHB / 2 always. + * + * @return Returns 0 on success + * Returns -1 on error + */ +int mxc_pm_dvfs(unsigned long arm_freq, long ahb_freq, long ipg_freq) +{ + u32 divider; + s32 pll_freq, ret; + unsigned long flags; + + if (mx27_pm_check_parameters(arm_freq, ahb_freq) != 0) { + return -1; + } + + local_irq_save(flags); + + /* Get the current PLL frequency */ + pll_freq = mxc_pll_clock(MCUPLL); + +#if MX27_LLPM_DEBUG + printk("MCU PLL frequency is %d\n", pll_freq); +#endif + + /* Decide whether to do integer scaling or pll scaling */ + if (arm_freq > pll_freq) { + /* Do PLL scaling */ + ret = mx27_pm_pllscale(arm_freq, ahb_freq, pll_freq); + } else { + /* We need integer divider values */ + divider = pll_freq / arm_freq; + if (!freq_equal(arm_freq, pll_freq / divider)) { + /* Do PLL scaling */ + ret = mx27_pm_pllscale(arm_freq, ahb_freq, pll_freq); + } else { + /* Do integer scaling */ + ret = mx27_pm_intscale(arm_freq, ahb_freq, pll_freq); + } + } + + local_irq_restore(flags); + return ret; +} +#endif +/* + * This API is not supported on i.MX27 + */ +int mxc_pm_intscale(long armfreq, long ahbfreq, long ipfreq) +{ + return -MXC_PM_API_NOT_SUPPORTED; +} + +/* + * This API is not supported on i.MX27 + */ +int mxc_pm_pllscale(long armfreq, long ahbfreq, long ipfreq) +{ + return -MXC_PM_API_NOT_SUPPORTED; +} + +/*! + * This function is used to load the module. + * + * @return Returns an Integer on success + */ +static int __init mxc_pm_init_module(void) +{ + printk(KERN_INFO "MX27: Power management module initialized\n"); + return 0; +} + +/*! + * This function is used to unload the module + */ +static void __exit mxc_pm_cleanup_module(void) +{ + printk(KERN_INFO "MX27: Power management module exit\n"); +} + +module_init(mxc_pm_init_module); +module_exit(mxc_pm_cleanup_module); + +EXPORT_SYMBOL(mxc_pm_lowpower); +//EXPORT_SYMBOL(mxc_pm_dvfs); +EXPORT_SYMBOL(mxc_pm_pllscale); +EXPORT_SYMBOL(mxc_pm_intscale); + +MODULE_AUTHOR("Freescale Semiconductor"); +MODULE_DESCRIPTION("i.MX27 low level PM driver"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-mx27/pm.c b/arch/arm/mach-mx27/pm.c new file mode 100644 index 000000000000..5fd5ecd5d883 --- /dev/null +++ b/arch/arm/mach-mx27/pm.c @@ -0,0 +1,105 @@ +/* + * linux/arch/arm/mach-mx27/pm.c + * + * MX27 Power Management Routines + * + * Original code for the SA11x0: + * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> + * + * Modified for the PXA250 by Nicolas Pitre: + * Copyright (c) 2002 Monta Vista Software, Inc. + * + * Modified for the OMAP1510 by David Singleton: + * Copyright (c) 2002 Monta Vista Software, Inc. + * + * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com> + * + * Modified for the MX27 + * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/pm.h> +#include <linux/sched.h> +#include <linux/proc_fs.h> +#include <linux/pm.h> + +#include <asm/io.h> +#include <asm/arch/mxc_pm.h> + +/* + * TODO: whatta save? + */ + +static int mx27_pm_enter(suspend_state_t state) +{ + pr_debug("Hi, from mx27_pm_enter\n"); + switch (state) { + case PM_SUSPEND_MEM: + mxc_pm_lowpower(STOP_MODE); + break; + + case PM_SUSPEND_STANDBY: + mxc_pm_lowpower(WAIT_MODE); + break; + + case PM_SUSPEND_STOP: + mxc_pm_lowpower(DSM_MODE); + break; + + default: + return -1; + } + return 0; +} + +/* + * Called after processes are frozen, but before we shut down devices. + */ +static int mx27_pm_prepare(suspend_state_t state) +{ + return 0; +} + +/* + * Called after devices are re-setup, but before processes are thawed. + */ +static int mx27_pm_finish(suspend_state_t state) +{ + return 0; +} + +struct pm_ops mx27_pm_ops = { + .prepare = mx27_pm_prepare, + .enter = mx27_pm_enter, + .finish = mx27_pm_finish, +}; + +static int __init mx27_pm_init(void) +{ + pr_debug("Power Management for Freescale MX27\n"); + pm_set_ops(&mx27_pm_ops); + + return 0; +} + +late_initcall(mx27_pm_init); diff --git a/arch/arm/mach-mx27/serial.c b/arch/arm/mach-mx27/serial.c new file mode 100644 index 000000000000..5eb8855a5eea --- /dev/null +++ b/arch/arm/mach-mx27/serial.c @@ -0,0 +1,275 @@ +/* + * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +/*! + * @file mach-mx27/serial.c + * + * @brief This file contains the UART initiliazation. + * + * @ingroup MSL_MX27 + */ +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/serial.h> +#include <asm/hardware.h> +#include <asm/arch/mxc_uart.h> +#include "serial.h" +#include "board-mx27ads.h" + +#if defined(CONFIG_SERIAL_MXC) || defined(CONFIG_SERIAL_MXC_MODULE) + +/*! + * This is an array where each element holds information about a UART port, + * like base address of the UART, interrupt numbers etc. This structure is + * passed to the serial_core.c file. Based on which UART is used, the core file + * passes back the appropriate port structure as an argument to the control + * functions. + */ +static uart_mxc_port mxc_ports[] = { + [0] = { + .port = { + .membase = (void *)IO_ADDRESS(UART1_BASE_ADDR), + .mapbase = UART1_BASE_ADDR, + .iotype = SERIAL_IO_MEM, + .irq = UART1_INT1, + .fifosize = 32, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 0, + }, + .ints_muxed = UART1_MUX_INTS, + .irqs = {UART1_INT2, UART1_INT3}, + .mode = UART1_MODE, + .ir_mode = UART1_IR, + .enabled = UART1_ENABLED, + .hardware_flow = UART1_HW_FLOW, + .cts_threshold = UART1_UCR4_CTSTL, + .dma_enabled = UART1_DMA_ENABLE, + .dma_rxbuf_size = UART1_DMA_RXBUFSIZE, + .rx_threshold = UART1_UFCR_RXTL, + .tx_threshold = UART1_UFCR_TXTL, + .shared = UART1_SHARED_PERI, + .dma_tx_id = MXC_DMA_UART1_TX, + .dma_rx_id = MXC_DMA_UART1_RX, + .rxd_mux = MXC_UART_RXDMUX, + .ir_tx_inv = MXC_IRDA_TX_INV, + .ir_rx_inv = MXC_IRDA_RX_INV, + }, + [1] = { + .port = { + .membase = (void *)IO_ADDRESS(UART2_BASE_ADDR), + .mapbase = UART2_BASE_ADDR, + .iotype = SERIAL_IO_MEM, + .irq = UART2_INT1, + .fifosize = 32, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 1, + }, + .ints_muxed = UART2_MUX_INTS, + .irqs = {UART2_INT2, UART2_INT3}, + .mode = UART2_MODE, + .ir_mode = UART2_IR, + .enabled = UART2_ENABLED, + .hardware_flow = UART2_HW_FLOW, + .cts_threshold = UART2_UCR4_CTSTL, + .dma_enabled = UART2_DMA_ENABLE, + .dma_rxbuf_size = UART2_DMA_RXBUFSIZE, + .rx_threshold = UART2_UFCR_RXTL, + .tx_threshold = UART2_UFCR_TXTL, + .shared = UART2_SHARED_PERI, + .dma_tx_id = MXC_DMA_UART2_TX, + .dma_rx_id = MXC_DMA_UART2_RX, + .rxd_mux = MXC_UART_RXDMUX, + .ir_tx_inv = MXC_IRDA_TX_INV, + .ir_rx_inv = MXC_IRDA_RX_INV, + }, + [2] = { + .port = { + .membase = (void *)IO_ADDRESS(UART3_BASE_ADDR), + .mapbase = UART3_BASE_ADDR, + .iotype = SERIAL_IO_MEM, + .irq = UART3_INT1, + .fifosize = 32, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 2, + }, + .ints_muxed = UART3_MUX_INTS, + .irqs = {UART3_INT2, UART3_INT3}, + .mode = UART3_MODE, + .ir_mode = UART3_IR, + .enabled = UART3_ENABLED, + .hardware_flow = UART3_HW_FLOW, + .cts_threshold = UART3_UCR4_CTSTL, + .dma_enabled = UART3_DMA_ENABLE, + .dma_rxbuf_size = UART3_DMA_RXBUFSIZE, + .rx_threshold = UART3_UFCR_RXTL, + .tx_threshold = UART3_UFCR_TXTL, + .shared = UART3_SHARED_PERI, + .dma_tx_id = MXC_DMA_UART3_TX, + .dma_rx_id = MXC_DMA_UART3_RX, + .rxd_mux = MXC_UART_IR_RXDMUX, + .ir_tx_inv = MXC_IRDA_TX_INV, + .ir_rx_inv = MXC_IRDA_RX_INV, + }, + [3] = { + .port = { + .membase = (void *)IO_ADDRESS(UART4_BASE_ADDR), + .mapbase = UART4_BASE_ADDR, + .iotype = SERIAL_IO_MEM, + .irq = UART4_INT1, + .fifosize = 32, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 3, + }, + .ints_muxed = UART4_MUX_INTS, + .irqs = {UART4_INT2, UART4_INT3}, + .mode = UART4_MODE, + .ir_mode = UART4_IR, + .enabled = UART4_ENABLED, + .hardware_flow = UART4_HW_FLOW, + .cts_threshold = UART4_UCR4_CTSTL, + .dma_enabled = UART4_DMA_ENABLE, + .dma_rxbuf_size = UART4_DMA_RXBUFSIZE, + .rx_threshold = UART4_UFCR_RXTL, + .tx_threshold = UART4_UFCR_TXTL, + .shared = UART4_SHARED_PERI, + .dma_tx_id = MXC_DMA_UART4_TX, + .dma_rx_id = MXC_DMA_UART4_RX, + .rxd_mux = MXC_UART_RXDMUX, + .ir_tx_inv = MXC_IRDA_TX_INV, + .ir_rx_inv = MXC_IRDA_RX_INV, + }, + [4] = { + .port = { + .membase = (void *)IO_ADDRESS(UART5_BASE_ADDR), + .mapbase = UART5_BASE_ADDR, + .iotype = SERIAL_IO_MEM, + .irq = UART5_INT1, + .fifosize = 32, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 4, + }, + .ints_muxed = UART5_MUX_INTS, + .irqs = {UART5_INT2, UART5_INT3}, + .mode = UART5_MODE, + .ir_mode = UART5_IR, + .enabled = UART5_ENABLED, + .hardware_flow = UART5_HW_FLOW, + .cts_threshold = UART5_UCR4_CTSTL, + .dma_enabled = UART5_DMA_ENABLE, + .dma_rxbuf_size = UART5_DMA_RXBUFSIZE, + .rx_threshold = UART5_UFCR_RXTL, + .tx_threshold = UART5_UFCR_TXTL, + .shared = UART5_SHARED_PERI, + .dma_tx_id = MXC_DMA_UART5_TX, + .dma_rx_id = MXC_DMA_UART5_RX, + .rxd_mux = MXC_UART_RXDMUX, + .ir_tx_inv = MXC_IRDA_TX_INV, + .ir_rx_inv = MXC_IRDA_RX_INV, + }, + [5] = { + .port = { + .membase = (void *)IO_ADDRESS(UART6_BASE_ADDR), + .mapbase = UART6_BASE_ADDR, + .iotype = SERIAL_IO_MEM, + .irq = UART6_INT1, + .fifosize = 32, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 5, + }, + .ints_muxed = UART6_MUX_INTS, + .irqs = {UART6_INT2, UART6_INT3}, + .mode = UART6_MODE, + .ir_mode = UART6_IR, + .enabled = UART6_ENABLED, + .hardware_flow = UART6_HW_FLOW, + .cts_threshold = UART6_UCR4_CTSTL, + .dma_enabled = UART6_DMA_ENABLE, + .dma_rxbuf_size = UART6_DMA_RXBUFSIZE, + .rx_threshold = UART6_UFCR_RXTL, + .tx_threshold = UART6_UFCR_TXTL, + .shared = UART6_SHARED_PERI, + .dma_tx_id = MXC_DMA_UART6_TX, + .dma_rx_id = MXC_DMA_UART6_RX, + .rxd_mux = MXC_UART_RXDMUX, + .ir_tx_inv = MXC_IRDA_TX_INV, + .ir_rx_inv = MXC_IRDA_RX_INV, + }, +}; + +static struct platform_device mxc_uart_device1 = { + .name = "mxcintuart", + .id = 0, + .dev = { + .platform_data = &mxc_ports[0], + }, +}; + +static struct platform_device mxc_uart_device2 = { + .name = "mxcintuart", + .id = 1, + .dev = { + .platform_data = &mxc_ports[1], + }, +}; + +static struct platform_device mxc_uart_device3 = { + .name = "mxcintuart", + .id = 2, + .dev = { + .platform_data = &mxc_ports[2], + }, +}; + +static struct platform_device mxc_uart_device4 = { + .name = "mxcintuart", + .id = 3, + .dev = { + .platform_data = &mxc_ports[3], + }, +}; +static struct platform_device mxc_uart_device5 = { + .name = "mxcintuart", + .id = 4, + .dev = { + .platform_data = &mxc_ports[4], + }, +}; +static struct platform_device mxc_uart_device6 = { + .name = "mxcintuart", + .id = 5, + .dev = { + .platform_data = &mxc_ports[5], + }, +}; + +static int __init mxc_init_uart(void) +{ + /* Register all the MXC UART platform device structures */ + platform_device_register(&mxc_uart_device1); + platform_device_register(&mxc_uart_device2); + platform_device_register(&mxc_uart_device3); + + platform_device_register(&mxc_uart_device4); + + platform_device_register(&mxc_uart_device5); + platform_device_register(&mxc_uart_device6); + return 0; +} + +#else +static int __init mxc_init_uart(void) +{ + return 0; +} +#endif + +arch_initcall(mxc_init_uart); diff --git a/arch/arm/mach-mx27/serial.h b/arch/arm/mach-mx27/serial.h new file mode 100644 index 000000000000..8f3e1a5b8e08 --- /dev/null +++ b/arch/arm/mach-mx27/serial.h @@ -0,0 +1,170 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef __ARCH_ARM_MACH_MX27_SERIAL_H__ +#define __ARCH_ARM_MACH_MX27_SERIAL_H__ + +/*! + * @file mach-mx27/serial.h + * + * @ingroup MSL_MX27 + */ +#include <asm/arch/mxc_uart.h> + +/* UART 1 configuration */ +/*! + * This option allows to choose either an interrupt-driven software controlled + * hardware flow control (set this option to 0) or hardware-driven hardware + * flow control (set this option to 1). + */ +#define UART1_HW_FLOW 1 +/*! + * This specifies the threshold at which the CTS pin is deasserted by the + * RXFIFO. Set this value in Decimal to anything from 0 to 32 for + * hardware-driven hardware flow control. Read the HW spec while specifying + * this value. When using interrupt-driven software controlled hardware + * flow control set this option to -1. + */ +#define UART1_UCR4_CTSTL 16 +/*! + * This is option to enable (set this option to 1) or disable DMA data transfer + */ +#define UART1_DMA_ENABLE 0 +/*! + * Specify the size of the DMA receive buffer. The buffer size should be same with + * sub buffer size which is defined in mxc_uart.c for all data can be transfered. + */ +#define UART1_DMA_RXBUFSIZE 128 +/*! + * Specify the MXC UART's Receive Trigger Level. This controls the threshold at + * which a maskable interrupt is generated by the RxFIFO. Set this value in + * Decimal to anything from 0 to 32. Read the HW spec while specifying this + * value. + */ +#define UART1_UFCR_RXTL 16 +/*! + * Specify the MXC UART's Transmit Trigger Level. This controls the threshold at + * which a maskable interrupt is generated by the TxFIFO. Set this value in + * Decimal to anything from 0 to 32. Read the HW spec while specifying this + * value. + */ +#define UART1_UFCR_TXTL 16 +/* UART 2 configuration */ +#define UART2_HW_FLOW 1 +#define UART2_UCR4_CTSTL 16 +#define UART2_DMA_ENABLE 0 +#define UART2_DMA_RXBUFSIZE 512 +#define UART2_UFCR_RXTL 16 +#define UART2_UFCR_TXTL 16 +/* UART 3 configuration */ +#define UART3_HW_FLOW 0 +#define UART3_UCR4_CTSTL -1 +#define UART3_DMA_ENABLE 0 +#define UART3_DMA_RXBUFSIZE 512 +#define UART3_UFCR_RXTL 16 +#define UART3_UFCR_TXTL 16 +/* UART 4 configuration */ +#define UART4_HW_FLOW 1 +#define UART4_UCR4_CTSTL 16 +#define UART4_DMA_ENABLE 0 +#define UART4_DMA_RXBUFSIZE 512 +#define UART4_UFCR_RXTL 16 +#define UART4_UFCR_TXTL 16 +/* UART 5 configuration */ +#define UART5_HW_FLOW 1 +#define UART5_UCR4_CTSTL 16 +#define UART5_DMA_ENABLE 0 +#define UART5_DMA_RXBUFSIZE 512 +#define UART5_UFCR_RXTL 16 +#define UART5_UFCR_TXTL 16 +/* UART 6 configuration */ +#define UART6_HW_FLOW 1 +#define UART6_UCR4_CTSTL 16 +#define UART6_DMA_ENABLE 0 +#define UART6_DMA_RXBUFSIZE 512 +#define UART6_UFCR_RXTL 16 +#define UART6_UFCR_TXTL 16 +/* + * UART Chip level Configuration that a user may not have to edit. These + * configuration vary depending on how the UART module is integrated with + * the ARM core + */ +/* + * Is the MUXED interrupt output sent to the ARM core + */ +#define INTS_NOTMUXED 0 +#define INTS_MUXED 1 +/* UART 1 configuration */ +/*! + * This define specifies whether the muxed ANDed interrupt line or the + * individual interrupts from the UART port is integrated with the ARM core. + * There exists a define like this for each UART port. Valid values that can + * be used are \b INTS_NOTMUXED or \b INTS_MUXED. + */ +#define UART1_MUX_INTS INTS_MUXED +/*! + * This define specifies the transmitter interrupt number or the interrupt + * number of the ANDed interrupt in case the interrupts are muxed. There exists + * a define like this for each UART port. + */ +#define UART1_INT1 INT_UART1 +/*! + * This define specifies the receiver interrupt number. If the interrupts of + * the UART are muxed, then we specify here a dummy value -1. There exists a + * define like this for each UART port. + */ +#define UART1_INT2 -1 +/*! + * This specifies the master interrupt number. If the interrupts of the UART + * are muxed, then we specify here a dummy value of -1. There exists a define + * like this for each UART port. + */ +#define UART1_INT3 -1 +/*! + * This specifies if the UART is a shared peripheral. It holds the shared + * peripheral number if it is shared or -1 if it is not shared. There exists + * a define like this for each UART port. + */ +#define UART1_SHARED_PERI -1 +/* UART 2 configuration */ +#define UART2_MUX_INTS INTS_MUXED +#define UART2_INT1 INT_UART2 +#define UART2_INT2 -1 +#define UART2_INT3 -1 +#define UART2_SHARED_PERI -1 +/* UART 3 configuration */ +#define UART3_MUX_INTS INTS_MUXED +#define UART3_INT1 INT_UART3 +#define UART3_INT2 -1 +#define UART3_INT3 -1 +#define UART3_SHARED_PERI -1 +/* UART 4 configuration */ +#define UART4_MUX_INTS INTS_MUXED +#define UART4_INT1 INT_UART4 +#define UART4_INT2 -1 +#define UART4_INT3 -1 +#define UART4_SHARED_PERI -1 +/* UART 5 configuration */ +#define UART5_MUX_INTS INTS_MUXED +#define UART5_INT1 INT_UART5 +#define UART5_INT2 -1 +#define UART5_INT3 -1 +#define UART5_SHARED_PERI -1 +/* UART 6 configuration */ +#define UART6_MUX_INTS INTS_MUXED +#define UART6_INT1 INT_UART6 +#define UART6_INT2 -1 +#define UART6_INT3 -1 +#define UART6_SHARED_PERI -1 + +#endif /* __ARCH_ARM_MACH_MX27_SERIAL_H__ */ diff --git a/arch/arm/mach-mx27/system.c b/arch/arm/mach-mx27/system.c new file mode 100644 index 000000000000..8566f3189581 --- /dev/null +++ b/arch/arm/mach-mx27/system.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 1999 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/clk.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/proc-fns.h> +#include <asm/system.h> + +/*! + * @defgroup MSL_MX27 i.MX27 Machine Specific Layer (MSL) + */ + +/*! + * @file mach-mx27/system.c + * @brief This file contains idle and reset functions. + * + * @ingroup MSL_MX27 + */ + +/*! + * This function puts the CPU into idle mode. It is called by default_idle() + * in process.c file. + */ +void arch_idle(void) +{ + /* + * This should do all the clock switching + * and wait for interrupt tricks. + */ + cpu_do_idle(); +} + +/* + * This function resets the system. It is called by machine_restart(). + * + * @param mode indicates different kinds of resets + */ +void arch_reset(char mode) +{ + /* Assert Watchdog Reset signal */ + mxc_wd_reset(); +} diff --git a/arch/arm/mach-mx27/time.c b/arch/arm/mach-mx27/time.c new file mode 100644 index 000000000000..d374c1e32dc9 --- /dev/null +++ b/arch/arm/mach-mx27/time.c @@ -0,0 +1,195 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/* System Timer Interrupt reconfigured to run in free-run mode. + * Author: Vitaly Wool + * Copyright 2004 MontaVista Software Inc. + */ + +/*! + * @defgroup Timers_MX27 RTC, OS tick, Watchdog Timers + * @ingroup MSL_MX27 + */ +/*! + * @file mach-mx27/time.c + * @brief This file contains OS tick implementations. + * + * This file contains OS tick implementations. + * + * @ingroup Timers_MX27 + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/mach/time.h> + +#include <asm/arch/hardware.h> + +#ifndef __noinstrument +#define __noinstrument +#endif + +extern unsigned long clk_early_get_timer_rate(void); + +/* + ***************************************** + * GPT Register definitions * + ***************************************** + */ +#define GPT_BASE_ADDR(x) (GPT ##x## _BASE_ADDR) +#define MXC_GPT_TCTL(x) (IO_ADDRESS(GPT_BASE_ADDR(x) + 0x00)) +#define MXC_GPT_TPRER(x) (IO_ADDRESS(GPT_BASE_ADDR(x) + 0x04)) +#define MXC_GPT_TCMP(x) (IO_ADDRESS(GPT_BASE_ADDR(x) + 0x08)) +#define MXC_GPT_TCR(x) (IO_ADDRESS(GPT_BASE_ADDR(x) + 0x0C)) +#define MXC_GPT_TCN(x) (IO_ADDRESS(GPT_BASE_ADDR(x) + 0x10)) +#define MXC_GPT_TSTAT(x) (IO_ADDRESS(GPT_BASE_ADDR(x) + 0x14)) +#define MXC_GPT_GPTCNT MXC_GPT_TCN(MXC_TIMER_GPT1) +#define GPT_TSTAT_COMP (1 << 0) +#define GPT_TSTAT_CAPT (1 << 1) +#define GPT_TCTL_TEN (1 << 0) +#define GPT_TCTL_SRC_PER1 (1 << 1) +#define GPT_TCTL_SRC_PER1_DIV4 (2 << 1) +#define GPT_TCTL_SRC_TIN (3 << 1) +#define GPT_TCTL_SRC_32K (4 << 1) +#define GPT_TCTL_COMPEN (1 << 4) +#define GPT_TCTL_CAPTEN (1 << 5) +#define GPT_TCTL_FRR (1 << 8) +#define GPT_TCTL_OM (1 << 9) +#define GPT_TCTL_CC (1 << 10) +#define GPT_TCTL_SWR (1 << 15) + +/* OS tick defines */ +#define MXC_GPT_INT_TICK INT_GPT +#define MXC_GPT_TCMP_TICK MXC_GPT_TCMP(MXC_TIMER_GPT1) +#define MXC_GPT_TSTAT_TICK MXC_GPT_TSTAT(MXC_TIMER_GPT1) +#define MXC_GPT_TCTL_TICK MXC_GPT_TCTL(MXC_TIMER_GPT1) +#define MXC_GPT_TPRER_TICK MXC_GPT_TPRER(MXC_TIMER_GPT1) +#define MXC_GPT_TCN_TICK MXC_GPT_TCN(MXC_TIMER_GPT1) +/* High resolution timer defines */ +#define MXC_GPT_INT_HRT INT_GPT2 +#define MXC_GPT_TCMP_HRT MXC_GPT_TCMP(MXC_TIMER_GPT2) +#define MXC_GPT_TSTAT_HRT MXC_GPT_TSTAT(MXC_TIMER_GPT2) +#define MXC_GPT_TCTL_HRT MXC_GPT_TCTL(MXC_TIMER_GPT2) +#define MXC_GPT_TPRER_HRT MXC_GPT_TPRER(MXC_TIMER_GPT2) +#define MXC_GPT_TCN_HRT MXC_GPT_TCN(MXC_TIMER_GPT2) + +/*! + * This is the timer interrupt service routine to do required tasks. + * + * @param irq GPT interrupt source number (not used) + * @param dev_id this parameter is not used + * @return always returns \b IRQ_HANDLED as defined in + * include/linux/interrupt.h. + */ +static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) +{ + unsigned int next_match; + + write_seqlock(&xtime_lock); + + do { + mxc_kick_wd(); + timer_tick(); + next_match = __raw_readl(MXC_GPT_TCMP_TICK) + LATCH; + __raw_writel(GPT_TSTAT_COMP, MXC_GPT_TSTAT_TICK); + __raw_writel(next_match, MXC_GPT_TCMP_TICK); + } while ((signed long)(next_match - __raw_readl(MXC_GPT_TCN_TICK)) <= + 0); + + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +/*! + * This function is used to obtain the number of microseconds since the last + * timer interrupt. Note that interrupts is disabled by do_gettimeofday(). + * + * @return the number of microseconds since the last timer interrupt. + */ +static unsigned long __noinstrument mxc_gettimeoffset(void) +{ + long ticks_to_match, elapsed, usec; + + /* Get ticks before next timer match */ + ticks_to_match = + __raw_readl(MXC_GPT_TCMP_TICK) - __raw_readl(MXC_GPT_TCN_TICK); + + /* We need elapsed ticks since last match */ + elapsed = LATCH - ticks_to_match; + + /* Now convert them to usec */ + usec = (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH; + + return usec; +} + +/*! + * The OS tick timer interrupt structure. + */ +static struct irqaction timer_irq = { + .name = "MXC Timer Tick", + .flags = IRQF_DISABLED | IRQF_TIMER, + .handler = mxc_timer_interrupt +}; + +/*! + * This function is used to initialize the GPT to produce an interrupt + * every 10 msec. It is called by the start_kernel() during system startup. + */ +void __init mxc_init_time(void) +{ + u32 reg, v; + + __raw_writel(0, MXC_GPT_TCTL_TICK); + __raw_writel(GPT_TCTL_SWR, MXC_GPT_TCTL_TICK); + + while ((__raw_readl(MXC_GPT_TCTL_TICK) & GPT_TCTL_SWR) != 0) + mb(); + + reg = GPT_TCTL_FRR | GPT_TCTL_COMPEN | GPT_TCTL_SRC_PER1; + + __raw_writel(reg, MXC_GPT_TCTL_TICK); + + v = clk_early_get_timer_rate(); + __raw_writel((v / CLOCK_TICK_RATE) - 1, MXC_GPT_TPRER_TICK); + + if ((v % CLOCK_TICK_RATE) != 0) { + pr_info("\nWARNING: Can't generate CLOCK_TICK_RATE at %d Hz\n", + CLOCK_TICK_RATE); + } + pr_info("Actual CLOCK_TICK_RATE is %d Hz\n", + v / ((__raw_readl(MXC_GPT_TPRER_TICK) & 0x7FF) + 1)); + + reg = __raw_readl(MXC_GPT_TCN_TICK); + reg += LATCH; + __raw_writel(reg, MXC_GPT_TCMP_TICK); + + setup_irq(MXC_GPT_INT_TICK, &timer_irq); + + reg = __raw_readl(MXC_GPT_TCTL_TICK) | GPT_TCTL_TEN; + __raw_writel(reg, MXC_GPT_TCTL_TICK); + +#ifdef CONFIG_KFI + os_timer_initialized = 1; +#endif +} + +struct sys_timer mxc_timer = { + .init = mxc_init_time, + .offset = mxc_gettimeoffset, +}; diff --git a/arch/arm/mach-mx27/usb.c b/arch/arm/mach-mx27/usb.c new file mode 100644 index 000000000000..07f9a89d400d --- /dev/null +++ b/arch/arm/mach-mx27/usb.c @@ -0,0 +1,343 @@ +/* + * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/*! + * @defgroup USB_MX27 ARC OTG USB Driver for i.MX27 + * @ingroup USB + */ + +/*! + * @file mach-mx27/usb.c + * + * @brief platform related part of usb driver. + * @ingroup USB_MX27 + */ + +/*! + *Include files + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/fsl_devices.h> +#include <linux/usb/fsl_xcvr.h> +#include <linux/usb/otg.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/system.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/arch/arc_otg.h> + +extern struct platform_device *host_pdev_register(struct resource *res, + int n_res, + struct fsl_usb2_platform_data + *config); +extern int fsl_usb_host_init(struct platform_device *pdev); +extern void fsl_usb_host_uninit(struct fsl_usb2_platform_data *pdata); +extern int usbotg_init(struct platform_device *pdev); +extern void usbotg_uninit(struct fsl_usb2_platform_data *pdata); +extern int gpio_usbh1_active(void); +extern void gpio_usbh1_inactive(void); +extern int gpio_usbh2_active(void); +extern void gpio_usbh2_inactive(void); +extern int gpio_usbotg_hs_active(void); +extern void gpio_usbotg_hs_inactive(void); +extern int gpio_usbotg_fs_active(void); +extern void gpio_usbotg_fs_inactive(void); + +#ifdef CONFIG_USB_EHCI_ARC_H1 +/*! + * HOST1 config + */ +/* *INDENT-OFF* */ +static struct fsl_usb2_platform_data usbh1_config = { + .name = "Host 1", + .platform_init = fsl_usb_host_init, + .platform_uninit = fsl_usb_host_uninit, + .usbmode = (u32) &UH1_USBMODE, + .power_budget = 500, /* 500 mA max power */ + .gpio_usb_active = gpio_usbh1_active, + .gpio_usb_inactive = gpio_usbh1_inactive, + .transceiver = "serial", +}; + +static struct resource usbh1_resources[] = { + { + .start = (u32) (USB_H1REGS_BASE), + .end = (u32) (USB_H1REGS_BASE + 0x1ff), + .flags = IORESOURCE_MEM, + }, + { + .start = INT_USB1, + .flags = IORESOURCE_IRQ, + }, +}; +/* *INDENT-ON* */ +#endif + +#ifdef CONFIG_USB_EHCI_ARC_H2 +/*! + * HOST2 config + */ +/* *INDENT-OFF* */ +static struct fsl_usb2_platform_data usbh2_config = { + .name = "Host 2", + .platform_init = fsl_usb_host_init, + .platform_uninit = fsl_usb_host_uninit, + .usbmode = (u32) &UH2_USBMODE, + .viewport = (u32) &UH2_ULPIVIEW, + .power_budget = 500, /* 500 mA max power */ + .gpio_usb_active = gpio_usbh2_active, + .gpio_usb_inactive = gpio_usbh2_inactive, + .transceiver = "isp1504", +}; + +static struct resource usbh2_resources[] = { + { + .start = (u32) (USB_H2REGS_BASE), + .end = (u32) (USB_H2REGS_BASE + 0x1ff), + .flags = IORESOURCE_MEM, + }, + { + .start = INT_USB2, + .flags = IORESOURCE_IRQ, + }, +}; +/* *INDENT-ON* */ +#endif + +/*! + * OTG config + */ +/* *INDENT-OFF* */ +#if defined(CONFIG_USB_EHCI_ARC_OTG) || defined(CONFIG_USB_GADGET_ARC) || defined(CONFIG_OTG_BTC_ARC) +#if defined(CONFIG_MC13783_MXC) +static struct fsl_usb2_platform_data mxc_serial_host_config = { + .name = "OTG", + .platform_init = usbotg_init, + .platform_uninit = usbotg_uninit, + .usbmode = (u32) &UOG_USBMODE, + .viewport = (u32) &UOG_ULPIVIEW, + .does_otg = 1, + .operating_mode = FSL_USB2_DR_HOST, + .power_budget = 500, /* 500 mA max power */ + .gpio_usb_active = gpio_usbotg_fs_active, + .gpio_usb_inactive = gpio_usbotg_fs_inactive, + .transceiver = "mc13783", +}; +#elif defined(CONFIG_ISP1301_MXC) +static struct fsl_usb2_platform_data mxc_serial_host_config = { + .name = "OTG", + .platform_init = usbotg_init, + .platform_uninit = usbotg_uninit, + .usbmode = (u32) &UOG_USBMODE, + .viewport = (u32) &UOG_ULPIVIEW, + .does_otg = 0, + .operating_mode = FSL_USB2_DR_HOST, + .power_budget = 500, /* 500 mA max power */ + .gpio_usb_active = gpio_usbotg_fs_active, + .gpio_usb_inactive = gpio_usbotg_fs_inactive, + .transceiver = "isp1301", +}; +#endif +#if defined(CONFIG_ISP1504_MXC) +static struct fsl_usb2_platform_data mxc_isp1504_config = { + .name = "OTG", + .platform_init = usbotg_init, + .platform_uninit = usbotg_uninit, + .usbmode = (u32) &UOG_USBMODE, + .viewport = (u32) &UOG_ULPIVIEW, + .does_otg = 1, + .power_budget = 500, /* 500 mA max power */ + .gpio_usb_active = gpio_usbotg_hs_active, + .gpio_usb_inactive = gpio_usbotg_hs_inactive, + .transceiver = "isp1504", +}; +#endif + +static struct resource otg_resources[] = { + { + .start = (u32) (USB_OTGREGS_BASE), + .end = (u32) (USB_OTGREGS_BASE + 0x1ff), + .flags = IORESOURCE_MEM, + }, + { + .start = INT_USB3, + .flags = IORESOURCE_IRQ, + }, +}; +#endif +/* *INDENT-ON* */ + +#if defined(CONFIG_USB_GADGET_ARC) || defined(CONFIG_OTG_BTC_ARC) +/*! + * OTG Gadget device + */ +static void udc_release(struct device *dev) +{ + /* normally not freed */ +} + +static u64 udc_dmamask = ~(u32) 0; + +#if defined(CONFIG_MC13783_MXC) +static struct fsl_usb2_platform_data mxc_serial_peripheral_config = { + .name = "OTG", + .platform_init = usbotg_init, + .platform_uninit = usbotg_uninit, + .usbmode = (u32) & UOG_USBMODE, + .does_otg = 1, + .operating_mode = FSL_USB2_DR_DEVICE, + .power_budget = 150, /* 150 mA max power */ + .gpio_usb_active = gpio_usbotg_fs_active, + .gpio_usb_inactive = gpio_usbotg_fs_inactive, + .transceiver = "mc13783", +}; +#elif defined(CONFIG_ISP1301_MXC) +static struct fsl_usb2_platform_data mxc_serial_peripheral_config = { + .name = "OTG", + .platform_init = usbotg_init, + .platform_uninit = usbotg_uninit, + .usbmode = (u32) & UOG_USBMODE, + .does_otg = 0, + .operating_mode = FSL_USB2_DR_DEVICE, + .power_budget = 150, /* 150 mA max power */ + .gpio_usb_active = gpio_usbotg_fs_active, + .gpio_usb_inactive = gpio_usbotg_fs_inactive, + .transceiver = "isp1301", +}; +#endif + +/* *INDENT-OFF* */ +static struct platform_device otg_udc_device = { + .name = "arc_udc", + .id = -1, + .dev = { + .release = udc_release, + .dma_mask = &udc_dmamask, + .coherent_dma_mask = 0xffffffff, +#if defined(CONFIG_MC13783_MXC) || defined(CONFIG_ISP1301_MXC) + .platform_data = &mxc_serial_peripheral_config, +#elif defined(CONFIG_ISP1504_MXC) + .platform_data = &mxc_isp1504_config, +#endif + }, + .resource = otg_resources, + .num_resources = ARRAY_SIZE(otg_resources), +}; +/* *INDENT-ON* */ +#endif + +#if defined(CONFIG_USB_OTG) +static void pindetect_release(struct device *dev) +{ +} + +/* *INDENT-OFF* */ +static struct resource pindetect_resources[] = { + { + .start = (u32) (USB_OTGREGS_BASE), + .end = (u32) (USB_OTGREGS_BASE + 0x1ff), + .flags = IORESOURCE_MEM, + }, + { + .start = INT_USB3, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 pindetect_dmamask = ~(u32) 0; + +static struct fsl_usb2_platform_data fsl_otg_config = { + .name = "fsl_arc", + .platform_init = usbotg_init, + .platform_uninit = usbotg_uninit, + .usbmode = (u32) &UOG_USBMODE, + .power_budget = 500, /* 500 mA max power */ +#if defined(CONFIG_MC13783_MXC) + .operating_mode = FSL_USB2_DR_DEVICE, + .gpio_usb_active = gpio_usbotg_fs_active, + .gpio_usb_inactive = gpio_usbotg_fs_inactive, + .transceiver = "mc13783", +#elif defined(CONFIG_ISP1504_MXC) + .gpio_usb_active = gpio_usbotg_hs_active, + .gpio_usb_inactive = gpio_usbotg_hs_inactive, + .transceiver = "isp1504", +#endif +}; + +static struct platform_device fsl_device = { + .name = "fsl_arc", + .id = -1, + .dev = { + .release = pindetect_release, + .dma_mask = &pindetect_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &fsl_otg_config, + }, + .resource = pindetect_resources, + .num_resources = ARRAY_SIZE(pindetect_resources), +}; +#endif /* CONFIG_USB_OTG */ + +static int __init mx27_usb_init(void) +{ + pr_debug("%s: \n", __FUNCTION__); + +#ifdef CONFIG_USB_EHCI_ARC_H1 + host_pdev_register(usbh1_resources, ARRAY_SIZE(usbh1_resources), + &usbh1_config); +#endif + +#ifdef CONFIG_USB_EHCI_ARC_H2 + host_pdev_register(usbh2_resources, ARRAY_SIZE(usbh2_resources), + &usbh2_config); +#endif + +#ifdef CONFIG_USB_EHCI_ARC_OTG +#if defined(CONFIG_MC13783_MXC) || defined(CONFIG_ISP1301_MXC) + host_pdev_register(otg_resources, ARRAY_SIZE(otg_resources), + &mxc_serial_host_config); +#elif defined(CONFIG_ISP1504_MXC) + host_pdev_register(otg_resources, ARRAY_SIZE(otg_resources), + &mxc_isp1504_config); +#endif +#endif + +#if defined(CONFIG_USB_GADGET_ARC) || defined(CONFIG_OTG_BTC_ARC) + if (platform_device_register(&otg_udc_device)) + printk(KERN_ERR "can't register OTG Gadget\n"); + else + printk(KERN_INFO "usb: OTG Gadget registered\n"); +#endif + +#ifdef CONFIG_USB_OTG + if (platform_device_register(&fsl_device)) { + printk(KERN_ERR "can't register otg device\n"); + } else { + pr_debug("usb: otg registered device=0x%p resources=0x%p.", + &fsl_device, fsl_device.resource); + } +#endif + + return 0; +} + +module_init(mx27_usb_init); |