diff -urNp linux-2.6.30-rc4/.config linux-2.6.30-rc4-karo/.config --- linux-2.6.30-rc4/.config 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30-rc4-karo/.config 2009-06-08 13:11:18.000000000 +0200 @@ -0,0 +1,1203 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.30-rc4 +# Fri Jun 5 21:17:57 2009 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +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_HAVE_LATENCYTOP_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_ARCH_MTD_XIP=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_ELF_CORE is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +# CONFIG_AIO is not set +# CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBD=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_FREEZER=y + +# +# 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_CLPS711X is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X 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_KIRKWOOD is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +CONFIG_ARCH_MXC=y +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX 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 +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_W90X900 is not set + +# +# Freescale MXC Implementations +# +# CONFIG_ARCH_MX1 is not set +CONFIG_ARCH_MX2=y +# CONFIG_ARCH_MX3 is not set +# CONFIG_MACH_MX21 is not set +# CONFIG_MACH_MX27 is not set +CONFIG_MACH_MX25=y + +# +# MX2 platforms: +# +CONFIG_MACH_TX25=y +# CONFIG_KARO_DEBUG is not set +CONFIG_MACH_STK5_BASEBOARD=y +# CONFIG_MXC_IRQ_PRIOR is not set +# CONFIG_MXC_PWM is not set +CONFIG_ARCH_MXC_IOMUX_V3=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_NOIFAR=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 +CONFIG_COMMON_CLKDEV=y + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +CONFIG_ARCH_FLATMEM_HAS_HOLES=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM 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_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_CMDLINE="init=/linuxrc root=1f01 rootfstype=jffs2 ro console=ttymxc0,115200 panic=1" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_VFP=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_VERBOSE=y +CONFIG_CAN_PM_TRACE=y +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_APM_EMULATION=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_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_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_TESTS=m +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-5 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_VERIFY_WRITE=y +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +CONFIG_MTD_NAND_MXC=y +CONFIG_MTD_NAND_MXC_FLASH_BBT=y +CONFIG_ARCH_MXC_HAS_NFC_V1=y +CONFIG_ARCH_MXC_HAS_NFC_V1_1=y +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_93CX6 is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +CONFIG_COMPAT_NET_DEV_OPS=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +CONFIG_SMSC_PHY=y +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +CONFIG_FEC=y +# CONFIG_FEC2 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +CONFIG_NETCONSOLE=y +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +# 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=m +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_EVBUG=m +# CONFIG_INPUT_APMPOWER 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_GPIO=m +CONFIG_INPUT_MOUSE=y +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_GPIO is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_IMX=y +CONFIG_SERIAL_IMX_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_DEBUG_GPIO=y +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y + +# +# Frame buffer hardware drivers +# +CONFIG_FB_IMX=y +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +# CONFIG_LEDS_TRIGGER_TIMER is not set +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_REGULATOR is not set +# CONFIG_UIO is not set +# CONFIG_STAGING 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=m +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4_FS is not set +CONFIG_JBD=m +CONFIG_FS_MBCACHE=m +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_FILE_LOCKING=y +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=y +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# 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=m +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +# 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=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1 +CONFIG_DETECT_HUNG_TASK=y +CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +CONFIG_DEBUG_SLAB=y +CONFIG_DEBUG_SLAB_LEAK=y +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_ARM_UNWIND=y +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff -urNp linux-2.6.30-rc4/arch/arm/configs/karo_tx25_defconfig linux-2.6.30-rc4-karo/arch/arm/configs/karo_tx25_defconfig --- linux-2.6.30-rc4/arch/arm/configs/karo_tx25_defconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30-rc4-karo/arch/arm/configs/karo_tx25_defconfig 2009-06-08 13:11:18.000000000 +0200 @@ -0,0 +1,1203 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.30-rc4 +# Fri Jun 5 21:17:57 2009 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +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_HAVE_LATENCYTOP_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_ARCH_MTD_XIP=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_ELF_CORE is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +# CONFIG_AIO is not set +# CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBD=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_FREEZER=y + +# +# 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_CLPS711X is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X 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_KIRKWOOD is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +CONFIG_ARCH_MXC=y +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX 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 +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_W90X900 is not set + +# +# Freescale MXC Implementations +# +# CONFIG_ARCH_MX1 is not set +CONFIG_ARCH_MX2=y +# CONFIG_ARCH_MX3 is not set +# CONFIG_MACH_MX21 is not set +# CONFIG_MACH_MX27 is not set +CONFIG_MACH_MX25=y + +# +# MX2 platforms: +# +CONFIG_MACH_TX25=y +# CONFIG_KARO_DEBUG is not set +CONFIG_MACH_STK5_BASEBOARD=y +# CONFIG_MXC_IRQ_PRIOR is not set +# CONFIG_MXC_PWM is not set +CONFIG_ARCH_MXC_IOMUX_V3=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_NOIFAR=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 +CONFIG_COMMON_CLKDEV=y + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +CONFIG_ARCH_FLATMEM_HAS_HOLES=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM 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_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_CMDLINE="init=/linuxrc root=1f01 rootfstype=jffs2 ro console=ttymxc0,115200 panic=1" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_VFP=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_VERBOSE=y +CONFIG_CAN_PM_TRACE=y +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_APM_EMULATION=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_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_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_TESTS=m +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-5 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_VERIFY_WRITE=y +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +CONFIG_MTD_NAND_MXC=y +CONFIG_MTD_NAND_MXC_FLASH_BBT=y +CONFIG_ARCH_MXC_HAS_NFC_V1=y +CONFIG_ARCH_MXC_HAS_NFC_V1_1=y +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_93CX6 is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +CONFIG_COMPAT_NET_DEV_OPS=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +CONFIG_SMSC_PHY=y +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +CONFIG_FEC=y +# CONFIG_FEC2 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +CONFIG_NETCONSOLE=y +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +# 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=m +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_EVBUG=m +# CONFIG_INPUT_APMPOWER 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_GPIO=m +CONFIG_INPUT_MOUSE=y +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_GPIO is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_IMX=y +CONFIG_SERIAL_IMX_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_DEBUG_GPIO=y +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y + +# +# Frame buffer hardware drivers +# +CONFIG_FB_IMX=y +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +# CONFIG_LEDS_TRIGGER_TIMER is not set +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_REGULATOR is not set +# CONFIG_UIO is not set +# CONFIG_STAGING 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=m +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4_FS is not set +CONFIG_JBD=m +CONFIG_FS_MBCACHE=m +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_FILE_LOCKING=y +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=y +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# 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=m +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +# 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=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1 +CONFIG_DETECT_HUNG_TASK=y +CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +CONFIG_DEBUG_SLAB=y +CONFIG_DEBUG_SLAB_LEAK=y +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_ARM_UNWIND=y +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/Kconfig linux-2.6.30-rc4-karo/arch/arm/mach-mx2/Kconfig --- linux-2.6.30-rc4/arch/arm/mach-mx2/Kconfig 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/Kconfig 2009-06-08 12:45:22.000000000 +0200 @@ -6,14 +6,26 @@ choice config MACH_MX21 bool "i.MX21 support" + select ARCH_MXC_IOMUX_V2 + select ARCH_MXC_HAS_NFC_V1 help This enables support for Freescale's MX2 based i.MX21 processor. config MACH_MX27 bool "i.MX27 support" + select ARCH_MXC_IOMUX_V2 + select ARCH_MXC_HAS_NFC_V1 help This enables support for Freescale's MX2 based i.MX27 processor. +config MACH_MX25 + bool "i.MX25 support" + select ARCH_MXC_IOMUX_V3 + select ARCH_MXC_HAS_NFC_V1_1 + select PHYLIB if FEC + help + This enables support for Freescale's MX2 based i.MX25 processor. + endchoice comment "MX2 platforms:" @@ -39,6 +51,26 @@ config MACH_PCM038 Include support for phyCORE-i.MX27 (aka pcm038) platform. This includes specific configurations for the module and its peripherals. +config MACH_TX25 + bool "Support Ka-Ro electronics TX25 module" + depends on MACH_MX25 + help + Include support for Ka-Ro TX25 processor module + +config KARO_DEBUG + bool "Enable Ka-Ro specific debug messages" + depends on MACH_TX25 || MACH_TX27 + help + Compile the architecture specific files with -DDEBUG to enable + additional debug messages + +config MACH_STK5_BASEBOARD + bool "Ka-Ro Starterkit-5 (STK5) development board" + depends on MACH_TX27 || MACH_TX25 + help + This adds board specific devices that can be found on Ka-Ro's + STK5 evaluation board. + choice prompt "Baseboard" depends on MACH_PCM038 @@ -60,3 +92,4 @@ config MACH_MX27_3DS Include support for MX27PDK platform. This includes specific configurations for the board and its peripherals. endif + diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/Makefile linux-2.6.30-rc4-karo/arch/arm/mach-mx2/Makefile --- linux-2.6.30-rc4/arch/arm/mach-mx2/Makefile 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/Makefile 2009-06-02 17:59:14.000000000 +0200 @@ -2,17 +2,31 @@ # Makefile for the linux kernel. # +ifeq ($(CONFIG_KARO_DEBUG),y) + EXTRA_CFLAGS += -DDEBUG +endif + # Object file lists. -obj-y := generic.o devices.o serial.o +obj-y := generic.o serial.o +obj-$(CONFIG_MACH_MX25) += devices_mx25.o +ifeq ($(CONFIG_MACH_MX25),) +obj-y += devices.o +endif + +obj-$(CONFIG_MACH_MX21) += clock_imx21.o -obj-$(CONFIG_MACH_MX21) += clock_imx21.o +obj-$(CONFIG_MACH_MX25) += clock_imx25.o +obj-$(CONFIG_MACH_MX25) += cpu_imx25.o -obj-$(CONFIG_MACH_MX27) += cpu_imx27.o -obj-$(CONFIG_MACH_MX27) += clock_imx27.o +obj-$(CONFIG_MACH_MX27) += cpu_imx27.o +obj-$(CONFIG_MACH_MX27) += clock_imx27.o -obj-$(CONFIG_MACH_MX21ADS) += mx21ads.o -obj-$(CONFIG_MACH_MX27ADS) += mx27ads.o -obj-$(CONFIG_MACH_PCM038) += pcm038.o -obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o -obj-$(CONFIG_MACH_MX27_3DS) += mx27pdk.o +obj-$(CONFIG_MACH_MX21ADS) += mx21ads.o +obj-$(CONFIG_MACH_MX27ADS) += mx27ads.o +obj-$(CONFIG_MACH_PCM038) += pcm038.o +obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o +obj-$(CONFIG_MACH_MX27_3DS) += mx27pdk.o +obj-$(CONFIG_MACH_TX27) += karo-tx27.o tx27_gpio.o +obj-$(CONFIG_MACH_TX25) += karo-tx25.o +obj-$(CONFIG_MACH_STK5_BASEBOARD) += stk5-baseboard.o diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/Makefile.boot linux-2.6.30-rc4-karo/arch/arm/mach-mx2/Makefile.boot --- linux-2.6.30-rc4/arch/arm/mach-mx2/Makefile.boot 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/Makefile.boot 2009-06-02 17:59:15.000000000 +0200 @@ -5,3 +5,7 @@ initrd_phys-$(CONFIG_MACH_MX21) := 0xC08 zreladdr-$(CONFIG_MACH_MX27) := 0xA0008000 params_phys-$(CONFIG_MACH_MX27) := 0xA0000100 initrd_phys-$(CONFIG_MACH_MX27) := 0xA0800000 + +zreladdr-$(CONFIG_MACH_MX25) := 0x80008000 +params_phys-$(CONFIG_MACH_MX25) := 0x80000100 +initrd_phys-$(CONFIG_MACH_MX25) := 0x80800000 diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/clock_imx21.c linux-2.6.30-rc4-karo/arch/arm/mach-mx2/clock_imx21.c --- linux-2.6.30-rc4/arch/arm/mach-mx2/clock_imx21.c 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/clock_imx21.c 2009-06-02 17:59:15.000000000 +0200 @@ -890,7 +890,7 @@ static struct clk clko_clk = { .con_id = n, \ .clk = &c, \ }, -static struct clk_lookup lookups[] __initdata = { +static struct clk_lookup lookups[] = { /* It's unlikely that any driver wants one of them directly: _REGISTER_CLOCK(NULL, "ckih", ckih_clk) _REGISTER_CLOCK(NULL, "ckil", ckil_clk) diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/clock_imx25.c linux-2.6.30-rc4-karo/arch/arm/mach-mx2/clock_imx25.c --- linux-2.6.30-rc4/arch/arm/mach-mx2/clock_imx25.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/clock_imx25.c 2009-06-08 12:46:51.000000000 +0200 @@ -0,0 +1,1848 @@ +/* + * Copyright 2008 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 + */ + +/* based on mach-mx27/clock.c */ + +#include +#include +#include +//#include + +#include +//#include + +#include +#include +#include + +/* Register offsets */ +#define MXC_CCM_MPCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x00) +#define MXC_CCM_UPCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x04) +#define MXC_CCM_CCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x08) +#define MXC_CCM_CGCR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x0C) +#define MXC_CCM_CGCR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x10) +#define MXC_CCM_CGCR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x14) +#define MXC_CCM_PCDR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x18) +#define MXC_CCM_PCDR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x1C) +#define MXC_CCM_PCDR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x20) +#define MXC_CCM_PCDR3 (IO_ADDRESS(CCM_BASE_ADDR) + 0x24) +#define MXC_CCM_RCSR (IO_ADDRESS(CCM_BASE_ADDR) + 0x28) +#define MXC_CCM_CRDR (IO_ADDRESS(CCM_BASE_ADDR) + 0x2C) +#define MXC_CCM_DCVR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x30) +#define MXC_CCM_DCVR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x34) +#define MXC_CCM_DCVR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x38) +#define MXC_CCM_DCVR3 (IO_ADDRESS(CCM_BASE_ADDR) + 0x3C) +#define MXC_CCM_LTR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x40) +#define MXC_CCM_LTR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x44) +#define MXC_CCM_LTR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x48) +#define MXC_CCM_LTR3 (IO_ADDRESS(CCM_BASE_ADDR) + 0x4C) +#define MXC_CCM_LTBR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x50) +#define MXC_CCM_LTBR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x54) +#define MXC_CCM_PMCR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x58) +#define MXC_CCM_PMCR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x5C) +#define MXC_CCM_PMCR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x60) +#define MXC_CCM_MCR (IO_ADDRESS(CCM_BASE_ADDR) + 0x64) + +#define MXC_CCM_MPCTL_BRMO (1 << 31) +#define MXC_CCM_MPCTL_PD_OFFSET 26 +#define MXC_CCM_MPCTL_PD_MASK (0xf << 26) +#define MXC_CCM_MPCTL_MFD_OFFSET 16 +#define MXC_CCM_MPCTL_MFD_MASK (0x3ff << 16) +#define MXC_CCM_MPCTL_MFI_OFFSET 10 +#define MXC_CCM_MPCTL_MFI_MASK (0xf << 10) +#define MXC_CCM_MPCTL_MFN_OFFSET 0 +#define MXC_CCM_MPCTL_MFN_MASK 0x3ff +#define MXC_CCM_MPCTL_LF (1 << 15) + +#define MXC_CCM_UPCTL_BRMO (1 << 31) +#define MXC_CCM_UPCTL_PD_OFFSET 26 +#define MXC_CCM_UPCTL_PD_MASK (0xf << 26) +#define MXC_CCM_UPCTL_MFD_OFFSET 16 +#define MXC_CCM_UPCTL_MFD_MASK (0x3ff << 16) +#define MXC_CCM_UPCTL_MFI_OFFSET 10 +#define MXC_CCM_UPCTL_MFI_MASK (0xf << 10) +#define MXC_CCM_UPCTL_MFN_OFFSET 0 +#define MXC_CCM_UPCTL_MFN_MASK 0x3ff +#define MXC_CCM_UPCTL_LF (1 << 15) + +#define MXC_CCM_CCTL_ARM_OFFSET 30 +#define MXC_CCM_CCTL_ARM_MASK (0x3 << 30) +#define MXC_CCM_CCTL_AHB_OFFSET 28 +#define MXC_CCM_CCTL_AHB_MASK (0x3 << 28) +#define MXC_CCM_CCTL_MPLL_RST (1 << 27) +#define MXC_CCM_CCTL_UPLL_RST (1 << 26) +#define MXC_CCM_CCTL_LP_CTL_OFFSET 24 +#define MXC_CCM_CCTL_LP_CTL_MASK (0x3 << 24) +#define MXC_CCM_CCTL_LP_MODE_RUN (0x0 << 24) +#define MXC_CCM_CCTL_LP_MODE_WAIT (0x1 << 24) +#define MXC_CCM_CCTL_LP_MODE_DOZE (0x2 << 24) +#define MXC_CCM_CCTL_LP_MODE_STOP (0x3 << 24) +#define MXC_CCM_CCTL_UPLL_DISABLE (1 << 23) +#define MXC_CCM_CCTL_MPLL_BYPASS (1 << 22) +#define MXC_CCM_CCTL_USB_DIV_OFFSET 16 +#define MXC_CCM_CCTL_USB_DIV_MASK (0x3 << 16) +#define MXC_CCM_CCTL_CG_CTRL (1 << 15) +#define MXC_CCM_CCTL_ARM_SRC (1 << 14) + +#define MXC_CCM_CGCR0_HCLK_ATA_OFFSET (16 + 0) +#define MXC_CCM_CGCR0_HCLK_BROM_OFFSET (16 + 1) +#define MXC_CCM_CGCR0_HCLK_CSI_OFFSET (16 + 2) +#define MXC_CCM_CGCR0_HCLK_EMI_OFFSET (16 + 3) +#define MXC_CCM_CGCR0_HCLK_ESAI_OFFSET (16 + 4) +#define MXC_CCM_CGCR0_HCLK_ESDHC1_OFFSET (16 + 5) +#define MXC_CCM_CGCR0_HCLK_ESDHC2_OFFSET (16 + 6) +#define MXC_CCM_CGCR0_HCLK_FEC_OFFSET (16 + 7) +#define MXC_CCM_CGCR0_HCLK_LCDC_OFFSET (16 + 8) +#define MXC_CCM_CGCR0_HCLK_RTIC_OFFSET (16 + 9) +#define MXC_CCM_CGCR0_HCLK_SDMA_OFFSET (16 + 10) +#define MXC_CCM_CGCR0_HCLK_SLCDC_OFFSET (16 + 11) +#define MXC_CCM_CGCR0_HCLK_USBOTG_OFFSET (16 + 12) + +#define MXC_CCM_CGCR0_PER_CSI_OFFSET 0 +#define MXC_CCM_CGCR0_PER_EPIT_OFFSET 1 +#define MXC_CCM_CGCR0_PER_ESAI_OFFSET 2 +#define MXC_CCM_CGCR0_PER_ESDHC1_OFFSET 3 +#define MXC_CCM_CGCR0_PER_ESDHC2_OFFSET 4 +#define MXC_CCM_CGCR0_PER_GPT_OFFSET 5 +#define MXC_CCM_CGCR0_PER_I2C_OFFSET 6 +#define MXC_CCM_CGCR0_PER_LCDC_OFFSET 7 +#define MXC_CCM_CGCR0_PER_NFC_OFFSET 8 +#define MXC_CCM_CGCR0_PER_OWIRE_OFFSET 9 +#define MXC_CCM_CGCR0_PER_PWM_OFFSET 10 +#define MXC_CCM_CGCR0_PER_SIM1_OFFSET 11 +#define MXC_CCM_CGCR0_PER_SIM2_OFFSET 12 +#define MXC_CCM_CGCR0_PER_SSI1_OFFSET 13 +#define MXC_CCM_CGCR0_PER_SSI2_OFFSET 14 +#define MXC_CCM_CGCR0_PER_UART_OFFSET 15 + +#define MXC_CCM_CGCR1_AUDMUX_OFFSET 0 +#define MXC_CCM_CGCR1_ATA_OFFSET 1 +#define MXC_CCM_CGCR1_CAN1_OFFSET 2 +#define MXC_CCM_CGCR1_CAN2_OFFSET 3 +#define MXC_CCM_CGCR1_CSI_OFFSET 4 +#define MXC_CCM_CGCR1_CSPI1_OFFSET 5 +#define MXC_CCM_CGCR1_CSPI2_OFFSET 6 +#define MXC_CCM_CGCR1_CSPI3_OFFSET 7 +#define MXC_CCM_CGCR1_DRYICE_OFFSET 8 +#define MXC_CCM_CGCR1_ECT_OFFSET 9 +#define MXC_CCM_CGCR1_EPIT1_OFFSET 10 +#define MXC_CCM_CGCR1_EPIT2_OFFSET 11 +#define MXC_CCM_CGCR1_ESAI_OFFSET 12 +#define MXC_CCM_CGCR1_ESDHC1_OFFSET 13 +#define MXC_CCM_CGCR1_ESDHC2_OFFSET 14 +#define MXC_CCM_CGCR1_FEC_OFFSET 15 +#define MXC_CCM_CGCR1_GPIO1_OFFSET 16 +#define MXC_CCM_CGCR1_GPIO2_OFFSET 17 +#define MXC_CCM_CGCR1_GPIO3_OFFSET 18 +#define MXC_CCM_CGCR1_GPT1_OFFSET 19 +#define MXC_CCM_CGCR1_GPT2_OFFSET 20 +#define MXC_CCM_CGCR1_GPT3_OFFSET 21 +#define MXC_CCM_CGCR1_GPT4_OFFSET 22 +#define MXC_CCM_CGCR1_I2C1_OFFSET 23 +#define MXC_CCM_CGCR1_I2C2_OFFSET 24 +#define MXC_CCM_CGCR1_I2C3_OFFSET 25 +#define MXC_CCM_CGCR1_IIM_OFFSET 26 +#define MXC_CCM_CGCR1_IOMUXC_OFFSET 27 +#define MXC_CCM_CGCR1_KPP_OFFSET 28 +#define MXC_CCM_CGCR1_LCDC_OFFSET 29 +#define MXC_CCM_CGCR1_OWIRE_OFFSET 30 +#define MXC_CCM_CGCR1_PWM1_OFFSET 31 + +#define MXC_CCM_CGCR2_PWM2_OFFSET (32 - 32) +#define MXC_CCM_CGCR2_PWM3_OFFSET (33 - 32) +#define MXC_CCM_CGCR2_PWM4_OFFSET (34 - 32) +#define MXC_CCM_CGCR2_RNGB_OFFSET (35 - 32) +#define MXC_CCM_CGCR2_RTIC_OFFSET (36 - 32) +#define MXC_CCM_CGCR2_SCC_OFFSET (37 - 32) +#define MXC_CCM_CGCR2_SDMA_OFFSET (38 - 32) +#define MXC_CCM_CGCR2_SIM1_OFFSET (39 - 32) +#define MXC_CCM_CGCR2_SIM2_OFFSET (40 - 32) +#define MXC_CCM_CGCR2_SLCDC_OFFSET (41 - 32) +#define MXC_CCM_CGCR2_SPBA_OFFSET (42 - 32) +#define MXC_CCM_CGCR2_SSI1_OFFSET (43 - 32) +#define MXC_CCM_CGCR2_SSI2_OFFSET (44 - 32) +#define MXC_CCM_CGCR2_TCHSCRN_OFFSET (45 - 32) +#define MXC_CCM_CGCR2_UART1_OFFSET (46 - 32) +#define MXC_CCM_CGCR2_UART2_OFFSET (47 - 32) +#define MXC_CCM_CGCR2_UART3_OFFSET (48 - 32) +#define MXC_CCM_CGCR2_UART4_OFFSET (49 - 32) +#define MXC_CCM_CGCR2_UART5_OFFSET (50 - 32) +#define MXC_CCM_CGCR2_WDOG_OFFSET (51 - 32) + +#define MXC_CCM_PCDR1_PERDIV1_MASK 0x3f + +#define MXC_CCM_MCR_USB_XTAL_MUX_OFFSET 31 +#define MXC_CCM_MCR_CLKO_EN_OFFSET 30 +#define MXC_CCM_MCR_CLKO_DIV_OFFSET 24 +#define MXC_CCM_MCR_CLKO_DIV_MASK (0x3F << 24) +#define MXC_CCM_MCR_CLKO_SEL_OFFSET 20 +#define MXC_CCM_MCR_CLKO_SEL_MASK (0xF << 20) +#define MXC_CCM_MCR_ESAI_CLK_MUX_OFFSET 19 +#define MXC_CCM_MCR_SSI2_CLK_MUX_OFFSET 18 +#define MXC_CCM_MCR_SSI1_CLK_MUX_OFFSET 17 +#define MXC_CCM_MCR_USB_CLK_MUX_OFFSET 16 + +#define MXC_CCM_MCR_PER_CLK_MUX_MASK (0xFFFF << 0) + +#define OSC24M_CLK_FREQ 24000000 /* 24MHz reference clk */ +#define OSC32K_CLK_FREQ 32768 /* 32.768kHz oscillator in */ + +static struct clk mpll_clk; +static struct clk upll_clk; +static struct clk ahb_clk; +static struct clk upll_24610k_clk; + +static int _clk_enable(struct clk *clk) +{ + unsigned long reg; + + if (!clk->enable_reg) + return 0; + + 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; + + if (!clk->enable_reg) + return; + + reg = __raw_readl(clk->enable_reg); + reg &= ~(1 << clk->enable_shift); + __raw_writel(reg, clk->enable_reg); +} + +static int _clk_upll_enable(struct clk *clk) +{ + unsigned long reg; + + reg = __raw_readl(MXC_CCM_CCTL); + reg &= ~MXC_CCM_CCTL_UPLL_DISABLE; + __raw_writel(reg, MXC_CCM_CCTL); + + while (!(__raw_readl(MXC_CCM_UPCTL) & MXC_CCM_UPCTL_LF)) + cpu_relax(); + + return 0; +} + +static void _clk_upll_disable(struct clk *clk) +{ + unsigned long reg; + + reg = __raw_readl(MXC_CCM_CCTL); + reg |= MXC_CCM_CCTL_UPLL_DISABLE; + __raw_writel(reg, MXC_CCM_CCTL); +} + +static int _perclk_enable(struct clk *clk) +{ + unsigned long reg; + + reg = __raw_readl(MXC_CCM_CGCR0); + reg |= 1 << clk->id; + __raw_writel(reg, MXC_CCM_CGCR0); + + return 0; +} + +static void _perclk_disable(struct clk *clk) +{ + unsigned long reg; + + reg = __raw_readl(MXC_CCM_CGCR0); + reg &= ~(1 << clk->id); + __raw_writel(reg, MXC_CCM_CGCR0); +} + +static int _clk_pll_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned long reg; + signed long pd = 1; /* Pre-divider */ + signed long mfi; /* Multiplication Factor (Integer part) */ + signed long mfn; /* Multiplication Factor (Integer part) */ + signed long mfd; /* Multiplication Factor (Denominator Part) */ + signed long tmp; + unsigned long ref_freq = clk_get_rate(clk->parent); + + while (((ref_freq / pd) * 10) > rate) + pd++; + + /* the ref_freq/2 in the following is to round up */ + mfi = (((rate / 2) * pd) + (ref_freq / 2)) / ref_freq; + if (mfi < 5 || mfi > 15) + return -EINVAL; + + /* pick a mfd value that will work + * then solve for mfn */ + mfd = ref_freq / 50000; + + /* + * pll_freq * pd * mfd + * mfn = -------------------- - (mfi * mfd) + * 2 * ref_freq + */ + /* the tmp/2 is for rounding */ + tmp = ref_freq / 10000; + mfn = ((((((rate / 2) + (tmp / 2)) / tmp) * pd) * mfd) / 10000) - + (mfi * mfd); + + printk(KERN_DEBUG "pll freq: %lu PD=%ld MFI=%ld MFD=%ld MFN=%ld (0x%03lx)\n", + rate, pd, mfi, mfd, mfn, (mfn + ((mfn < 0) ? 1024 : 0)) & 0x3ff); + + mfn = (mfn + ((mfn < 0) ? 1024 : 0)) & 0x3ff; + pd--; + mfd--; + + /* Change the Pll value */ + reg = (mfi << MXC_CCM_MPCTL_MFI_OFFSET) | + (mfn << MXC_CCM_MPCTL_MFN_OFFSET) | + (mfd << MXC_CCM_MPCTL_MFD_OFFSET) | + (pd << MXC_CCM_MPCTL_PD_OFFSET); + + if (clk == &mpll_clk) { + printk(KERN_DEBUG "Changing MPCTL from %08x to %08lx\n", + __raw_readl(MXC_CCM_MPCTL), reg); + } else if (clk == &upll_clk) { + printk(KERN_DEBUG "Changing UPCTL from %08x to %08lx\n", + __raw_readl(MXC_CCM_UPCTL), reg); + } + if (clk == &mpll_clk) + __raw_writel(reg, MXC_CCM_MPCTL); + else if (clk == &upll_clk) + __raw_writel(reg, MXC_CCM_UPCTL); + return 0; +} + +static unsigned long _clk_pll_getrate(struct clk *clk) +{ + unsigned long rate; + signed long mfi, mfn, mfd, pdf; + unsigned long ref_clk; + unsigned long reg; + + ref_clk = clk_get_rate(clk->parent); + + if (clk == &mpll_clk) { + reg = __raw_readl(MXC_CCM_MPCTL); + pdf = (reg & MXC_CCM_MPCTL_PD_MASK) >> MXC_CCM_MPCTL_PD_OFFSET; + mfd = (reg & MXC_CCM_MPCTL_MFD_MASK) >> MXC_CCM_MPCTL_MFD_OFFSET; + mfi = (reg & MXC_CCM_MPCTL_MFI_MASK) >> MXC_CCM_MPCTL_MFI_OFFSET; + mfn = (reg & MXC_CCM_MPCTL_MFN_MASK) >> MXC_CCM_MPCTL_MFN_OFFSET; + } else if (clk == &upll_clk) { + reg = __raw_readl(MXC_CCM_UPCTL); + pdf = (reg & MXC_CCM_UPCTL_PD_MASK) >> MXC_CCM_UPCTL_PD_OFFSET; + mfd = (reg & MXC_CCM_UPCTL_MFD_MASK) >> MXC_CCM_UPCTL_MFD_OFFSET; + mfi = (reg & MXC_CCM_UPCTL_MFI_MASK) >> MXC_CCM_UPCTL_MFI_OFFSET; + mfn = (reg & MXC_CCM_UPCTL_MFN_MASK) >> MXC_CCM_UPCTL_MFN_OFFSET; + } else { + BUG(); /* oops */ + } + + mfi = (mfi < 5) ? 5 : mfi; + rate = 2LL * ref_clk * mfn; + do_div(rate, mfd + 1); + rate = 2LL * ref_clk * mfi + rate; + do_div(rate, pdf + 1); + + return rate; +} + +static unsigned long _clk_cpu_round_rate(struct clk *clk, unsigned long rate) +{ + int div = clk_get_rate(clk->parent) / rate; + + if (clk_get_rate(clk->parent) % rate) + div++; + + if (div > 4) + div = 4; + + return clk_get_rate(clk->parent) / div; +} + +static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate) +{ + int div, reg; + unsigned long cctl = __raw_readl(MXC_CCM_CCTL); + + div = clk_get_rate(clk->parent) / rate; + + if (div > 4 || div < 1 || ((clk_get_rate(clk->parent) / div) != rate)) + return -EINVAL; + div--; + + reg = (cctl & ~MXC_CCM_CCTL_ARM_MASK) | + (div << MXC_CCM_CCTL_ARM_OFFSET); + __raw_writel(reg, MXC_CCM_CCTL); + + return 0; +} + +static unsigned long _clk_cpu_getrate(struct clk *clk) +{ + unsigned long div; + unsigned long cctl = __raw_readl(MXC_CCM_CCTL); + unsigned long rate; + + div = (cctl & MXC_CCM_CCTL_ARM_MASK) >> MXC_CCM_CCTL_ARM_OFFSET; + + rate = clk_get_rate(clk->parent) / (div + 1); + + if (cctl & MXC_CCM_CCTL_ARM_SRC) { + rate *= 3; + rate /= 4; + } + return rate; +} + +static unsigned long _clk_ahb_getrate(struct clk *clk) +{ + unsigned long div; + unsigned long cctl = __raw_readl(MXC_CCM_CCTL); + + div = (cctl & MXC_CCM_CCTL_AHB_MASK) >> MXC_CCM_CCTL_AHB_OFFSET; + + return clk_get_rate(clk->parent) / (div + 1); +} + +static void __iomem *pcdr_a[4] = { + MXC_CCM_PCDR0, MXC_CCM_PCDR1, MXC_CCM_PCDR2, MXC_CCM_PCDR3 +}; + +static unsigned long _clk_perclkx_getrate(struct clk *clk) +{ + unsigned long perclk_pdf; + unsigned long pcdr; + + if (clk->id < 0 || clk->id > 15) + return 0; + + pcdr = __raw_readl(pcdr_a[clk->id >> 2]); + + perclk_pdf = + (pcdr >> ((clk->id & 3) << 3)) & MXC_CCM_PCDR1_PERDIV1_MASK; + + return clk_get_rate(clk->parent) / (perclk_pdf + 1); +} + +static unsigned long _clk_perclkx_round_rate(struct clk *clk, + unsigned long rate) +{ + unsigned long div; + + div = clk_get_rate(clk->parent) / rate; + if (clk_get_rate(clk->parent) % rate) + div++; + + if (div > 64) + div = 64; + + return clk_get_rate(clk->parent) / div; +} + +static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned long reg; + unsigned long div; + + if (clk->id < 0 || clk->id > 15) + return -EINVAL; + + div = clk_get_rate(clk->parent) / rate; + printk(KERN_DEBUG "%s: perclk[%d] parent_rate=%lu rate=%lu div=%lu\n", + __FUNCTION__, clk->id, clk_get_rate(clk->parent), rate, div); + if (div > 64 || div < 1 || ((clk_get_rate(clk->parent) / div) != rate)) + return -EINVAL; + div--; + + reg = + __raw_readl(pcdr_a[clk->id >> 2]) & ~(MXC_CCM_PCDR1_PERDIV1_MASK << + ((clk->id & 3) << 3)); + reg |= div << ((clk->id & 3) << 3); + __raw_writel(reg, pcdr_a[clk->id >> 2]); + + return 0; +} + +static int _clk_perclkx_set_parent(struct clk *clk, struct clk *parent) +{ + unsigned long mcr; + + if (clk->parent == parent) + return 0; + if (parent != &upll_clk && parent != &ahb_clk) + return -EINVAL; + + clk->parent = parent; + mcr = __raw_readl(MXC_CCM_MCR); + if (parent == &upll_clk) + mcr |= (1 << clk->id); + else + mcr &= ~(1 << clk->id); + + __raw_writel(mcr, MXC_CCM_MCR); + + return 0; +} + +static int _clk_perclkx_set_parent3(struct clk *clk, struct clk *parent) +{ + unsigned long mcr = __raw_readl(MXC_CCM_MCR); + int bit; + + if (clk->parent == parent) + return 0; + if (parent != &upll_clk && parent != &ahb_clk && + parent != &upll_24610k_clk) + return -EINVAL; + + switch (clk->id) { + case 2: + bit = MXC_CCM_MCR_ESAI_CLK_MUX_OFFSET; + break; + case 13: + bit = MXC_CCM_MCR_SSI1_CLK_MUX_OFFSET; + break; + case 14: + bit = MXC_CCM_MCR_SSI2_CLK_MUX_OFFSET; + break; + default: + return -EINVAL; + } + + if (parent == &upll_24610k_clk) { + mcr |= bit; + __raw_writel(mcr, MXC_CCM_MCR); + clk->parent = parent; + } else { + mcr &= ~bit; + __raw_writel(mcr, MXC_CCM_MCR); + return _clk_perclkx_set_parent(clk, parent); + } + + return 0; +} + +static unsigned long _clk_ipg_getrate(struct clk *clk) +{ + return clk_get_rate(clk->parent) / 2; /* Always AHB / 2 */ +} + +/* Top-level clocks */ +static unsigned long ckih_rate = OSC24M_CLK_FREQ; + +static unsigned long clk_ckih_get_rate(struct clk *clk) +{ + return ckih_rate; +} + +static unsigned long clk_ckil_get_rate(struct clk *clk) +{ + return OSC32K_CLK_FREQ; +} + +static struct clk osc24m_clk = { + .get_rate = clk_ckih_get_rate, +}; + +static struct clk osc32k_clk = { + .get_rate = clk_ckil_get_rate, +}; + +static struct clk mpll_clk = { + .parent = &osc24m_clk, + .get_rate = _clk_pll_getrate, + .set_rate = _clk_pll_set_rate, +}; + +static struct clk upll_clk = { + .parent = &osc24m_clk, + .get_rate = _clk_pll_getrate, + .set_rate = _clk_pll_set_rate, + .enable = _clk_upll_enable, + .disable = _clk_upll_disable, +}; + +static unsigned long _clk_24610k_getrate(struct clk *clk) +{ + long long rate = clk_get_rate(clk->parent) * 2461LL; + + do_div(rate, 24000); + + return rate; /* Always (UPLL * 24.61 / 240) */ +} + +static struct clk upll_24610k_clk = { + .parent = &upll_clk, + .get_rate = _clk_24610k_getrate, +}; + +/* Mid-level clocks */ + +static struct clk cpu_clk = { /* ARM clock */ + .parent = &mpll_clk, + .set_rate = _clk_cpu_set_rate, + .get_rate = _clk_cpu_getrate, + .round_rate = _clk_cpu_round_rate, +}; + +static struct clk ahb_clk = { /* a.k.a. HCLK */ + .parent = &cpu_clk, + .get_rate = _clk_ahb_getrate, +}; + +static struct clk ipg_clk = { + .parent = &ahb_clk, + .get_rate = _clk_ipg_getrate, +}; + +/* Bottom-level clocks */ + +struct clk usbotg_clk = { + .id = 0, + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR0, + .enable_shift = MXC_CCM_CGCR0_HCLK_USBOTG_OFFSET, + .disable = _clk_disable, +}; + +struct clk rtic_clk = { + .id = 0, + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR0, + .enable_shift = MXC_CCM_CGCR0_HCLK_RTIC_OFFSET, + .disable = _clk_disable, +}; + +struct clk emi_clk = { + .id = 0, + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR0, + .enable_shift = MXC_CCM_CGCR0_HCLK_EMI_OFFSET, + .disable = _clk_disable, +}; + +struct clk brom_clk = { + .id = 0, + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR0, + .enable_shift = MXC_CCM_CGCR0_HCLK_BROM_OFFSET, + .disable = _clk_disable, +}; + +static struct clk per_clk[] = { + { + .id = 0, + .parent = &ahb_clk, /* can be AHB or UPLL */ + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .set_parent = _clk_perclkx_set_parent, + .get_rate = _clk_perclkx_getrate, + .enable = _perclk_enable, + .disable = _perclk_disable, + }, + { + .id = 1, + .parent = &ahb_clk, /* can be AHB or UPLL */ + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .set_parent = _clk_perclkx_set_parent, + .get_rate = _clk_perclkx_getrate, + .enable = _perclk_enable, + .disable = _perclk_disable, + }, + { + .id = 2, + .parent = &ahb_clk, /* can be AHB or UPLL or 24.61MHz */ + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .set_parent = _clk_perclkx_set_parent3, + .get_rate = _clk_perclkx_getrate, + .enable = _perclk_enable, + .disable = _perclk_disable, + }, + { + .id = 3, + .parent = &ahb_clk, /* can be AHB or UPLL */ + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .set_parent = _clk_perclkx_set_parent, + .get_rate = _clk_perclkx_getrate, + .enable = _perclk_enable, + }, + { + .id = 4, + .parent = &ahb_clk, /* can be AHB or UPLL */ + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .set_parent = _clk_perclkx_set_parent, + .get_rate = _clk_perclkx_getrate, + .enable = _perclk_enable, + .disable = _perclk_disable, + }, + { + .id = 5, + .parent = &upll_clk, /* can be AHB or UPLL */ + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .set_parent = _clk_perclkx_set_parent, + .get_rate = _clk_perclkx_getrate, + .enable = _perclk_enable, + .disable = _perclk_disable, + }, + { + .id = 6, + .parent = &ahb_clk, /* can be AHB or UPLL */ + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .set_parent = _clk_perclkx_set_parent, + .get_rate = _clk_perclkx_getrate, + .enable = _perclk_enable, + .disable = _perclk_disable, + }, + { + .id = 7, + .parent = &ahb_clk, /* can be AHB or UPLL */ + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .set_parent = _clk_perclkx_set_parent, + .get_rate = _clk_perclkx_getrate, + .enable = _perclk_enable, + .disable = _perclk_disable, + }, + { + .id = 8, + .parent = &ahb_clk, /* can be AHB or UPLL */ + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .set_parent = _clk_perclkx_set_parent, + .get_rate = _clk_perclkx_getrate, + .enable = _perclk_enable, + .disable = _perclk_disable, + }, + { + .id = 9, + .parent = &ahb_clk, /* can be AHB or UPLL */ + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .set_parent = _clk_perclkx_set_parent, + .get_rate = _clk_perclkx_getrate, + .enable = _perclk_enable, + .disable = _perclk_disable, + }, + { + .id = 10, + .parent = &ahb_clk, /* can be AHB or UPLL */ + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .set_parent = _clk_perclkx_set_parent, + .get_rate = _clk_perclkx_getrate, + .enable = _perclk_enable, + .disable = _perclk_disable, + }, + { + .id = 11, + .parent = &ahb_clk, /* can be AHB or UPLL */ + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .set_parent = _clk_perclkx_set_parent, + .get_rate = _clk_perclkx_getrate, + .enable = _perclk_enable, + .disable = _perclk_disable, + }, + { + .id = 12, + .parent = &ahb_clk, /* can be AHB or UPLL */ + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .set_parent = _clk_perclkx_set_parent, + .get_rate = _clk_perclkx_getrate, + .enable = _perclk_enable, + .disable = _perclk_disable, + }, + { + .id = 13, + .parent = &ahb_clk, /* can be AHB or UPLL or 24.61MHz */ + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .set_parent = _clk_perclkx_set_parent3, + .get_rate = _clk_perclkx_getrate, + .enable = _perclk_enable, + .disable = _perclk_disable, + }, + { + .id = 14, + .parent = &ahb_clk, /* can be AHB or UPLL or 24.61MHz */ + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .set_parent = _clk_perclkx_set_parent3, + .get_rate = _clk_perclkx_getrate, + .enable = _perclk_enable, + .disable = _perclk_disable, + }, + { + .id = 15, + .parent = &ahb_clk, /* can be AHB or UPLL */ + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .set_parent = _clk_perclkx_set_parent, + .get_rate = _clk_perclkx_getrate, + .enable = _perclk_enable, + .disable = _perclk_disable, + }, +}; + +struct clk nfc_clk = { + .id = 0, + .parent = &per_clk[8], +}; + +struct clk audmux_clk = { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_AUDMUX_OFFSET, + .disable = _clk_disable, +}; + +struct clk ata_clk[] = { + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_ATA_OFFSET, + .disable = _clk_disable, + .secondary = &ata_clk[1], + }, + { + .id = 0, + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR0, + .enable_shift = MXC_CCM_CGCR0_HCLK_ATA_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk can_clk[] = { + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_CAN1_OFFSET, + .disable = _clk_disable, + }, + { + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_CAN2_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk csi_clk[] = { + { + .id = 0, + .parent = &per_clk[0], + .secondary = &csi_clk[1], + }, + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_CSI_OFFSET, + .disable = _clk_disable, + .secondary = &csi_clk[2], + }, + { + .id = 0, + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR0, + .enable_shift = MXC_CCM_CGCR0_HCLK_CSI_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk cspi_clk[] = { + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_CSPI1_OFFSET, + .disable = _clk_disable, + }, + { + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_CSPI2_OFFSET, + .disable = _clk_disable, + }, + { + .id = 2, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_CSPI3_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk dryice_clk = { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_DRYICE_OFFSET, + .disable = _clk_disable, +}; + +struct clk ect_clk = { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_ECT_OFFSET, + .disable = _clk_disable, +}; + +struct clk epit1_clk[] = { + { + .id = 0, + .parent = &per_clk[1], + .secondary = &epit1_clk[1], + }, + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_EPIT1_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk epit2_clk[] = { + { + .id = 1, + .parent = &per_clk[1], + .secondary = &epit2_clk[1], + }, + { + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_EPIT2_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk esai_clk[] = { + { + .id = 0, + .parent = &per_clk[2], + .secondary = &esai_clk[1], + }, + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_ESAI_OFFSET, + .disable = _clk_disable, + .secondary = &esai_clk[2], + }, + { + .id = 0, + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR0, + .enable_shift = MXC_CCM_CGCR0_HCLK_ESAI_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk esdhc1_clk[] = { + { + .id = 0, + .parent = &per_clk[3], + .secondary = &esdhc1_clk[1], + }, + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_ESDHC1_OFFSET, + .disable = _clk_disable, + .secondary = &esdhc1_clk[2], + }, + { + .id = 0, + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR0, + .enable_shift = MXC_CCM_CGCR0_HCLK_ESDHC1_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk esdhc2_clk[] = { + { + .id = 1, + .parent = &per_clk[4], + .secondary = &esdhc2_clk[1], + }, + { + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_ESDHC2_OFFSET, + .disable = _clk_disable, + .secondary = &esdhc2_clk[2], + }, + { + .id = 1, + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR0, + .enable_shift = MXC_CCM_CGCR0_HCLK_ESDHC2_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk fec_clk[] = { + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_FEC_OFFSET, + .disable = _clk_disable, + .secondary = &fec_clk[1], + }, + { + .id = 0, + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR0, + .enable_shift = MXC_CCM_CGCR0_HCLK_FEC_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk gpio_clk[] = { + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_GPIO1_OFFSET, + .disable = _clk_disable, + }, + { + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_GPIO2_OFFSET, + .disable = _clk_disable, + }, + { + .id = 2, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_GPIO3_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk gpt1_clk[] = { + { + .id = 0, + .parent = &per_clk[5], + .secondary = &gpt1_clk[1], + }, + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_GPT1_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk gpt2_clk[] = { + { + .id = 1, + .parent = &per_clk[5], + .secondary = &gpt1_clk[1], + }, + { + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_GPT2_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk gpt3_clk[] = { + { + .id = 2, + .parent = &per_clk[5], + .secondary = &gpt1_clk[1], + }, + { + .id = 2, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_GPT3_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk gpt4_clk[] = { + { + .id = 3, + .parent = &per_clk[5], + .secondary = &gpt1_clk[1], + }, + { + .id = 3, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_GPT4_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk i2c_clk[] = { + { + .id = 0, + .parent = &per_clk[6], + }, + { + .id = 1, + .parent = &per_clk[6], + }, + { + .id = 2, + .parent = &per_clk[6], + }, +}; + +struct clk iim_clk = { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_IIM_OFFSET, + .disable = _clk_disable, +}; + +struct clk iomuxc_clk = { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_IOMUXC_OFFSET, + .disable = _clk_disable, +}; + +struct clk kpp_clk = { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_KPP_OFFSET, + .disable = _clk_disable, +}; + +struct clk lcdc_clk[] = { + { + .id = 0, + .parent = &per_clk[7], + .secondary = &lcdc_clk[1], + }, + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_LCDC_OFFSET, + .disable = _clk_disable, + .secondary = &lcdc_clk[2], + }, + { + .id = 0, + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR0, + .enable_shift = MXC_CCM_CGCR0_HCLK_LCDC_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk owire_clk[] = { + { + .id = 0, + .parent = &per_clk[9], + .secondary = &owire_clk[1], + }, + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_OWIRE_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk pwm1_clk[] = { + { + .id = 0, + .parent = &per_clk[10], + .secondary = &pwm1_clk[1], + }, + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR1, + .enable_shift = MXC_CCM_CGCR1_PWM1_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk pwm2_clk[] = { + { + .id = 1, + .parent = &per_clk[10], + .secondary = &pwm2_clk[1], + }, + { + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR2, + .enable_shift = MXC_CCM_CGCR2_PWM2_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk pwm3_clk[] = { + { + .id = 2, + .parent = &per_clk[10], + .secondary = &pwm3_clk[1], + }, + { + .id = 2, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR2, + .enable_shift = MXC_CCM_CGCR2_PWM3_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk pwm4_clk[] = { + { + .id = 3, + .parent = &per_clk[10], + .secondary = &pwm4_clk[1], + }, + { + .id = 3, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR2, + .enable_shift = MXC_CCM_CGCR2_PWM3_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk rngb_clk = { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR2, + .enable_shift = MXC_CCM_CGCR2_RNGB_OFFSET, + .disable = _clk_disable, +}; + +struct clk scc_clk = { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR2, + .enable_shift = MXC_CCM_CGCR2_SCC_OFFSET, + .disable = _clk_disable, +}; + +struct clk sdma_clk[] = { + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR2, + .enable_shift = MXC_CCM_CGCR2_SDMA_OFFSET, + .disable = _clk_disable, + .secondary = &sdma_clk[1], + }, + { + .id = 0, + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR0, + .enable_shift = MXC_CCM_CGCR0_HCLK_SDMA_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk sim1_clk[] = { + { + .id = 0, + .parent = &per_clk[11], + .secondary = &sim1_clk[1], + }, + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR2, + .enable_shift = MXC_CCM_CGCR2_SIM1_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk sim2_clk[] = { + { + .id = 1, + .parent = &per_clk[12], + .secondary = &sim2_clk[1], + }, + { + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR2, + .enable_shift = MXC_CCM_CGCR2_SIM2_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk slcdc_clk[] = { + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR2, + .enable_shift = MXC_CCM_CGCR2_SLCDC_OFFSET, + .disable = _clk_disable, + .secondary = &slcdc_clk[1], + }, + { + .id = 0, + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR0, + .enable_shift = MXC_CCM_CGCR0_HCLK_SLCDC_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk spba_clk = { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR2, + .enable_shift = MXC_CCM_CGCR2_SPBA_OFFSET, + .disable = _clk_disable, +}; + +struct clk ssi1_clk[] = { + { + .id = 0, + .parent = &per_clk[13], + .secondary = &ssi1_clk[1], + }, + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR2, + .enable_shift = MXC_CCM_CGCR2_SSI1_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk ssi2_clk[] = { + { + .id = 1, + .parent = &per_clk[14], + .secondary = &ssi2_clk[1], + }, + { + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR2, + .enable_shift = MXC_CCM_CGCR2_SSI2_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk tchscrn_clk = { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR2, + .enable_shift = MXC_CCM_CGCR2_TCHSCRN_OFFSET, + .disable = _clk_disable, +}; + +struct clk uart1_clk[] = { + { + .id = 0, + .parent = &per_clk[15], + .secondary = &uart1_clk[1], + }, + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR2, + .enable_shift = MXC_CCM_CGCR2_UART1_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk uart2_clk[] = { + { + .id = 1, + .parent = &per_clk[15], + .secondary = &uart2_clk[1], + }, + { + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR2, + .enable_shift = MXC_CCM_CGCR2_UART2_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk uart3_clk[] = { + { + .id = 2, + .parent = &per_clk[15], + .secondary = &uart3_clk[1], + }, + { + .id = 2, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR2, + .enable_shift = MXC_CCM_CGCR2_UART3_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk uart4_clk[] = { + { + .id = 3, + .parent = &per_clk[15], + .secondary = &uart4_clk[1], + }, + { + .id = 3, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR2, + .enable_shift = MXC_CCM_CGCR2_UART4_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk uart5_clk[] = { + { + .id = 4, + .parent = &per_clk[15], + .secondary = &uart5_clk[1], + }, + { + .id = 4, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR2, + .enable_shift = MXC_CCM_CGCR2_UART5_OFFSET, + .disable = _clk_disable, + }, +}; + +struct clk wdog_clk = { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGCR2, + .enable_shift = MXC_CCM_CGCR2_WDOG_OFFSET, + .disable = _clk_disable, +}; + +static unsigned long _clk_usb_round_rate(struct clk *clk, unsigned long rate) +{ + unsigned long div; + + div = clk_get_rate(clk->parent) / rate; + if (clk_get_rate(clk->parent) % rate) + div++; + + if (div > 64) + return -EINVAL; + + return clk_get_rate(clk->parent) / div; +} + +static int _clk_usb_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned long reg; + unsigned long div; + + div = clk_get_rate(clk->parent) / rate; + + if (clk_get_rate(clk->parent) / div != rate) + return -EINVAL; + if (div > 64) + return -EINVAL; + + reg = __raw_readl(MXC_CCM_CCTL) & ~MXC_CCM_CCTL_USB_DIV_MASK; + reg |= (div - 1) << MXC_CCM_CCTL_USB_DIV_OFFSET; + __raw_writel(reg, MXC_CCM_MCR); + + return 0; +} + +static unsigned long _clk_usb_getrate(struct clk *clk) +{ + unsigned long div = + __raw_readl(MXC_CCM_MCR) & MXC_CCM_CCTL_USB_DIV_MASK; + + div >>= MXC_CCM_CCTL_USB_DIV_OFFSET; + + return clk_get_rate(clk->parent) / (div + 1); +} + +static int _clk_usb_set_parent(struct clk *clk, struct clk *parent) +{ + unsigned long mcr; + + if (clk->parent == parent) + return 0; + if (parent != &upll_clk && parent != &ahb_clk) + return -EINVAL; + + clk->parent = parent; + mcr = __raw_readl(MXC_CCM_MCR); + if (parent == &ahb_clk) + mcr |= (1 << MXC_CCM_MCR_USB_CLK_MUX_OFFSET); + else + mcr &= ~(1 << MXC_CCM_MCR_USB_CLK_MUX_OFFSET); + + __raw_writel(mcr, MXC_CCM_MCR); + + return 0; +} + +static struct clk usb_clk = { + .parent = &upll_clk, + .get_rate = _clk_usb_getrate, + .set_rate = _clk_usb_set_rate, + .round_rate = _clk_usb_round_rate, + .set_parent = _clk_usb_set_parent, +}; + +/* CLKO */ + +static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate) +{ + unsigned long div; + + div = clk_get_rate(clk->parent) / rate; + if (clk_get_rate(clk->parent) % rate) + div++; + + if (div > 64) + return -EINVAL; + + return clk_get_rate(clk->parent) / div; +} + +static int _clk_clko_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned long reg; + unsigned long div; + + div = clk_get_rate(clk->parent) / rate; + + if ((clk_get_rate(clk->parent) / div) != rate) + return -EINVAL; + if (div > 64) + return -EINVAL; + + reg = __raw_readl(MXC_CCM_MCR) & ~MXC_CCM_MCR_CLKO_DIV_MASK; + reg |= (div - 1) << MXC_CCM_MCR_CLKO_DIV_OFFSET; + __raw_writel(reg, MXC_CCM_MCR); + + return 0; +} + +static unsigned long _clk_clko_getrate(struct clk *clk) +{ + unsigned long div = __raw_readl(MXC_CCM_MCR); + + div &= MXC_CCM_MCR_CLKO_DIV_MASK; + div >>= MXC_CCM_MCR_CLKO_DIV_OFFSET; + + return clk_get_rate(clk->parent) / (div + 1); +} + +static struct clk *clko_sources[] = { + &osc32k_clk, /* 0x0 */ + &osc24m_clk, /* 0x1 */ + &cpu_clk, /* 0x2 */ + &ahb_clk, /* 0x3 */ + &ipg_clk, /* 0x4 */ + NULL, /* 0x5 */ + NULL, /* 0x6 */ + NULL, /* 0x7 */ + NULL, /* 0x8 */ + NULL, /* 0x9 */ + &per_clk[0], /* 0xA */ + &per_clk[2], /* 0xB */ + &per_clk[13], /* 0xC */ + &per_clk[14], /* 0xD */ + &usb_clk, /* 0xE */ + NULL, /* 0xF */ +}; + +#define NR_CLKO_SOURCES (sizeof(clko_sources) / sizeof(struct clk *)) + +static int _clk_clko_set_parent(struct clk *clk, struct clk *parent) +{ + unsigned long reg; + struct clk **src; + int i; + + if (clk->parent == parent) + return 0; + for (i = 0, src = clko_sources; i < NR_CLKO_SOURCES; i++, src++) + if (*src == parent) + break; + + if (i == NR_CLKO_SOURCES) + return -EINVAL; + + clk->parent = parent; + + reg = __raw_readl(MXC_CCM_MCR) & ~MXC_CCM_MCR_CLKO_SEL_MASK; + reg |= i << MXC_CCM_MCR_CLKO_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_MCR); + + return 0; +} + +static struct clk clko_clk = { + .set_rate = _clk_clko_set_rate, + .round_rate = _clk_clko_round_rate, + .set_parent = _clk_clko_set_parent, + .get_rate = _clk_clko_getrate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_MCR, + .enable_shift = MXC_CCM_MCR_CLKO_EN_OFFSET, + .disable = _clk_disable, +}; + +#define _REGISTER_CLOCK(d, n, c) \ + { \ + .dev_id = d, \ + .con_id = n, \ + .clk = &c, \ + }, + +static struct clk_lookup lookups[] = { + _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) + _REGISTER_CLOCK(NULL, "audmux", audmux_clk) + _REGISTER_CLOCK(NULL, "ata", ata_clk[0]) + _REGISTER_CLOCK(NULL, "can", can_clk[0]) + _REGISTER_CLOCK(NULL, "csi", csi_clk[0]) + _REGISTER_CLOCK(NULL, "cspi.0", cspi_clk[0]) + _REGISTER_CLOCK(NULL, "cspi.1", cspi_clk[1]) + _REGISTER_CLOCK(NULL, "cspi.2", cspi_clk[2]) + _REGISTER_CLOCK(NULL, "dryice", dryice_clk) + _REGISTER_CLOCK(NULL, "ect", ect_clk) + _REGISTER_CLOCK(NULL, "epit1", epit1_clk[0]) + _REGISTER_CLOCK(NULL, "epit2", epit2_clk[0]) + _REGISTER_CLOCK(NULL, "esai", esai_clk[0]) + _REGISTER_CLOCK("mxc-mmc.0", NULL, esdhc1_clk[0]) + _REGISTER_CLOCK("mxc-mmc.1", NULL, esdhc2_clk[0]) + _REGISTER_CLOCK("fec.0", NULL, fec_clk[0]) + _REGISTER_CLOCK(NULL, "gpio0", gpio_clk[0]) + _REGISTER_CLOCK(NULL, "gpio1", gpio_clk[1]) + _REGISTER_CLOCK(NULL, "gpio2", gpio_clk[2]) + _REGISTER_CLOCK(NULL, "gpt1", gpt1_clk[0]) + _REGISTER_CLOCK(NULL, "gpt2", gpt2_clk[0]) + _REGISTER_CLOCK(NULL, "gpt3", gpt3_clk[0]) + _REGISTER_CLOCK(NULL, "gpt4", gpt4_clk[0]) + _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk[0]) + _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk[1]) + _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk[2]) + _REGISTER_CLOCK(NULL, "iim", iim_clk) + _REGISTER_CLOCK(NULL, "iomuxc", iomuxc_clk) + _REGISTER_CLOCK(NULL, "kpp", kpp_clk) + _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk[0]) + _REGISTER_CLOCK(NULL, "owire", owire_clk[0]) + _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk[0]) + _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk[0]) + _REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk[0]) + _REGISTER_CLOCK("mxc_pwm.3", NULL, pwm4_clk[0]) + _REGISTER_CLOCK(NULL, "rngb", rngb_clk) + _REGISTER_CLOCK(NULL, "scc", scc_clk) + _REGISTER_CLOCK(NULL, "sdma", sdma_clk[0]) + _REGISTER_CLOCK(NULL, "sim1", sim1_clk[0]) + _REGISTER_CLOCK(NULL, "sim2", sim2_clk[0]) + _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk[0]) + _REGISTER_CLOCK(NULL, "spba", spba_clk) + _REGISTER_CLOCK(NULL, "ssi1", ssi1_clk[0]) + _REGISTER_CLOCK(NULL, "ssi2", ssi2_clk[0]) + _REGISTER_CLOCK(NULL, "tchscrn", tchscrn_clk) + _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk[0]) + _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk[0]) + _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk[0]) + _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk[0]) + _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk[0]) + _REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk) + _REGISTER_CLOCK(NULL, "usb", usb_clk) + _REGISTER_CLOCK(NULL, "clko", clko_clk) + _REGISTER_CLOCK(NULL, "brom", brom_clk) +}; + +int __init mx25_clocks_init(unsigned long fref) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(lookups); i++) { + printk(KERN_DEBUG "Registering clock '%s' '%s'\n", + lookups[i].dev_id ? lookups[i].dev_id : "", + lookups[i].con_id ? lookups[i].con_id : ""); + clkdev_add(&lookups[i]); + } + + ckih_rate = fref; +#ifndef CONFIG_DEBUG_LL + /* Turn off all possible clocks */ + __raw_writel((1 << MXC_CCM_CGCR0_HCLK_EMI_OFFSET), MXC_CCM_CGCR0); + + __raw_writel((1 << MXC_CCM_CGCR1_GPT1_OFFSET) | + (1 << MXC_CCM_CGCR1_IIM_OFFSET), MXC_CCM_CGCR1); + __raw_writel(1 << MXC_CCM_CGCR2_SCC_OFFSET, MXC_CCM_CGCR2); +#endif +#if 1 + /* Set all perclk sources to upll */ + for (i = 0; i < ARRAY_SIZE(per_clk); i++) { + int ret; + unsigned long rate = per_clk[i].get_rate(&per_clk[i]); + +#ifdef CONFIG_DEBUG_LL + if (i == 15) { + printk(KERN_DEBUG "skipping per_clk[%d] rate=%lu\n", i, rate); + continue; + } +#endif + { + unsigned long new_rate; + + per_clk[i].set_parent(&per_clk[i], &upll_clk); + new_rate = per_clk[i].round_rate(&per_clk[i], rate); + if (rate == new_rate) + break; + if ((ret = per_clk[i].set_rate(&per_clk[i], new_rate)) < 0) { + printk(KERN_ERR "Error %d setting clk[%d] rate to %lu\n", + ret, i, new_rate); + } + } + } +#endif + /* the NFC clock must be derived from AHB clock */ + clk_set_parent(&per_clk[8], &ahb_clk); + clk_set_rate(&per_clk[8], clk_get_rate(&ahb_clk) / 6); + + /* This will propagate to all children and init all the clock rates */ +#ifdef CONFIG_DEBUG_LL + clk_enable(&uart1_clk[0]); +#endif + clk_enable(&emi_clk); + clk_enable(&gpio_clk[0]); + clk_enable(&gpio_clk[1]); + clk_enable(&gpio_clk[2]); + clk_enable(&iim_clk); + clk_enable(&gpt1_clk[0]); + clk_enable(&iomuxc_clk); + clk_enable(&scc_clk); + + pr_info("Clock input source is %ld\n", clk_get_rate(&osc24m_clk)); + + pr_info("CPU: %lu.%03luMHz\n", + clk_get_rate(&cpu_clk) / 1000000, clk_get_rate(&cpu_clk) / 1000 % 1000); + pr_info("AHB: %lu.%03luMHz\n", + clk_get_rate(&ahb_clk) / 1000000, clk_get_rate(&ahb_clk) / 1000 % 1000); + pr_info("MPLL: %lu.%03luMHz\n", + clk_get_rate(&mpll_clk) / 1000000, clk_get_rate(&mpll_clk) / 1000 % 1000); + pr_info("UPLL: %lu.%03luMHz\n", + clk_get_rate(&upll_clk) / 1000000, clk_get_rate(&upll_clk) / 1000 % 1000); + clk_set_rate(&mpll_clk, clk_get_rate(&mpll_clk)); + clk_set_rate(&upll_clk, clk_get_rate(&upll_clk)); + + mxc_timer_init(&gpt1_clk[0]); + return 0; +} diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/clock_imx27.c linux-2.6.30-rc4-karo/arch/arm/mach-mx2/clock_imx27.c --- linux-2.6.30-rc4/arch/arm/mach-mx2/clock_imx27.c 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/clock_imx27.c 2009-06-02 17:59:15.000000000 +0200 @@ -621,7 +621,7 @@ DEFINE_CLOCK1(csi_clk, 0, 0, 0, .clk = &c, \ }, -static struct clk_lookup lookups[] __initdata = { +static struct clk_lookup lookups[] = { _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/cpu_imx25.c linux-2.6.30-rc4-karo/arch/arm/mach-mx2/cpu_imx25.c --- linux-2.6.30-rc4/arch/arm/mach-mx2/cpu_imx25.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/cpu_imx25.c 2009-06-02 17:59:17.000000000 +0200 @@ -0,0 +1,65 @@ +/* + * arch/arm/mach-mx2/cpu_mx25.c + * + * Copyright 2009 Lothar Wassmann + * derived from: cpu_mx27.c + * 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 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +/* + * i.MX25 specific CPU detection code + */ + +#include +#include + +#include + +static int cpu_silicon_rev = -1; +static int cpu_partnumber; + +#define IIM_PREV_REG IO_ADDRESS(IIM_BASE_ADDR + 0x20) +#define IIM_SREV_REG IO_ADDRESS(IIM_BASE_ADDR + 0x24) + +static void query_silicon_parameter(void) +{ + cpu_partnumber = __raw_readl(IIM_PREV_REG) >> 3; + cpu_silicon_rev = __raw_readl(IIM_SREV_REG); + + printk(KERN_DEBUG "CPU rev: 0x%02x chip_rev: 0x%02x\n", + cpu_partnumber, cpu_silicon_rev); + if (WARN_ON(cpu_partnumber != 0x1f)) { + printk(KERN_WARNING "Unsupported CPU rev: 0x%02x\n", cpu_partnumber); + } +} + +/* + * Returns: + * the silicon revision of the cpu + * -EINVAL - not a mx25 + */ +int mx25_revision(void) +{ + if (cpu_silicon_rev == -1) + query_silicon_parameter(); + + if (cpu_partnumber != 0x1f) + return -EINVAL; + + return cpu_silicon_rev; +} +EXPORT_SYMBOL(mx25_revision); diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/crm_regs_mx25.h linux-2.6.30-rc4-karo/arch/arm/mach-mx2/crm_regs_mx25.h --- linux-2.6.30-rc4/arch/arm/mach-mx2/crm_regs_mx25.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/crm_regs_mx25.h 2009-06-02 17:59:17.000000000 +0200 @@ -0,0 +1,190 @@ +/* + * Copyright 2008 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_MX25_CRM_REGS_H__ +#define __ARCH_ARM_MACH_MX25_CRM_REGS_H__ + +#include + +/* Register offsets */ +#define MXC_CCM_MPCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x00) +#define MXC_CCM_UPCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x04) +#define MXC_CCM_CCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x08) +#define MXC_CCM_CGCR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x0C) +#define MXC_CCM_CGCR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x10) +#define MXC_CCM_CGCR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x14) +#define MXC_CCM_PCDR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x18) +#define MXC_CCM_PCDR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x1C) +#define MXC_CCM_PCDR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x20) +#define MXC_CCM_PCDR3 (IO_ADDRESS(CCM_BASE_ADDR) + 0x24) +#define MXC_CCM_RCSR (IO_ADDRESS(CCM_BASE_ADDR) + 0x28) +#define MXC_CCM_CRDR (IO_ADDRESS(CCM_BASE_ADDR) + 0x2C) +#define MXC_CCM_DCVR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x30) +#define MXC_CCM_DCVR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x34) +#define MXC_CCM_DCVR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x38) +#define MXC_CCM_DCVR3 (IO_ADDRESS(CCM_BASE_ADDR) + 0x3C) +#define MXC_CCM_LTR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x40) +#define MXC_CCM_LTR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x44) +#define MXC_CCM_LTR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x48) +#define MXC_CCM_LTR3 (IO_ADDRESS(CCM_BASE_ADDR) + 0x4C) +#define MXC_CCM_LTBR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x50) +#define MXC_CCM_LTBR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x54) +#define MXC_CCM_PMCR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x58) +#define MXC_CCM_PMCR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x5C) +#define MXC_CCM_PMCR2 (IO_ADDRESS(CCM_BASE_ADDR) + 0x60) +#define MXC_CCM_MCR (IO_ADDRESS(CCM_BASE_ADDR) + 0x64) + +#define MXC_CCM_MPCTL_BRMO (1 << 31) +#define MXC_CCM_MPCTL_PD_OFFSET 26 +#define MXC_CCM_MPCTL_PD_MASK (0xf << 26) +#define MXC_CCM_MPCTL_MFD_OFFSET 16 +#define MXC_CCM_MPCTL_MFD_MASK (0x3ff << 16) +#define MXC_CCM_MPCTL_MFI_OFFSET 10 +#define MXC_CCM_MPCTL_MFI_MASK (0xf << 10) +#define MXC_CCM_MPCTL_MFN_OFFSET 0 +#define MXC_CCM_MPCTL_MFN_MASK 0x3ff +#define MXC_CCM_MPCTL_LF (1 << 15) + +#define MXC_CCM_UPCTL_BRMO (1 << 31) +#define MXC_CCM_UPCTL_PD_OFFSET 26 +#define MXC_CCM_UPCTL_PD_MASK (0xf << 26) +#define MXC_CCM_UPCTL_MFD_OFFSET 16 +#define MXC_CCM_UPCTL_MFD_MASK (0x3ff << 16) +#define MXC_CCM_UPCTL_MFI_OFFSET 10 +#define MXC_CCM_UPCTL_MFI_MASK (0xf << 10) +#define MXC_CCM_UPCTL_MFN_OFFSET 0 +#define MXC_CCM_UPCTL_MFN_MASK 0x3ff +#define MXC_CCM_UPCTL_LF (1 << 15) + +#define MXC_CCM_CCTL_ARM_OFFSET 30 +#define MXC_CCM_CCTL_ARM_MASK (0x3 << 30) +#define MXC_CCM_CCTL_AHB_OFFSET 28 +#define MXC_CCM_CCTL_AHB_MASK (0x3 << 28) +#define MXC_CCM_CCTL_MPLL_RST (1 << 27) +#define MXC_CCM_CCTL_UPLL_RST (1 << 26) +#define MXC_CCM_CCTL_LP_CTL_OFFSET 24 +#define MXC_CCM_CCTL_LP_CTL_MASK (0x3 << 24) +#define MXC_CCM_CCTL_LP_MODE_RUN (0x0 << 24) +#define MXC_CCM_CCTL_LP_MODE_WAIT (0x1 << 24) +#define MXC_CCM_CCTL_LP_MODE_DOZE (0x2 << 24) +#define MXC_CCM_CCTL_LP_MODE_STOP (0x3 << 24) +#define MXC_CCM_CCTL_UPLL_DISABLE (1 << 23) +#define MXC_CCM_CCTL_MPLL_BYPASS (1 << 22) +#define MXC_CCM_CCTL_USB_DIV_OFFSET 16 +#define MXC_CCM_CCTL_USB_DIV_MASK (0x3 << 16) +#define MXC_CCM_CCTL_CG_CTRL (1 << 15) +#define MXC_CCM_CCTL_ARM_SRC (1 << 14) + +#define MXC_CCM_CGCR0_HCLK_ATA_OFFSET 16 +#define MXC_CCM_CGCR0_HCLK_BROM_OFFSET 17 +#define MXC_CCM_CGCR0_HCLK_CSI_OFFSET 18 +#define MXC_CCM_CGCR0_HCLK_EMI_OFFSET 19 +#define MXC_CCM_CGCR0_HCLK_ESAI_OFFSET 20 +#define MXC_CCM_CGCR0_HCLK_ESDHC1_OFFSET 21 +#define MXC_CCM_CGCR0_HCLK_ESDHC2_OFFSET 22 +#define MXC_CCM_CGCR0_HCLK_FEC_OFFSET 23 +#define MXC_CCM_CGCR0_HCLK_LCDC_OFFSET 24 +#define MXC_CCM_CGCR0_HCLK_RTIC_OFFSET 25 +#define MXC_CCM_CGCR0_HCLK_SDMA_OFFSET 26 +#define MXC_CCM_CGCR0_HCLK_SLCDC_OFFSET 27 +#define MXC_CCM_CGCR0_HCLK_USBOTG_OFFSET 28 + +#define MXC_CCM_CGCR0_PER_CSI_OFFSET 0 +#define MXC_CCM_CGCR0_PER_EPIT_OFFSET 1 +#define MXC_CCM_CGCR0_PER_ESAI_OFFSET 2 +#define MXC_CCM_CGCR0_PER_ESDHC1_OFFSET 3 +#define MXC_CCM_CGCR0_PER_ESDHC2_OFFSET 4 +#define MXC_CCM_CGCR0_PER_GPT_OFFSET 5 +#define MXC_CCM_CGCR0_PER_I2C_OFFSET 6 +#define MXC_CCM_CGCR0_PER_LCDC_OFFSET 7 +#define MXC_CCM_CGCR0_PER_NFC_OFFSET 8 +#define MXC_CCM_CGCR0_PER_OWIRE_OFFSET 9 +#define MXC_CCM_CGCR0_PER_PWM_OFFSET 10 +#define MXC_CCM_CGCR0_PER_SIM1_OFFSET 11 +#define MXC_CCM_CGCR0_PER_SIM2_OFFSET 12 +#define MXC_CCM_CGCR0_PER_SSI1_OFFSET 13 +#define MXC_CCM_CGCR0_PER_SSI2_OFFSET 14 +#define MXC_CCM_CGCR0_PER_UART_OFFSET 15 + +#define MXC_CCM_CGCR1_AUDMUX_OFFSET 0 +#define MXC_CCM_CGCR1_ATA_OFFSET 1 +#define MXC_CCM_CGCR1_CAN1_OFFSET 2 +#define MXC_CCM_CGCR1_CAN2_OFFSET 3 +#define MXC_CCM_CGCR1_CSI_OFFSET 4 +#define MXC_CCM_CGCR1_CSPI1_OFFSET 5 +#define MXC_CCM_CGCR1_CSPI2_OFFSET 6 +#define MXC_CCM_CGCR1_CSPI3_OFFSET 7 +#define MXC_CCM_CGCR1_DRYICE_OFFSET 8 +#define MXC_CCM_CGCR1_ECT_OFFSET 9 +#define MXC_CCM_CGCR1_EPIT1_OFFSET 10 +#define MXC_CCM_CGCR1_EPIT2_OFFSET 11 +#define MXC_CCM_CGCR1_ESAI_OFFSET 12 +#define MXC_CCM_CGCR1_ESDHC1_OFFSET 13 +#define MXC_CCM_CGCR1_ESDHC2_OFFSET 14 +#define MXC_CCM_CGCR1_FEC_OFFSET 15 +#define MXC_CCM_CGCR1_GPIO1_OFFSET 16 +#define MXC_CCM_CGCR1_GPIO2_OFFSET 17 +#define MXC_CCM_CGCR1_GPIO3_OFFSET 18 +#define MXC_CCM_CGCR1_GPT1_OFFSET 19 +#define MXC_CCM_CGCR1_GPT2_OFFSET 20 +#define MXC_CCM_CGCR1_GPT3_OFFSET 21 +#define MXC_CCM_CGCR1_GPT4_OFFSET 22 +#define MXC_CCM_CGCR1_I2C1_OFFSET 23 +#define MXC_CCM_CGCR1_I2C2_OFFSET 24 +#define MXC_CCM_CGCR1_I2C3_OFFSET 25 +#define MXC_CCM_CGCR1_IIM_OFFSET 26 +#define MXC_CCM_CGCR1_IOMUXC_OFFSET 27 +#define MXC_CCM_CGCR1_KPP_OFFSET 28 +#define MXC_CCM_CGCR1_LCDC_OFFSET 29 +#define MXC_CCM_CGCR1_OWIRE_OFFSET 30 +#define MXC_CCM_CGCR1_PWM1_OFFSET 31 + +#define MXC_CCM_CGCR2_PWM2_OFFSET (32-32) +#define MXC_CCM_CGCR2_PWM3_OFFSET (33-32) +#define MXC_CCM_CGCR2_PWM4_OFFSET (34-32) +#define MXC_CCM_CGCR2_RNGB_OFFSET (35-32) +#define MXC_CCM_CGCR2_RTIC_OFFSET (36-32) +#define MXC_CCM_CGCR2_SCC_OFFSET (37-32) +#define MXC_CCM_CGCR2_SDMA_OFFSET (38-32) +#define MXC_CCM_CGCR2_SIM1_OFFSET (39-32) +#define MXC_CCM_CGCR2_SIM2_OFFSET (40-32) +#define MXC_CCM_CGCR2_SLCDC_OFFSET (41-32) +#define MXC_CCM_CGCR2_SPBA_OFFSET (42-32) +#define MXC_CCM_CGCR2_SSI1_OFFSET (43-32) +#define MXC_CCM_CGCR2_SSI2_OFFSET (44-32) +#define MXC_CCM_CGCR2_TCHSCRN_OFFSET (45-32) +#define MXC_CCM_CGCR2_UART1_OFFSET (46-32) +#define MXC_CCM_CGCR2_UART2_OFFSET (47-32) +#define MXC_CCM_CGCR2_UART3_OFFSET (48-32) +#define MXC_CCM_CGCR2_UART4_OFFSET (49-32) +#define MXC_CCM_CGCR2_UART5_OFFSET (50-32) +#define MXC_CCM_CGCR2_WDOG_OFFSET (51-32) + +#define MXC_CCM_PCDR1_PERDIV1_MASK 0x3f + +#define MXC_CCM_RCSR_NF16B (1 << 14) + +#define MXC_CCM_MCR_USB_XTAL_MUX_OFFSET 31 +#define MXC_CCM_MCR_CLKO_EN_OFFSET 30 +#define MXC_CCM_MCR_CLKO_DIV_OFFSET 24 +#define MXC_CCM_MCR_CLKO_DIV_MASK (0x3F << 24) +#define MXC_CCM_MCR_CLKO_SEL_OFFSET 20 +#define MXC_CCM_MCR_CLKO_SEL_MASK (0xF << 20) +#define MXC_CCM_MCR_ESAI_CLK_MUX_OFFSET 19 +#define MXC_CCM_MCR_SSI2_CLK_MUX_OFFSET 18 +#define MXC_CCM_MCR_SSI1_CLK_MUX_OFFSET 17 +#define MXC_CCM_MCR_USB_CLK_MUX_OFFSET 16 + +#define MXC_CCM_MCR_PER_CLK_MUX_MASK (0xFFFF << 0) + +#endif /* __ARCH_ARM_MACH_MX25_CRM_REGS_H__ */ diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/devices.h linux-2.6.30-rc4-karo/arch/arm/mach-mx2/devices.h --- linux-2.6.30-rc4/arch/arm/mach-mx2/devices.h 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/devices.h 2009-06-02 17:59:16.000000000 +0200 @@ -20,3 +20,9 @@ extern struct platform_device mxc_i2c_de extern struct platform_device mxc_i2c_device1; extern struct platform_device mxc_sdhc_device0; extern struct platform_device mxc_sdhc_device1; +#ifdef CONFIG_MACH_MX25 +extern struct platform_device mx25_i2c_device0; +extern struct platform_device mx25_i2c_device1; +extern struct platform_device mx25_i2c_device2; +extern struct platform_device mxc_sdhc_device2; +#endif diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/devices_mx25.c linux-2.6.30-rc4-karo/arch/arm/mach-mx2/devices_mx25.c --- linux-2.6.30-rc4/arch/arm/mach-mx2/devices_mx25.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/devices_mx25.c 2009-06-02 17:59:17.000000000 +0200 @@ -0,0 +1,402 @@ +/* + * Copyright 2008 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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "sdma_script_code.h" + +#include "karo.h" + +void mx25_sdma_get_script_info(sdma_script_start_addrs * sdma_script_addr) +{ + sdma_script_addr->mxc_sdma_ap_2_ap_addr = ap_2_ap_ADDR; + sdma_script_addr->mxc_sdma_ap_2_bp_addr = -1; + sdma_script_addr->mxc_sdma_bp_2_ap_addr = -1; + sdma_script_addr->mxc_sdma_loopback_on_dsp_side_addr = -1; + sdma_script_addr->mxc_sdma_mcu_interrupt_only_addr = -1; + + sdma_script_addr->mxc_sdma_firi_2_per_addr = -1; + sdma_script_addr->mxc_sdma_firi_2_mcu_addr = -1; + sdma_script_addr->mxc_sdma_per_2_firi_addr = -1; + sdma_script_addr->mxc_sdma_mcu_2_firi_addr = -1; + + sdma_script_addr->mxc_sdma_uart_2_per_addr = uart_2_per_ADDR; + sdma_script_addr->mxc_sdma_uart_2_mcu_addr = uart_2_mcu_ADDR; + sdma_script_addr->mxc_sdma_per_2_app_addr = per_2_app_ADDR; + sdma_script_addr->mxc_sdma_mcu_2_app_addr = mcu_2_app_ADDR; + + sdma_script_addr->mxc_sdma_per_2_per_addr = -1; + + sdma_script_addr->mxc_sdma_uartsh_2_per_addr = uartsh_2_per_ADDR; + sdma_script_addr->mxc_sdma_uartsh_2_mcu_addr = uartsh_2_mcu_ADDR; + sdma_script_addr->mxc_sdma_per_2_shp_addr = per_2_shp_ADDR; + sdma_script_addr->mxc_sdma_mcu_2_shp_addr = mcu_2_shp_ADDR; + + sdma_script_addr->mxc_sdma_ata_2_mcu_addr = ata_2_mcu_ADDR; + sdma_script_addr->mxc_sdma_mcu_2_ata_addr = mcu_2_ata_ADDR; + + sdma_script_addr->mxc_sdma_app_2_per_addr = app_2_per_ADDR; + sdma_script_addr->mxc_sdma_app_2_mcu_addr = app_2_mcu_ADDR; + sdma_script_addr->mxc_sdma_shp_2_per_addr = shp_2_per_ADDR; + sdma_script_addr->mxc_sdma_shp_2_mcu_addr = shp_2_mcu_ADDR; + + sdma_script_addr->mxc_sdma_mshc_2_mcu_addr = -1; + sdma_script_addr->mxc_sdma_mcu_2_mshc_addr = -1; + + sdma_script_addr->mxc_sdma_spdif_2_mcu_addr = -1; + sdma_script_addr->mxc_sdma_mcu_2_spdif_addr = -1; + + sdma_script_addr->mxc_sdma_asrc_2_mcu_addr = -1; + + sdma_script_addr->mxc_sdma_dptc_dvfs_addr = -1; + sdma_script_addr->mxc_sdma_ext_mem_2_ipu_addr = ext_mem__ipu_ram_ADDR; + sdma_script_addr->mxc_sdma_descrambler_addr = -1; + + sdma_script_addr->mxc_sdma_start_addr = (unsigned short *)sdma_code; + sdma_script_addr->mxc_sdma_ram_code_size = RAM_CODE_SIZE; + sdma_script_addr->mxc_sdma_ram_code_start_addr = RAM_CODE_START_ADDR; +} + +#if defined(CONFIG_MXC_WATCHDOG) || defined(CONFIG_MXC_WATCHDOG_MODULE) +static struct resource wdt_resources[] = { + { + .start = WDOG_BASE_ADDR, + .end = WDOG_BASE_ADDR + 0x2f, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mx25_wdt_device = { + .name = "mxc_wdt", + .id = 0, + .num_resources = ARRAY_SIZE(wdt_resources), + .resource = wdt_resources, +}; + +static void mx25_init_wdt(void) +{ + (void)platform_device_register(&mx25_wdt_device); +} +#else +static inline void mx25_init_wdt(void) +{ +} +#endif + +/* + * lcdc: + * - i.MX1: the basic controller + * - i.MX21: to be checked + * - i.MX27: like i.MX1, with slightly variations + */ +static struct resource mxc_fb[] = { + { + .start = LCDC_BASE_ADDR, + .end = LCDC_BASE_ADDR + 0xFFF, + .flags = IORESOURCE_MEM, + }, + { + .start = MXC_INT_LCDC, + .end = MXC_INT_LCDC, + .flags = IORESOURCE_IRQ, + } +}; + +/* mxc lcd driver */ +struct platform_device mxc_fb_device = { + .name = "imx-fb", + .id = 0, + .num_resources = ARRAY_SIZE(mxc_fb), + .resource = mxc_fb, + .dev = { + .coherent_dma_mask = 0xFFFFFFFF, + }, +}; + +/* 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 mx25_spi1_resources[] = { + [0] = { + .start = CSPI1_BASE_ADDR, + .end = CSPI1_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_CSPI1, + .end = MXC_INT_CSPI1, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Platform Data for MXC CSPI1 */ +static struct mxc_spi_master mx25_spi1_data = { + .maxchipselect = 4, + .spi_version = 7, +}; + +/*! Device Definition for MXC CSPI1 */ +static struct platform_device mx25_spi1_device = { + .name = "mxc_spi", + .id = 0, + .dev = { + .platform_data = &mx25_spi1_data, + }, + .num_resources = ARRAY_SIZE(mx25_spi1_resources), + .resource = mx25_spi1_resources, +}; + +#endif /* CONFIG_SPI_MXC_SELECT1 */ + +#ifdef CONFIG_SPI_MXC_SELECT2 +/*! + * Resource definition for the CSPI2 + */ +static struct resource mx25_spi2_resources[] = { + [0] = { + .start = CSPI2_BASE_ADDR, + .end = CSPI2_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_CSPI2, + .end = MXC_INT_CSPI2, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Platform Data for MXC CSPI2 */ +static struct mxc_spi_master mx25_spi2_data = { + .maxchipselect = 4, + .spi_version = 7, +}; + +/*! Device Definition for MXC CSPI2 */ +static struct platform_device mx25_spi2_device = { + .name = "mxc_spi", + .id = 1, + .dev = { + .platform_data = &mx25_spi2_data, + }, + .num_resources = ARRAY_SIZE(mx25_spi2_resources), + .resource = mx25_spi2_resources, +}; +#endif /* CONFIG_SPI_MXC_SELECT2 */ + +#ifdef CONFIG_SPI_MXC_SELECT3 +/*! + * Resource definition for the CSPI3 + */ +static struct resource mx25_spi3_resources[] = { + [0] = { + .start = CSPI3_BASE_ADDR, + .end = CSPI3_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_CSPI3, + .end = MXC_INT_CSPI3, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Platform Data for MXC CSPI3 */ +static struct mxc_spi_master mx25_spi3_data = { + .maxchipselect = 4, + .spi_version = 7, +}; + +/*! Device Definition for MXC CSPI3 */ +static struct platform_device mx25_spi3_device = { + .name = "mxc_spi", + .id = 2, + .dev = { + .platform_data = &mx25_spi3_data, + }, + .num_resources = ARRAY_SIZE(mx25_spi3_resources), + .resource = mx25_spi3_resources, +}; +#endif /* CONFIG_SPI_MXC_SELECT3 */ + +static inline void mx25_init_spi(void) +{ + spba_take_ownership(SPBA_CSPI2, SPBA_MASTER_A); + spba_take_ownership(SPBA_CSPI3, SPBA_MASTER_A); + +#ifdef CONFIG_SPI_MXC_SELECT1 + if (platform_device_register(&mx25_spi1_device) < 0) + printk(KERN_ERR "Error: Registering the SPI Controller_1\n"); +#endif /* CONFIG_SPI_MXC_SELECT1 */ +#ifdef CONFIG_SPI_MXC_SELECT2 + if (platform_device_register(&mx25_spi2_device) < 0) + printk(KERN_ERR "Error: Registering the SPI Controller_2\n"); +#endif /* CONFIG_SPI_MXC_SELECT2 */ +#ifdef CONFIG_SPI_MXC_SELECT3 + if (platform_device_register(&mx25_spi3_device) < 0) + printk(KERN_ERR "Error: Registering the SPI Controller_3\n"); +#endif /* CONFIG_SPI_MXC_SELECT3 */ +} +#else +static inline void mx25_init_spi(void) +{ +} +#endif + +/* I2C controller and device data */ +#if defined(CONFIG_I2C_IMX) || defined(CONFIG_I2C_IMX_MODULE) + +/*! + * Resource definition for the I2C1 + */ +static struct resource mx25_i2c1_resources[] = { + [0] = { + .start = I2C_BASE_ADDR, + .end = I2C_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_I2C, + .end = MXC_INT_I2C, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! + * Resource definition for the I2C2 + */ +static struct resource mx25_i2c2_resources[] = { + [0] = { + .start = I2C2_BASE_ADDR, + .end = I2C2_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_I2C2, + .end = MXC_INT_I2C2, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! + * Resource definition for the I2C3 + */ +static struct resource mx25_i2c3_resources[] = { + [0] = { + .start = I2C3_BASE_ADDR, + .end = I2C3_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_I2C3, + .end = MXC_INT_I2C3, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Device Definition for MXC I2C1 */ +struct platform_device mx25_i2c_device0 = { + .name = "imx-i2c", + .id = 0, + .num_resources = ARRAY_SIZE(mx25_i2c1_resources), + .resource = mx25_i2c1_resources, +}; + +struct platform_device mx25_i2c_device1 = { + .name = "imx-i2c", + .id = 1, + .num_resources = ARRAY_SIZE(mx25_i2c2_resources), + .resource = mx25_i2c2_resources, +}; + +struct platform_device mx25_i2c_device2 = { + .name = "imx-i2c", + .id = 2, + .num_resources = ARRAY_SIZE(mx25_i2c3_resources), + .resource = mx25_i2c3_resources, +}; +#endif + +static struct mxc_gpio_port mx25_gpio_ports[] = { + { + .chip.label = "gpio-1", + .base = IO_ADDRESS(GPIO1_BASE_ADDR), + .irq = MXC_INT_GPIO1, + .virtual_irq_start = MXC_GPIO_IRQ_START, + }, + { + .chip.label = "gpio-2", + .base = IO_ADDRESS(GPIO2_BASE_ADDR), + .irq = MXC_INT_GPIO2, + .virtual_irq_start = MXC_GPIO_IRQ_START + 1 * 32, + }, + { + .chip.label = "gpio-3", + .base = IO_ADDRESS(GPIO3_BASE_ADDR), + .irq = MXC_INT_GPIO3, + .virtual_irq_start = MXC_GPIO_IRQ_START + 2 * 32, + }, + { + .chip.label = "gpio-4", + .base = IO_ADDRESS(GPIO4_BASE_ADDR), + .irq = MXC_INT_GPIO4, + .virtual_irq_start = MXC_GPIO_IRQ_START + 3 * 32, + }, +}; + +static inline void mx25_init_ssi(void) +{ + /* SPBA configuration for SSI - SDMA and MCU are set */ + spba_take_ownership(SPBA_SSI1, SPBA_MASTER_A | SPBA_MASTER_C); + spba_take_ownership(SPBA_SSI2, SPBA_MASTER_A | SPBA_MASTER_C); +} + +static struct platform_device mx25_dma_device = { + .name = "mxc_dma", + .id = 0, +}; + +static inline void mx25_init_dma(void) +{ + (void)platform_device_register(&mx25_dma_device); +} + +static int __init mx25_init_devices(void) +{ + mx25_init_wdt(); + mx25_init_spi(); + mx25_init_dma(); + mx25_init_ssi(); + + return 0; +} +arch_initcall(mx25_init_devices); + +int __init mxc_register_gpios(void) +{ + return mxc_gpio_init(mx25_gpio_ports, ARRAY_SIZE(mx25_gpio_ports)); +} diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/generic.c linux-2.6.30-rc4-karo/arch/arm/mach-mx2/generic.c --- linux-2.6.30-rc4/arch/arm/mach-mx2/generic.c 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/generic.c 2009-06-02 17:59:16.000000000 +0200 @@ -26,6 +26,7 @@ #include /* MX27 memory map definition */ +#if defined(CONFIG_MACH_MX27) || defined(CONFIG_MACH_MX21) static struct map_desc mxc_io_desc[] __initdata = { /* * this fixed mapping covers: @@ -61,7 +62,7 @@ static struct map_desc mxc_io_desc[] __i .pfn = __phys_to_pfn(X_MEMC_BASE_ADDR), .length = X_MEMC_SIZE, .type = MT_DEVICE - } + }, }; /* @@ -82,4 +83,46 @@ void __init mx27_map_io(void) iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); } +#endif + +#ifdef CONFIG_MACH_MX25 +static struct map_desc mx25_io_desc[] __initdata = { + { + .virtual = (unsigned long)X_MEMC_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(X_MEMC_BASE_ADDR), + .length = X_MEMC_SIZE, + .type = MT_DEVICE + }, + { + .virtual = (unsigned long)ASIC_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(ASIC_BASE_ADDR), + .length = ASIC_SIZE, + .type = MT_DEVICE_NONSHARED + }, + { + .virtual = (unsigned long)AIPS1_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(AIPS1_BASE_ADDR), + .length = AIPS1_SIZE, + .type = MT_DEVICE_NONSHARED + }, + { + .virtual = (unsigned long)AIPS2_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), + .length = AIPS2_SIZE, + .type = MT_DEVICE_NONSHARED + }, + { + .virtual = (unsigned long)SPBA0_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), + .length = SPBA0_SIZE, + .type = MT_DEVICE_NONSHARED + }, +}; + +void __init mx25_map_io(void) +{ + mxc_set_cpu_type(MXC_CPU_MX25); + iotable_init(mx25_io_desc, ARRAY_SIZE(mx25_io_desc)); +} +#endif diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/karo-tx25.c linux-2.6.30-rc4-karo/arch/arm/mach-mx2/karo-tx25.c --- linux-2.6.30-rc4/arch/arm/mach-mx2/karo-tx25.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/karo-tx25.c 2009-06-08 12:47:51.000000000 +0200 @@ -0,0 +1,1122 @@ +/* + * arch/arm/mach-mx2/karo-tx25.c + * + * Copyright (C) 2008 Lothar Wassmann + * + * based on: arch/arm/mach-mx27ads.c (C) Freescale Semiconductor, Inc. + * + * 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 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * + * This file adds support for the Ka-Ro electronics TX25 processor modules + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +//#include +#include +#include +#include +#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE) +#include +#include +#include +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +//#include +#include +#include +#include +//#include +//#include +//#include + +#include "crm_regs.h" +#include "devices.h" +#include "karo.h" + +#ifdef DEBUG +int tx25_debug = 1; +module_param(tx25_debug, int, S_IRUGO | S_IWUSR); +#else +static int tx25_debug; +module_param(tx25_debug, int, 0); +#endif + +//#include "karo.h" + +int karo_board_type = 0; +int karo_mod_type = -1; + + +#ifdef CONFIG_USB_EHCI_MXC + +#define SMSC_VENDOR_ID 0x0424 +#define USB3317_PROD_ID 0x0006 +#define ULPI_FCTL 7 + +static inline const char *ulpi_name(void __iomem *view) +{ + if ((unsigned long)view & 0x400) { + return "USBH2"; + } else { + return "USBOTG"; + } +} + +static int usb3317_init(void __iomem *view) +{ + int vid, pid, ret; +#if 1 + /* This is a kludge until we know why we sometimes read a wrong + * vendor or product ID! + */ + int retries = 3; + + retry: +#endif + ret = ulpi_read(ISP1504_VID_HIGH, view); + if (ret < 0) { + goto err; + } + vid = ret << 8; + + ret = ulpi_read(ISP1504_VID_LOW, view); + if (ret < 0) { + goto err; + } + vid |= ret; + + ret = ulpi_read(ISP1504_PID_HIGH, view); + if (ret < 0) { + goto err; + } + pid = ret << 8; + + ret = ulpi_read(ISP1504_PID_LOW, view); + if (ret < 0) { + goto err; + } + pid |= ret; + + pr_info("ULPI on %s port Vendor ID 0x%x Product ID 0x%x\n", + ulpi_name(view), vid, pid); + if (vid != SMSC_VENDOR_ID || pid != USB3317_PROD_ID) { + if (retries-- < 0) { + pr_err("No USB3317 found\n"); + return -ENODEV; + } + goto retry; + } + err: + if (ret < 0) { + printk(KERN_ERR "ULPI read on %s port failed with error %d\n", + ulpi_name(view), ret); + return ret; + } + return 0; +} + +static int usb3317_set_vbus_power(void __iomem *view, int on) +{ + int ret; + + DBG(0, "%s: Switching %s port VBUS power %s\n", __FUNCTION__, + ulpi_name(view), on ? "on" : "off"); + + if (on) { + ret = ulpi_set(DRV_VBUS_EXT | /* enable external Vbus */ + DRV_VBUS | /* enable internal Vbus */ + CHRG_VBUS, /* charge Vbus */ + ISP1504_OTGCTL, view); + } else { + ret = ulpi_clear(DRV_VBUS_EXT | /* disable external Vbus */ + DRV_VBUS, /* disable internal Vbus */ + ISP1504_OTGCTL, view); + if (ret == 0) { + ret = ulpi_set(DISCHRG_VBUS, /* discharge Vbus */ + ISP1504_OTGCTL, view); + } + } + if (ret < 0) { + printk(KERN_ERR "ULPI read on %s port failed with error %d\n", + ulpi_name(view), ret); + return ret; + } + return 0; +} + +static int tx25_usbh2_init(struct platform_device *pdev) +{ + int ret; + u32 temp; + unsigned long flags; + void __iomem *view = IO_ADDRESS(OTG_BASE_ADDR + 0x570); + + local_irq_save(flags); + temp = readl(IO_ADDRESS(OTG_BASE_ADDR) + 0x600); + temp &= ~((3 << 21) | (1 << 0)); + temp |= (1 << 5) | (1 << 16) | (1 << 19) | (1 << 20); + writel(temp, IO_ADDRESS(OTG_BASE_ADDR) + 0x600); + local_irq_restore(flags); + + /* select ULPI transceiver */ + /* this must be done _before_ setting up the GPIOs! */ + temp = readl(view + 0x14); + DBG(0, "%s: Changing USBH2_PORTSC1 from %08x to %08x\n", __FUNCTION__, + temp, (temp & ~(3 << 30)) | (2 << 30)); + temp &= ~(3 << 30); + temp |= 2 << 30; + writel(temp, view + 0x14); + + /* Set to Host mode */ + temp = readl(view + 0x38); + DBG(0, "%s: Changing USBH2_USBMODE from %08x to %08x\n", __FUNCTION__, + temp, temp | 3); + writel(temp | 0x3, view + 0x38); + + ret = gpio_usbh2_active(); + if (ret != 0) { + return ret; + } + + ret = usb3317_init(view); + if (ret != 0) { + goto err; + } + ret = usb3317_set_vbus_power(view, 1); + if (ret != 0) { + goto err; + } + return 0; + + err: + gpio_usbh2_inactive(); + return ret; +} + +static int tx25_usbh2_exit(struct platform_device *pdev) +{ + gpio_usbh2_inactive(); + return 0; +} + +static struct mxc_usbh_platform_data tx25_usbh2_data = { + .init = tx25_usbh2_init, + .exit = tx25_usbh2_exit, +}; + +int tx25_usbh2_register(void) +{ + int ret; + + ret = mxc_register_device(&mxc_ehci2, &tx25_usbh2_data); + return ret; +} +device_initcall(tx25_usbh2_register); +#endif // CONFIG_USB_EHCI_MXC + +//#define FEC_MII_IRQ IRQ_GPIOD(8) + +#if defined(CONFIG_FEC) || defined(CONFIG_FEC_MODULE) +static struct resource fec_resources[] = { + { + .start = FEC_BASE_ADDR, + .end = FEC_BASE_ADDR + 0x18f, + .flags = IORESOURCE_MEM, + }, { + .start = FEC_BASE_ADDR + 0x200, + .end = FEC_BASE_ADDR + 0x30b, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_FEC, + .end = MXC_INT_FEC, + .flags = IORESOURCE_IRQ, +#ifdef FEC_MII_IRQ + }, { + .start = FEC_MII_IRQ, + .end = FEC_MII_IRQ, + .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, +#endif + }, +}; + +/* + * Setup GPIO for FEC device to be active + * + */ +static struct pad_desc karo_tx25_fec_gpios_off[] = { + MX25_PAD_FEC_MDC__GPIO_3_5, + MX25_PAD_FEC_MDIO__GPIO_3_6, + MX25_PAD_FEC_TDATA0__GPIO_3_7, + MX25_PAD_FEC_TDATA1__GPIO_3_8, + MX25_PAD_FEC_TX_EN__GPIO_3_9, + MX25_PAD_FEC_RDATA0__GPIO_3_10, + MX25_PAD_FEC_RDATA1__GPIO_3_11, + MX25_PAD_FEC_RX_DV__GPIO_3_12, + MX25_PAD_FEC_TX_CLK__GPIO_3_13, + MX25_PAD_D12__GPIO_4_8, + MX25_PAD_D10__GPIO_4_10, +}; + +static struct pad_desc karo_tx25_fec_pwr_gpios[] = { + MX25_PAD_D11__GPIO_4_9, /* FEC PHY power on pin */ + MX25_PAD_D13__GPIO_4_7, /* FEC reset */ +}; + +static struct pad_desc karo_tx25_fec_gpios_on[] = { + MX25_PAD_FEC_MDC__FEC_MDC, + MX25_PAD_FEC_MDIO__FEC_MDIO, + MX25_PAD_FEC_TDATA0__FEC_TDATA0, + MX25_PAD_FEC_TDATA1__FEC_TDATA1, + MX25_PAD_FEC_TX_EN__FEC_TX_EN, + MX25_PAD_FEC_RDATA0__FEC_RDATA0, + MX25_PAD_FEC_RDATA1__FEC_RDATA1, + MX25_PAD_FEC_RX_DV__FEC_RX_DV, + MX25_PAD_FEC_TX_CLK__FEC_TX_CLK, + MX25_PAD_D12__GPIO_4_8, + MX25_PAD_D10__GPIO_4_10, +}; + +static struct gpio_desc { + unsigned int gpio:7; + unsigned int dir:1; + unsigned int level:1; +} karo_tx25_fec_strap_gpios[] = { + /* configure the PHY strap pins to the correct values */ + { GPIO_PORTC | 5, 1, 0, }, + { GPIO_PORTC | 6, 1, 0, }, + { GPIO_PORTC | 7, 1, 0, }, + { GPIO_PORTC | 8, 1, 0, }, + { GPIO_PORTC | 9, 1, 0, }, + { GPIO_PORTC | 10, 1, 1, }, + { GPIO_PORTC | 11, 1, 1, }, + { GPIO_PORTC | 12, 0, 1, }, + { GPIO_PORTC | 13, 1, 0, }, + + { GPIO_PORTD | 8, 0, 0, }, + { GPIO_PORTD | 10, 0, 0, }, + { GPIO_PORTD | 9, 1, 1, }, + { GPIO_PORTD | 7, 1, 0, }, +}; + +#define TX25_FEC_PWR_GPIO (GPIO_PORTD | 9) +#define TX25_FEC_RST_GPIO (GPIO_PORTD | 7) + +static int gpio_fec_active(void) +{ + int ret; + int i; + +#ifdef FEC_MII_IRQ + DBG(0, "%s: Using IRQ %d (GPIO %d) for MII\n", __FUNCTION__, + FEC_MII_IRQ, irq_to_gpio(FEC_MII_IRQ)); + + set_irq_type(FEC_MII_IRQ, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING); +#endif + ret = mxc_iomux_v3_setup_multiple_pads(karo_tx25_fec_pwr_gpios, + ARRAY_SIZE(karo_tx25_fec_pwr_gpios)); + if (ret) { + return ret; + } + /* + * If the PHY is already powered on, assume it has been + * correctly configured (by the boot loader) + */ + if (0 && gpio_get_value(TX25_FEC_PWR_GPIO) && + gpio_get_value(TX25_FEC_RST_GPIO)) { + ret = mxc_iomux_v3_setup_multiple_pads(karo_tx25_fec_gpios_on, + ARRAY_SIZE(karo_tx25_fec_gpios_on)); + if (ret) { + mxc_iomux_v3_release_multiple_pads(karo_tx25_fec_pwr_gpios, + ARRAY_SIZE(karo_tx25_fec_pwr_gpios)); + return ret; + } + } else { + /* switch PHY strap pins into required state */ + ret = mxc_iomux_v3_setup_multiple_pads(karo_tx25_fec_gpios_off, + ARRAY_SIZE(karo_tx25_fec_gpios_off)); + if (ret) { + mxc_iomux_v3_release_multiple_pads(karo_tx25_fec_pwr_gpios, + ARRAY_SIZE(karo_tx25_fec_pwr_gpios)); + return ret; + } + DBG(0, "%s: Switching FEC PHY power on\n", __FUNCTION__); + //gpio_set_value(TX25_FEC_PWR_GPIO, 1); +#if 0 + while (1) { + gpio_set_value(TX25_FEC_PWR_GPIO, 1); + mdelay(1000); + gpio_set_value(TX25_FEC_PWR_GPIO, 0); + mdelay(1000); + } +#endif + DBG(0, "%s: Asserting FEC PHY reset\n", __FUNCTION__); +// gpio_set_value(TX25_FEC_RST_GPIO, 0); + for (i = 0; i < ARRAY_SIZE(karo_tx25_fec_strap_gpios); i++) { + struct gpio_desc *pd = &karo_tx25_fec_strap_gpios[i]; + + ret = gpio_request(pd->gpio, "FEC"); + if (ret < 0) { + DBG(0, "%s: Failed to request GPIO%d_%d: %d\n", + __FUNCTION__, pd->gpio / 32 + 1, pd->gpio % 32, ret); + goto rel_mux; + } + if (pd->dir) { + gpio_direction_output(pd->gpio, + pd->level); + } else { + gpio_direction_input(pd->gpio); + } + } +#ifdef DEBUG + for (i = 0; i < ARRAY_SIZE(karo_tx25_fec_strap_gpios); i++) { + struct gpio_desc *pd = &karo_tx25_fec_strap_gpios[i]; + int grp = pd->gpio / 32 + 1; + int ofs = pd->gpio % 32; + + if (pd->dir && pd->level != gpio_get_value(pd->gpio)) { + DBG(0, "%s: GPIO%d_%d is %d instead of %d\n", __FUNCTION__, + grp, ofs, gpio_get_value(pd->gpio), + pd->level); + } + } +#endif + DBG(0, "%s: Delaying for 22ms\n", __FUNCTION__); + mdelay(22); + DBG(0, "%s: Deasserting FEC PHY reset\n", __FUNCTION__); + gpio_set_value(TX25_FEC_RST_GPIO, 1); +#ifdef DEBUG + for (i = 0; i < ARRAY_SIZE(karo_tx25_fec_strap_gpios); i++) { + struct gpio_desc *pd = &karo_tx25_fec_strap_gpios[i]; + int grp = pd->gpio / 32 + 1; + int ofs = pd->gpio % 32; + + DBG(0, "%s: GPIO%d_%d is %d\n", __FUNCTION__, + grp, ofs, gpio_get_value(pd->gpio)); + } +#endif + mxc_iomux_v3_release_multiple_pads(karo_tx25_fec_gpios_off, + ARRAY_SIZE(karo_tx25_fec_gpios_off)); + ret = mxc_iomux_v3_setup_multiple_pads(karo_tx25_fec_gpios_on, + ARRAY_SIZE(karo_tx25_fec_gpios_on)); + if (ret) { + goto rel_gpio; + } +#ifdef DEBUG + for (i = 0; i < ARRAY_SIZE(karo_tx25_fec_strap_gpios); i++) { + struct gpio_desc *pd = &karo_tx25_fec_strap_gpios[i]; + int grp = pd->gpio / 32 + 1; + int ofs = pd->gpio % 32; + + DBG(0, "%s: GPIO%d_%d is %d\n", __FUNCTION__, + grp, ofs, gpio_get_value(pd->gpio)); + } +#endif + } + return ret; + + rel_mux: + mxc_iomux_v3_release_multiple_pads(karo_tx25_fec_gpios_off, + ARRAY_SIZE(karo_tx25_fec_gpios_off)); + rel_gpio: + while (--i >= 0) { + struct gpio_desc *pd = &karo_tx25_fec_strap_gpios[i]; +#ifdef DEBUG + int grp = pd->gpio / 32 + 1; + int ofs = pd->gpio % 32; + + DBG(0, "%s: Freeing GPIO%d_%d\n", __FUNCTION__, + grp, ofs); +#endif + gpio_free(pd->gpio); + } + mxc_iomux_v3_release_multiple_pads(karo_tx25_fec_pwr_gpios, + ARRAY_SIZE(karo_tx25_fec_pwr_gpios)); + return ret; +} + +/* + * Setup GPIO for FEC device to be inactive + * + */ +static void gpio_fec_inactive(void) +{ + int i; + + mxc_iomux_v3_release_multiple_pads(karo_tx25_fec_gpios_on, + ARRAY_SIZE(karo_tx25_fec_gpios_on)); + mxc_iomux_v3_setup_multiple_pads(karo_tx25_fec_gpios_off, + ARRAY_SIZE(karo_tx25_fec_gpios_off)); + DBG(0, "%s: Asserting FEC PHY reset\n", __FUNCTION__); + gpio_set_value(TX25_FEC_RST_GPIO, 0); + DBG(0, "%s: Switching FEC PHY power off\n", __FUNCTION__); + gpio_set_value(TX25_FEC_PWR_GPIO, 0); + + mxc_iomux_v3_release_multiple_pads(karo_tx25_fec_gpios_off, + ARRAY_SIZE(karo_tx25_fec_gpios_off)); + mxc_iomux_v3_release_multiple_pads(karo_tx25_fec_pwr_gpios, + ARRAY_SIZE(karo_tx25_fec_pwr_gpios)); + for (i = 0; i < ARRAY_SIZE(karo_tx25_fec_strap_gpios); i++) { + struct gpio_desc *pd = &karo_tx25_fec_strap_gpios[i]; +#ifdef DEBUG + int grp = pd->gpio / 32 + 1; + int ofs = pd->gpio % 32; + + DBG(0, "%s: Freeing GPIO%d_%d\n", __FUNCTION__, + grp, ofs); +#endif + gpio_free(pd->gpio); + } +} + +static struct clk *tx25_fec_clk; + +static int tx25_fec_suspend(struct platform_device *pdev) +{ + BUG_ON(tx25_fec_clk == NULL); + DBG(1, "%s: Switching FEC PHY off\n", __FUNCTION__); + gpio_fec_inactive(); + clk_disable(tx25_fec_clk); + return 0; +} + +static int tx25_fec_resume(struct platform_device *pdev) +{ + BUG_ON(tx25_fec_clk == NULL); + DBG(1, "%s: Switching FEC PHY on\n", __FUNCTION__); + clk_enable(tx25_fec_clk); + gpio_fec_active(); + return 0; +} + +#if 0 +/* + * i.MX25 allows RMII mode to be configured via a gasket + */ +#define FEC_MIIGSK_CFGR_FRCONT (1 << 6) +#define FEC_MIIGSK_CFGR_LBMODE (1 << 4) +#define FEC_MIIGSK_CFGR_EMODE (1 << 3) +#define FEC_MIIGSK_CFGR_IF_MODE_MASK (3 << 0) +#define FEC_MIIGSK_CFGR_IF_MODE_MII (0 << 0) +#define FEC_MIIGSK_CFGR_IF_MODE_RMII (1 << 0) + +#define FEC_MIIGSK_ENR_READY (1 << 2) +#define FEC_MIIGSK_ENR_EN (1 << 1) + +#include "../arch/arm/mach-mx25/crm_regs.h" +static void __inline__ fec_localhw_setup(struct net_device *dev) +{ + struct fec_enet_private *fep = netdev_priv(dev); + + /* + * Set up the MII gasket for RMII mode + */ + printk("%s: enable RMII gasket\n", dev->name); + + /* disable the gasket and wait */ + fec_reg_write16(fep, FEC_MIIGSK_ENR, 0); + while (fec_reg_read16(fep, FEC_MIIGSK_ENR) & FEC_MIIGSK_ENR_READY) + udelay(1); + + /* configure the gasket for RMII, 50 MHz, no loopback, no echo */ + fec_reg_write16(fep, FEC_MIIGSK_CFGR, FEC_MIIGSK_CFGR_IF_MODE_RMII); + + /* re-enable the gasket */ + fec_reg_write16(fep, FEC_MIIGSK_ENR, FEC_MIIGSK_ENR_EN); + fec_reg_read16(fep, FEC_MIIGSK_CFGR); + fec_reg_read16(fep, FEC_MIIGSK_ENR); +} +#endif + +static int fec_arch_init(struct platform_device *pdev) +{ + int ret; + + DBG(0, "%s: Activating FEC GPIOs\n", __FUNCTION__); + dump_regs(); + + ret = gpio_fec_active(); + if (ret) { + printk(KERN_ERR "%s: could not enable FEC gpios: %d\n", __FUNCTION__, ret); + return ret; + } + + BUG_ON(tx25_fec_clk != NULL); + tx25_fec_clk = clk_get(&pdev->dev, NULL); + if (unlikely(IS_ERR(tx25_fec_clk))) { + printk(KERN_ERR "Failed to get fec_clk\n"); + return PTR_ERR(tx25_fec_clk); + } + DBG(0, "%s: Enabling FEC clock\n", __FUNCTION__); + clk_enable(tx25_fec_clk); + dump_regs(); + return 0; +} + +static void fec_arch_exit(struct platform_device *pdev) +{ + BUG_ON(tx25_fec_clk == NULL); + if (unlikely(IS_ERR(tx25_fec_clk))) { + printk(KERN_ERR "Failed to get fec_clk\n"); + return; + } + DBG(0, "%s: Disabling FEC clock\n", __FUNCTION__); + clk_disable(tx25_fec_clk); + clk_put(tx25_fec_clk); + tx25_fec_clk = NULL; + DBG(0, "%s: Deactivating FEC GPIOs\n", __FUNCTION__); + gpio_fec_inactive(); +} + +static struct fec_enet_platform_data fec_data = { + .arch_init = fec_arch_init, + .arch_exit = fec_arch_exit, + .suspend = tx25_fec_suspend, + .resume = tx25_fec_resume, +}; + +static struct platform_device fec_device = { + .name = "fec", + .id = 0, + .num_resources = ARRAY_SIZE(fec_resources), + .resource = fec_resources, + .dev = { + .platform_data = &fec_data, + .coherent_dma_mask = 0xFFFFFFFF, + }, +}; +#endif + +/* MTD NAND flash */ +#if defined(CONFIG_MTD_NAND_MXC) || defined(CONFIG_MTD_NAND_MXC_MODULE) +static struct pad_desc karo_tx25_nand_pads[] = { + MX25_PAD_NF_CE0__NF_CE0, + MX25_PAD_NFWE_B__NFWE_B, + MX25_PAD_NFRE_B__NFRE_B, + MX25_PAD_NFALE__NFALE, + MX25_PAD_NFCLE__NFCLE, + MX25_PAD_NFWP_B__NFWP_B, + MX25_PAD_NFRB__NFRB, + MX25_PAD_D7__D7, + MX25_PAD_D6__D6, + MX25_PAD_D5__D5, + MX25_PAD_D4__D4, + MX25_PAD_D3__D3, + MX25_PAD_D2__D2, + MX25_PAD_D1__D1, + MX25_PAD_D0__D0, +}; + +#ifdef CONFIG_ARCH_MXC_HAS_NFC_V2 +static struct mtd_partition tx25_nand_partitions[] = { + { + .name = "RedBoot", + .offset = 0, + .size = 0x00040000, + }, { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = 0x001A0000, + }, { + .name = "rootfs", + .offset = MTDPART_OFS_APPEND, + .size = 0x07E000000, + }, { + .name = "FIS directory", + .offset = MTDPART_OFS_APPEND, + .size = 0x00003000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "RedBoot config", + .offset = MTDPART_OFS_APPEND, + .size = 0x00001000, + .mask_flags = MTD_WRITEABLE, + }, +}; + +static int tx25_nand_init(void) +{ + int ret; + + DBG(0, "%s: Configuring NAND pins\n", __FUNCTION__); + ret = mxc_iomux_v3_setup_multiple_pads(karo_tx25_nand_pads, + ARRAY_SIZE(karo_tx25_nand_pads)); + if (ret) { + return ret; + } + return 0; +} + +static void tx25_nand_exit(void) +{ + mxc_iomux_v3_release_multiple_pads(karo_tx25_nand_pads, + ARRAY_SIZE(karo_tx25_nand_pads)); +} + +static struct flash_platform_data tx25_nand_data = { + .map_name = "nand_probe", + .name = "tx25-nand", + .parts = tx25_nand_partitions, + .nr_parts = ARRAY_SIZE(tx25_nand_partitions), + .width = 1, + .init = tx25_nand_init, + .exit = tx25_nand_exit, +}; +#else +static struct mxc_nand_platform_data tx25_nand_data = { + .hw_ecc = 1, + .width = 1, +}; + +static int tx25_nand_init(void) +{ + int ret; + + DBG(0, "%s: Configuring NAND pins\n", __FUNCTION__); + ret = mxc_iomux_v3_setup_multiple_pads(karo_tx25_nand_pads, + ARRAY_SIZE(karo_tx25_nand_pads)); + if (ret) { + return ret; + } + return 0; +} +arch_initcall(tx25_nand_init); +#endif + +static struct resource tx25_nand_resources[] = { + { + .start = NFC_BASE_ADDR + 0x1e00, + .end = NFC_BASE_ADDR + 0x1e2f, + .flags = IORESOURCE_MEM, + }, { + .start = NFC_BASE_ADDR, + .end = NFC_BASE_ADDR + 0x11ff, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_NANDFC, + .end = MXC_INT_NANDFC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device tx25_nand_mtd_device = { + .name = "mxc_nand", + .id = 0, + .num_resources = ARRAY_SIZE(tx25_nand_resources), + .resource = tx25_nand_resources, + .dev = { + .platform_data = &tx25_nand_data, + }, +}; +#endif + +#if defined(CONFIG_VIDEO_MXC_EMMA_OUTPUT) || defined(CONFIG_VIDEO_MXC_EMMA_OUTPUT_MODULE) +static u64 mxc_emma_dmamask = 0xffffffffUL; + +static struct platform_device tx25_v4l2out_device = { + .name = "MXC Video Output", + .id = 0, + .dev = { + .dma_mask = &mxc_emma_dmamask, + .coherent_dma_mask = ~0UL, + }, +}; +#endif + +#if 0 +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +static struct pad_desc mxc_i2c0_pins[] = { + /* + * it seems the data line misses a pullup, so we must enable + * the internal pullup as a local workaround + */ + MX25_PAD_I2C1_CLK__I2C1_CLK, + MX25_PAD_I2C1_DAT__I2C1_DAT, +}; + +static int karo_tx25_i2c_0_init(struct device *dev) +{ + DBG(-1, "%s: \n", __FUNCTION__); + return mxc_iomux_v3_setup_multiple_pads(mxc_i2c0_pins, + ARRAY_SIZE(mxc_i2c0_pins)); +} + +static void karo_tx25_i2c_0_exit(struct device *dev) +{ + DBG(-1, "%s: \n", __FUNCTION__); + mxc_iomux_v3_release_multiple_pads(mxc_i2c0_pins, + ARRAY_SIZE(mxc_i2c0_pins)); +} + +static struct imxi2c_platform_data karo_tx25_i2c_0_data = { + .bitrate = 100000, + .init = karo_tx25_i2c_0_init, + .exit = karo_tx25_i2c_0_exit, +}; + +static struct at24_platform_data karo_tx25_eeprom = { + .byte_len = 2048, + .page_size = 32, + .flags = AT24_FLAG_ADDR16 | AT24_FLAG_TAKE8ADDR, +}; + +static struct i2c_board_info karo_i2c_0_boardinfo[] __initdata = { + { + I2C_BOARD_INFO("24c16", 0x50), + .platform_data = &karo_tx25_eeprom, + .type = "24c16", + }, +}; + +int __init karo_i2c_init(void) +{ + int ret; + + DBG(0, "%s: Registering I2C bus 0\n", __FUNCTION__); + ret = mxc_register_device(&mx25_i2c_device0, &karo_tx25_i2c_0_data); + if (ret != 0) { + printk(KERN_ERR "Failed to register I2C device: %d\n", ret); + return ret; + } + ret = i2c_register_board_info(0, karo_i2c_0_boardinfo, + ARRAY_SIZE(karo_i2c_0_boardinfo)); + if (ret != 0) { + printk(KERN_ERR "Failed to register I2C board info: %d\n", ret); + } + return ret; +} +device_initcall(karo_i2c_init); +#endif +#endif + +struct platform_dev_list { + struct platform_device *pdev; + int flag; +} tx25_devices[] __initdata = { +#if defined(CONFIG_RTC_MXC) || defined(CONFIG_RTC_MXC_MODULE) + { .pdev = &mxc_rtc_device, .flag = -1, }, +#endif +#if defined(CONFIG_MTD_NAND_MXC) || defined(CONFIG_MTD_NAND_MXC_MODULE) + { .pdev = &tx25_nand_mtd_device, .flag = 1, }, +#endif +#if defined(CONFIG_FEC) || defined(CONFIG_FEC_MODULE) + { .pdev = &fec_device, .flag = 1, }, +#endif +#if defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE) + { .pdev = &mxcspi1_device, .flag = 1, }, +#endif +#if defined(CONFIG_VIDEO_MXC_EMMA_OUTPUT) || defined(CONFIG_VIDEO_MXC_EMMA_OUTPUT_MODULE) + { .pdev = &tx25_v4l2out_device, .flag = 1, }, +#endif +#if defined(CONFIG_MXC_VPU) || defined(CONFIG_MXC_VPU_MODULE) + { .pdev = &mxc_vpu_device, .flag = 1, }, +#endif +}; +#define TX25_NUM_DEVICES ARRAY_SIZE(tx25_devices) + +static __init void karo_tx25_board_init(void) +{ + int i; + + DBG(0, "%s: \n", __FUNCTION__); + + dump_regs(); + + for (i = 0; i < TX25_NUM_DEVICES; i++) { + int ret; + + if (tx25_devices[i].pdev == NULL) continue; + if (!tx25_devices[i].flag) { + DBG(0, "%s: Skipping platform device[%d] @ %p dev %p: %s\n", + __FUNCTION__, i, tx25_devices[i].pdev, &tx25_devices[i].pdev->dev, + tx25_devices[i].pdev->name); + continue; + } + DBG(0, "%s: Registering platform device[%d] @ %p dev %p: %s\n", + __FUNCTION__, i, tx25_devices[i].pdev, &tx25_devices[i].pdev->dev, + tx25_devices[i].pdev->name); + ret = platform_device_register(tx25_devices[i].pdev); + if (ret) { + printk(KERN_WARNING "%s: Failed to register platform_device[%d]: %s: %d\n", + __FUNCTION__, i, tx25_devices[i].pdev->name, ret); + } + } + DBG(0, "%s: Done\n", __FUNCTION__); +} + +static struct pad_desc karo_tx25_gpios[] __initdata = { + MX25_PAD_GPIO_A__GPIO_A, + MX25_PAD_GPIO_B__GPIO_B, + MX25_PAD_GPIO_C__GPIO_C, + MX25_PAD_GPIO_D__GPIO_D, + MX25_PAD_GPIO_E__GPIO_E, + MX25_PAD_GPIO_F__GPIO_F, + MX25_PAD_CSI_D7__GPIO_1_6, + MX25_PAD_CSI_D8__GPIO_1_7, + MX25_PAD_CSI_MCLK__GPIO_1_8, + MX25_PAD_CSI_VSYNC__GPIO_1_9, + MX25_PAD_CSI_HSYNC__GPIO_1_10, + MX25_PAD_CSI_PIXCLK__GPIO_1_11, + MX25_PAD_I2C1_CLK__GPIO_1_12, + MX25_PAD_I2C1_DAT__GPIO_1_13, + MX25_PAD_CSPI1_MOSI__GPIO_1_14, + MX25_PAD_CSPI1_MISO__GPIO_1_15, + MX25_PAD_CSPI1_SS0__GPIO_1_16, + MX25_PAD_CSPI1_SS1__GPIO_1_17, + MX25_PAD_CSPI1_SCLK__GPIO_1_18, + MX25_PAD_LD5__GPIO_1_19, + MX25_PAD_LD6__GPIO_1_20, + MX25_PAD_LD7__GPIO_1_21, + MX25_PAD_HSYNC__GPIO_1_22, + MX25_PAD_VSYNC__GPIO_1_23, + MX25_PAD_LSCLK__GPIO_1_24, + MX25_PAD_OE_ACD__GPIO_1_25, + MX25_PAD_PWM__GPIO_1_26, + MX25_PAD_CSI_D2__GPIO_1_27, + MX25_PAD_CSI_D3__GPIO_1_28, + MX25_PAD_CSI_D4__GPIO_1_29, + MX25_PAD_CSI_D5__GPIO_1_30, + MX25_PAD_CSI_D6__GPIO_1_31, + + MX25_PAD_A14__GPIO_2_0, + MX25_PAD_A15__GPIO_2_1, + MX25_PAD_A16__GPIO_2_2, + MX25_PAD_A17__GPIO_2_3, + MX25_PAD_A18__GPIO_2_4, + MX25_PAD_A19__GPIO_2_5, + MX25_PAD_A20__GPIO_2_6, + MX25_PAD_A21__GPIO_2_7, + MX25_PAD_A22__GPIO_2_8, + MX25_PAD_A23__GPIO_2_9, + MX25_PAD_A24__GPIO_2_10, + MX25_PAD_A25__GPIO_2_11, + MX25_PAD_EB0__GPIO_2_12, + MX25_PAD_EB1__GPIO_2_13, + MX25_PAD_OE__GPIO_2_14, + MX25_PAD_LD0__GPIO_2_15, + MX25_PAD_LD1__GPIO_2_16, + MX25_PAD_LD2__GPIO_2_17, + MX25_PAD_LD3__GPIO_2_18, + MX25_PAD_LD4__GPIO_2_19, + MX25_PAD_DE_B__GPIO_2_20, + MX25_PAD_CLKO__GPIO_2_21, + MX25_PAD_CSPI1_RDY__GPIO_2_22, + MX25_PAD_SD1_CMD__GPIO_2_23, + MX25_PAD_SD1_CLK__GPIO_2_24, + MX25_PAD_SD1_DATA0__GPIO_2_25, + MX25_PAD_SD1_DATA1__GPIO_2_26, + MX25_PAD_SD1_DATA2__GPIO_2_27, + MX25_PAD_SD1_DATA3__GPIO_2_28, + MX25_PAD_KPP_ROW0__GPIO_2_29, + MX25_PAD_KPP_ROW1__GPIO_2_30, + MX25_PAD_KPP_ROW2__GPIO_2_31, + + MX25_PAD_KPP_ROW3__GPIO_3_0, + MX25_PAD_KPP_COL0__GPIO_3_1, + MX25_PAD_KPP_COL1__GPIO_3_2, + MX25_PAD_KPP_COL2__GPIO_3_3, + MX25_PAD_KPP_COL3__GPIO_3_4, + MX25_PAD_FEC_MDC__GPIO_3_5, + MX25_PAD_FEC_MDIO__GPIO_3_6, + MX25_PAD_FEC_TDATA0__GPIO_3_7, + MX25_PAD_FEC_TDATA1__GPIO_3_8, + MX25_PAD_FEC_TX_EN__GPIO_3_9, + MX25_PAD_FEC_RDATA0__GPIO_3_10, + MX25_PAD_FEC_RDATA1__GPIO_3_11, + MX25_PAD_FEC_RX_DV__GPIO_3_12, + MX25_PAD_FEC_TX_CLK__GPIO_3_13, + MX25_PAD_RTCK__GPIO_3_14, + MX25_PAD_EXT_ARMCLK__GPIO_3_15, + MX25_PAD_UPLL_BYPCLK__GPIO_3_16, + MX25_PAD_VSTBY_REQ__GPIO_3_17, + MX25_PAD_VSTBY_ACK__GPIO_3_18, + MX25_PAD_POWER_FAIL__GPIO_3_19, + MX25_PAD_CS4__GPIO_3_20, + MX25_PAD_CS5__GPIO_3_21, + MX25_PAD_NF_CE0__GPIO_3_22, + MX25_PAD_ECB__GPIO_3_23, + MX25_PAD_LBA__GPIO_3_24, + MX25_PAD_RW__GPIO_3_25, + MX25_PAD_NFWE_B__GPIO_3_26, + MX25_PAD_NFRE_B__GPIO_3_27, + MX25_PAD_NFALE__GPIO_3_28, + MX25_PAD_NFCLE__GPIO_3_29, + MX25_PAD_NFWP_B__GPIO_3_30, + MX25_PAD_NFRB__GPIO_3_31, + + MX25_PAD_A10__GPIO_4_0, + MX25_PAD_A13__GPIO_4_1, + MX25_PAD_CS0__GPIO_4_2, + MX25_PAD_CS1__GPIO_4_3, + MX25_PAD_BCLK__GPIO_4_4, + MX25_PAD_D15__GPIO_4_5, + MX25_PAD_D14__GPIO_4_6, + MX25_PAD_D13__GPIO_4_7, + MX25_PAD_D12__GPIO_4_8, + MX25_PAD_D11__GPIO_4_9, + MX25_PAD_D10__GPIO_4_10, + MX25_PAD_D9__GPIO_4_11, + MX25_PAD_D8__GPIO_4_12, + MX25_PAD_D7__GPIO_4_13, + MX25_PAD_D6__GPIO_4_14, + MX25_PAD_D5__GPIO_4_15, + MX25_PAD_D4__GPIO_4_16, + MX25_PAD_D3__GPIO_4_17, + MX25_PAD_D2__GPIO_4_18, + MX25_PAD_D1__GPIO_4_19, + MX25_PAD_D0__GPIO_4_20, + MX25_PAD_CSI_D9__GPIO_4_21, + MX25_PAD_UART1_RXD__GPIO_4_22, + MX25_PAD_UART1_TXD__GPIO_4_23, + MX25_PAD_UART1_RTS__GPIO_4_24, + MX25_PAD_UART1_CTS__GPIO_4_25, + MX25_PAD_UART2_RXD__GPIO_4_26, + MX25_PAD_UART2_TXD__GPIO_4_27, + MX25_PAD_UART2_RTS__GPIO_4_28, + MX25_PAD_UART2_CTS__GPIO_4_29, + MX25_PAD_BOOT_MODE0__GPIO_4_30, + MX25_PAD_BOOT_MODE1__GPIO_4_31, +}; + +static int __init karo_tx25_setup_gpios(void) +{ + int i; + int ret; + int count = 0; + + for (i = 0; i < ARRAY_SIZE(karo_tx25_gpios); i++) { + struct pad_desc *pd = &karo_tx25_gpios[i]; +#if 0 + if (i - 64 >= 16 && i - 64 < 32) { + continue; + } +#endif + ret = mxc_iomux_v3_setup_pad(pd); + if (ret == 0) { +#ifdef IOMUX_DEBUG + DBG(0, "%s: PAD[%d] %s set up as GPIO\n", __FUNCTION__, i, pd->name); +#else + DBG(0, "%s: PAD[%d] set up as GPIO\n", __FUNCTION__, i); +#endif + count++; + mxc_iomux_v3_release_pad(pd); + } else { +#ifdef IOMUX_DEBUG + DBG(0, "%s: PAD[%d] %s skipped\n", __FUNCTION__, i, pd->name); +#else + DBG(0, "%s: PAD[%d] skipped\n", __FUNCTION__, i); +#endif + } + } + DBG(0, "%s: %d out of %d pins set up as GPIO\n", __FUNCTION__, count, i); +#if 0 + if (gpio_request(42, "TEST") == 0) { + gpio_direction_output(42, 1); + while (1) { + gpio_set_value(42, 0); + if (gpio_get_value(42)) { + DBG(0, "%s: GPIO 42 is HIGH instead of LOW\n", __FUNCTION__); + } + msleep(1000); + gpio_set_value(42, 1); + if (!gpio_get_value(42)) { + DBG(0, "%s: GPIO 42 is LOW instead of HIGH\n", __FUNCTION__); + } + msleep(1000); + } + } + gpio_free(42); +#endif + return 0; +} +late_initcall(karo_tx25_setup_gpios); + +static void __init karo_tx25_map_io(void) +{ + mx25_map_io(); +} + +static void __init karo_tx25_fixup(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ +} + +static void __init karo_tx25_timer_init(void) +{ + DBG(0, "%s: \n", __FUNCTION__); + mx25_clocks_init(24000000); + DBG(0, "%s: Done\n", __FUNCTION__); +} + +struct sys_timer karo_tx25_timer = { + .init = karo_tx25_timer_init, +}; + +static int __init karo_mod_type_setup(char *line) +{ + get_option(&line, &karo_mod_type); + DBG(0, "%s: Module type set to 0x%02x by kernel cmd line\n", __FUNCTION__, karo_mod_type); + + return 1; +} +__setup("module_type=", karo_mod_type_setup); + +static int __init karo_board_type_setup(char *line) +{ + get_option(&line, &karo_board_type); + DBG(0, "%s: Board type set to 0x%02x by kernel cmd line\n", __FUNCTION__, karo_board_type); + + return 1; +} +__setup("board_type=", karo_board_type_setup); + +MACHINE_START(TX25, "Ka-Ro electronics TX25 module (Freescale i.MX25)") + /* Maintainer: */ + .phys_io = AIPS1_BASE_ADDR, + .io_pg_offst = ((unsigned long)AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc, + .fixup = karo_tx25_fixup, + .map_io = karo_tx25_map_io, + .init_irq = mxc_init_irq, + .init_machine = karo_tx25_board_init, + .timer = &karo_tx25_timer, +MACHINE_END diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/karo.h linux-2.6.30-rc4-karo/arch/arm/mach-mx2/karo.h --- linux-2.6.30-rc4/arch/arm/mach-mx2/karo.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/karo.h 2009-06-02 17:59:18.000000000 +0200 @@ -0,0 +1,99 @@ +/* + * arch/arm/mach-mx2/karo.h + * + * Copyright (C) 2009 Lothar Wassmann + * + * 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 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * + * This file provides platform specific definitions for the + * Ka-Ro electronics TX25 processor modules + */ + +#include +#include "crm_regs_mx25.h" + +enum { + BOARD_KARO_STK5, +}; + +extern int karo_board_type; +extern int karo_mod_type; + +#ifdef DEBUG +extern int tx25_debug; +#define dbg_lvl(n) ((n) < tx25_debug) +#define DBG(lvl, fmt...) do { if (dbg_lvl(lvl)) printk(KERN_DEBUG fmt); } while (0) +#else +#define dbg_lvl(n) 0 +#define DBG(lvl, fmt...) do { } while (0) +#endif + +static inline int karo_get_board_type(void) +{ + return karo_board_type; +} + +static inline int karo_get_module_type(void) +{ + return karo_mod_type; +} + +#define SHOW_REG(reg) DBG(0, "%s[%08lx]=%08x\n", #reg, MXC_PHYS_ADDRESS(reg), __raw_readl(reg)) + +#define SHOW_GPIO_REG(port, reg) \ + DBG(0, "GPIO%d_%s[%08lx]=%08x\n", port, #reg, \ + GPIO_BASE_ADDR(port) + GPIO_##reg, \ + __raw_readl(IO_ADDRESS(GPIO_BASE_ADDR(port) + GPIO_##reg))) + +static inline void dump_regs(void) +{ + int i; + + SHOW_REG(MXC_CCM_MPCTL); + SHOW_REG(MXC_CCM_UPCTL); + SHOW_REG(MXC_CCM_CCTL); + SHOW_REG(MXC_CCM_RCSR); + SHOW_REG(MXC_CCM_CRDR); + SHOW_REG(MXC_CCM_PCDR0); + SHOW_REG(MXC_CCM_PCDR1); + SHOW_REG(MXC_CCM_PCDR2); + SHOW_REG(MXC_CCM_PCDR3); + SHOW_REG(MXC_CCM_CGCR0); + SHOW_REG(MXC_CCM_CGCR1); + SHOW_REG(MXC_CCM_CGCR2); + SHOW_REG(MXC_CCM_MCR); + SHOW_REG(MXC_CCM_PMCR0); + SHOW_REG(MXC_CCM_PMCR1); + SHOW_REG(MXC_CCM_PMCR2); + SHOW_REG(MXC_CCM_LTBR0); + SHOW_REG(MXC_CCM_LTBR1); + SHOW_REG(MXC_CCM_LTR0); + SHOW_REG(MXC_CCM_LTR1); + SHOW_REG(MXC_CCM_LTR2); + SHOW_REG(MXC_CCM_LTR3); + SHOW_REG(MXC_CCM_DCVR0); + SHOW_REG(MXC_CCM_DCVR1); + SHOW_REG(MXC_CCM_DCVR2); + SHOW_REG(MXC_CCM_DCVR3); + + for (i = 1; i <= 4; i++) { + SHOW_GPIO_REG(i, DR); + SHOW_GPIO_REG(i, GDIR); + SHOW_GPIO_REG(i, PSR); + SHOW_GPIO_REG(i, ICR1); + SHOW_GPIO_REG(i, ICR2); + SHOW_GPIO_REG(i, IMR); + SHOW_GPIO_REG(i, ISR); + } +} diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/sdma_script_code.h linux-2.6.30-rc4-karo/arch/arm/mach-mx2/sdma_script_code.h --- linux-2.6.30-rc4/arch/arm/mach-mx2/sdma_script_code.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/sdma_script_code.h 2009-06-02 17:59:18.000000000 +0200 @@ -0,0 +1,159 @@ + +/* + * Copyright 2008 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 + */ + +/*! + * @file sdma_script_code.h + * @brief This file contains functions of SDMA scripts code initialization + * + * The file was generated automatically. Based on sdma scripts library. + * + * @ingroup SDMA + */ +/************************************************************************ + + SDMA RELEASE LABEL: "SS15_SENNA" + +************************************************************************/ + +#ifndef SDMA_SCRIPT_CODE_H +#define SDMA_SCRIPT_CODE_H + +/*! + * SDMA ROM scripts start addresses and sizes + */ +#define start_ADDR 0 +#define start_SIZE 22 + +#define core_ADDR 80 +#define core_SIZE 233 + +#define common_ADDR 313 +#define common_SIZE 416 + +#define ap_2_ap_ADDR 729 +#define ap_2_ap_SIZE 41 + +#define app_2_mcu_ADDR 770 +#define app_2_mcu_SIZE 64 + +#define mcu_2_app_ADDR 834 +#define mcu_2_app_SIZE 70 + +#define uart_2_mcu_ADDR 904 +#define uart_2_mcu_SIZE 75 + +#define shp_2_mcu_ADDR 979 +#define shp_2_mcu_SIZE 69 + +#define mcu_2_shp_ADDR 1048 +#define mcu_2_shp_SIZE 72 + +#define uartsh_2_mcu_ADDR 1120 +#define uartsh_2_mcu_SIZE 69 + +#define app_2_per_ADDR 1189 +#define app_2_per_SIZE 66 + +#define per_2_app_ADDR 1255 +#define per_2_app_SIZE 74 + +#define per_2_shp_ADDR 1329 +#define per_2_shp_SIZE 78 + +#define shp_2_per_ADDR 1407 +#define shp_2_per_SIZE 72 + +#define mcu_2_ata_ADDR 1479 +#define mcu_2_ata_SIZE 81 + +#define ata_2_mcu_ADDR 1560 +#define ata_2_mcu_SIZE 96 + +#define loop_DMAs_routines_ADDR 1656 +#define loop_DMAs_routines_SIZE 227 + +#define test_ADDR 1883 +#define test_SIZE 63 + +#define signature_ADDR 1022 +#define signature_SIZE 1 + +/*! + * SDMA RAM scripts start addresses and sizes + */ +#define ext_mem__ipu_ram_ADDR 6144 +#define ext_mem__ipu_ram_SIZE 123 + +#define uart_2_per_ADDR 6267 +#define uart_2_per_SIZE 73 + +#define uartsh_2_per_ADDR 6340 +#define uartsh_2_per_SIZE 67 + +/*! + * SDMA RAM image start address and size + */ +#define RAM_CODE_START_ADDR 6144 +#define RAM_CODE_SIZE 263 + +/*! + * Buffer that holds the SDMA RAM image + */ +__attribute__ ((__aligned__(4))) +#ifndef CONFIG_XIP_KERNEL +const +#endif +static const short sdma_code[] = { + 0x0e70, 0x0611, 0x5616, 0xc18a, 0x7d2a, 0x5ade, 0x008e, 0xc19c, + 0x7c26, 0x5be0, 0x5ef0, 0x5ce8, 0x0688, 0x08ff, 0x0011, 0x28ff, + 0x00bc, 0x53f6, 0x05df, 0x7d0b, 0x6dc5, 0x03df, 0x7d03, 0x6bd5, + 0xd84f, 0x982b, 0x6b05, 0xc6d8, 0x7e27, 0x7f29, 0x982b, 0x6d01, + 0x03df, 0x7d05, 0x6bd5, 0xc702, 0x7e18, 0x7f1a, 0x982b, 0x6b05, + 0xc678, 0x7e07, 0x7f06, 0x52de, 0x53e6, 0xc1a8, 0x7dd7, 0x0200, + 0x9803, 0x0007, 0x6004, 0x680c, 0x53f6, 0x028e, 0x00a3, 0xc2ad, + 0x048b, 0x0498, 0x0454, 0x068a, 0x982b, 0x0207, 0x680c, 0x6ddf, + 0x0107, 0x68ff, 0x60d0, 0x9834, 0x0207, 0x68ff, 0x6d28, 0x0107, + 0x6004, 0x680c, 0x9834, 0x0007, 0x68ff, 0x60d0, 0x9834, 0x0288, + 0x03a5, 0x3b03, 0x3d03, 0x4d00, 0x7d0a, 0x0804, 0x00a5, 0x00da, + 0x7d1a, 0x02a0, 0x7b01, 0x65d8, 0x7eee, 0x65ff, 0x7eec, 0x0804, + 0x02d0, 0x7d11, 0x4b00, 0x7c0f, 0x008a, 0x3003, 0x6dcf, 0x6bdf, + 0x0015, 0x0015, 0x7b02, 0x65d8, 0x0000, 0x7edd, 0x63ff, 0x7edb, + 0x3a03, 0x6dcd, 0x6bdd, 0x008a, 0x7b02, 0x65d8, 0x0000, 0x7ed3, + 0x65ff, 0x7ed1, 0x0006, 0xc23a, 0x57db, 0x52f3, 0x6ad5, 0x56fb, + 0x028e, 0x1a94, 0x6ac3, 0x62c8, 0x0269, 0x7d1e, 0x1e94, 0x6ee3, + 0x62d0, 0x5aeb, 0x62c8, 0x0248, 0x6ed3, 0x6ac8, 0x2694, 0x52eb, + 0x6ad5, 0x6ee3, 0x62c8, 0x026e, 0x7d27, 0x6ac8, 0x7f23, 0x2501, + 0x4d00, 0x7d26, 0x028e, 0x1a98, 0x6ac3, 0x62c8, 0x6ec3, 0x0260, + 0x7df1, 0x62d0, 0xc2d1, 0x98c0, 0x6ee3, 0x008f, 0x2001, 0x00d5, + 0x7d01, 0x008d, 0x05a0, 0x62c8, 0x026e, 0x7d0e, 0x6ac8, 0x7f0a, + 0x2001, 0x7cf9, 0x6add, 0x7f06, 0x0000, 0x4d00, 0x7d09, 0xc251, + 0x57db, 0x987f, 0x0007, 0x6aff, 0x62d0, 0xc2d1, 0x0458, 0x0454, + 0x6add, 0x7ff8, 0xc261, 0x987c, 0xc230, 0xc23a, 0x57db, 0x52f3, + 0x6ad5, 0x56fb, 0x028e, 0x1a94, 0x5202, 0x0269, 0x7d17, 0x1e94, + 0x5206, 0x0248, 0x5a06, 0x2694, 0x5206, 0x026e, 0x7d26, 0x6ac8, + 0x7f22, 0x2501, 0x4d00, 0x7d27, 0x028e, 0x1a98, 0x5202, 0x0260, + 0x7df3, 0x6add, 0x7f18, 0x62d0, 0xc2d1, 0x9903, 0x008f, 0x2001, + 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x5206, 0x026e, 0x7d0e, 0x6ac8, + 0x7f0a, 0x2001, 0x7cf9, 0x6add, 0x7f06, 0x0000, 0x4d00, 0x7d0b, + 0xc251, 0x57db, 0x98c9, 0x0007, 0x6aff, 0x6add, 0x7ffc, 0x62d0, + 0xc2d1, 0x0458, 0x0454, 0x6add, 0x7ff6, 0xc261, 0x98c6 +}; +#endif diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx2/stk5-baseboard.c linux-2.6.30-rc4-karo/arch/arm/mach-mx2/stk5-baseboard.c --- linux-2.6.30-rc4/arch/arm/mach-mx2/stk5-baseboard.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30-rc4-karo/arch/arm/mach-mx2/stk5-baseboard.c 2009-06-02 17:59:18.000000000 +0200 @@ -0,0 +1,1003 @@ +/* + * arch/arm/mach-mx2/stk5-baseboard.c + * + * Copyright (C) 2009 Lothar Wassmann + * + * + * 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 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * + * This file adds support for devices found on Ka-Ro electronics + * Starterkit-5 (STK5) baseboard + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +//#include +//#include +#include + +#include "crm_regs.h" +#include "devices.h" +#include "karo.h" + +#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE) +static struct pad_desc stk5_uart_pads[][4] = { + { + MX25_PAD_UART1_TXD__UART1_TXD, + MX25_PAD_UART1_RXD__UART1_RXD, + MX25_PAD_UART1_CTS__UART1_CTS, + MX25_PAD_UART1_RTS__UART1_RTS, + }, { + MX25_PAD_UART2_TXD__UART2_TXD, + MX25_PAD_UART2_RXD__UART2_RXD, + MX25_PAD_UART2_CTS__UART2_CTS, + MX25_PAD_UART2_RTS__UART2_RTS, + }, { + MX25_PAD_ECB__UART5_TXD_MUX, + MX25_PAD_LBA__UART5_RXD_MUX, + MX25_PAD_CS4__UART5_CTS, + MX25_PAD_CS5__UART5_RTS, +#if 0 + }, { + MX25_PAD_UART4_TXD__UART4_TXD, + MX25_PAD_UART4_RXD__UART4_RXD, + MX25_PAD_UART4_CTS__UART4_CTS, + MX25_PAD_UART4_RTS__UART4_RTS, + }, { + MX25_PAD_UART5_TXD__UART5_TXD, + MX25_PAD_UART5_RXD__UART5_RXD, + MX25_PAD_UART5_CTS__UART5_CTS, + MX25_PAD_UART5_RTS__UART5_RTS, +#endif + }, +}; + +static int stk5_uart_init(struct platform_device *pdev) +{ + DBG(0, "%s: \n", __FUNCTION__); + return mxc_iomux_v3_setup_multiple_pads(stk5_uart_pads[pdev->id], + ARRAY_SIZE(stk5_uart_pads[pdev->id])); +} + +static void stk5_uart_exit(struct platform_device *pdev) +{ + DBG(0, "%s: \n", __FUNCTION__); + mxc_iomux_v3_release_multiple_pads(stk5_uart_pads[pdev->id], + ARRAY_SIZE(stk5_uart_pads[pdev->id])); +} + +static struct imxuart_platform_data stk5_uart_ports[] = { + { + .init = stk5_uart_init, + .exit = stk5_uart_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, { + .init = stk5_uart_init, + .exit = stk5_uart_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, { + .init = stk5_uart_init, + .exit = stk5_uart_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, { + .init = stk5_uart_init, + .exit = stk5_uart_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, { + .init = stk5_uart_init, + .exit = stk5_uart_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, { + .init = stk5_uart_init, + .exit = stk5_uart_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, +}; + +static struct platform_device *stk5_uart_devices[] = { +#if UART1_ENABLED + &mxc_uart_device0, +#endif +#if UART2_ENABLED + &mxc_uart_device1, +#endif +#if UART3_ENABLED + &mxc_uart_device2, +#endif +#if UART4_ENABLED + &mxc_uart_device3, +#endif +#if UART5_ENABLED + &mxc_uart_device4, +#endif +}; + +static void __init karo_stk5_serial_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(stk5_uart_devices); i++) { + int ret; + int port = stk5_uart_devices[i]->id; + + DBG(0, "%s: Registering platform device[%d] @ %p dev %p: %s\n", + __FUNCTION__, i, stk5_uart_devices[i], + &stk5_uart_devices[i]->dev, stk5_uart_devices[i]->name); + ret = mxc_register_device(stk5_uart_devices[i], + &stk5_uart_ports[port]); + if (ret != 0) { + printk(KERN_WARNING "%s: Failed to register platform_device[%d]: %s: %d\n", + __FUNCTION__, i, stk5_uart_devices[i]->name, ret); + } + } +} +#else +static void __init karo_stk5_serial_init(void) +{ +} +#endif + +#ifdef CONFIG_USB_EHCI_MXC + +#define SMSC_VENDOR_ID 0x0424 +#define USB3317_PROD_ID 0x0006 +#define ULPI_FCTL 7 + +static inline const char *ulpi_name(void __iomem *view) +{ + if ((unsigned long)view & 0x400) { + return "USBH2"; + } else { + return "USBOTG"; + } +} + +static int usb3317_init(void __iomem *view) +{ + int vid, pid, ret; + + ret = ulpi_read(ISP1504_VID_HIGH, view); + if (ret < 0) { + goto err; + } + vid = ret << 8; + + ret = ulpi_read(ISP1504_VID_LOW, view); + if (ret < 0) { + goto err; + } + vid |= ret; + + ret = ulpi_read(ISP1504_PID_HIGH, view); + if (ret < 0) { + goto err; + } + pid = ret << 8; + + ret = ulpi_read(ISP1504_PID_LOW, view); + if (ret < 0) { + goto err; + } + pid |= ret; + + pr_info("ULPI on %s port Vendor ID 0x%x Product ID 0x%x\n", + ulpi_name(view), vid, pid); + if (vid != SMSC_VENDOR_ID || pid != USB3317_PROD_ID) { + pr_err("No USB3317 found\n"); + return -ENODEV; + } + err: + if (ret < 0) { + printk(KERN_ERR "ULPI read on %s port failed with error %d\n", + ulpi_name(view), ret); + return ret; + } + return 0; +} + +static int usb3317_set_vbus_power(void __iomem *view, int on) +{ + int ret; + + DBG(0, "%s: Switching %s port VBUS power %s\n", __FUNCTION__, + ulpi_name(view), on ? "on" : "off"); + + if (on) { + ret = ulpi_set(DRV_VBUS_EXT | /* enable external Vbus */ + DRV_VBUS | /* enable internal Vbus */ + CHRG_VBUS, /* charge Vbus */ + ISP1504_OTGCTL, view); + } else { + ret = ulpi_clear(DRV_VBUS_EXT | /* disable external Vbus */ + DRV_VBUS, /* disable internal Vbus */ + ISP1504_OTGCTL, view); + if (ret == 0) { + ret = ulpi_set(DISCHRG_VBUS, /* discharge Vbus */ + ISP1504_OTGCTL, view); + } + } + if (ret < 0) { + printk(KERN_ERR "ULPI read on %s port failed with error %d\n", + ulpi_name(view), ret); + return ret; + } + return 0; +} + +static int stk5_usbh2_init(struct platform_device *pdev) +{ + int ret; + u32 temp; + unsigned long flags; + void __iomem *view = IO_ADDRESS(OTG_BASE_ADDR + 0x570); + + local_irq_save(flags); + temp = readl(IO_ADDRESS(OTG_BASE_ADDR) + 0x600); + temp &= ~((3 << 21) | (1 << 0)); + temp |= (1 << 5) | (1 << 16) | (1 << 19) | (1 << 20); + writel(temp, IO_ADDRESS(OTG_BASE_ADDR) + 0x600); + local_irq_restore(flags); + + /* select ULPI transceiver */ + /* this must be done _before_ setting up the GPIOs! */ + temp = readl(view + 0x14); + DBG(0, "%s: Changing USBH2_PORTSC1 from %08x to %08x\n", __FUNCTION__, + temp, (temp & ~(3 << 30)) | (2 << 30)); + temp &= ~(3 << 30); + temp |= 2 << 30; + writel(temp, view + 0x14); + + /* Set to Host mode */ + temp = readl(view + 0x38); + DBG(0, "%s: Changing USBH2_USBMODE from %08x to %08x\n", __FUNCTION__, + temp, temp | 3); + writel(temp | 0x3, view + 0x38); + + ret = gpio_usbh2_active(); + if (ret != 0) { + return ret; + } + + ret = usb3317_init(view); + if (ret != 0) { + goto err; + } + ret = usb3317_set_vbus_power(view, 1); + if (ret != 0) { + goto err; + } + return 0; + + err: + gpio_usbh2_inactive(); + return ret; +} + +static int stk5_usbh2_exit(struct platform_device *pdev) +{ + gpio_usbh2_inactive(); + return 0; +} + +static struct mxc_usbh_platform_data stk5_usbh2_data = { + .init = stk5_usbh2_init, + .exit = stk5_usbh2_exit, +}; + +static int __init karo_stk5_usbh2_register(void) +{ + int ret; + + ret = mxc_register_device(&mxc_ehci2, &stk5_usbh2_data); + return ret; +} +#else +static inline int karo_stk5_usbh2_register(void) +{ + return 0; +} +#endif // CONFIG_USB_EHCI_MXC + +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +static struct gpio_led stk5_leds[] = { + { + .name = "GPIO-LED", + .default_trigger = "heartbeat", + .gpio = GPIO_PORTB | 7, + }, +}; + +static struct gpio_led_platform_data stk5_led_data = { + .leds = stk5_leds, + .num_leds = ARRAY_SIZE(stk5_leds), +}; + +static struct platform_device stk5_led_device = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &stk5_led_data, + }, +}; +#endif + +#if defined(CONFIG_KEYBOARD_MXC) || defined(CONFIG_KEYBOARD_MXC_MODULE) +/*! + * This array is used for mapping mx25 ADS keypad scancodes to input keyboard + * keycodes. + */ +static u16 stk5_kpd_keycodes[] = { + KEY_POWER, +}; + +static struct keypad_data stk5_keypad = { + .rowmax = 1, + .colmax = 1, + .irq = MXC_INT_KPP, + .learning = 0, + //.delay = 2, /* unused in the driver! */ + .matrix = stk5_kpd_keycodes, +}; + +static struct resource stk5_kpp_resources[] = { + { + .start = MXC_INT_KPP, + .end = MXC_INT_KPP, + .flags = IORESOURCE_IRQ, + }, +}; + +/* stk5 keypad driver */ +static struct platform_device stk5_keypad_device = { + .name = "mxc_keypad", + .id = 0, + .num_resources = ARRAY_SIZE(stk5_kpp_resources), + .resource = stk5_kpp_resources, + .dev = { + .platform_data = &stk5_keypad, + }, +}; +#endif + +#if defined(CONFIG_FB_IMX) || defined(CONFIG_FB_IMX_MODULE) +/* + * Setup GPIO for LCDC device to be active + * + */ +static struct pad_desc mx25_lcdc_gpios[] = { +#if 0 + MXC_PIN(A, 30, GPIO, GPIO_OUT | GPIO_DFLT_LOW), /* PA30 */ + MXC_PIN(A, 25, GPIO, GPIO_OUT | GPIO_DFLT_LOW), /* PA25 */ + MXC_PIN(A, 26, GPIO, GPIO_OUT | GPIO_DFLT_LOW), /* PA26 */ + MXC_PIN(A, 24, GPIO, GPIO_OUT | GPIO_DFLT_LOW), /* PA24 */ + MXC_PIN(A, 27, GPIO, GPIO_OUT | GPIO_DFLT_LOW), /* PA27 */ +#endif + MX25_PAD_LSCLK__LSCLK, + MX25_PAD_LD0__LD0, + MX25_PAD_LD1__LD1, + MX25_PAD_LD2__LD2, + MX25_PAD_LD3__LD3, + MX25_PAD_LD4__LD4, + MX25_PAD_LD5__LD5, + MX25_PAD_LD6__LD6, + MX25_PAD_LD7__LD7, + MX25_PAD_LD8__LD8, + MX25_PAD_LD9__LD9, + MX25_PAD_LD10__LD10, + MX25_PAD_LD11__LD11, + MX25_PAD_LD12__LD12, + MX25_PAD_LD13__LD13, + MX25_PAD_LD14__LD14, + MX25_PAD_LD15__LD15, + MX25_PAD_D15__LD16, + MX25_PAD_D14__LD17, + MX25_PAD_HSYNC__HSYNC, + MX25_PAD_VSYNC__VSYNC, + MX25_PAD_OE_ACD__OE_ACD, +}; + +static int stk5_gpio_lcdc_active(struct platform_device *dev) +{ + int ret; + + DBG(0, "%s: Setting up GPIO pins for LCD\n", __FUNCTION__); + ret = mxc_iomux_v3_setup_multiple_pads(mx25_lcdc_gpios, + ARRAY_SIZE(mx25_lcdc_gpios)); + if (ret) { + DBG(0, "%s: Failed to setup GPIO pins for LCD: %d\n", + __FUNCTION__, ret); + return ret; + } + return 0; +} + +/* + * Setup GPIO for LCDC device to be inactive + * + */ +static void stk5_gpio_lcdc_inactive(struct platform_device *dev) +{ + mxc_iomux_v3_release_multiple_pads(mx25_lcdc_gpios, + ARRAY_SIZE(mx25_lcdc_gpios)); +} + +static struct imx_fb_platform_data stk5_fb_data[] __initdata = { + { + //.fb_mode = "Xenarc_700_Y-18", + .init = stk5_gpio_lcdc_active, + .exit = stk5_gpio_lcdc_inactive, + .lcd_power = NULL, + .backlight_power = NULL, + + .pixclock = 34576, + .xres = 640, + .yres = 480, + + .bpp = 32, + + .hsync_len = 64, + .right_margin = 60 + 1, + .left_margin = 80 + 3, + + .vsync_len = 2, + .upper_margin = 54, + .lower_margin = 54, +#if 0 + /* currently not used by driver! */ + .sync = ((0*FB_SYNC_HOR_HIGH_ACT) | + (0*FB_SYNC_VERT_HIGH_ACT) | + (1*FB_SYNC_OE_ACT_HIGH)), +#else + .pcr = PCR_TFT | PCR_COLOR | PCR_PBSIZ_8 | + PCR_BPIX_18 | PCR_END_SEL | PCR_FLMPOL | PCR_LPPOL | PCR_SCLK_SEL, + .dmacr = 0x800a0078, +#endif + .cmap_greyscale = 0, + .cmap_inverse = 0, + .cmap_static = 0, + + .fixed_screen_cpu = NULL, + }, { + //.fb_mode = "Xenarc_700_Y-16", + .init = stk5_gpio_lcdc_active, + .exit = stk5_gpio_lcdc_inactive, + .lcd_power = NULL, + .backlight_power = NULL, + + .pixclock = 34576, + .xres = 640, + .yres = 480, + + .bpp = 16, + + .hsync_len = 64, + .right_margin = 138 + 1, + .left_margin = 118 + 3, + + .vsync_len = 7, + .upper_margin = 44, + .lower_margin = 44, +#if 0 + /* currently not used by driver! */ + .sync = ((0*FB_SYNC_HOR_HIGH_ACT) | + (0*FB_SYNC_VERT_HIGH_ACT) | + (1*FB_SYNC_OE_ACT_HIGH)), +#else + .pcr = PCR_TFT | PCR_COLOR | PCR_PBSIZ_8 | + PCR_BPIX_16 | PCR_FLMPOL | PCR_LPPOL | PCR_SCLK_SEL, + .dmacr = 0x80040060, +#endif + .cmap_greyscale = 0, + .cmap_inverse = 0, + .cmap_static = 0, + + .fixed_screen_cpu = NULL, + }, { + //.fb_mode = "SHARP LQ10D42-16", + .init = stk5_gpio_lcdc_active, + .exit = stk5_gpio_lcdc_inactive, + .lcd_power = NULL, + .backlight_power = NULL, + + .pixclock = 34576, + .xres = 640, + .yres = 480, + +#ifdef USE_18BPP + .bpp = 32, +#else + .bpp = 16, +#endif + .hsync_len = 64, + .right_margin = 138 + 1, + .left_margin = 118 + 3, + + .vsync_len = 7, + .upper_margin = 28, + .lower_margin = 60, +#if 0 + /* currently not used by driver! */ + .sync = ((0*FB_SYNC_HOR_HIGH_ACT) | + (0*FB_SYNC_VERT_HIGH_ACT) | + (1*FB_SYNC_OE_ACT_HIGH)), +#else + .pcr = PCR_TFT | PCR_COLOR | PCR_PBSIZ_8 | +#ifdef USE_18BPP + PCR_BPIX_18 | PCR_END_SEL | PCR_FLMPOL | PCR_LPPOL | PCR_SCLK_SEL, +#else + PCR_BPIX_16 | PCR_FLMPOL | PCR_LPPOL | PCR_SCLK_SEL, +#endif + .dmacr = 0x80040060, +#endif + .cmap_greyscale = 0, + .cmap_inverse = 0, + .cmap_static = 0, + + .fixed_screen_cpu = NULL, + }, { + //.fb_mode = "SHARP LQ104V1DG61-16", + .init = stk5_gpio_lcdc_active, + .exit = stk5_gpio_lcdc_inactive, + .lcd_power = NULL, + .backlight_power = NULL, + + .pixclock = 40000, + .xres = 640, + .yres = 480, + +#ifdef USE_18BPP + .bpp = 32, +#else + .bpp = 16, +#endif + .hsync_len = 32, + .right_margin = 32 + 1, + .left_margin = 0 + 3, + + .vsync_len = 35, + .upper_margin = 0, + .lower_margin = 0, +#if 0 + /* currently not used by driver! */ + .sync = ((0*FB_SYNC_HOR_HIGH_ACT) | + (0*FB_SYNC_VERT_HIGH_ACT) | + (1*FB_SYNC_OE_ACT_HIGH)), +#else + .pcr = PCR_TFT | PCR_COLOR | PCR_PBSIZ_8 | +#ifdef USE_18BPP + PCR_BPIX_18 | PCR_END_SEL | PCR_FLMPOL | PCR_LPPOL | PCR_SCLK_SEL, +#else + PCR_BPIX_16 | PCR_FLMPOL | PCR_LPPOL | PCR_CLKPOL | PCR_SCLK_SEL, +#endif + .dmacr = 0x80040060, +#endif + .cmap_greyscale = 0, + .cmap_inverse = 0, + .cmap_static = 0, + + .fixed_screen_cpu = NULL, + }, +}; + +static int __init karo_stk5_fb_register(void) +{ + int ret; + + ret = mxc_register_device(&mxc_fb_device, &stk5_fb_data[0]); + if (ret != 0) { + DBG(0, "%s: Failed to register FB device: %d\n", __FUNCTION__, ret); + } + return ret; +} +#else +static inline int karo_stk5_fb_register(void) +{ + return 0; +} +#endif + +#if defined(CONFIG_MMC_MXC) || defined(CONFIG_MMC_MXC_MODULE) +/*! + * Resource definition for the SDHC1 + */ +static struct resource stk5_sdhc1_resources[] = { + { + .start = MMC_SDHC1_BASE_ADDR, + .end = MMC_SDHC1_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_SDHC1, + .end = MXC_INT_SDHC1, + .flags = IORESOURCE_IRQ, + }, { + .start = gpio_to_irq(4 * 32 + 4), + .end = gpio_to_irq(4 * 32 + 4), + .flags = IORESOURCE_IRQ, +#if 0 + }, { + .name = "sdhc1", + .start = DMA_REQ_SDHC1, + .end = DMA_REQ_SDHC1, + .flags = IORESOURCE_DMA +#endif + }, +}; + +static inline int stk5_mmc_get_irq(int id) +{ + int irq; + + switch (id) { + case 0: + irq = stk5_sdhc1_resources[2].start; + break; + default: + BUG(); + } + return irq; +} + +static const char *stk5_mmc_irqdesc[] = { + "MMC card 0 detect", +}; + +static struct pad_desc stk5_sdhc_pads[] = { +}; + +static int stk5_mmc_init(struct device *dev, irqreturn_t (*mmc_detect_irq)(int, void *), + void *data) +{ + int err; + int id = to_platform_device(dev)->id; + struct mmc_host *host = data; + int irq = stk5_mmc_get_irq(id); + + err = mxc_iomux_v3_setup_multiple_pads(stk5_sdhc_pads, + ARRAY_SIZE(stk5_sdhc_pads)); + if (err) { + return err; + } + + host->caps |= MMC_CAP_4_BIT_DATA; + + err = request_irq(irq, mmc_detect_irq, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + stk5_mmc_irqdesc[id], data); + if (err) { + printk(KERN_ERR "%s: MMC/SD: can't request MMC card detect IRQ %d\n", + __FUNCTION__, irq); + return err; + } + device_set_wakeup_capable(dev, 1); + + return 0; +} + +static void stk5_mmc_exit(struct device *dev, void *data) +{ + int id = to_platform_device(dev)->id; + int irq = stk5_mmc_get_irq(id); + + free_irq(irq, data); + mxc_iomux_v3_release_multiple_pads(stk5_sdhc_pads, + ARRAY_SIZE(stk5_sdhc_pads)); +} + +#if 0 +static int stk5_mmc_suspend(struct device *dev, pm_message_t state) +{ + int id = to_platform_device(dev)->id; + int irq = stk5_mmc_get_irq(id); + + if (device_may_wakeup(dev)) { + DBG(0, "%s: Enabling IRQ %d wakeup\n", __FUNCTION__, irq); + return enable_irq_wake(irq); + } + return 0; +} + +static int stk5_mmc_resume(struct device *dev) +{ + int id = to_platform_device(dev)->id; + int irq = stk5_mmc_get_irq(id); + + if (device_may_wakeup(dev)) { + DBG(0, "%s: Disabling IRQ %d wakeup\n", __FUNCTION__, irq); + return disable_irq_wake(irq); + } + return 0; +} +#endif + +static struct imxmmc_platform_data stk5_sdhc1_data = { + //.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + //.min_clk = 150000, + //.max_clk = 25000000, + //.detect_delay = 20, + .init = stk5_mmc_init, + .exit = stk5_mmc_exit, +// .suspend = stk5_mmc_suspend, +// .resume = stk5_mmc_resume, +}; + +static struct platform_device stk5_sdhc1_device = { + .name = "imx-mmc", + .id = 0, + .dev = { + .platform_data = &stk5_sdhc1_data, + }, + .num_resources = ARRAY_SIZE(stk5_sdhc1_resources), + .resource = stk5_sdhc1_resources, +}; +#endif + +#if defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE) +static struct resource mxcspi1_resources[] = { + { + .start = CSPI1_BASE_ADDR, + .end = CSPI1_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_CSPI1, + .end = MXC_INT_CSPI1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct mxc_spi_master mxcspi1_data = { + .maxchipselect = 2, + .spi_version = 0, +}; + +static struct platform_device mxcspi1_device = { + .name = "mxc_spi", + .id = 0, + .dev = { + .platform_data = &mxcspi1_data, + }, + .num_resources = ARRAY_SIZE(mxcspi1_resources), + .resource = mxcspi1_resources, +}; +#endif // defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE) + +#if defined(CONFIG_AC97_BUS) || defined(CONFIG_AC97_BUS_MODULE) +static u64 stk5_dma_mask = ~0UL; + +static struct pad_desc stk5_ac97_pads_on[] = { + MX25_PAD_VSTBY_ACK__GPIO_3_18, /* UCB1400 Reset */ + MX25_PAD_RW__AUD4_TXFS, + MX25_PAD_EB0__AUD4_TXD, + MX25_PAD_EB1__AUD4_RXD, + MX25_PAD_OE__AUD4_TXC, +}; + +static struct pad_desc stk5_ac97_pads_off[] = { + MX25_PAD_VSTBY_ACK__GPIO_3_18, /* UCB1400 Reset */ + MX25_PAD_RW__GPIO_3_25, + MX25_PAD_EB0__GPIO_2_12, + MX25_PAD_EB1__AUD4_RXD, + MX25_PAD_OE__AUD4_TXC, +}; + +static struct gpio_desc { + unsigned int gpio:7; + unsigned int dir:1; + unsigned int level:1; +} stk5_ac97_gpios[] = { + /* configure the PHY strap pins to the correct values */ + { GPIO_PORTC | 18, 1, 0, }, + { GPIO_PORTC | 25, 1, 0, }, + { GPIO_PORTB | 12, 1, 0, }, +}; + +static int stk5_ac97_init(struct platform_device *dev) +{ + int ret; + int i; + + DBG(0, "%s: \n", __FUNCTION__); + + ret = mxc_iomux_v3_setup_multiple_pads(stk5_ac97_pads_off, + ARRAY_SIZE(stk5_ac97_pads_off)); + if (ret == 0) { + for (i = 0; i < ARRAY_SIZE(stk5_ac97_gpios); i++) { + struct gpio_desc *pd = &stk5_ac97_gpios[i]; + + ret = gpio_request(pd->gpio, "AC97"); + if (ret < 0) { + DBG(0, "%s: Failed to request GPIO%d_%d: %d\n", + __FUNCTION__, pd->gpio / 32 + 1, pd->gpio % 32, ret); + goto rel_mux; + } + if (pd->dir) { + gpio_direction_output(pd->gpio, + pd->level); + } else { + gpio_direction_input(pd->gpio); + } + } + + ret = mxc_iomux_v3_setup_multiple_pads(stk5_ac97_pads_on, + ARRAY_SIZE(stk5_ac97_pads_on)); + if (ret != 0) { + goto rel_gpio; + } + udelay(1); + gpio_set_value(stk5_ac97_gpios[0].gpio, !stk5_ac97_gpios[0].level); + } + return ret; + + rel_mux: + mxc_iomux_v3_release_multiple_pads(stk5_ac97_gpios_off, + ARRAY_SIZE(stk5_ac97_gpios_off)); + rel_gpio: + while (--i >= 0) { + struct gpio_desc *pd = &stk5_ac97_gpios[i]; + int grp = pd->gpio / 32 + 1; + int ofs = pd->gpio % 32; + + DBG(0, "%s: Freeing GPIO%d_%d\n", __FUNCTION__, + grp, ofs); + gpio_free(pd->gpio); + } + return ret; +} + +static void stk5_ac97_exit(struct platform_device *dev) +{ + int i; + + DBG(0, "%s: Releasing AC97 GPIO pins\n", __FUNCTION__); + + mxc_iomux_v3_release_multiple_pads(stk5_ac97_pads_on, + ARRAY_SIZE(stk5_ac97_pads_on)); + for (i = 0; i < ARRAY_SIZE(stk5_ac97_gpios); i++) { + struct gpio_desc *pd = &stk5_ac97_gpios[i]; + int grp = pd->gpio / 32 + 1; + int ofs = pd->gpio % 32; + + DBG(0, "%s: Freeing GPIO%d_%d\n", __FUNCTION__, + grp, ofs); + gpio_free(pd->gpio); + } +} + +static struct mxc_ac97_audio_ops stk5_ac97_ops = { + .init = stk5_ac97_init, + .exit = stk5_ac97_exit, + .startup = NULL, + .shutdown = NULL, + .suspend = NULL, + .resume = NULL, + .priv = NULL, +}; + +static struct platform_device ac97_device = { + .name = "mx25-ac97", + .id = -1, + .dev = { + .dma_mask = &stk5_dma_mask, + .coherent_dma_mask = ~0UL, + .platform_data = &stk5_ac97_ops, + }, +}; +#endif + +static struct platform_dev_list { + struct platform_device *pdev; + int flag; +} stk5_devices[] __initdata = { +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) + { .pdev = &stk5_led_device, .flag = -1, }, +#endif +#if defined(CONFIG_KEYBOARD_MXC) || defined(CONFIG_KEYBOARD_MXC_MODULE) + { .pdev = &stk5_keypad_device, .flag = 1, }, +#endif +#if defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE) + { .pdev = &mxcspi1_device, .flag = 1, }, +#endif +#if defined(CONFIG_AC97_BUS) || defined(CONFIG_AC97_BUS_MODULE) + { .pdev = &ac97_device, .flag = 1, }, +#endif +#if defined(CONFIG_MMC_MXC) || defined(CONFIG_MMC_MXC_MODULE) + { .pdev = &stk5_sdhc1_device, .flag = 1, }, +#endif +}; +#define STK5_NUM_DEVICES ARRAY_SIZE(stk5_devices) + +static __init int karo_stk5_board_init(void) +{ + int ret; + int i; + + if (karo_get_board_type() != BOARD_KARO_STK5) { + return -ENODEV; + } + DBG(0, "%s: \n", __FUNCTION__); + + karo_stk5_serial_init(); + + dump_regs(); + + /* enable SSI1_INT (GPIO_3_15) for IRQ probing */ + set_irq_flags(gpio_to_irq(GPIO_PORTC | 15), IRQF_VALID | IRQF_PROBE); + + ret = karo_stk5_fb_register(); + if (ret) { + printk(KERN_WARNING "%s: karo_stk5_fb_register() failed: %d\n", + __FUNCTION__, ret); + } + ret = karo_stk5_usbh2_register(); + if (ret) { + printk(KERN_WARNING "%s: karo_stk5_usbh2_register() failed: %d\n", + __FUNCTION__, ret); + } + + for (i = 0; i < STK5_NUM_DEVICES; i++) { + if (stk5_devices[i].pdev == NULL) continue; + if (!stk5_devices[i].flag) { + DBG(0, "%s: Skipping platform device[%d] @ %p dev %p: %s\n", + __FUNCTION__, i, stk5_devices[i].pdev, &stk5_devices[i].pdev->dev, + stk5_devices[i].pdev->name); + continue; + } + DBG(0, "%s: Registering platform device[%d] @ %p dev %p: %s\n", + __FUNCTION__, i, stk5_devices[i].pdev, &stk5_devices[i].pdev->dev, + stk5_devices[i].pdev->name); + ret = platform_device_register(stk5_devices[i].pdev); + if (ret) { + printk(KERN_WARNING "%s: Failed to register platform_device[%d]: %s: %d\n", + __FUNCTION__, i, stk5_devices[i].pdev->name, ret); + } + } + DBG(0, "%s: Done\n", __FUNCTION__); + return 0; +} +subsys_initcall(karo_stk5_board_init); diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx3/clock-imx35.c linux-2.6.30-rc4-karo/arch/arm/mach-mx3/clock-imx35.c --- linux-2.6.30-rc4/arch/arm/mach-mx3/clock-imx35.c 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/mach-mx3/clock-imx35.c 2009-06-02 17:59:19.000000000 +0200 @@ -381,7 +381,7 @@ DEFINE_CLOCK(gpu2d_clk, 0, CCM_CGR3, 4 .clk = &c, \ }, -static struct clk_lookup lookups[] __initdata = { +static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "asrc", asrc_clk) _REGISTER_CLOCK(NULL, "ata", ata_clk) _REGISTER_CLOCK(NULL, "audmux", audmux_clk) diff -urNp linux-2.6.30-rc4/arch/arm/mach-mx3/clock.c linux-2.6.30-rc4-karo/arch/arm/mach-mx3/clock.c --- linux-2.6.30-rc4/arch/arm/mach-mx3/clock.c 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/mach-mx3/clock.c 2009-06-02 17:59:19.000000000 +0200 @@ -516,7 +516,7 @@ DEFINE_CLOCK(ipg_clk, 0, NULL, .clk = &c, \ }, -static struct clk_lookup lookups[] __initdata = { +static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "emi", emi_clk) _REGISTER_CLOCK(NULL, "cspi", cspi1_clk) _REGISTER_CLOCK(NULL, "cspi", cspi2_clk) diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/Kconfig linux-2.6.30-rc4-karo/arch/arm/plat-mxc/Kconfig --- linux-2.6.30-rc4/arch/arm/plat-mxc/Kconfig 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/Kconfig 2009-06-02 18:01:59.000000000 +0200 @@ -56,6 +56,9 @@ config ARCH_HAS_RNGA bool depends on ARCH_MXC +config ARCH_MXC_IOMUX_V2 + bool + config ARCH_MXC_IOMUX_V3 bool endif diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/Makefile linux-2.6.30-rc4-karo/arch/arm/plat-mxc/Makefile --- linux-2.6.30-rc4/arch/arm/plat-mxc/Makefile 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/Makefile 2009-06-02 18:02:00.000000000 +0200 @@ -5,7 +5,7 @@ # Common support obj-y := irq.o clock.o gpio.o time.o devices.o cpu.o system.o -obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.o dma-mx1-mx2.o -obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o -obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o -obj-$(CONFIG_MXC_PWM) += pwm.o +obj-$(CONFIG_ARCH_MXC_IOMUX_V2) += iomux-mx1-mx2.o dma-mx1-mx2.o +obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o +obj-$(CONFIG_MXC_PWM) += pwm.o +obj-$(CONFIG_MACH_MX25) += spba.o diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/board-stk5.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/board-stk5.h --- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/board-stk5.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/board-stk5.h 2009-06-02 18:02:13.000000000 +0200 @@ -0,0 +1,17 @@ +/* + * Copyright 2009 + * + * 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 + */ + +#define UART1_ENABLED 1 +#define UART2_ENABLED 1 +#define UART3_ENABLED 1 +/* Not available on TX25 */ +#define UART4_ENABLED 0 +#define UART5_ENABLED 0 diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/board-tx25.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/board-tx25.h --- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/board-tx25.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/board-tx25.h 2009-06-02 18:02:13.000000000 +0200 @@ -0,0 +1,13 @@ +/* + * Copyright 2009 + * + * 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 + */ + +#define MXC_LL_UART_PADDR UART1_BASE_ADDR +#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/common.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/common.h --- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/common.h 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/common.h 2009-06-02 18:02:05.000000000 +0200 @@ -17,6 +17,7 @@ struct clk; extern void mx1_map_io(void); extern void mx21_map_io(void); extern void mx27_map_io(void); +extern void mx25_map_io(void); extern void mx31_map_io(void); extern void mx35_map_io(void); extern void mxc_init_irq(void); @@ -24,6 +25,7 @@ extern void mxc_timer_init(struct clk *t extern int mx1_clocks_init(unsigned long fref); extern int mx21_clocks_init(unsigned long lref, unsigned long fref); extern int mx27_clocks_init(unsigned long fref); +extern int mx25_clocks_init(unsigned long fref); extern int mx31_clocks_init(unsigned long fref); extern int mx35_clocks_init(void); extern int mxc_register_gpios(void); diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/dma.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/dma.h --- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/dma.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/dma.h 2009-06-02 18:02:13.000000000 +0200 @@ -0,0 +1,259 @@ +/* + * Copyright 2004-2008 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. + */ + +#ifndef __ASM_ARCH_MXC_DMA_H__ +#define __ASM_ARCH_MXC_DMA_H__ + +#include + +#define MXC_DMA_DYNAMIC_CHANNEL 255 + +#define MXC_DMA_DONE 0x0 +#define MXC_DMA_REQUEST_TIMEOUT 0x1 +#define MXC_DMA_TRANSFER_ERROR 0x2 + +/*! This defines the list of device ID's for DMA */ +typedef enum mxc_dma_device { + MXC_DMA_UART1_RX, + MXC_DMA_UART1_TX, + MXC_DMA_UART2_RX, + MXC_DMA_UART2_TX, + MXC_DMA_UART3_RX, + MXC_DMA_UART3_TX, + MXC_DMA_UART4_RX, + MXC_DMA_UART4_TX, + MXC_DMA_UART5_RX, + MXC_DMA_UART5_TX, + MXC_DMA_UART6_RX, + MXC_DMA_UART6_TX, + MXC_DMA_MMC1_WIDTH_1, + MXC_DMA_MMC1_WIDTH_4, + MXC_DMA_MMC2_WIDTH_1, + MXC_DMA_MMC2_WIDTH_4, + MXC_DMA_SSI1_8BIT_RX0, + MXC_DMA_SSI1_8BIT_TX0, + MXC_DMA_SSI1_16BIT_RX0, + MXC_DMA_SSI1_16BIT_TX0, + MXC_DMA_SSI1_24BIT_RX0, + MXC_DMA_SSI1_24BIT_TX0, + MXC_DMA_SSI1_8BIT_RX1, + MXC_DMA_SSI1_8BIT_TX1, + MXC_DMA_SSI1_16BIT_RX1, + MXC_DMA_SSI1_16BIT_TX1, + MXC_DMA_SSI1_24BIT_RX1, + MXC_DMA_SSI1_24BIT_TX1, + MXC_DMA_SSI2_8BIT_RX0, + MXC_DMA_SSI2_8BIT_TX0, + MXC_DMA_SSI2_16BIT_RX0, + MXC_DMA_SSI2_16BIT_TX0, + MXC_DMA_SSI2_24BIT_RX0, + MXC_DMA_SSI2_24BIT_TX0, + MXC_DMA_SSI2_8BIT_RX1, + MXC_DMA_SSI2_8BIT_TX1, + MXC_DMA_SSI2_16BIT_RX1, + MXC_DMA_SSI2_16BIT_TX1, + MXC_DMA_SSI2_24BIT_RX1, + MXC_DMA_SSI2_24BIT_TX1, + MXC_DMA_FIR_RX, + MXC_DMA_FIR_TX, + MXC_DMA_CSPI1_RX, + MXC_DMA_CSPI1_TX, + MXC_DMA_CSPI2_RX, + MXC_DMA_CSPI2_TX, + MXC_DMA_CSPI3_RX, + MXC_DMA_CSPI3_TX, + MXC_DMA_ATA_RX, + MXC_DMA_ATA_TX, + MXC_DMA_MEMORY, + MXC_DMA_FIFO_MEMORY, + MXC_DMA_DSP_PACKET_DATA0_RD, + MXC_DMA_DSP_PACKET_DATA0_WR, + MXC_DMA_DSP_PACKET_DATA1_RD, + MXC_DMA_DSP_PACKET_DATA1_WR, + MXC_DMA_DSP_LOG0_CHNL, + MXC_DMA_DSP_LOG1_CHNL, + MXC_DMA_DSP_LOG2_CHNL, + MXC_DMA_DSP_LOG3_CHNL, + MXC_DMA_CSI_RX, + MXC_DMA_SPDIF_16BIT_TX, + MXC_DMA_SPDIF_16BIT_RX, + MXC_DMA_SPDIF_32BIT_TX, + MXC_DMA_SPDIF_32BIT_RX, + MXC_DMA_ASRC_A_RX, + MXC_DMA_ASRC_A_TX, + MXC_DMA_ASRC_B_RX, + MXC_DMA_ASRC_B_TX, + MXC_DMA_ASRC_C_RX, + MXC_DMA_ASRC_C_TX, + MXC_DMA_ESAI_16BIT_RX, + MXC_DMA_ESAI_16BIT_TX, + MXC_DMA_ESAI_24BIT_RX, + MXC_DMA_ESAI_24BIT_TX, + MXC_DMA_TEST_RAM2D2RAM, + MXC_DMA_TEST_RAM2RAM2D, + MXC_DMA_TEST_RAM2D2RAM2D, + MXC_DMA_TEST_RAM2RAM, + MXC_DMA_TEST_HW_CHAINING, + MXC_DMA_TEST_SW_CHAINING +} mxc_dma_device_t; + +/*! This defines the prototype of callback funtion registered by the drivers */ +typedef void (*mxc_dma_callback_t) (void *arg, int error_status, + unsigned int count); + +/*! This defines the type of DMA transfer requested */ +typedef enum mxc_dma_mode { + MXC_DMA_MODE_READ, + MXC_DMA_MODE_WRITE, +} mxc_dma_mode_t; + +/*! This defines the DMA channel parameters */ +typedef struct mxc_dma_channel { + unsigned int active:1; /*!< When there has a active tranfer, it is set to 1 */ + unsigned int lock; /*!< Defines the channel is allocated or not */ + int curr_buf; /*!< Current buffer */ + mxc_dma_mode_t mode; /*!< Read or Write */ + unsigned int channel; /*!< Channel info */ + unsigned int dynamic:1; /*!< Channel not statically allocated when 1 */ + char *dev_name; /*!< Device name */ + void *private; /*!< Private structure for platform */ + mxc_dma_callback_t cb_fn; /*!< The callback function */ + void *cb_args; /*!< The argument of callback function */ +} mxc_dma_channel_t; + +/*! This structure contains the information about a dma transfer */ +typedef struct mxc_dma_requestbuf { + dma_addr_t src_addr; /*!< source address */ + dma_addr_t dst_addr; /*!< destination address */ + int num_of_bytes; /*!< the length of this transfer : bytes */ +} mxc_dma_requestbuf_t; + +/*! + * This function is generally called by the driver at open time. + * The DMA driver would do any initialization steps that is required + * to get the channel ready for data transfer. + * + * @param channel_id a pre-defined id. The peripheral driver would specify + * the id associated with its peripheral. This would be + * used by the DMA driver to identify the peripheral + * requesting DMA and do the necessary setup on the + * channel associated with the particular peripheral. + * The DMA driver could use static or dynamic DMA channel + * allocation. + * @param dev_name module name or device name + * @return returns a negative number on error if request for a DMA channel did not + * succeed, returns the channel number to be used on success. + */ +extern int mxc_dma_request(mxc_dma_device_t channel_id, char *dev_name); + +/*! + * This function is generally called by the driver at close time. The DMA + * driver would do any cleanup associated with this channel. + * + * @param channel_num the channel number returned at request time. This + * would be used by the DMA driver to identify the calling + * driver and do the necessary cleanup on the channel + * associated with the particular peripheral + * @return returns a negative number on error or 0 on success + */ +extern int mxc_dma_free(int channel_num); + +/*! + * This function would just configure the buffers specified by the user into + * dma channel. The caller must call mxc_dma_enable to start this transfer. + * + * @param channel_num the channel number returned at request time. This + * would be used by the DMA driver to identify the calling + * driver and do the necessary cleanup on the channel + * associated with the particular peripheral + * @param dma_buf an array of physical addresses to the user defined + * buffers. The caller must guarantee the dma_buf is + * available until the transfer is completed. + * @param num_buf number of buffers in the array + * @param mode specifies whether this is READ or WRITE operation + * @return This function returns a negative number on error if buffer could not be + * added with DMA for transfer. On Success, it returns 0 + */ +extern int mxc_dma_config(int channel_num, mxc_dma_requestbuf_t * dma_buf, + int num_buf, mxc_dma_mode_t mode); + +/*! + * This function would just configure the scatterlist specified by the + * user into dma channel. This is a slight variation of mxc_dma_config(), + * it is provided for the convenience of drivers that have a scatterlist + * passed into them. It is the calling driver's responsibility to have the + * correct physical address filled in the "dma_address" field of the + * scatterlist. + * + * @param channel_num the channel number returned at request time. This + * would be used by the DMA driver to identify the calling + * driver and do the necessary cleanup on the channel + * associated with the particular peripheral + * @param sg a scatterlist of buffers. The caller must guarantee + * the dma_buf is available until the transfer is + * completed. + * @param num_buf number of buffers in the array + * @param num_of_bytes total number of bytes to transfer. If set to 0, this + * would imply to use the length field of the scatterlist + * for each DMA transfer. Else it would calculate the size + * for each DMA transfer. + * @param mode specifies whether this is READ or WRITE operation + * @return This function returns a negative number on error if buffer could not + * be added with DMA for transfer. On Success, it returns 0 + */ +extern int mxc_dma_sg_config(int channel_num, struct scatterlist *sg, + int num_buf, int num_of_bytes, + mxc_dma_mode_t mode); + +/*! + * This function is provided if the driver would like to set/change its + * callback function. + * + * @param channel_num the channel number returned at request time. This + * would be used by the DMA driver to identify the calling + * driver and do the necessary cleanup on the channel + * associated with the particular peripheral + * @param callback a callback function to provide notification on transfer + * completion, user could specify NULL if he does not wish + * to be notified + * @param arg an argument that gets passed in to the callback + * function, used by the user to do any driver specific + * operations. + * @return this function returns a negative number on error if the callback + * could not be set for the channel or 0 on success + */ +extern int mxc_dma_callback_set(int channel_num, mxc_dma_callback_t callback, + void *arg); + +/*! + * This stops the DMA channel and any ongoing transfers. Subsequent use of + * mxc_dma_enable() will restart the channel and restart the transfer. + * + * @param channel_num the channel number returned at request time. This + * would be used by the DMA driver to identify the calling + * driver and do the necessary cleanup on the channel + * associated with the particular peripheral + * @return returns a negative number on error or 0 on success + */ +extern int mxc_dma_disable(int channel_num); + +/*! + * This starts DMA transfer. Or it restarts DMA on a stopped channel + * previously stopped with mxc_dma_disable(). + * + * @param channel_num the channel number returned at request time. This + * would be used by the DMA driver to identify the calling + * driver and do the necessary cleanup on the channel + * associated with the particular peripheral + * @return returns a negative number on error or 0 on success + */ +extern int mxc_dma_enable(int channel_num); + +#endif diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/hardware.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/hardware.h --- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/hardware.h 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/hardware.h 2009-06-02 18:02:06.000000000 +0200 @@ -29,13 +29,18 @@ #endif #ifdef CONFIG_ARCH_MX2 +#ifndef CONFIG_MACH_MX25 # include +#endif # ifdef CONFIG_MACH_MX21 # include # endif # ifdef CONFIG_MACH_MX27 # include # endif +# ifdef CONFIG_MACH_MX25 +# include +# endif #endif #ifdef CONFIG_ARCH_MX1 diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/imxfb.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/imxfb.h --- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/imxfb.h 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/imxfb.h 2009-06-02 18:02:06.000000000 +0200 @@ -13,7 +13,8 @@ #define PCR_BPIX_4 (2 << 25) #define PCR_BPIX_8 (3 << 25) #define PCR_BPIX_12 (4 << 25) -#define PCR_BPIX_16 (4 << 25) +#define PCR_BPIX_16 (5 << 25) +#define PCR_BPIX_18 (6 << 25) #define PCR_PIXPOL (1 << 24) #define PCR_FLMPOL (1 << 23) #define PCR_LPPOL (1 << 22) diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/iomux-mx25.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/iomux-mx25.h --- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/iomux-mx25.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/iomux-mx25.h 2009-06-02 18:02:13.000000000 +0200 @@ -0,0 +1,905 @@ +/* + * arch/arm/plat-mxc/include/mach/iomux-mx25.h + * + * Copyright (C) 2009 by Lothar Wassmann + * + * based on arch/arm/mach-mx25/mx25_pins.h + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * and + * arch/arm/plat-mxc/include/mach/iomux-mx35.h + * Copyright (C, NO_PAD_CTRL) 2009 by Jan Weitzel Phytec Messtechnik GmbH + * + * 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 __IOMUX_MX25_H__ +#define __IOMUX_MX25_H__ + +#include + +/* + * + * @brief MX25 I/O Pin List + * + * @ingroup GPIO_MX25 + */ + +#ifndef __ASSEMBLY__ + +/* + * IOMUX/PAD Bit field definitions + */ + +#define MX25_PAD_A10__A10 IOMUX_PAD(A10, A10, 0x000, 0x008, 0x00, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_A10__GPIO_4_0 IOMUX_PAD(A10, GPIO_4_0, 0x000, 0x008, 0x05, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_A13__A13 IOMUX_PAD(A13, A13, 0x22C, 0x00c, 0x00, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A13__GPIO_4_1 IOMUX_PAD(A13, GPIO_4_1, 0x22C, 0x00c, 0x05, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A14__A14 IOMUX_PAD(A14, A14, 0x230, 0x010, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A14__GPIO_2_0 IOMUX_PAD(A14, GPIO_2_0, 0x230, 0x010, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A15__A15 IOMUX_PAD(A15, A15, 0x234, 0x014, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A15__GPIO_2_1 IOMUX_PAD(A15, GPIO_2_1, 0x234, 0x014, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A16__A16 IOMUX_PAD(A16, A16, 0x000, 0x018, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_A16__GPIO_2_2 IOMUX_PAD(A16, GPIO_2_2, 0x000, 0x018, 0x15, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_A17__A17 IOMUX_PAD(A17, A17, 0x238, 0x01c, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A17__GPIO_2_3 IOMUX_PAD(A17, GPIO_2_3, 0x238, 0x01c, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A18__A18 IOMUX_PAD(A18, A18, 0x23c, 0x020, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A18__GPIO_2_4 IOMUX_PAD(A18, GPIO_2_4, 0x23c, 0x020, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A18__FEC_COL IOMUX_PAD(A18, FEC_COL, 0x23c, 0x020, 0x17, 0x504, 0, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_A19__A19 IOMUX_PAD(A19, A19, 0x240, 0x024, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A19__FEC_RX_ER IOMUX_PAD(A19, FEC_RX_ER, 0x240, 0x024, 0x17, 0x518, 0, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_A19__GPIO_2_5 IOMUX_PAD(A19, GPIO_2_5, 0x240, 0x024, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A20__A20 IOMUX_PAD(A20, A20, 0x244, 0x028, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A20__GPIO_2_6 IOMUX_PAD(A20, GPIO_2_6, 0x244, 0x028, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A20__FEC_RDATA2 IOMUX_PAD(A20, FEC_RDATA2, 0x244, 0x028, 0x17, 0x50c, 0, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_A21__A21 IOMUX_PAD(A21, A21, 0x248, 0x02c, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A21__GPIO_2_7 IOMUX_PAD(A21, GPIO_2_7, 0x248, 0x02c, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A21__FEC_RDATA3 IOMUX_PAD(A21, FEC_RDATA3, 0x248, 0x02c, 0x17, 0x510, 0, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_A22__A22 IOMUX_PAD(A22, A22, 0x000, 0x030, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A22__GPIO_2_8 IOMUX_PAD(A22, GPIO_2_8, 0x000, 0x030, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A23__A23 IOMUX_PAD(A23, A23, 0x24c, 0x034, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A23__GPIO_2_9 IOMUX_PAD(A23, GPIO_2_9, 0x24c, 0x034, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A24__A24 IOMUX_PAD(A24, A24, 0x250, 0x038, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A24__GPIO_2_10 IOMUX_PAD(A24, GPIO_2_10, 0x250, 0x038, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A24__FEC_RX_CLK IOMUX_PAD(A24, FEC_RX_CLK, 0x250, 0x038, 0x17, 0x514, 0, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_A25__A25 IOMUX_PAD(A25, A25, 0x254, 0x03c, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A25__GPIO_2_11 IOMUX_PAD(A25, GPIO_2_11, 0x254, 0x03c, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_A25__FEC_CRS IOMUX_PAD(A25, FEC_CRS, 0x254, 0x03c, 0x17, 0x508, 0, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_EB0__EB0 IOMUX_PAD(EB0, EB0, 0x258, 0x040, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_EB0__AUD4_TXD IOMUX_PAD(EB0, AUD4_TXD, 0x258, 0x040, 0x14, 0x464, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_EB0__GPIO_2_12 IOMUX_PAD(EB0, GPIO_2_12, 0x258, 0x040, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_EB1__EB1 IOMUX_PAD(EB1, EB1, 0x25c, 0x044, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_EB1__AUD4_RXD IOMUX_PAD(EB1, AUD4_RXD, 0x25c, 0x044, 0x14, 0x460, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_EB1__GPIO_2_13 IOMUX_PAD(EB1, GPIO_2_13, 0x25c, 0x044, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_OE__OE IOMUX_PAD(OE, OE, 0x260, 0x048, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_OE__AUD4_TXC IOMUX_PAD(OE, AUD4_TXC, 0x260, 0x048, 0x14, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_OE__GPIO_2_14 IOMUX_PAD(OE, GPIO_2_14, 0x260, 0x048, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CS0__CS0 IOMUX_PAD(CS0, CS0, 0x000, 0x04c, 0x00, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CS0__GPIO_4_2 IOMUX_PAD(CS0, GPIO_4_2, 0x000, 0x04c, 0x05, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CS1__CS1 IOMUX_PAD(CS1, CS1, 0x000, 0x050, 0x00, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CS1__GPIO_4_3 IOMUX_PAD(CS1, GPIO_4_3, 0x000, 0x050, 0x05, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CS4__CS4 IOMUX_PAD(CS4, CS4, 0x264, 0x054, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CS4__UART5_CTS IOMUX_PAD(CS4, UART5_CTS, 0x264, 0x054, 0x13, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CS4__GPIO_3_20 IOMUX_PAD(CS4, GPIO_3_20, 0x264, 0x054, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CS5__CS5 IOMUX_PAD(CS5, CS5, 0x268, 0x058, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CS5__UART5_RTS IOMUX_PAD(CS5, UART5_RTS, 0x268, 0x058, 0x13, 0x574, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CS5__GPIO_3_21 IOMUX_PAD(CS5, GPIO_3_21, 0x268, 0x058, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_NF_CE0__NF_CE0 IOMUX_PAD(NF_CE0, NF_CE0, 0x26c, 0x05c, 0x10, 0, 0, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_NF_CE0__GPIO_3_22 IOMUX_PAD(NF_CE0, GPIO_3_22, 0x26c, 0x05c, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_ECB__ECB IOMUX_PAD(ECB, ECB, 0x270, 0x060, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_ECB__UART5_TXD_MUX IOMUX_PAD(ECB, UART5_TXD_MUX, 0x270, 0x060, 0x13, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_ECB__GPIO_3_23 IOMUX_PAD(ECB, GPIO_3_23, 0x270, 0x060, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LBA__LBA IOMUX_PAD(LBA, LBA, 0x274, 0x064, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LBA__UART5_RXD_MUX IOMUX_PAD(LBA, UART5_RXD_MUX, 0x274, 0x064, 0x13, 0x578, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LBA__GPIO_3_24 IOMUX_PAD(LBA, GPIO_3_24, 0x274, 0x064, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_BCLK__BCLK IOMUX_PAD(BCLK, BCLK, 0x000, 0x068, 0x00, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_BCLK__GPIO_4_4 IOMUX_PAD(BCLK, GPIO_4_4, 0x000, 0x068, 0x05, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_RW__RW IOMUX_PAD(RW, RW, 0x278, 0x06c, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_RW__AUD4_TXFS IOMUX_PAD(RW, AUD4_TXFS, 0x278, 0x06c, 0x14, 0x474, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_RW__GPIO_3_25 IOMUX_PAD(RW, GPIO_3_25, 0x278, 0x06c, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_NFWE_B__NFWE_B IOMUX_PAD(NFWE_B, NFWE_B, 0x000, 0x070, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_NFWE_B__GPIO_3_26 IOMUX_PAD(NFWE_B, GPIO_3_26, 0x000, 0x070, 0x15, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_NFRE_B__NFRE_B IOMUX_PAD(NFRE_B, NFRE_B, 0x000, 0x074, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_NFRE_B__GPIO_3_27 IOMUX_PAD(NFRE_B, GPIO_3_27, 0x000, 0x074, 0x15, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_NFALE__NFALE IOMUX_PAD(NFALE, NFALE, 0x000, 0x078, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_NFALE__GPIO_3_28 IOMUX_PAD(NFALE, GPIO_3_28, 0x000, 0x078, 0x15, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_NFCLE__NFCLE IOMUX_PAD(NFCLE, NFCLE, 0x000, 0x07c, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_NFCLE__GPIO_3_29 IOMUX_PAD(NFCLE, GPIO_3_29, 0x000, 0x07c, 0x15, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_NFWP_B__NFWP_B IOMUX_PAD(NFWP_B, NFWP_B, 0x000, 0x080, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_NFWP_B__GPIO_3_30 IOMUX_PAD(NFWP_B, GPIO_3_30, 0x000, 0x080, 0x15, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_NFRB__NFRB IOMUX_PAD(NFRB, NFRB, 0x27c, 0x084, 0x10, 0, 0, PAD_CTL_PULL_KEEPER) +#define MX25_PAD_NFRB__GPIO_3_31 IOMUX_PAD(NFRB, GPIO_3_31, 0x27c, 0x084, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D15__D15 IOMUX_PAD(D15, D15, 0x280, 0x088, 0x00, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D15__LD16 IOMUX_PAD(D15, LD16, 0x280, 0x088, 0x01, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D15__GPIO_4_5 IOMUX_PAD(D15, GPIO_4_5, 0x280, 0x088, 0x05, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D14__D14 IOMUX_PAD(D14, D14, 0x284, 0x08c, 0x00, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D14__LD17 IOMUX_PAD(D14, LD17, 0x284, 0x08c, 0x01, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D14__GPIO_4_6 IOMUX_PAD(D14, GPIO_4_6, 0x284, 0x08c, 0x05, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D13__D13 IOMUX_PAD(D13, D13, 0x288, 0x090, 0x00, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D13__LD18 IOMUX_PAD(D13, LD18, 0x288, 0x090, 0x01, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D13__GPIO_4_7 IOMUX_PAD(D13, GPIO_4_7, 0x288, 0x090, 0x05, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D12__D12 IOMUX_PAD(D12, D12, 0x28c, 0x094, 0x00, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D12__GPIO_4_8 IOMUX_PAD(D12, GPIO_4_8, 0x28c, 0x094, 0x05, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D11__D11 IOMUX_PAD(D11, D11, 0x290, 0x098, 0x00, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D11__GPIO_4_9 IOMUX_PAD(D11, GPIO_4_9, 0x290, 0x098, 0x05, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D10__D10 IOMUX_PAD(D10, D10, 0x294, 0x09c, 0x00, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D10__GPIO_4_10 IOMUX_PAD(D10, GPIO_4_10, 0x294, 0x09c, 0x05, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D10__USBOTG_OC IOMUX_PAD(D10, USBOTG_OC, 0x294, 0x09c, 0x06, 0x57c, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D9__D9 IOMUX_PAD(D9, D9, 0x298, 0x0a0, 0x00, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D9__GPIO_4_11 IOMUX_PAD(D9, GPIO_4_11, 0x298, 0x0a0, 0x05, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D9__USBH2_PWR IOMUX_PAD(D9, USBH2_PWR, 0x298, 0x0a0, 0x06, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D8__D8 IOMUX_PAD(D8, D8, 0x29c, 0x0a4, 0x00, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D8__GPIO_4_12 IOMUX_PAD(D8, GPIO_4_12, 0x29c, 0x0a4, 0x05, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D8__USBH2_OC IOMUX_PAD(D8, USBH2_OC, 0x29c, 0x0a4, 0x06, 0x580, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D7__D7 IOMUX_PAD(D7, D7, 0x2a0, 0x0a8, 0x00, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D7__GPIO_4_13 IOMUX_PAD(D7, GPIO_4_13, 0x2a0, 0x0a8, 0x05, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D6__D6 IOMUX_PAD(D6, D6, 0x2a4, 0x0ac, 0x00, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D6__GPIO_4_14 IOMUX_PAD(D6, GPIO_4_14, 0x2a4, 0x0ac, 0x05, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D5__D5 IOMUX_PAD(D5, D5, 0x2a8, 0x0b0, 0x00, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D5__GPIO_4_15 IOMUX_PAD(D5, GPIO_4_15, 0x2a8, 0x0b0, 0x05, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D4__D4 IOMUX_PAD(D4, D4, 0x2ac, 0x0b4, 0x00, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D4__GPIO_4_16 IOMUX_PAD(D4, GPIO_4_16, 0x2ac, 0x0b4, 0x05, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D3__D3 IOMUX_PAD(D3, D3, 0x2b0, 0x0b8, 0x00, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D3__GPIO_4_17 IOMUX_PAD(D3, GPIO_4_17, 0x2b0, 0x0b8, 0x05, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D2__D2 IOMUX_PAD(D2, D2, 0x2b4, 0x0bc, 0x00, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D2__GPIO_4_18 IOMUX_PAD(D2, GPIO_4_18, 0x2b4, 0x0bc, 0x05, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D1__D1 IOMUX_PAD(D1, D1, 0x2b8, 0x0c0, 0x00, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D1__GPIO_4_19 IOMUX_PAD(D1, GPIO_4_19, 0x2b8, 0x0c0, 0x05, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D0__D0 IOMUX_PAD(D0, D0, 0x2bc, 0x0c4, 0x00, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_D0__GPIO_4_20 IOMUX_PAD(D0, GPIO_4_20, 0x2bc, 0x0c4, 0x05, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD0__LD0 IOMUX_PAD(LD0, LD0, 0x2c0, 0x0c8, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD0__CSI_D0 IOMUX_PAD(LD0, CSI_D0, 0x2c0, 0x0c8, 0x12, 0x488, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD0__GPIO_2_15 IOMUX_PAD(LD0, GPIO_2_15, 0x2c0, 0x0c8, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD1__LD1 IOMUX_PAD(LD1, LD1, 0x2c4, 0x0cc, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD1__CSI_D1 IOMUX_PAD(LD1, CSI_D1, 0x2c4, 0x0cc, 0x12, 0x48c, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD1__GPIO_2_16 IOMUX_PAD(LD1, GPIO_2_16, 0x2c4, 0x0cc, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD2__LD2 IOMUX_PAD(LD2, LD2, 0x2c8, 0x0d0, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD2__GPIO_2_17 IOMUX_PAD(LD2, GPIO_2_17, 0x2c8, 0x0d0, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD3__LD3 IOMUX_PAD(LD3, LD3, 0x2cc, 0x0d4, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD3__GPIO_2_18 IOMUX_PAD(LD3, GPIO_2_18, 0x2cc, 0x0d4, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD4__LD4 IOMUX_PAD(LD4, LD4, 0x2d0, 0x0d8, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD4__GPIO_2_19 IOMUX_PAD(LD4, GPIO_2_19, 0x2d0, 0x0d8, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD5__LD5 IOMUX_PAD(LD5, LD5, 0x2d4, 0x0dc, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD5__GPIO_1_19 IOMUX_PAD(LD5, GPIO_1_19, 0x2d4, 0x0dc, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD6__LD6 IOMUX_PAD(LD6, LD6, 0x2d8, 0x0e0, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD6__GPIO_1_20 IOMUX_PAD(LD6, GPIO_1_20, 0x2d8, 0x0e0, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD7__LD7 IOMUX_PAD(LD7, LD7, 0x2dc, 0x0e4, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD7__GPIO_1_21 IOMUX_PAD(LD7, GPIO_1_21, 0x2dc, 0x0e4, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD8__LD8 IOMUX_PAD(LD8, LD8, 0x2e0, 0x0e8, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD8__FEC_TX_ERR IOMUX_PAD(LD8, FEC_TX_ERR, 0x2e0, 0x0e8, 0x15, 0, 0, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_LD9__LD9 IOMUX_PAD(LD9, LD9, 0x2e4, 0x0ec, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD9__FEC_COL IOMUX_PAD(LD9, FEC_COL, 0x2e4, 0x0ec, 0x15, 0x504, 1, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_LD10__LD10 IOMUX_PAD(LD10, LD10, 0x2e8, 0x0f0, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD10__FEC_RX_ER IOMUX_PAD(LD10, FEC_RX_ER, 0x2e8, 0x0f0, 0x15, 0x518, 1, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_LD11__LD11 IOMUX_PAD(LD11, LD11, 0x2ec, 0x0f4, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD11__FEC_RDATA2 IOMUX_PAD(LD11, FEC_RDATA2, 0x2ec, 0x0f4, 0x15, 0x50c, 1, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_LD12__LD12 IOMUX_PAD(LD12, LD12, 0x2f0, 0x0f8, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD12__FEC_RDATA3 IOMUX_PAD(LD12, FEC_RDATA3, 0x2f0, 0x0f8, 0x15, 0x510, 1, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_LD13__LD13 IOMUX_PAD(LD13, LD13, 0x2f4, 0x0fc, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD13__FEC_TDATA2 IOMUX_PAD(LD13, FEC_TDATA2, 0x2f4, 0x0fc, 0x15, 0, 0, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_LD14__LD14 IOMUX_PAD(LD14, LD14, 0x2f8, 0x100, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD14__FEC_TDATA3 IOMUX_PAD(LD14, FEC_TDATA3, 0x2f8, 0x100, 0x15, 0, 0, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_LD15__LD15 IOMUX_PAD(LD15, LD15, 0x2fc, 0x104, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LD15__FEC_RX_CLK IOMUX_PAD(LD15, FEC_RX_CLK, 0x2fc, 0x104, 0x15, 0x514, 1, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_HSYNC__HSYNC IOMUX_PAD(HSYNC, HSYNC, 0x300, 0x108, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_HSYNC__GPIO_1_22 IOMUX_PAD(HSYNC, GPIO_1_22, 0x300, 0x108, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_VSYNC__VSYNC IOMUX_PAD(VSYNC, VSYNC, 0x304, 0x10c, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_VSYNC__GPIO_1_23 IOMUX_PAD(VSYNC, GPIO_1_23, 0x304, 0x10c, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LSCLK__LSCLK IOMUX_PAD(LSCLK, LSCLK, 0x308, 0x110, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_LSCLK__GPIO_1_24 IOMUX_PAD(LSCLK, GPIO_1_24, 0x308, 0x110, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_OE_ACD__OE_ACD IOMUX_PAD(OE_ACD, OE_ACD, 0x30c, 0x114, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_OE_ACD__GPIO_1_25 IOMUX_PAD(OE_ACD, GPIO_1_25, 0x30c, 0x114, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CONTRAST__CONTRAST IOMUX_PAD(CONTRAST, CONTRAST, 0x310, 0x118, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CONTRAST__FEC_CRS IOMUX_PAD(CONTRAST, FEC_CRS, 0x310, 0x118, 0x15, 0x508, 1, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_PWM__PWM IOMUX_PAD(PWM, PWM, 0x314, 0x11c, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_PWM__GPIO_1_26 IOMUX_PAD(PWM, GPIO_1_26, 0x314, 0x11c, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_PWM__USBH2_OC IOMUX_PAD(PWM, USBH2_OC, 0x314, 0x11c, 0x16, 0x580, 1, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_D2__CSI_D2 IOMUX_PAD(CSI_D2, CSI_D2, 0x318, 0x120, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_D2__UART5_RXD_MUX IOMUX_PAD(CSI_D2, UART5_RXD_MUX, 0x318, 0x120, 0x11, 0x578, 1, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_D2__GPIO_1_27 IOMUX_PAD(CSI_D2, GPIO_1_27, 0x318, 0x120, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_D3__CSI_D3 IOMUX_PAD(CSI_D3, CSI_D3, 0x31c, 0x124, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_D3__GPIO_1_28 IOMUX_PAD(CSI_D3, GPIO_1_28, 0x31c, 0x124, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_D4__CSI_D4 IOMUX_PAD(CSI_D4, CSI_D4, 0x320, 0x128, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_D4__UART5_RTS IOMUX_PAD(CSI_D4, UART5_RTS, 0x320, 0x128, 0x11, 0x574, 1, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_D4__GPIO_1_29 IOMUX_PAD(CSI_D4, GPIO_1_29, 0x320, 0x128, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_D5__CSI_D5 IOMUX_PAD(CSI_D5, CSI_D5, 0x324, 0x12c, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_D5__GPIO_1_30 IOMUX_PAD(CSI_D5, GPIO_1_30, 0x324, 0x12c, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_D6__CSI_D6 IOMUX_PAD(CSI_D6, CSI_D6, 0x328, 0x130, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_D6__GPIO_1_31 IOMUX_PAD(CSI_D6, GPIO_1_31, 0x328, 0x130, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_D7__CSI_D7 IOMUX_PAD(CSI_D7, CSI_D7, 0x32c, 0x134, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_D7__GPIO_1_6 IOMUX_PAD(CSI_D7, GPIO_1_6, 0x32c, 0x134, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_D8__CSI_D8 IOMUX_PAD(CSI_D8, CSI_D8, 0x330, 0x138, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_D8__GPIO_1_7 IOMUX_PAD(CSI_D8, GPIO_1_7, 0x330, 0x138, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_D9__CSI_D9 IOMUX_PAD(CSI_D9, CSI_D9, 0x334, 0x13c, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_D9__GPIO_4_21 IOMUX_PAD(CSI_D9, GPIO_4_21, 0x334, 0x13c, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_MCLK__CSI_MCLK IOMUX_PAD(CSI_MCLK, CSI_MCLK, 0x338, 0x140, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_MCLK__GPIO_1_8 IOMUX_PAD(CSI_MCLK, GPIO_1_8, 0x338, 0x140, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_VSYNC__CSI_VSYNC IOMUX_PAD(CSI_VSYNC, CSI_VSYNC, 0x33c, 0x144, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_VSYNC__GPIO_1_9 IOMUX_PAD(CSI_VSYNC, GPIO_1_9, 0x33c, 0x144, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_HSYNC__CSI_HSYNC IOMUX_PAD(CSI_HSYNC, CSI_HSYNC, 0x340, 0x148, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_HSYNC__GPIO_1_10 IOMUX_PAD(CSI_HSYNC, GPIO_1_10, 0x340, 0x148, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_PIXCLK__CSI_PIXCLK IOMUX_PAD(CSI_PIXCLK, CSI_PIXCLK, 0x344, 0x14c, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSI_PIXCLK__GPIO_1_11 IOMUX_PAD(CSI_PIXCLK, GPIO_1_11, 0x344, 0x14c, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_I2C1_CLK__I2C1_CLK IOMUX_PAD(I2C1_CLK, I2C1_CLK, 0x348, 0x150, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_I2C1_CLK__GPIO_1_12 IOMUX_PAD(I2C1_CLK, GPIO_1_12, 0x348, 0x150, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_I2C1_DAT__I2C1_DAT IOMUX_PAD(I2C1_DAT, I2C1_DAT, 0x34c, 0x154, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_I2C1_DAT__GPIO_1_13 IOMUX_PAD(I2C1_DAT, GPIO_1_13, 0x34c, 0x154, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSPI1_MOSI__CSPI1_MOSI IOMUX_PAD(CSPI1_MOSI, CSPI1_MOSI, 0x350, 0x158, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSPI1_MOSI__GPIO_1_14 IOMUX_PAD(CSPI1_MOSI, GPIO_1_14, 0x350, 0x158, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSPI1_MISO__CSPI1_MISO IOMUX_PAD(CSPI1_MISO, CSPI1_MISO, 0x354, 0x15c, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSPI1_MISO__GPIO_1_15 IOMUX_PAD(CSPI1_MISO, GPIO_1_15, 0x354, 0x15c, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSPI1_SS0__CSPI1_SS0 IOMUX_PAD(CSPI1_SS0, CSPI1_SS0, 0x358, 0x160, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSPI1_SS0__GPIO_1_16 IOMUX_PAD(CSPI1_SS0, GPIO_1_16, 0x358, 0x160, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSPI1_SS1__CSPI1_SS1 IOMUX_PAD(CSPI1_SS1, CSPI1_SS1, 0x35c, 0x164, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSPI1_SS1__GPIO_1_17 IOMUX_PAD(CSPI1_SS1, GPIO_1_17, 0x35c, 0x164, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSPI1_SCLK__CSPI1_SCLK IOMUX_PAD(CSPI1_SCLK, CSPI1_SCLK, 0x360, 0x168, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSPI1_SCLK__GPIO_1_18 IOMUX_PAD(CSPI1_SCLK, GPIO_1_18, 0x360, 0x168, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CSPI1_RDY__CSPI1_RDY IOMUX_PAD(CSPI1_RDY, CSPI1_RDY, 0x364, 0x16c, 0x10, 0, 0, PAD_CTL_PULL_KEEPER) +#define MX25_PAD_CSPI1_RDY__GPIO_2_22 IOMUX_PAD(CSPI1_RDY, GPIO_2_22, 0x364, 0x16c, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_UART1_RXD__UART1_RXD IOMUX_PAD(UART1_RXD, UART1_RXD, 0x368, 0x170, 0x10, 0, 0, PAD_CTL_PULL_DOWN_100K) +#define MX25_PAD_UART1_RXD__GPIO_4_22 IOMUX_PAD(UART1_RXD, GPIO_4_22, 0x368, 0x170, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_UART1_TXD__UART1_TXD IOMUX_PAD(UART1_TXD, UART1_TXD, 0x36c, 0x174, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_UART1_TXD__GPIO_4_23 IOMUX_PAD(UART1_TXD, GPIO_4_23, 0x36c, 0x174, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_UART1_RTS__UART1_RTS IOMUX_PAD(UART1_RTS, UART1_RTS, 0x370, 0x178, 0x10, 0, 0, PAD_CTL_PULL_UP_100K) +#define MX25_PAD_UART1_RTS__CSI_D0 IOMUX_PAD(UART1_RTS, CSI_D0, 0x370, 0x178, 0x11, 0x488, 1, 0 | NO_PAD_CTRL) +#define MX25_PAD_UART1_RTS__GPIO_4_24 IOMUX_PAD(UART1_RTS, GPIO_4_24, 0x370, 0x178, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_UART1_CTS__UART1_CTS IOMUX_PAD(UART1_CTS, UART1_CTS, 0x374, 0x17c, 0x10, 0, 0, PAD_CTL_PULL_UP_100K) +#define MX25_PAD_UART1_CTS__CSI_D1 IOMUX_PAD(UART1_CTS, CSI_D1, 0x374, 0x17c, 0x11, 0x48c, 1, 0 | NO_PAD_CTRL) +#define MX25_PAD_UART1_CTS__GPIO_4_25 IOMUX_PAD(UART1_CTS, GPIO_4_25, 0x374, 0x17c, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_UART2_RXD__UART2_RXD IOMUX_PAD(UART2_RXD, UART2_RXD, 0x378, 0x180, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_UART2_RXD__GPIO_4_26 IOMUX_PAD(UART2_RXD, GPIO_4_26, 0x378, 0x180, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_UART2_TXD__UART2_TXD IOMUX_PAD(UART2_TXD, UART2_TXD, 0x37c, 0x184, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_UART2_TXD__GPIO_4_27 IOMUX_PAD(UART2_TXD, GPIO_4_27, 0x37c, 0x184, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_UART2_RTS__UART2_RTS IOMUX_PAD(UART2_RTS, UART2_RTS, 0x380, 0x188, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_UART2_RTS__FEC_COL IOMUX_PAD(UART2_RTS, FEC_COL, 0x380, 0x188, 0x12, 0x504, 2, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_UART2_RTS__GPIO_4_28 IOMUX_PAD(UART2_RTS, GPIO_4_28, 0x380, 0x188, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_UART2_CTS__FEC_RX_ER IOMUX_PAD(UART2_CTS, FEC_RX_ER, 0x384, 0x18c, 0x12, 0x518, 2, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_UART2_CTS__UART2_CTS IOMUX_PAD(UART2_CTS, UART2_CTS, 0x384, 0x18c, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_UART2_CTS__GPIO_4_29 IOMUX_PAD(UART2_CTS, GPIO_4_29, 0x384, 0x18c, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(SD1_CMD, SD1_CMD, 0x388, 0x190, 0x10, 0, 0, PAD_CTL_PULL_UP_47K | PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_SD1_CMD__FEC_RDATA2 IOMUX_PAD(SD1_CMD, FEC_RDATA2, 0x388, 0x190, 0x12, 0x50c, 2, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_SD1_CMD__GPIO_2_23 IOMUX_PAD(SD1_CMD, GPIO_2_23, 0x388, 0x190, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(SD1_CLK, SD1_CLK, 0x38c, 0x194, 0x10, 0, 0, PAD_CTL_PULL_UP_47K | PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_SD1_CLK__FEC_RDATA3 IOMUX_PAD(SD1_CLK, FEC_RDATA3, 0x38c, 0x194, 0x12, 0x510, 2, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_SD1_CLK__GPIO_2_24 IOMUX_PAD(SD1_CLK, GPIO_2_24, 0x38c, 0x194, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(SD1_DATA0, SD1_DATA0, 0x390, 0x198, 0x10, 0, 0, PAD_CTL_PULL_UP_47K | PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_SD1_DATA0__GPIO_2_25 IOMUX_PAD(SD1_DATA0, GPIO_2_25, 0x390, 0x198, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_SD1_DATA1__SD1_DATA1 IOMUX_PAD(SD1_DATA1, SD1_DATA1, 0x394, 0x19c, 0x10, 0, 0, PAD_CTL_PULL_UP_47K | PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_SD1_DATA1__AUD7_RXD IOMUX_PAD(SD1_DATA1, AUD7_RXD, 0x394, 0x19c, 0x13, 0x478, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_SD1_DATA1__GPIO_2_26 IOMUX_PAD(SD1_DATA1, GPIO_2_26, 0x394, 0x19c, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(SD1_DATA2, SD1_DATA2, 0x398, 0x1a0, 0x10, 0, 0, PAD_CTL_PULL_UP_47K | PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_SD1_DATA2__FEC_RX_CLK IOMUX_PAD(SD1_DATA2, FEC_RX_CLK, 0x398, 0x1a0, 0x15, 0x514, 2, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_SD1_DATA2__GPIO_2_27 IOMUX_PAD(SD1_DATA2, GPIO_2_27, 0x398, 0x1a0, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(SD1_DATA3, SD1_DATA3, 0x39c, 0x1a4, 0x10, 0, 0, PAD_CTL_PULL_UP_47K | PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_SD1_DATA3__FEC_CRS IOMUX_PAD(SD1_DATA3, FEC_CRS, 0x39c, 0x1a4, 0x10, 0x508, 2, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_SD1_DATA3__GPIO_2_28 IOMUX_PAD(SD1_DATA3, GPIO_2_28, 0x39c, 0x1a4, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_KPP_ROW0__KPP_ROW0 IOMUX_PAD(KPP_ROW0, KPP_ROW0, 0x3a0, 0x1a8, 0x10, 0, 0, PAD_CTL_PULL_KEEPER) +#define MX25_PAD_KPP_ROW0__GPIO_2_29 IOMUX_PAD(KPP_ROW0, GPIO_2_29, 0x3a0, 0x1a8, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_KPP_ROW1__KPP_ROW1 IOMUX_PAD(KPP_ROW1, KPP_ROW1, 0x3a4, 0x1ac, 0x10, 0, 0, PAD_CTL_PULL_KEEPER) +#define MX25_PAD_KPP_ROW1__GPIO_2_30 IOMUX_PAD(KPP_ROW1, GPIO_2_30, 0x3a4, 0x1ac, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_KPP_ROW2__KPP_ROW2 IOMUX_PAD(KPP_ROW2, KPP_ROW2, 0x3a8, 0x1b0, 0x10, 0, 0, PAD_CTL_PULL_KEEPER) +#define MX25_PAD_KPP_ROW2__CSI_D0 IOMUX_PAD(KPP_ROW2, CSI_D0, 0x3a8, 0x1b0, 0x13, 0x488, 2, 0 | NO_PAD_CTRL) +#define MX25_PAD_KPP_ROW2__GPIO_2_31 IOMUX_PAD(KPP_ROW2, GPIO_2_31, 0x3a8, 0x1b0, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_KPP_ROW3__KPP_ROW3 IOMUX_PAD(KPP_ROW3, KPP_ROW3, 0x3ac, 0x1b4, 0x10, 0, 0, PAD_CTL_PULL_KEEPER) +#define MX25_PAD_KPP_ROW3__CSI_LD1 IOMUX_PAD(KPP_ROW3, CSI_LD1, 0x3ac, 0x1b4, 0x13, 0x48c, 2, 0 | NO_PAD_CTRL) +#define MX25_PAD_KPP_ROW3__GPIO_3_0 IOMUX_PAD(KPP_ROW3, GPIO_3_0, 0x3ac, 0x1b4, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_KPP_COL0__KPP_COL0 IOMUX_PAD(KPP_COL0, KPP_COL0, 0x3b0, 0x1b8, 0x10, 0, 0, PAD_CTL_PULL_KEEPER | PAD_CTL_OUTPUT_OPEN_DRAIN) +#define MX25_PAD_KPP_COL0__GPIO_3_1 IOMUX_PAD(KPP_COL0, GPIO_3_1, 0x3b0, 0x1b8, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_KPP_COL1__KPP_COL1 IOMUX_PAD(KPP_COL1, KPP_COL1, 0x3b4, 0x1bc, 0x10, 0, 0, PAD_CTL_PULL_KEEPER | PAD_CTL_OUTPUT_OPEN_DRAIN) +#define MX25_PAD_KPP_COL1__GPIO_3_2 IOMUX_PAD(KPP_COL1, GPIO_3_2, 0x3b4, 0x1bc, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_KPP_COL2__KPP_COL2 IOMUX_PAD(KPP_COL2, KPP_COL2, 0x3b8, 0x1c0, 0x10, 0, 0, PAD_CTL_PULL_KEEPER | PAD_CTL_OUTPUT_OPEN_DRAIN) +#define MX25_PAD_KPP_COL2__GPIO_3_3 IOMUX_PAD(KPP_COL2, GPIO_3_3, 0x3b8, 0x1c0, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_KPP_COL3__KPP_COL3 IOMUX_PAD(KPP_COL3, KPP_COL3, 0x3bc, 0x1c4, 0x10, 0, 0, PAD_CTL_PULL_KEEPER | PAD_CTL_OUTPUT_OPEN_DRAIN) +#define MX25_PAD_KPP_COL3__GPIO_3_4 IOMUX_PAD(KPP_COL3, GPIO_3_4, 0x3bc, 0x1c4, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_FEC_MDC__FEC_MDC IOMUX_PAD(FEC_MDC, FEC_MDC, 0x3c0, 0x1c8, 0x10, 0, 0, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_FEC_MDC__AUD4_TXD IOMUX_PAD(FEC_MDC, AUD4_TXD, 0x3c0, 0x1c8, 0x12, 0x464, 1, 0 | NO_PAD_CTRL) +#define MX25_PAD_FEC_MDC__GPIO_3_5 IOMUX_PAD(FEC_MDC, GPIO_3_5, 0x3c0, 0x1c8, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_FEC_MDIO__FEC_MDIO IOMUX_PAD(FEC_MDIO, FEC_MDIO, 0x3c4, 0x1cc, 0x10, 0, 0, PAD_CTL_HYSTERESIS | PAD_CTL_PULL_UP_22K | PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_FEC_MDIO__AUD4_RXD IOMUX_PAD(FEC_MDIO, AUD4_RXD, 0x3c4, 0x1cc, 0x12, 0x460, 1, 0 | NO_PAD_CTRL) +#define MX25_PAD_FEC_MDIO__GPIO_3_6 IOMUX_PAD(FEC_MDIO, GPIO_3_6, 0x3c4, 0x1cc, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_FEC_TDATA0__FEC_TDATA0 IOMUX_PAD(FEC_TDATA0, FEC_TDATA0, 0x3c8, 0x1d0, 0x10, 0, 0, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_FEC_TDATA0__GPIO_3_7 IOMUX_PAD(FEC_TDATA0, GPIO_3_7, 0x3c8, 0x1d0, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_FEC_TDATA1__FEC_TDATA1 IOMUX_PAD(FEC_TDATA1, FEC_TDATA1, 0x3cc, 0x1d4, 0x10, 0, 0, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_FEC_TDATA1__AUD4_TXFS IOMUX_PAD(FEC_TDATA1, AUD4_TXFS, 0x3cc, 0x1d4, 0x12, 0x474, 1, 0 | NO_PAD_CTRL) +#define MX25_PAD_FEC_TDATA1__GPIO_3_8 IOMUX_PAD(FEC_TDATA1, GPIO_3_8, 0x3cc, 0x1d4, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_FEC_TX_EN__FEC_TX_EN IOMUX_PAD(FEC_TX_EN, FEC_TX_EN, 0x3d0, 0x1d8, 0x10, 0, 0, PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_FEC_TX_EN__GPIO_3_9 IOMUX_PAD(FEC_TX_EN, GPIO_3_9 , 0x3d0, 0x1d8, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_FEC_RDATA0__FEC_RDATA0 IOMUX_PAD(FEC_RDATA0, FEC_RDATA0, 0x3d4, 0x1dc, 0x10, 0, 0, PAD_CTL_PULL_DOWN_100K | PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_FEC_RDATA0__GPIO_3_10 IOMUX_PAD(FEC_RDATA0, GPIO_3_10, 0x3d4, 0x1dc, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_FEC_RDATA1__FEC_RDATA1 IOMUX_PAD(FEC_RDATA1, FEC_RDATA1, 0x3d8, 0x1e0, 0x10, 0, 0, PAD_CTL_PULL_DOWN_100K | PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_FEC_RDATA1__GPIO_3_11 IOMUX_PAD(FEC_RDATA1, GPIO_3_11, 0x3d8, 0x1e0, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_FEC_RX_DV__FEC_RX_DV IOMUX_PAD(FEC_RX_DV, FEC_RX_DV, 0x3dc, 0x1e4, 0x10, 0, 0, PAD_CTL_PULL_DOWN_100K | PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_FEC_RX_DV__CAN2_RX IOMUX_PAD(FEC_RX_DV, CAN2_RX, 0x3dc, 0x1e4, 0x14, 0x484, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_FEC_RX_DV__GPIO_3_12 IOMUX_PAD(FEC_RX_DV, GPIO_3_12, 0x3dc, 0x1e4, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_FEC_TX_CLK__FEC_TX_CLK IOMUX_PAD(FEC_TX_CLK, FEC_TX_CLK, 0x3e0, 0x1e8, 0x10, 0, 0, PAD_CTL_HYSTERESIS | PAD_CTL_PULL_DOWN_100K | PAD_CTL_SLEW_RATE_FAST) +#define MX25_PAD_FEC_TX_CLK__GPIO_3_13 IOMUX_PAD(FEC_TX_CLK, GPIO_3_13, 0x3e0, 0x1e8, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_RTCK__RTCK IOMUX_PAD(RTCK, RTCK, 0x3e4, 0x1ec, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_RTCK__OWIRE IOMUX_PAD(RTCK, OWIRE, 0x3e4, 0x1ec, 0x11, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_RTCK__GPIO_3_14 IOMUX_PAD(RTCK, GPIO_3_14, 0x3e4, 0x1ec, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_DE_B__DE_B IOMUX_PAD(DE_B, DE_B, 0x3ec, 0x1f0, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_DE_B__GPIO_2_20 IOMUX_PAD(DE_B, GPIO_2_20, 0x3ec, 0x1f0, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_TDO__TDO IOMUX_PAD(TDO, TDO, 0x3e8, 0x000, 0x00, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_GPIO_A__GPIO_A IOMUX_PAD(GPIO_A, GPIO_A, 0x3f0, 0x1f4, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_GPIO_A__USBOTG_PWR IOMUX_PAD(GPIO_A, USBOTG_PWR, 0x3f0, 0x1f4, 0x12, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_GPIO_B__GPIO_B IOMUX_PAD(GPIO_B, GPIO_B, 0x3f4, 0x1f8, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_GPIO_B__USBOTG_OC IOMUX_PAD(GPIO_B, USBOTG_OC, 0x3f4, 0x1f8, 0x12, 0x57c, 1, 0 | NO_PAD_CTRL) +#define MX25_PAD_GPIO_C__GPIO_C IOMUX_PAD(GPIO_C, GPIO_C, 0x3f8, 0x1fc, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_GPIO_C__CAN2_TX IOMUX_PAD(GPIO_C, CAN2_TX, 0x3f8, 0x1fc, 0x16, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_GPIO_D__GPIO_D IOMUX_PAD(GPIO_D, GPIO_D, 0x3fc, 0x200, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_GPIO_D__CAN2_RX IOMUX_PAD(GPIO_D, CAN2_RX, 0x3fc, 0x200, 0x16, 0x484, 1, 0 | NO_PAD_CTRL) +#define MX25_PAD_GPIO_E__GPIO_E IOMUX_PAD(GPIO_E, GPIO_E, 0x400, 0x204, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_GPIO_E__AUD7_TXD IOMUX_PAD(GPIO_E, AUD7_TXD, 0x400, 0x204, 0x14, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_GPIO_F__GPIO_F IOMUX_PAD(GPIO_F, GPIO_F, 0x404, 0x208, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_GPIO_F__AUD7_TXC IOMUX_PAD(GPIO_F, AUD7_TXC, 0x404, 0x208, 0x14, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_EXT_ARMCLK__EXT_ARMCLK IOMUX_PAD(EXT_ARMCLK, EXT_ARMCLK, 0x000, 0x20c, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_EXT_ARMCLK__GPIO_3_15 IOMUX_PAD(EXT_ARMCLK, GPIO_3_15, 0x000, 0x20c, 0x15, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_UPLL_BYPCLK__UPLL_BYPCLK IOMUX_PAD(UPLL_BYPCLK, UPLL_BYPCLK, 0x000, 0x210, 0x10, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_UPLL_BYPCLK__GPIO_3_16 IOMUX_PAD(UPLL_BYPCLK, GPIO_3_16, 0x000, 0x210, 0x15, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_VSTBY_REQ__VSTBY_REQ IOMUX_PAD(VSTBY_REQ, VSTBY_REQ, 0x408, 0x214, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_VSTBY_REQ__AUD7_TXFS IOMUX_PAD(VSTBY_REQ, AUD7_TXFS, 0x408, 0x214, 0x14, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_VSTBY_REQ__GPIO_3_17 IOMUX_PAD(VSTBY_REQ, GPIO_3_17, 0x408, 0x214, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_VSTBY_ACK__VSTBY_ACK IOMUX_PAD(VSTBY_ACK, VSTBY_ACK, 0x40c, 0x218, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_VSTBY_ACK__GPIO_3_18 IOMUX_PAD(VSTBY_ACK, GPIO_3_18, 0x40c, 0x218, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_POWER_FAIL__POWER_FAIL IOMUX_PAD(POWER_FAIL, POWER_FAIL, 0x410, 0x21c, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_POWER_FAIL__AUD7_RXD IOMUX_PAD(POWER_FAIL, AUD7_RXD, 0x410, 0x21c, 0x14, 0x478, 1, 0 | NO_PAD_CTRL) +#define MX25_PAD_POWER_FAIL__GPIO_3_19 IOMUX_PAD(POWER_FAIL, GPIO_3_19, 0x410, 0x21c, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CLKO__CLKO IOMUX_PAD(CLKO, CLKO, 0x414, 0x220, 0x10, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_CLKO__GPIO_2_21 IOMUX_PAD(CLKO, GPIO_2_21, 0x414, 0x220, 0x15, 0, 0, 0 | NO_PAD_CTRL) +#define MX25_PAD_BOOT_MODE0__BOOT_MODE0 IOMUX_PAD(BOOT_MODE0, BOOT_MODE0, 0x000, 0x224, 0x00, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_BOOT_MODE0__GPIO_4_30 IOMUX_PAD(BOOT_MODE0, GPIO_4_30, 0x000, 0x224, 0x05, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_BOOT_MODE1__BOOT_MODE1 IOMUX_PAD(BOOT_MODE1, BOOT_MODE1, 0x000, 0x228, 0x00, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_BOOT_MODE1__GPIO_4_31 IOMUX_PAD(BOOT_MODE1, GPIO_4_31, 0x000, 0x228, 0x05, 0, 0, NO_PAD_CTRL) + +#define MX25_PAD_CTL_GRP_DVS_MISC IOMUX_PAD(0x418, 0x000, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CTL_GRP_DSE_FEC IOMUX_PAD(0x41c, 0x000, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CTL_GRP_DVS_JTAG IOMUX_PAD(0x420, 0x000, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CTL_GRP_DSE_NFC IOMUX_PAD(0x424, 0x000, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CTL_GRP_DSE_CSI IOMUX_PAD(0x428, 0x000, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CTL_GRP_DSE_WEIM IOMUX_PAD(0x42c, 0x000, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CTL_GRP_DSE_DDR IOMUX_PAD(0x430, 0x000, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CTL_GRP_DVS_CRM IOMUX_PAD(0x434, 0x000, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CTL_GRP_DSE_KPP IOMUX_PAD(0x438, 0x000, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CTL_GRP_DSE_SDHC1 IOMUX_PAD(0x43c, 0x000, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CTL_GRP_DSE_LCD IOMUX_PAD(0x440, 0x000, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CTL_GRP_DSE_UART IOMUX_PAD(0x444, 0x000, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CTL_GRP_DVS_NFC IOMUX_PAD(0x448, 0x000, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CTL_GRP_DVS_CSI IOMUX_PAD(0x44c, 0x000, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CTL_GRP_DSE_CSPI1 IOMUX_PAD(0x450, 0x000, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CTL_GRP_DDRTYPE IOMUX_PAD(0x454, 0x000, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CTL_GRP_DVS_SDHC1 IOMUX_PAD(0x458, 0x000, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_CTL_GRP_DVS_LCD IOMUX_PAD(0x45c, 0x000, 0, 0, 0, NO_PAD_CTRL) + +#if 0 +enum { + GPIO_A, + GPIO_B, + GPIO_C, + GPIO_D, + GPIO_E, + GPIO_F, + GPIO_1_6, + GPIO_1_7, + GPIO_1_8, + GPIO_1_9, + GPIO_1_10, + GPIO_1_11, + GPIO_1_12, + GPIO_1_13, + GPIO_1_14, + GPIO_1_15, + GPIO_1_16, + GPIO_1_17, + GPIO_1_18, + GPIO_1_19, + GPIO_1_20, + GPIO_1_21, + GPIO_1_22, + GPIO_1_23, + GPIO_1_24, + GPIO_1_25, + GPIO_1_26, + GPIO_1_27, + GPIO_1_28, + GPIO_1_29, + GPIO_1_30, + GPIO_1_31, + GPIO_2_0, + GPIO_2_1, + GPIO_2_2, + GPIO_2_3, + GPIO_2_4, + GPIO_2_5, + GPIO_2_6, + GPIO_2_7, + GPIO_2_8, + GPIO_2_9, + GPIO_2_10, + GPIO_2_11, + GPIO_2_12, + GPIO_2_13, + GPIO_2_14, + GPIO_2_15, + GPIO_2_16, + GPIO_2_17, + GPIO_2_18, + GPIO_2_19, + GPIO_2_20, + GPIO_2_21, + GPIO_2_22, + GPIO_2_23, + GPIO_2_24, + GPIO_2_25, + GPIO_2_26, + GPIO_2_27, + GPIO_2_28, + GPIO_2_29, + GPIO_2_30, + GPIO_2_31, + GPIO_3_0, + GPIO_3_1, + GPIO_3_2, + GPIO_3_3, + GPIO_3_4, + GPIO_3_5, + GPIO_3_6, + GPIO_3_7, + GPIO_3_8, + GPIO_3_9, + GPIO_3_10, + GPIO_3_11, + GPIO_3_12, + GPIO_3_13, + GPIO_3_14, + GPIO_3_15, + GPIO_3_16, + GPIO_3_17, + GPIO_3_18, + GPIO_3_19, + GPIO_3_20, + GPIO_3_21, + GPIO_3_22, + GPIO_3_23, + GPIO_3_24, + GPIO_3_25, + GPIO_3_26, + GPIO_3_27, + GPIO_3_28, + GPIO_3_29, + GPIO_3_30, + GPIO_3_31, + GPIO_4_0, + GPIO_4_1, + GPIO_4_2, + GPIO_4_3, + GPIO_4_4, + GPIO_4_5, + GPIO_4_6, + GPIO_4_7, + GPIO_4_8, + GPIO_4_9, + GPIO_4_10, + GPIO_4_11, + GPIO_4_12, + GPIO_4_13, + GPIO_4_14, + GPIO_4_15, + GPIO_4_16, + GPIO_4_17, + GPIO_4_18, + GPIO_4_19, + GPIO_4_20, + GPIO_4_21, + GPIO_4_22, + GPIO_4_23, + GPIO_4_24, + GPIO_4_25, + GPIO_4_26, + GPIO_4_27, + GPIO_4_28, + GPIO_4_29, + GPIO_4_30, + GPIO_4_31, +}; + +#define IOMUX_TO_GPIO(__pad_desc) ({ \ + int __gpio = -1; \ + struct pad_desc *__pd = __pad_desc; \ + \ + switch (__pd->mux_ctrl_ofs) { \ + case MX25_PAD_GPIO_A__GPIO_A: \ + __gpio = GPIO_A; \ + break; \ + case MX25_PAD_GPIO_B__GPIO_B: \ + __gpio = GPIO_B; \ + break; \ + case MX25_PAD_GPIO_C__GPIO_C: \ + __gpio = GPIO_C; \ + break; \ + case MX25_PAD_GPIO_D__GPIO_D: \ + __gpio = GPIO_D; \ + break; \ + case MX25_PAD_GPIO_E__GPIO_E: \ + __gpio = GPIO_E; \ + break; \ + case MX25_PAD_GPIO_F__GPIO_F: \ + __gpio = GPIO_F; \ + break; \ + case MX25_PAD_CSI_D7__GPIO_1_6: \ + __gpio = GPIO_1_6; \ + break; \ + case MX25_PAD_CSI_D8__GPIO_1_7: \ + __gpio = GPIO_1_7; \ + break; \ + case MX25_PAD_CSI_MCLK__GPIO_1_8: \ + __gpio = GPIO_1_8; \ + break; \ + case MX25_PAD_CSI_VSYNC__GPIO_1_9: \ + __gpio = GPIO_1_9; \ + break; \ + case MX25_PAD_CSI_HSYNC__GPIO_1_10: \ + __gpio = GPIO_1_10; \ + break; \ + case MX25_PAD_CSI_PIXCLK__GPIO_1_11: \ + __gpio = GPIO_1_11; \ + break; \ + case MX25_PAD_I2C1_CLK__GPIO_1_12: \ + __gpio = GPIO_1_12; \ + break; \ + case MX25_PAD_I2C1_DAT__GPIO_1_13: \ + __gpio = GPIO_1_13; \ + break; \ + case MX25_PAD_CSPI1_MOSI__GPIO_1_14: \ + __gpio = GPIO_1_14; \ + break; \ + case MX25_PAD_CSPI1_MISO__GPIO_1_15: \ + __gpio = GPIO_1_15; \ + break; \ + case MX25_PAD_CSPI1_SS0__GPIO_1_16: \ + __gpio = GPIO_1_16; \ + break; \ + case MX25_PAD_CSPI1_SS1__GPIO_1_17: \ + __gpio = GPIO_1_17; \ + break; \ + case MX25_PAD_CSPI1_SCLK__GPIO_1_18: \ + __gpio = GPIO_1_18; \ + break; \ + case MX25_PAD_LD5__GPIO_1_19: \ + __gpio = GPIO_1_19; \ + break; \ + case MX25_PAD_LD6__GPIO_1_20: \ + __gpio = GPIO_1_20; \ + break; \ + case MX25_PAD_LD7__GPIO_1_21: \ + __gpio = GPIO_1_21; \ + break; \ + case MX25_PAD_HSYNC__GPIO_1_22: \ + __gpio = GPIO_1_22; \ + break; \ + case MX25_PAD_VSYNC__GPIO_1_23: \ + __gpio = GPIO_1_23; \ + break; \ + case MX25_PAD_LSCLK__GPIO_1_24: \ + __gpio = GPIO_1_24; \ + break; \ + case MX25_PAD_OE_ACD__GPIO_1_25: \ + __gpio = GPIO_1_25; \ + break; \ + case MX25_PAD_PWM__GPIO_1_26: \ + __gpio = GPIO_1_26; \ + break; \ + case MX25_PAD_CSI_D2__GPIO_1_27: \ + __gpio = GPIO_1_27; \ + break; \ + case MX25_PAD_CSI_D3__GPIO_1_28: \ + __gpio = GPIO_1_28; \ + break; \ + case MX25_PAD_CSI_D4__GPIO_1_29: \ + __gpio = GPIO_1_29; \ + break; \ + case MX25_PAD_CSI_D5__GPIO_1_30: \ + __gpio = GPIO_1_30; \ + break; \ + case MX25_PAD_CSI_D6__GPIO_1_31: \ + __gpio = GPIO_1_31; \ + break; \ + \ + case MX25_PAD_A14__GPIO_2_0: \ + __gpio = GPIO_2_0; \ + break; \ + case MX25_PAD_A15__GPIO_2_1: \ + __gpio = GPIO_2_1; \ + break; \ + case MX25_PAD_A16__GPIO_2_2: \ + __gpio = GPIO_2_2; \ + break; \ + case MX25_PAD_A17__GPIO_2_3: \ + __gpio = GPIO_2_3; \ + break; \ + case MX25_PAD_A18__GPIO_2_4: \ + __gpio = GPIO_2_4; \ + break; \ + case MX25_PAD_A19__GPIO_2_5: \ + __gpio = GPIO_2_5; \ + break; \ + case MX25_PAD_A20__GPIO_2_6: \ + __gpio = GPIO_2_6; \ + break; \ + case MX25_PAD_A21__GPIO_2_7: \ + __gpio = GPIO_2_7; \ + break; \ + case MX25_PAD_A22__GPIO_2_8: \ + __gpio = GPIO_2_8; \ + break; \ + case MX25_PAD_A23__GPIO_2_9: \ + __gpio = GPIO_2_9; \ + break; \ + case MX25_PAD_A24__GPIO_2_10: \ + __gpio = GPIO_2_10; \ + break; \ + case MX25_PAD_A25__GPIO_2_11: \ + __gpio = GPIO_2_11; \ + break; \ + case MX25_PAD_EB0__GPIO_2_12: \ + __gpio = GPIO_2_12; \ + break; \ + case MX25_PAD_EB1__GPIO_2_13: \ + __gpio = GPIO_2_13; \ + break; \ + case MX25_PAD_OE__GPIO_2_14: \ + __gpio = GPIO_2_14; \ + break; \ + case MX25_PAD_LD0__GPIO_2_15: \ + __gpio = GPIO_2_15; \ + break; \ + case MX25_PAD_LD1__GPIO_2_16: \ + __gpio = GPIO_2_16; \ + break; \ + case MX25_PAD_LD2__GPIO_2_17: \ + __gpio = GPIO_2_17; \ + break; \ + case MX25_PAD_LD3__GPIO_2_18: \ + __gpio = GPIO_2_18; \ + break; \ + case MX25_PAD_LD4__GPIO_2_19: \ + __gpio = GPIO_2_19; \ + break; \ + case MX25_PAD_DE_B__GPIO_2_20: \ + __gpio = GPIO_2_20; \ + break; \ + case MX25_PAD_CLKO__GPIO_2_21: \ + __gpio = GPIO_2_21; \ + break; \ + case MX25_PAD_CSPI1_RDY__GPIO_2_22: \ + __gpio = GPIO_2_22; \ + break; \ + case MX25_PAD_SD1_CMD__GPIO_2_23: \ + __gpio = GPIO_2_23; \ + break; \ + case MX25_PAD_SD1_CLK__GPIO_2_24: \ + __gpio = GPIO_2_24; \ + break; \ + case MX25_PAD_SD1_DATA0__GPIO_2_25: \ + __gpio = GPIO_2_25; \ + break; \ + case MX25_PAD_SD1_DATA1__GPIO_2_26: \ + __gpio = GPIO_2_26; \ + break; \ + case MX25_PAD_SD1_DATA2__GPIO_2_27: \ + __gpio = GPIO_2_27; \ + break; \ + case MX25_PAD_SD1_DATA3__GPIO_2_28: \ + __gpio = GPIO_2_28; \ + break; \ + case MX25_PAD_KPP_ROW0__GPIO_2_29: \ + __gpio = GPIO_2_29; \ + break; \ + case MX25_PAD_KPP_ROW1__GPIO_2_30: \ + __gpio = GPIO_2_30; \ + break; \ + case MX25_PAD_KPP_ROW2__GPIO_2_31: \ + __gpio = GPIO_2_31; \ + break; \ + \ + case MX25_PAD_KPP_ROW3__GPIO_3_0: \ + __gpio = GPIO_3_0; \ + break; \ + case MX25_PAD_KPP_COL0__GPIO_3_1: \ + __gpio = GPIO_3_1; \ + break; \ + case MX25_PAD_KPP_COL1__GPIO_3_2: \ + __gpio = GPIO_3_2; \ + break; \ + case MX25_PAD_KPP_COL2__GPIO_3_3: \ + __gpio = GPIO_3_3; \ + break; \ + case MX25_PAD_KPP_COL3__GPIO_3_4: \ + __gpio = GPIO_3_4; \ + break; \ + case MX25_PAD_FEC_MDC__GPIO_3_5: \ + __gpio = GPIO_3_5; \ + break; \ + case MX25_PAD_FEC_MDIO__GPIO_3_6: \ + __gpio = GPIO_3_6; \ + break; \ + case MX25_PAD_FEC_TDATA0__GPIO_3_7: \ + __gpio = GPIO_3_7; \ + break; \ + case MX25_PAD_FEC_TDATA1__GPIO_3_8: \ + __gpio = GPIO_3_8; \ + break; \ + case MX25_PAD_FEC_TX_EN__GPIO_3_9: \ + __gpio = GPIO_3_9; \ + break; \ + case MX25_PAD_FEC_RDATA0__GPIO_3_10: \ + __gpio = GPIO_3_10; \ + break; \ + case MX25_PAD_FEC_RDATA1__GPIO_3_11: \ + __gpio = GPIO_3_11; \ + break; \ + case MX25_PAD_FEC_RX_DV__GPIO_3_12: \ + __gpio = GPIO_3_12; \ + break; \ + case MX25_PAD_FEC_TX_CLK__GPIO_3_13: \ + __gpio = GPIO_3_13; \ + break; \ + case MX25_PAD_RTCK__GPIO_3_14: \ + __gpio = GPIO_3_14; \ + break; \ + case MX25_PAD_EXT_ARMCLK__GPIO_3_15: \ + __gpio = GPIO_3_15; \ + break; \ + case MX25_PAD_UPLL_BYPCLK__GPIO_3_16: \ + __gpio = GPIO_3_16; \ + break; \ + case MX25_PAD_VSTBY_REQ__GPIO_3_17: \ + __gpio = GPIO_3_17; \ + break; \ + case MX25_PAD_VSTBY_ACK__GPIO_3_18: \ + __gpio = GPIO_3_18; \ + break; \ + case MX25_PAD_POWER_FAIL__GPIO_3_19: \ + __gpio = GPIO_3_19; \ + break; \ + case MX25_PAD_CS4__GPIO_3_20: \ + __gpio = GPIO_3_20; \ + break; \ + case MX25_PAD_CS5__GPIO_3_21: \ + __gpio = GPIO_3_21; \ + break; \ + case MX25_PAD_NF_CE0__GPIO_3_22: \ + __gpio = GPIO_3_22; \ + break; \ + case MX25_PAD_ECB__GPIO_3_23: \ + __gpio = GPIO_3_23; \ + break; \ + case MX25_PAD_LBA__GPIO_3_24: \ + __gpio = GPIO_3_24; \ + break; \ + case MX25_PAD_RW__GPIO_3_25: \ + __gpio = GPIO_3_25; \ + break; \ + case MX25_PAD_NFWE_B__GPIO_3_26: \ + __gpio = GPIO_3_26; \ + break; \ + case MX25_PAD_NFRE_B__GPIO_3_27: \ + __gpio = GPIO_3_27; \ + break; \ + case MX25_PAD_NFALE__GPIO_3_28: \ + __gpio = GPIO_3_28; \ + break; \ + case MX25_PAD_NFCLE__GPIO_3_29: \ + __gpio = GPIO_3_29; \ + break; \ + case MX25_PAD_NFWP_B__GPIO_3_30: \ + __gpio = GPIO_3_30; \ + break; \ + case MX25_PAD_NFRB__GPIO_3_31: \ + __gpio = GPIO_3_31; \ + break; \ + \ + case MX25_PAD_A10__GPIO_4_0: \ + __gpio = GPIO_4_0; \ + break; \ + case MX25_PAD_A13__GPIO_4_1: \ + __gpio = GPIO_4_1; \ + break; \ + case MX25_PAD_CS0__GPIO_4_2: \ + __gpio = GPIO_4_2; \ + break; \ + case MX25_PAD_CS1__GPIO_4_3: \ + __gpio = GPIO_4_3; \ + break; \ + case MX25_PAD_BCLK__GPIO_4_4: \ + __gpio = GPIO_4_4; \ + break; \ + case MX25_PAD_D15__GPIO_4_5: \ + __gpio = GPIO_4_5; \ + break; \ + case MX25_PAD_D14__GPIO_4_6: \ + __gpio = GPIO_4_6; \ + break; \ + case MX25_PAD_D13__GPIO_4_7: \ + __gpio = GPIO_4_7; \ + break; \ + case MX25_PAD_D12__GPIO_4_8: \ + __gpio = GPIO_4_8; \ + break; \ + case MX25_PAD_D11__GPIO_4_9: \ + __gpio = GPIO_4_9; \ + break; \ + case MX25_PAD_D10__GPIO_4_10: \ + __gpio = GPIO_4_10; \ + break; \ + case MX25_PAD_D9__GPIO_4_11: \ + __gpio = GPIO_4_11; \ + break; \ + case MX25_PAD_D8__GPIO_4_12: \ + __gpio = GPIO_4_12; \ + break; \ + case MX25_PAD_D7__GPIO_4_13: \ + __gpio = GPIO_4_13; \ + break; \ + case MX25_PAD_D6__GPIO_4_14: \ + __gpio = GPIO_4_14; \ + break; \ + case MX25_PAD_D5__GPIO_4_15: \ + __gpio = GPIO_4_15; \ + break; \ + case MX25_PAD_D4__GPIO_4_16: \ + __gpio = GPIO_4_16; \ + break; \ + case MX25_PAD_D3__GPIO_4_17: \ + __gpio = GPIO_4_17; \ + break; \ + case MX25_PAD_D2__GPIO_4_18: \ + __gpio = GPIO_4_18; \ + break; \ + case MX25_PAD_D1__GPIO_4_19: \ + __gpio = GPIO_4_19; \ + break; \ + case MX25_PAD_D0__GPIO_4_20: \ + __gpio = GPIO_4_20; \ + break; \ + case MX25_PAD_CSI_D9__GPIO_4_21: \ + __gpio = GPIO_4_21; \ + break; \ + case MX25_PAD_UART1_RXD__GPIO_4_22: \ + __gpio = GPIO_4_22; \ + break; \ + case MX25_PAD_UART1_TXD__GPIO_4_23: \ + __gpio = GPIO_4_23; \ + break; \ + case MX25_PAD_UART1_RTS__GPIO_4_24: \ + __gpio = GPIO_4_24; \ + break; \ + case MX25_PAD_UART1_CTS__GPIO_4_25: \ + __gpio = GPIO_4_25; \ + break; \ + case MX25_PAD_UART2_RXD__GPIO_4_26: \ + __gpio = GPIO_4_26; \ + break; \ + case MX25_PAD_UART2_TXD__GPIO_4_27: \ + __gpio = GPIO_4_27; \ + break; \ + case MX25_PAD_UART2_RTS__GPIO_4_28: \ + __gpio = GPIO_4_28; \ + break; \ + case MX25_PAD_UART2_CTS__GPIO_4_29: \ + __gpio = GPIO_4_29; \ + break; \ + case MX25_PAD_BOOT_MODE0__GPIO_4_30: \ + __gpio = GPIO_4_30; \ + break; \ + case MX25_PAD_BOOT_MODE1__GPIO_4_31: \ + __gpio = GPIO_4_31; \ + break; \ + } \ + __gpio; \ +}) +#endif + +#endif // __ASSEMBLY__ +#endif // __IOMUX_MX25_H__ diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/iomux-v3.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/iomux-v3.h --- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/iomux-v3.h 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/iomux-v3.h 2009-06-02 18:02:08.000000000 +0200 @@ -54,7 +54,7 @@ struct pad_desc { unsigned select_input:3; }; -#define IOMUX_PAD(_pad_ctrl_ofs, _mux_ctrl_ofs, _mux_mode, _select_input_ofs, \ +#define IOMUX_PAD(_pad, _func, _pad_ctrl_ofs, _mux_ctrl_ofs, _mux_mode, _select_input_ofs, \ _select_input, _pad_ctrl) \ { \ .mux_ctrl_ofs = _mux_ctrl_ofs, \ @@ -68,28 +68,28 @@ struct pad_desc { /* * Use to set PAD control */ -#define PAD_CTL_DRIVE_VOLTAGE_3_3_V 0 -#define PAD_CTL_DRIVE_VOLTAGE_1_8_V 1 +#define PAD_CTL_DRIVE_VOLTAGE_3_3_V (0 << 13) +#define PAD_CTL_DRIVE_VOLTAGE_1_8_V (1 << 13) -#define PAD_CTL_NO_HYSTERESIS 0 -#define PAD_CTL_HYSTERESIS 1 +#define PAD_CTL_NO_HYSTERESIS (0 << 8) +#define PAD_CTL_HYSTERESIS (1 << 8) -#define PAD_CTL_PULL_DISABLED 0x0 -#define PAD_CTL_PULL_KEEPER 0xa -#define PAD_CTL_PULL_DOWN_100K 0xc -#define PAD_CTL_PULL_UP_47K 0xd -#define PAD_CTL_PULL_UP_100K 0xe -#define PAD_CTL_PULL_UP_22K 0xf - -#define PAD_CTL_OUTPUT_CMOS 0 -#define PAD_CTL_OUTPUT_OPEN_DRAIN 1 - -#define PAD_CTL_DRIVE_STRENGTH_NORM 0 -#define PAD_CTL_DRIVE_STRENGTH_HIGH 1 -#define PAD_CTL_DRIVE_STRENGTH_MAX 2 +#define PAD_CTL_PULL_DISABLED (0x0 << 4) +#define PAD_CTL_PULL_KEEPER (0x8 << 4) +#define PAD_CTL_PULL_DOWN_100K (0xc << 4) +#define PAD_CTL_PULL_UP_47K (0xd << 4) +#define PAD_CTL_PULL_UP_100K (0xe << 4) +#define PAD_CTL_PULL_UP_22K (0xf << 4) + +#define PAD_CTL_OUTPUT_CMOS (0 << 3) +#define PAD_CTL_OUTPUT_OPEN_DRAIN (1 << 3) + +#define PAD_CTL_DRIVE_STRENGTH_NORM (0 << 1) +#define PAD_CTL_DRIVE_STRENGTH_HIGH (1 << 1) +#define PAD_CTL_DRIVE_STRENGTH_MAX (2 << 1) -#define PAD_CTL_SLEW_RATE_SLOW 0 -#define PAD_CTL_SLEW_RATE_FAST 1 +#define PAD_CTL_SLEW_RATE_SLOW (0 << 0) +#define PAD_CTL_SLEW_RATE_FAST (1 << 0) /* * setups a single pad: diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/iomux.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/iomux.h --- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/iomux.h 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/iomux.h 2009-06-02 18:02:08.000000000 +0200 @@ -24,10 +24,14 @@ * GPIO Module and I/O Multiplexer * x = 0..3 for reg_A, reg_B, reg_C, reg_D */ +#ifndef CONFIG_MACH_MX25 #define VA_GPIO_BASE IO_ADDRESS(GPIO_BASE_ADDR) +#endif #define MXC_DDIR(x) (0x00 + ((x) << 8)) +#ifndef CONFIG_MACH_MX25 #define MXC_OCR1(x) (0x04 + ((x) << 8)) #define MXC_OCR2(x) (0x08 + ((x) << 8)) +#endif #define MXC_ICONFA1(x) (0x0c + ((x) << 8)) #define MXC_ICONFA2(x) (0x10 + ((x) << 8)) #define MXC_ICONFB1(x) (0x14 + ((x) << 8)) @@ -96,16 +100,20 @@ #ifdef CONFIG_ARCH_MX1 -#include +# include #endif #ifdef CONFIG_ARCH_MX2 -#include -#ifdef CONFIG_MACH_MX21 -#include -#endif -#ifdef CONFIG_MACH_MX27 -#include -#endif +# ifndef CONFIG_MACH_MX25 +# include +# ifdef CONFIG_MACH_MX21 +# include +# endif +# endif +# ifdef CONFIG_MACH_MX27 +# include +# else +# include +# endif #endif diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/irqs.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/irqs.h --- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/irqs.h 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/irqs.h 2009-06-02 18:02:09.000000000 +0200 @@ -21,7 +21,11 @@ #if defined CONFIG_ARCH_MX1 #define MXC_GPIO_IRQS (32 * 4) #elif defined CONFIG_ARCH_MX2 +#ifndef CONFIG_MACH_MX25 #define MXC_GPIO_IRQS (32 * 6) +#else +#define MXC_GPIO_IRQS (32 * 4) +#endif #elif defined CONFIG_ARCH_MX3 #define MXC_GPIO_IRQS (32 * 3) #endif diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/memory.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/memory.h --- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/memory.h 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/memory.h 2009-06-02 18:02:09.000000000 +0200 @@ -14,12 +14,13 @@ #if defined CONFIG_ARCH_MX1 #define PHYS_OFFSET UL(0x08000000) #elif defined CONFIG_ARCH_MX2 -#ifdef CONFIG_MACH_MX21 +# if defined(CONFIG_MACH_MX21) #define PHYS_OFFSET UL(0xC0000000) -#endif -#ifdef CONFIG_MACH_MX27 +# elif defined(CONFIG_MACH_MX27) #define PHYS_OFFSET UL(0xA0000000) -#endif +# elif defined(CONFIG_MACH_MX25) +#define PHYS_OFFSET UL(0x80000000) +# endif #elif defined CONFIG_ARCH_MX3 #define PHYS_OFFSET UL(0x80000000) #endif diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/mx25.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/mx25.h --- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/mx25.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/mx25.h 2009-06-02 18:02:13.000000000 +0200 @@ -0,0 +1,482 @@ +/* + * Copyright 2008-2009 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 arch-mxc/mx25.h + * @brief This file contains register definitions. + * + * @ingroup MSL_MX25 + */ + +#ifndef __ASM_ARCH_MXC_MX25_H__ +#define __ASM_ARCH_MXC_MX25_H__ + +#ifndef __ASM_ARCH_MXC_HARDWARE_H__ +#error "Do not include directly." +#endif + +#ifdef CONFIG_DEBUG_LL +#ifdef CONFIG_MACH_TX25 +#include +#endif +#endif // CONFIG_DEBUG_LL + +/* + * MX25 memory map: + * + * Virt Phys Size What + * --------------------------------------------------------------------------- + * FC000000 43F00000 1M AIPS 1 + * FC100000 50000000 1M SPBA + * FC200000 53F00000 1M AIPS 2 + * FC300000 60000000 1M ROMPATCH (128M) + * FC400000 68000000 1M ASIC (128M) + * FC500000 78000000 128K FBC RAM (IRAM) + * 80000000 256M SDRAM0 + * 90000000 256M SDRAM1 + * A0000000 128M CS0 Flash + * A8000000 128M CS1 Flash + * B0000000 32M CS2 SRAM + * B2000000 32M CS3 + * B4000000 32M CS4 + * B6000000 32M CS5 + * FC520000 B8000000 64K SDRAM, WEIM, M3IF, EMI controllers + * FC530000 BB000000 8K NFC + */ + +#include +#define VA(x) _AT(void __force __iomem *,x) + +/* + * IRAM + */ +#define IRAM_BASE_ADDR UL(0x78000000) /* internal ram */ +#define IRAM_BASE_ADDR_VIRT VA(0xFC500000) +#define IRAM_SIZE SZ_128K + +/* + * AIPS 1 + */ +#define AIPS1_BASE_ADDR UL(0x43F00000) +#define AIPS1_BASE_ADDR_VIRT VA(0xFC000000) +#define AIPS1_SIZE SZ_1M + +#define MAX_BASE_ADDR (AIPS1_BASE_ADDR + 0x00004000) +#define CLKCTL_BASE_ADDR (AIPS1_BASE_ADDR + 0x00008000) +#define ETB_SLOT4_BASE_ADDR (AIPS1_BASE_ADDR + 0x0000C000) +#define ETB_SLOT5_BASE_ADDR (AIPS1_BASE_ADDR + 0x00010000) +#define AAPE_BASE_ADDR (AIPS1_BASE_ADDR + 0x00014000) +#define I2C_BASE_ADDR (AIPS1_BASE_ADDR + 0x00080000) +#define I2C3_BASE_ADDR (AIPS1_BASE_ADDR + 0x00084000) +#define CAN1_BASE_ADDR (AIPS1_BASE_ADDR + 0x00088000) +#define CAN3_BASE_ADDR (AIPS1_BASE_ADDR + 0x0008C000) +#define UART1_BASE_ADDR (AIPS1_BASE_ADDR + 0x00090000) +#define UART2_BASE_ADDR (AIPS1_BASE_ADDR + 0x00094000) +#define I2C2_BASE_ADDR (AIPS1_BASE_ADDR + 0x00098000) +#define OWIRE_BASE_ADDR (AIPS1_BASE_ADDR + 0x0009C000) +#define ATA_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A0000) +#define CSPI1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A4000) +#define KPP_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A8000) +#define IOMUXC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000AC000) +#define AUDMUX_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B0000) +#define ECT_A_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B8000) +#define ECT_B_BASE_ADDR (AIPS1_BASE_ADDR + 0x000BC000) + +/* + * SPBA global module enabled #0 + */ +#define SPBA0_BASE_ADDR UL(0x50000000) +#define SPBA0_BASE_ADDR_VIRT VA(0xFC100000) +#define SPBA0_SIZE SZ_1M + +#define CSPI3_BASE_ADDR (SPBA0_BASE_ADDR + 0x00004000) +#define UART4_BASE_ADDR (SPBA0_BASE_ADDR + 0x00008000) +#define UART3_BASE_ADDR (SPBA0_BASE_ADDR + 0x0000C000) +#define CSPI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00010000) +#define SSI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00014000) +#define ESAI_BASE_ADDR (SPBA0_BASE_ADDR + 0x00018000) +#define ATA_DMA_BASE_ADDR (SPBA0_BASE_ADDR + 0x00020000) +#define SIM1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00024000) +#define SIM2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00028000) +#define UART5_BASE_ADDR (SPBA0_BASE_ADDR + 0x0002C000) +#define TSC_BASE_ADDR (SPBA0_BASE_ADDR + 0x00030000) +#define SSI1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00034000) +#define FEC_BASE_ADDR (SPBA0_BASE_ADDR + 0x00038000) +#define SPBA_CTRL_BASE_ADDR (SPBA0_BASE_ADDR + 0x0003C000) + +/*! + * defines for SPBA modules + */ +#define SPBA_CSPI3 (0x1 << 2) +#define SPBA_UART4 (0x2 << 2) +#define SPBA_UART3 (0x3 << 2) +#define SPBA_CSPI2 (0x4 << 2) +#define SPBA_SSI2 (0x5 << 2) +#define SPBA_ESAI (0x6 << 2) +#define SPBA_ATA (0x8 << 2) +#define SPBA_SIM1 (0x9 << 2) +#define SPBA_SIM2 (0xA << 2) +#define SPBA_UART5 (0xB << 2) +#define SPBA_ANALOG (0xC << 2) +#define SPBA_SSI1 (0xD << 2) +#define SPBA_FEC (0xE << 2) + +/*! + * Defines for modules using static and dynamic DMA channels + */ +#define MXC_DMA_CHANNEL_IRAM 30 +#define MXC_DMA_CHANNEL_UART1_RX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_UART1_TX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_UART2_RX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_UART2_TX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_UART3_RX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_UART3_TX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_UART4_RX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_UART4_TX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_UART5_RX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_UART5_TX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_MMC1 MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_SSI1_RX MXC_DMA_DYNAMIC_CHANNEL +#ifdef CONFIG_SDMA_IRAM +#define MXC_DMA_CHANNEL_SSI1_TX (MXC_DMA_CHANNEL_IRAM + 1) +#else +#define MXC_DMA_CHANNEL_SSI1_TX MXC_DMA_DYNAMIC_CHANNEL +#endif +#define MXC_DMA_CHANNEL_SSI2_RX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_SSI2_TX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_CSPI1_RX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_CSPI1_TX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_CSPI2_RX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_CSPI2_TX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_CSPI3_RX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_CSPI3_TX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_ATA_RX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_ATA_TX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_MEMORY MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_ESAI_RX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_ESAI_TX MXC_DMA_DYNAMIC_CHANNEL + +/* + * AIPS 2 + */ +#define AIPS2_BASE_ADDR UL(0x53F00000) +#define AIPS2_BASE_ADDR_VIRT VA(0xFC200000) +#define AIPS2_SIZE SZ_1M + +#define CCM_BASE_ADDR (AIPS2_BASE_ADDR + 0x00080000) +#define GPT4_BASE_ADDR (AIPS2_BASE_ADDR + 0x00084000) +#define GPT3_BASE_ADDR (AIPS2_BASE_ADDR + 0x00088000) +#define GPT2_BASE_ADDR (AIPS2_BASE_ADDR + 0x0008C000) +#define GPT1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00090000) +#define EPIT1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00094000) +#define EPIT2_BASE_ADDR (AIPS2_BASE_ADDR + 0x00098000) +#define GPIO4_BASE_ADDR (AIPS2_BASE_ADDR + 0x0009C000) +#define PWM2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A0000) +#define GPIO3_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A4000) +#define PWM3_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A8000) +#define SCC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000AC000) +#define RNGD_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B0000) +#define MMC_SDHC1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B4000) +#define MMC_SDHC2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B8000) +#define LCDC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000BC000) +#define SLCDC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C0000) +#define PWM4_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C8000) +#define GPIO1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000CC000) +#define GPIO2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D0000) +#define SDMA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D4000) +#define WDOG_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DC000) +#define PWM1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000E0000) +#define RTIC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000EC000) +#define IIM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000F0000) +#define USBOTG_BASE_ADDR (AIPS2_BASE_ADDR + 0x000F4000) +#define OTG_BASE_ADDR USBOTG_BASE_ADDR +#define CSI_BASE_ADDR (AIPS2_BASE_ADDR + 0x000F8000) +#define DRYICE_BASE_ADDR (AIPS2_BASE_ADDR + 0x000FC000) + +/* + * ROMP and ASIC + */ +#define ROMP_BASE_ADDR UL(0x60000000) +#define ROMP_BASE_ADDR_VIRT VA(0xFC300000) +#define ROMP_SIZE SZ_1M + +#define ASIC_BASE_ADDR UL(0x68000000) +#define ASIC_BASE_ADDR_VIRT VA(0xFC400000) +#define ASIC_SIZE SZ_1M +#define AVIC_BASE_ADDR ASIC_BASE_ADDR +#define AVIC_BASE_ADDR_VIRT ASIC_BASE_ADDR_VIRT +#define AVIC_SIZE ASIC_SIZE + +/* + * SDRAM, WEIM, M3IF, EMI controllers + */ +#define X_MEMC_BASE_ADDR UL(0xB8000000) +#define X_MEMC_BASE_ADDR_VIRT VA(0xFC520000) +#define X_MEMC_SIZE SZ_64K + +#define SDRAMC_BASE_ADDR (X_MEMC_BASE_ADDR + 0x1000) +#define WEIM_BASE_ADDR (X_MEMC_BASE_ADDR + 0x2000) +#define M3IF_BASE_ADDR (X_MEMC_BASE_ADDR + 0x3000) +#define EMI_CTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x4000) + +/* + * NFC controller + */ +#define NFC_BASE_ADDR UL(0xBB000000) +#define NFC_BASE_ADDR_VIRT VA(0xFC530000) +#define NFC_SIZE SZ_8K + +/* + * Memory regions and CS + */ +#define CSD0_BASE_ADDR UL(0x80000000) +#define CSD1_BASE_ADDR UL(0x90000000) + +#define SDRAM_BASE_ADDR CSD0_BASE_ADDR + +#define CS0_BASE_ADDR UL(0xA0000000) +#define CS1_BASE_ADDR UL(0xA8000000) +#define CS2_BASE_ADDR UL(0xB0000000) +#define CS3_BASE_ADDR UL(0xB2000000) +#define CS4_BASE_ADDR UL(0xB4000000) +#define CS4_SIZE SZ_32M +#define CS5_BASE_ADDR UL(0xB6000000) +#define CS5_SIZE SZ_32M + +/*! + * This macro defines the physical to virtual address mapping for all the + * peripheral modules. It is used by passing in the physical address as x + * and returning the virtual address. If the physical address is not mapped, + * it returns 0 + */ +#define IO_ADDRESS(x) \ + VA((((x) >= AIPS1_BASE_ADDR) && ((x) < (AIPS1_BASE_ADDR + AIPS1_SIZE))) ? AIPS1_IO_ADDRESS(x): \ + (((x) >= SPBA0_BASE_ADDR) && ((x) < (SPBA0_BASE_ADDR + SPBA0_SIZE))) ? SPBA0_IO_ADDRESS(x): \ + (((x) >= AIPS2_BASE_ADDR) && ((x) < (AIPS2_BASE_ADDR + AIPS2_SIZE))) ? AIPS2_IO_ADDRESS(x): \ + (((x) >= ROMP_BASE_ADDR) && ((x) < (ROMP_BASE_ADDR + ROMP_SIZE))) ? ROMP_IO_ADDRESS(x): \ + (((x) >= ASIC_BASE_ADDR) && ((x) < (ASIC_BASE_ADDR + AVIC_SIZE))) ? ASIC_IO_ADDRESS(x): \ + (((x) >= IRAM_BASE_ADDR) && ((x) < (IRAM_BASE_ADDR + IRAM_SIZE))) ? IRAM_IO_ADDRESS(x): \ + (((x) >= X_MEMC_BASE_ADDR) && ((x) < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? X_MEMC_IO_ADDRESS(x): \ + (((x) >= NFC_BASE_ADDR) && ((x) < (NFC_BASE_ADDR + NFC_SIZE))) ? NFC_IO_ADDRESS(x): \ + 0) + +#define MXC_VADDR_RANGE(v,n) \ + (((v)) >= n##_BASE_ADDR_VIRT) && \ + (((v)) < n##_BASE_ADDR_VIRT + n##_SIZE) ? \ + ((v)-n##_BASE_ADDR_VIRT + n##_BASE_ADDR) : + +#define MXC_PHYS_ADDRESS(v) \ + UL(MXC_VADDR_RANGE(v,AIPS1) \ + MXC_VADDR_RANGE(v,AIPS2) \ + MXC_VADDR_RANGE(v,SPBA0) \ + MXC_VADDR_RANGE(v,ROMP) \ + MXC_VADDR_RANGE(v,ASIC) \ + MXC_VADDR_RANGE(v,IRAM) \ + MXC_VADDR_RANGE(v,X_MEMC) \ + MXC_VADDR_RANGE(v,NFC) \ + 0) + +#define GPIO_BASE_ADDR(port) \ + ((port == 1 ? GPIO1_BASE_ADDR : \ + (port == 2 ? GPIO2_BASE_ADDR : \ + (port == 3 ? GPIO3_BASE_ADDR : \ + (port == 4 ? GPIO4_BASE_ADDR : 0))))) + +/* + * define the address mapping macros: in physical address order + */ + +#define AIPS1_IO_ADDRESS(x) \ + (((x) - AIPS1_BASE_ADDR) + AIPS1_BASE_ADDR_VIRT) + +#define SPBA0_IO_ADDRESS(x) \ + (((x) - SPBA0_BASE_ADDR) + SPBA0_BASE_ADDR_VIRT) + +#define AIPS2_IO_ADDRESS(x) \ + (((x) - AIPS2_BASE_ADDR) + AIPS2_BASE_ADDR_VIRT) + +#define ROMP_IO_ADDRESS(x) \ + (((x) - ROMP_BASE_ADDR) + ROMP_BASE_ADDR_VIRT) + +#define ASIC_IO_ADDRESS(x) \ + (((x) - ASIC_BASE_ADDR) + ASIC_BASE_ADDR_VIRT) + +/* for entry-macro.S */ +#define AVIC_IO_ADDRESS(x) ASIC_IO_ADDRESS(x) + +#define IRAM_IO_ADDRESS(x) \ + (((x) - IRAM_BASE_ADDR) + IRAM_BASE_ADDR_VIRT) + +#define X_MEMC_IO_ADDRESS(x) \ + (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT) + +#define NFC_IO_ADDRESS(x) \ + (((x) - NFC_BASE_ADDR) + NFC_BASE_ADDR_VIRT) + +/* + * DMA request assignments + */ +#define DMA_REQ_EXTREQ0 0 +#define DMA_REQ_CCM 1 +#define DMA_REQ_ATA_TX_END 2 +#define DMA_REQ_ATA_TX 3 +#define DMA_REQ_ATA_RX 4 +#define DMA_REQ_CSPI2_RX 6 +#define DMA_REQ_CSPI2_TX 7 +#define DMA_REQ_CSPI1_RX 8 +#define DMA_REQ_CSPI1_TX 9 +#define DMA_REQ_UART3_RX 10 +#define DMA_REQ_UART3_TX 11 +#define DMA_REQ_UART4_RX 12 +#define DMA_REQ_UART4_TX 13 +#define DMA_REQ_EXTREQ1 14 +#define DMA_REQ_EXTREQ2 15 +#define DMA_REQ_UART2_RX 16 +#define DMA_REQ_UART2_TX 17 +#define DMA_REQ_UART1_RX 18 +#define DMA_REQ_UART1_TX 19 +#define DMA_REQ_SSI2_RX1 22 +#define DMA_REQ_SSI2_TX1 23 +#define DMA_REQ_SSI2_RX0 24 +#define DMA_REQ_SSI2_TX0 25 +#define DMA_REQ_SSI1_RX1 26 +#define DMA_REQ_SSI1_TX1 27 +#define DMA_REQ_SSI1_RX0 28 +#define DMA_REQ_SSI1_TX0 29 +#define DMA_REQ_NFC 30 +#define DMA_REQ_ECT 31 +#define DMA_REQ_ESAI_RX 32 +#define DMA_REQ_ESAI_TX 33 +#define DMA_REQ_CSPI3_RX 34 +#define DMA_REQ_CSPI3_TX 35 +#define DMA_REQ_SIM2_RX 36 +#define DMA_REQ_SIM2_TX 37 +#define DMA_REQ_SIM1_RX 38 +#define DMA_REQ_SIM1_TX 39 +#define DMA_REQ_TSC_GCQ 44 +#define DMA_REQ_TSC_TCQ 45 +#define DMA_REQ_UART5_RX 46 +#define DMA_REQ_UART5_TX 47 + +/* + * Interrupt numbers + */ +#define MXC_INT_CSPI3 0 +#define MXC_INT_GPT4 1 +#define MXC_INT_OWIRE 2 +#define MXC_INT_I2C 3 +#define MXC_INT_I2C2 4 +#define MXC_INT_UART4 5 +#define MXC_INT_RTIC 6 +#define MXC_INT_ESAI 7 +#define MXC_INT_SDHC2 8 +#define MXC_INT_SDHC1 9 +#define MXC_INT_I2C3 10 +#define MXC_INT_SSI2 11 +#define MXC_INT_SSI1 12 +#define MXC_INT_CSPI2 13 +#define MXC_INT_CSPI1 14 +#define MXC_INT_ATA 15 +#define MXC_INT_GPIO3 16 +#define MXC_INT_CSI 17 +#define MXC_INT_UART3 18 +#define MXC_INT_IIM 19 +#define MXC_INT_SIM1 20 +#define MXC_INT_SIM2 21 +#define MXC_INT_RNGD 22 +#define MXC_INT_GPIO4 23 +#define MXC_INT_KPP 24 +#define MXC_INT_DRYICE_RTC 25 +#define MXC_INT_PWM 26 +#define MXC_INT_EPIT2 27 +#define MXC_INT_EPIT1 28 +#define MXC_INT_GPT3 29 +#define MXC_INT_POWER_FAIL 30 +#define MXC_INT_CRM 31 +#define MXC_INT_UART2 32 +#define MXC_INT_NANDFC 33 +#define MXC_INT_SDMA 34 +#define MXC_INT_USB_HTG 35 +#define MXC_INT_PWM2 36 +#define MXC_INT_USB_OTG 37 +#define MXC_INT_SLCDC 38 +#define MXC_INT_LCDC 39 +#define MXC_INT_UART5 40 +#define MXC_INT_PWM3 41 +#define MXC_INT_PWM4 42 +#define MXC_INT_CAN1 43 +#define MXC_INT_CAN2 44 +#define MXC_INT_UART1 45 +#define MXC_INT_TSC 46 +#define MXC_INT_ECT 48 +#define MXC_INT_SCC_SCM 49 +#define MXC_INT_SCC_SMN 50 +#define MXC_INT_GPIO2 51 +#define MXC_INT_GPIO1 52 +#define MXC_INT_GPT2 53 +#define MXC_INT_GPT1 54 +#define MXC_INT_WDOG 55 +#define MXC_INT_DRYICE 56 +#define MXC_INT_FEC 57 +#define MXC_INT_EXT_INT5 58 +#define MXC_INT_EXT_INT4 59 +#define MXC_INT_EXT_INT3 60 +#define MXC_INT_EXT_INT2 61 +#define MXC_INT_EXT_INT1 62 +#define MXC_INT_EXT_INT0 63 + +#define MXC_INT_GPT MXC_INT_GPT1 + +/* silicon revisions specific to i.MX25 */ +#define CHIP_REV_1_0 0x00 +#define CHIP_REV_1_1 0x01 + +/* gpio and gpio based interrupt handling */ +#define GPIO_DR 0x00 +#define GPIO_GDIR 0x04 +#define GPIO_PSR 0x08 +#define GPIO_ICR1 0x0C +#define GPIO_ICR2 0x10 +#define GPIO_IMR 0x14 +#define GPIO_ISR 0x18 +#define GPIO_INT_LOW_LEV 0x0 +#define GPIO_INT_HIGH_LEV 0x1 +#define GPIO_INT_RISE_EDGE 0x2 +#define GPIO_INT_FALL_EDGE 0x3 +#define GPIO_INT_NONE 0x4 + +/* Mandatory defines used globally */ + +/* this CPU supports up to 96 GPIOs */ +#define ARCH_NR_GPIOS 128 + +#define MXC_TIMER_GPT1 1 +#define MXC_TIMER_GPT2 2 +#define MXC_TIMER_GPT3 3 +#define MXC_TIMER_GPT4 4 + +/*! + * NFMS bit in RCSR register for pagesize of nandflash + */ +#define NFMS_REG IO_ADDRESS(CCM_BASE_ADDR + 0x28) +#define NFMS_NF_DWIDTH 14 +#define NFMS_NF_PG_SZ 8 + +#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) +#include + +extern int mx25_revision(void); + +#endif + +#endif /* __ASM_ARCH_MXC_MX25_H__ */ diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/mx2x.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/mx2x.h --- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/mx2x.h 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/mx2x.h 2009-06-02 18:02:11.000000000 +0200 @@ -79,7 +79,7 @@ * This macro defines the physical to virtual address mapping for all the * peripheral modules. It is used by passing in the physical address as x * and returning the virtual address. If the physical address is not mapped, - * it returns 0xDEADBEEF + * it returns 0 */ #define IO_ADDRESS(x) \ (void __force __iomem *) \ @@ -88,7 +88,7 @@ ((x >= SAHB1_BASE_ADDR) && (x < (SAHB1_BASE_ADDR + SAHB1_SIZE))) ? \ SAHB1_IO_ADDRESS(x) : \ ((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? \ - X_MEMC_IO_ADDRESS(x) : 0xDEADBEEF) + X_MEMC_IO_ADDRESS(x) : 0) /* define the address mapping macros: in physical address order */ #define AIPI_IO_ADDRESS(x) \ diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/mxc.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/mxc.h --- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/mxc.h 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/mxc.h 2009-06-02 18:02:12.000000000 +0200 @@ -27,6 +27,7 @@ #define MXC_CPU_MX1 1 #define MXC_CPU_MX21 21 #define MXC_CPU_MX27 27 +#define MXC_CPU_MX25 25 #define MXC_CPU_MX31 31 #define MXC_CPU_MX35 35 @@ -70,6 +71,18 @@ extern unsigned int __mxc_cpu_type; # define cpu_is_mx27() (0) #endif +#ifdef CONFIG_MACH_MX25 +# ifdef mxc_cpu_type +# undef mxc_cpu_type +# define mxc_cpu_type __mxc_cpu_type +# else +# define mxc_cpu_type MXC_CPU_MX25 +# endif +# define cpu_is_mx25() (mxc_cpu_type == MXC_CPU_MX25) +#else +# define cpu_is_mx25() (0) +#endif + #ifdef CONFIG_ARCH_MX31 # ifdef mxc_cpu_type # undef mxc_cpu_type @@ -101,6 +114,6 @@ extern unsigned int __mxc_cpu_type; #endif #define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35()) -#define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27()) +#define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx25() || cpu_is_mx27()) #endif /* __ASM_ARCH_MXC_H__ */ diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/sdma.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/sdma.h --- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/sdma.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/sdma.h 2009-06-02 18:02:13.000000000 +0200 @@ -0,0 +1,504 @@ + +/* + * Copyright 2004-2008 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_SDMA_H__ +#define __ASM_ARCH_MXC_SDMA_H__ + +/*! + * @defgroup SDMA Smart Direct Memory Access (SDMA) Driver + */ + +/*! + * @file arch-mxc/sdma.h + * + * @brief This file contains the SDMA API declarations. + * + * SDMA is responsible on moving data between peripherals and memories (MCU, EMI and DSP). + * + * @ingroup SDMA + */ + +#include +#include +#include +#include + +/*! + * This defines maximum DMA address + */ +#define MAX_DMA_ADDRESS 0xffffffff + +/*! + * This defines maximum number of DMA channels + */ +#ifdef CONFIG_MXC_SDMA_API +#define MAX_DMA_CHANNELS 32 +#define MAX_BD_NUMBER 16 +#define MXC_SDMA_DEFAULT_PRIORITY 1 +#define MXC_SDMA_MIN_PRIORITY 1 +#define MXC_SDMA_MAX_PRIORITY 7 +#else +#define MAX_DMA_CHANNELS 0 +#endif + +#define MXC_FIFO_MEM_DEST_FIXED 0x1 +#define MXC_FIFO_MEM_SRC_FIXED 0x2 +/*! + * This enumerates transfer types + */ +typedef enum { + emi_2_per = 0, /*!< EMI memory to peripheral */ + emi_2_int, /*!< EMI memory to internal RAM */ + emi_2_emi, /*!< EMI memory to EMI memory */ + emi_2_dsp, /*!< EMI memory to DSP memory */ + per_2_int, /*!< Peripheral to internal RAM */ + per_2_emi, /*!< Peripheral to internal EMI memory */ + per_2_dsp, /*!< Peripheral to DSP memory */ + per_2_per, /*!< Peripheral to Peripheral */ + int_2_per, /*!< Internal RAM to peripheral */ + int_2_int, /*!< Internal RAM to Internal RAM */ + int_2_emi, /*!< Internal RAM to EMI memory */ + int_2_dsp, /*!< Internal RAM to DSP memory */ + dsp_2_per, /*!< DSP memory to peripheral */ + dsp_2_int, /*!< DSP memory to internal RAM */ + dsp_2_emi, /*!< DSP memory to EMI memory */ + dsp_2_dsp, /*!< DSP memory to DSP memory */ + emi_2_dsp_loop, /*!< EMI memory to DSP memory loopback */ + dsp_2_emi_loop, /*!< DSP memory to EMI memory loopback */ + dvfs_pll, /*!< DVFS script with PLL change */ + dvfs_pdr /*!< DVFS script without PLL change */ +} sdma_transferT; + +/*! + * This enumerates peripheral types + */ +typedef enum { + SSI, /*!< MCU domain SSI */ + SSI_SP, /*!< Shared SSI */ + MMC, /*!< MMC */ + SDHC, /*!< SDHC */ + UART, /*!< MCU domain UART */ + UART_SP, /*!< Shared UART */ + FIRI, /*!< FIRI */ + CSPI, /*!< MCU domain CSPI */ + CSPI_SP, /*!< Shared CSPI */ + SIM, /*!< SIM */ + ATA, /*!< ATA */ + CCM, /*!< CCM */ + EXT, /*!< External peripheral */ + MSHC, /*!< Memory Stick Host Controller */ + MSHC_SP, /*!< Shared Memory Stick Host Controller */ + DSP, /*!< DSP */ + MEMORY, /*!< Memory */ + FIFO_MEMORY, /*!< FIFO type Memory */ + SPDIF, /*!< SPDIF */ + IPU_MEMORY, /*!< IPU Memory */ + ASRC, /*!< ASRC */ + ESAI, /*!< ESAI */ +} sdma_periphT; + +#ifndef TRANSFER_32BIT +/*! + * This defines SDMA access data size + */ +#define TRANSFER_32BIT 0x00 +#define TRANSFER_8BIT 0x01 +#define TRANSFER_16BIT 0x02 +#define TRANSFER_24BIT 0x03 + +#endif + +/*! + * This defines maximum device name length passed during mxc_request_dma(). + */ +#define MAX_DEVNAME_LENGTH 32 + +/*! + * This defines SDMA interrupt callback function prototype. + */ +typedef void (*dma_callback_t) (void *arg); + +/*! + * Structure containing sdma channel parameters. + */ +typedef struct { + __u32 watermark_level; /*!< Lower/upper threshold that + * triggers SDMA event + */ + __u32 per_address; /*!< Peripheral source/destination + * physical address + */ + sdma_periphT peripheral_type; /*!< Peripheral type */ + sdma_transferT transfer_type; /*!< Transfer type */ + int event_id; /*!< Event number, + * needed by all channels + * that started by peripherals dma + * request (per_2_*,*_2_per) + * Not used for memory and DSP + * transfers. + */ + int event_id2; /*!< Second event number, + * used in ATA scripts only. + */ + int bd_number; /*!< Buffer descriptors number. + * If not set, single buffer + * descriptor will be used. + */ + dma_callback_t callback; /*! callback function */ + void *arg; /*! callback argument */ + unsigned long word_size:8; /*!< SDMA data access word size */ +} dma_channel_params; + +/*! + * Structure containing sdma request parameters. + */ +typedef struct { + /*! physical source memory address */ + __u8 *sourceAddr; + /*! physical destination memory address */ + __u8 *destAddr; + /*! amount of data to transfer, + * updated during mxc_dma_get_config + */ + __u16 count; + /*!< DONE bit of the buffer descriptor, + * updated during mxc_dma_get_config + * 0 - means the BD is done and closed by SDMA + * 1 - means the BD is still being processed by SDMA + */ + int bd_done; + /*!< CONT bit of the buffer descriptor, + * set it if full multi-buffer descriptor mechanism + * required. + */ + int bd_cont; + /*!< ERROR bit of the buffer descriptor, + * updated during mxc_dma_get_config. + * If it is set - there was an error during BD processing. + */ + int bd_error; +} dma_request_t; + +/*! + * Structure containing sdma request parameters. + */ +typedef struct { + /*! address of ap_2_ap script */ + int mxc_sdma_ap_2_ap_addr; + /*! address of ap_2_bp script */ + int mxc_sdma_ap_2_bp_addr; + /*! address of ap_2_ap_fixed script */ + int mxc_sdma_ap_2_ap_fixed_addr; + /*! address of bp_2_ap script */ + int mxc_sdma_bp_2_ap_addr; + /*! address of loopback_on_dsp_side script */ + int mxc_sdma_loopback_on_dsp_side_addr; + /*! address of mcu_interrupt_only script */ + int mxc_sdma_mcu_interrupt_only_addr; + + /*! address of firi_2_per script */ + int mxc_sdma_firi_2_per_addr; + /*! address of firi_2_mcu script */ + int mxc_sdma_firi_2_mcu_addr; + /*! address of per_2_firi script */ + int mxc_sdma_per_2_firi_addr; + /*! address of mcu_2_firi script */ + int mxc_sdma_mcu_2_firi_addr; + + /*! address of uart_2_per script */ + int mxc_sdma_uart_2_per_addr; + /*! address of uart_2_mcu script */ + int mxc_sdma_uart_2_mcu_addr; + /*! address of per_2_app script */ + int mxc_sdma_per_2_app_addr; + /*! address of mcu_2_app script */ + int mxc_sdma_mcu_2_app_addr; + /*! address of per_2_per script */ + int mxc_sdma_per_2_per_addr; + + /*! address of uartsh_2_per script */ + int mxc_sdma_uartsh_2_per_addr; + /*! address of uartsh_2_mcu script */ + int mxc_sdma_uartsh_2_mcu_addr; + /*! address of per_2_shp script */ + int mxc_sdma_per_2_shp_addr; + /*! address of mcu_2_shp script */ + int mxc_sdma_mcu_2_shp_addr; + + /*! address of ata_2_mcu script */ + int mxc_sdma_ata_2_mcu_addr; + /*! address of mcu_2_ata script */ + int mxc_sdma_mcu_2_ata_addr; + + /*! address of app_2_per script */ + int mxc_sdma_app_2_per_addr; + /*! address of app_2_mcu script */ + int mxc_sdma_app_2_mcu_addr; + /*! address of shp_2_per script */ + int mxc_sdma_shp_2_per_addr; + /*! address of shp_2_mcu script */ + int mxc_sdma_shp_2_mcu_addr; + + /*! address of mshc_2_mcu script */ + int mxc_sdma_mshc_2_mcu_addr; + /*! address of mcu_2_mshc script */ + int mxc_sdma_mcu_2_mshc_addr; + + /*! address of spdif_2_mcu script */ + int mxc_sdma_spdif_2_mcu_addr; + /*! address of mcu_2_spdif script */ + int mxc_sdma_mcu_2_spdif_addr; + + /*! address of asrc_2_mcu script */ + int mxc_sdma_asrc_2_mcu_addr; + + /*! address of ext_mem_2_ipu script */ + int mxc_sdma_ext_mem_2_ipu_addr; + + /*! address of descrambler script */ + int mxc_sdma_descrambler_addr; + + /*! address of dptc_dvfs script */ + int mxc_sdma_dptc_dvfs_addr; + + int mxc_sdma_utra_addr; + + /*! address where ram code starts */ + int mxc_sdma_ram_code_start_addr; + /*! size of the ram code */ + int mxc_sdma_ram_code_size; + /*! RAM image address */ + unsigned short *mxc_sdma_start_addr; +} sdma_script_start_addrs; + +/*! Structure to store the initialized dma_channel parameters */ +typedef struct mxc_sdma_channel_params { + /*! Channel params */ + dma_channel_params chnl_params; + /*! Channel type (static channel number or dynamic channel) */ + unsigned int channel_num; + /*! Channel priority [0x1(lowest) - 0x7(highest)] */ + unsigned int chnl_priority; +} mxc_sdma_channel_params_t; + +/*! Private SDMA data structure */ +typedef struct mxc_dma_channel_private { + /*! ID of the buffer that was processed */ + unsigned int buf_tail; + /*! Tasklet for the channel */ + struct tasklet_struct chnl_tasklet; + /*! Flag indicates if interrupt is required after every BD transfer */ + int intr_after_every_bd; +} mxc_dma_channel_private_t; + +/*! + * Setup channel according to parameters. + * Must be called once after mxc_request_dma() + * + * @param channel channel number + * @param p channel parameters pointer + * @return 0 on success, error code on fail + */ +int mxc_dma_setup_channel(int channel, dma_channel_params * p); + +/*! + * Setup the channel priority. This can be used to change the default priority + * for the channel. + * + * @param channel channel number + * @param priority priority to be set for the channel + * + * @return 0 on success, error code on failure + */ +int mxc_dma_set_channel_priority(unsigned int channel, unsigned int priority); + +/*! + * Allocates dma channel. + * If channel's value is 0, then the function allocates a free channel + * dynamically and sets its value to channel. + * Else allocates requested channel if it is free. + * If the channel is busy or no free channels (in dynamic allocation) -EBUSY returned. + * + * @param channel pointer to channel number + * @param devicename device name + * @return 0 on success, error code on fail + */ +int mxc_request_dma(int *channel, const char *devicename); + +/*! + * Configures request parameters. Can be called multiple times after + * mxc_request_dma() and mxc_dma_setup_channel(). + * + * + * @param channel channel number + * @param p request parameters pointer + * @param bd_index index of buffer descriptor to set + * @return 0 on success, error code on fail + */ +/* int mxc_dma_set_config(int channel, dma_request_t *p, int bd_index); */ +int mxc_dma_set_config(int channel, dma_request_t * p, int bd_index); + +/*! + * Returns request parameters. + * + * @param channel channel number + * @param p request parameters pointer + * @param bd_index index of buffer descriptor to get + * @return 0 on success, error code on fail + */ +/* int mxc_dma_get_config(int channel, dma_request_t *p, int bd_index); */ +int mxc_dma_get_config(int channel, dma_request_t * p, int bd_index); + +/*! + * This function is used by MXC IPC's write_ex2. It passes the a pointer to the + * data control structure to iapi_write_ipcv2() + * + * @param channel SDMA channel number + * @param ctrl_ptr Data Control structure pointer + */ +int mxc_sdma_write_ipcv2(int channel, void *ctrl_ptr); + +/*! + * This function is used by MXC IPC's read_ex2. It passes the a pointer to the + * data control structure to iapi_read_ipcv2() + * + * @param channel SDMA channel number + * @param ctrl_ptr Data Control structure pointer + */ +int mxc_sdma_read_ipcv2(int channel, void *ctrl_ptr); + +/*! + * Starts dma channel. + * + * @param channel channel number + */ +int mxc_dma_start(int channel); + +/*! + * Stops dma channel. + * + * @param channel channel number + */ +int mxc_dma_stop(int channel); + +/*! + * Frees dma channel. + * + * @param channel channel number + */ +void mxc_free_dma(int channel); + +/*! + * Sets callback function. Used with standard dma api + * for supporting interrupts + * + * @param channel channel number + * @param callback callback function pointer + * @param arg argument for callback function + */ +void mxc_dma_set_callback(int channel, dma_callback_t callback, void *arg); + +/*! + * Allocates uncachable buffer. Uses hash table. + * + * @param size size of allocated buffer + * @return pointer to buffer + */ +void *sdma_malloc(size_t size); + +#ifdef CONFIG_SDMA_IRAM +/*! + * Allocates uncachable buffer from IRAM.. + * + * @param size size of allocated buffer + * @return pointer to buffer + */ +void *sdma_iram_malloc(size_t size); +#endif /*CONFIG_SDMA_IRAM */ + +/*! + * Frees uncachable buffer. Uses hash table. + */ +void sdma_free(void *buf); + +/*! + * Converts virtual to physical address. Uses hash table. + * + * @param buf virtual address pointer + * @return physical address value + */ +unsigned long sdma_virt_to_phys(void *buf); + +/*! + * Converts physical to virtual address. Uses hash table. + * + * @param buf physical address value + * @return virtual address pointer + */ +void *sdma_phys_to_virt(unsigned long buf); + +/*! + * Configures the BD_INTR bit on a buffer descriptor parameters. + * + * + * @param channel channel number + * @param bd_index index of buffer descriptor to set + * @param bd_intr flag to set or clear the BD_INTR bit + */ +void mxc_dma_set_bd_intr(int channel, int bd_index, int bd_intr); + +/*! + * Gets the BD_INTR bit on a buffer descriptor. + * + * + * @param channel channel number + * @param bd_index index of buffer descriptor to set + * + * @return returns the BD_INTR bit status + */ +int mxc_dma_get_bd_intr(int channel, int bd_index); + +/*! + * Stop the current transfer + * + * @param channel channel number + * @param buffer_number number of buffers (beginning with 0), + * whose done bits should be reset to 0 + */ +int mxc_dma_reset(int channel, int buffer_number); + +/*! + * This functions Returns the SDMA paramaters associated for a module + * + * @param channel_id the ID of the module requesting DMA + * @return returns the sdma parameters structure for the device + */ +mxc_sdma_channel_params_t *mxc_sdma_get_channel_params(mxc_dma_device_t + channel_id); + +/*! + * This functions marks the SDMA channels that are statically allocated + * + * @param chnl the channel array used to store channel information + */ +void mxc_get_static_channels(mxc_dma_channel_t * chnl); + +/*! + * Initializes SDMA driver + */ +int __init sdma_init(void); + +#define DEFAULT_ERR 1 + +#endif diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/spba.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/spba.h --- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/spba.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/spba.h 2009-06-02 18:02:13.000000000 +0200 @@ -0,0 +1,66 @@ + +/* + * Copyright 2004-2008 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 SPBA Shared Peripheral Bus Arbiter (SPBA) + * @ingroup MSL_MX31 MSL_MX35 MSL_MX37 MSL_MX51 MSL_MXC91321 + */ + +/*! + * @file arch-mxc/spba.h + * @brief This file contains the Shared Peripheral Bus Arbiter (spba) API. + * + * @ingroup SPBA + */ + +#ifndef __ASM_ARCH_MXC_SPBA_H__ +#define __ASM_ARCH_MXC_SPBA_H__ + +#ifdef __KERNEL__ + +#define MXC_SPBA_RAR_MASK 0x7 + +/*! + * Defines three SPBA masters: A - ARM, C - SDMA (no master B for MX31) + */ +enum spba_masters { + SPBA_MASTER_A = 1, + SPBA_MASTER_B = 2, + SPBA_MASTER_C = 4, +}; + +/*! + * This function allows the three masters (A, B, C) to take ownership of a + * shared peripheral. + * + * @param mod specified module as defined in \b enum \b #spba_module + * @param master one of more (or-ed together) masters as defined in \b enum \b #spba_masters + * + * @return 0 if successful; -1 otherwise. + */ +int spba_take_ownership(int mod, int master); + +/*! + * This function releases the ownership for a shared peripheral. + * + * @param mod specified module as defined in \b enum \b #spba_module + * @param master one of more (or-ed together) masters as defined in \b enum \b #spba_masters + * + * @return 0 if successful; -1 otherwise. + */ +int spba_rel_ownership(int mod, int master); + +#endif /* __KERNEL__ */ + +#endif /* __ASM_ARCH_MXC_SPBA_H__ */ diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/timex.h linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/timex.h --- linux-2.6.30-rc4/arch/arm/plat-mxc/include/mach/timex.h 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/include/mach/timex.h 2009-06-02 18:02:12.000000000 +0200 @@ -23,7 +23,11 @@ #if defined CONFIG_ARCH_MX1 #define CLOCK_TICK_RATE 16000000 #elif defined CONFIG_ARCH_MX2 +#ifndef CONFIG_MACH_MX25 #define CLOCK_TICK_RATE 13300000 +#else +#define CLOCK_TICK_RATE 12000000 +#endif #elif defined CONFIG_ARCH_MX3 #define CLOCK_TICK_RATE 16625000 #endif diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/iomux-mx1-mx2.c linux-2.6.30-rc4-karo/arch/arm/plat-mxc/iomux-mx1-mx2.c --- linux-2.6.30-rc4/arch/arm/plat-mxc/iomux-mx1-mx2.c 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/iomux-mx1-mx2.c 2009-06-02 18:02:01.000000000 +0200 @@ -74,11 +74,12 @@ void mxc_gpio_mode(int gpio_mode) __raw_writel(tmp, VA_GPIO_BASE + MXC_GIUS(port)); if (pin < 16) { +#ifndef CONFIG_MACH_MX25 tmp = __raw_readl(VA_GPIO_BASE + MXC_OCR1(port)); tmp &= ~(3 << (pin * 2)); tmp |= (ocr << (pin * 2)); __raw_writel(tmp, VA_GPIO_BASE + MXC_OCR1(port)); - +#endif tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFA1(port)); tmp &= ~(3 << (pin * 2)); tmp |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2); @@ -90,12 +91,12 @@ void mxc_gpio_mode(int gpio_mode) __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFB1(port)); } else { pin -= 16; - +#ifndef CONFIG_MACH_MX25 tmp = __raw_readl(VA_GPIO_BASE + MXC_OCR2(port)); tmp &= ~(3 << (pin * 2)); tmp |= (ocr << (pin * 2)); __raw_writel(tmp, VA_GPIO_BASE + MXC_OCR2(port)); - +#endif tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFA2(port)); tmp &= ~(3 << (pin * 2)); tmp |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2); diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/iomux-v3.c linux-2.6.30-rc4-karo/arch/arm/plat-mxc/iomux-v3.c --- linux-2.6.30-rc4/arch/arm/plat-mxc/iomux-v3.c 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/iomux-v3.c 2009-06-02 18:02:02.000000000 +0200 @@ -31,7 +31,24 @@ #define IOMUX_BASE IO_ADDRESS(IOMUXC_BASE_ADDR) -static unsigned long iomux_v3_pad_alloc_map[0x200 / BITS_PER_LONG]; +#ifdef CONFIG_MACH_MX25 +#define NUM_PADS 0x228 +#else +#define NUM_PADS 0x200 +#endif + +static unsigned long iomux_v3_pad_alloc_map[NUM_PADS / BITS_PER_LONG]; + +static inline int mxc_iomux_v3_pad_offset(struct pad_desc *pad) +{ + int pad_ofs; + if (cpu_is_mx25()) + pad_ofs = pad->mux_ctrl_ofs; + else + pad_ofs = pad->pad_ctrl_ofs; + BUG_ON((pad_ofs >> 7) >= ARRAY_SIZE(iomux_v3_pad_alloc_map)); + return pad_ofs; +} /* * setups a single pin: @@ -40,7 +57,7 @@ static unsigned long iomux_v3_pad_alloc_ */ int mxc_iomux_v3_setup_pad(struct pad_desc *pad) { - unsigned int pad_ofs = pad->pad_ctrl_ofs; + unsigned int pad_ofs = mxc_iomux_v3_pad_offset(pad); if (test_and_set_bit(pad_ofs >> 2, iomux_v3_pad_alloc_map)) return -EBUSY; @@ -65,8 +82,10 @@ int mxc_iomux_v3_setup_multiple_pads(str for (i = 0; i < count; i++) { ret = mxc_iomux_v3_setup_pad(p); - if (ret) + if (ret) { + printk(KERN_ERR "Failed to setup PAD[%d]: %d\n", i, ret); goto setup_error; + } p++; } return 0; @@ -79,7 +98,7 @@ EXPORT_SYMBOL(mxc_iomux_v3_setup_multipl void mxc_iomux_v3_release_pad(struct pad_desc *pad) { - unsigned int pad_ofs = pad->pad_ctrl_ofs; + unsigned int pad_ofs = mxc_iomux_v3_pad_offset(pad); clear_bit(pad_ofs >> 2, iomux_v3_pad_alloc_map); } diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/pwm.c linux-2.6.30-rc4-karo/arch/arm/plat-mxc/pwm.c --- linux-2.6.30-rc4/arch/arm/plat-mxc/pwm.c 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/pwm.c 2009-06-02 18:02:02.000000000 +0200 @@ -55,7 +55,7 @@ int pwm_config(struct pwm_device *pwm, i if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) return -EINVAL; - if (cpu_is_mx27() || cpu_is_mx3()) { + if (cpu_is_mx27() || cpu_is_mx3() || cpu_is_mx25()) { unsigned long long c; unsigned long period_cycles, duty_cycles, prescale; c = clk_get_rate(pwm->clk); diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/spba.c linux-2.6.30-rc4-karo/arch/arm/plat-mxc/spba.c --- linux-2.6.30-rc4/arch/arm/plat-mxc/spba.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/spba.c 2009-06-02 18:02:03.000000000 +0200 @@ -0,0 +1,143 @@ +/* + * Copyright 2004-2008 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 +#include +#include +#include +#include +#include +#include + +/*! + * @file plat-mxc/spba.c + * + * @brief This file contains the SPBA API implementation details. + * + * @ingroup SPBA + */ + +static DEFINE_SPINLOCK(spba_lock); + +#define SPBA_MASTER_MIN 1 +#define SPBA_MASTER_MAX 7 + +/*! + * the base addresses for the SPBA modules + */ +static unsigned long spba_base = (unsigned long)IO_ADDRESS(SPBA_CTRL_BASE_ADDR); + +/*! + * SPBA clock + */ +static struct clk *spba_clk; +/*! + * This function allows the three masters (A, B, C) to take ownership of a + * shared peripheral. + * + * @param mod specified module as defined in \b enum \b #spba_module + * @param master one of more (or-ed together) masters as defined in \b enum \b #spba_masters + * + * @return 0 if successful; a negative errno value otherwise. + */ +int spba_take_ownership(int mod, int master) +{ + unsigned long spba_flags; + int rtn_val = -EIO; + + if (master < SPBA_MASTER_MIN || master > SPBA_MASTER_MAX) { + printk("%s() invalid master %d\n", __FUNCTION__, master); + return -EINVAL; + } + + if (spba_clk == NULL) { + spba_clk = clk_get(NULL, "spba"); + if (IS_ERR(spba_clk)) { + int ret = PTR_ERR(spba_clk); + + spba_clk = NULL; + return ret; + } + } + clk_enable(spba_clk); + + spin_lock_irqsave(&spba_lock, spba_flags); + __raw_writel(master, spba_base + mod); + + if ((__raw_readl(spba_base + mod) & MXC_SPBA_RAR_MASK) == master) { + rtn_val = 0; + } + + spin_unlock_irqrestore(&spba_lock, spba_flags); + + clk_disable(spba_clk); + return rtn_val; +} + +/*! + * This function releases the ownership for a shared peripheral. + * + * @param mod specified module as defined in \b enum \b #spba_module + * @param master one of more (or-ed together) masters as defined in \b enum \b #spba_masters + * + * @return 0 if successful; a negativ errno value otherwise. + */ +int spba_rel_ownership(int mod, int master) +{ + unsigned long spba_flags; + volatile unsigned long rar; + + if (master < SPBA_MASTER_MIN || master > SPBA_MASTER_MAX) { + printk("%s() invalid master %d\n", __FUNCTION__, master); + return -EINVAL; + } + + if (spba_clk == NULL) { + spba_clk = clk_get(NULL, "spba"); + if (IS_ERR(spba_clk)) { + int ret = PTR_ERR(spba_clk); + spba_clk = NULL; + return ret; + } + } + clk_enable(spba_clk); + + if ((__raw_readl(spba_base + mod) & master) == 0) { + clk_disable(spba_clk); + return -EBUSY; /* does not own it */ + } + + spin_lock_irqsave(&spba_lock, spba_flags); + + /* Since only the last 3 bits are writeable, doesn't need to mask off + bits 31-3 */ + rar = __raw_readl(spba_base + mod) & (~master); + __raw_writel(rar, spba_base + mod); + + if ((__raw_readl(spba_base + mod) & master) != 0) { + spin_unlock_irqrestore(&spba_lock, spba_flags); + clk_disable(spba_clk); + return -EIO; + } + spin_unlock_irqrestore(&spba_lock, spba_flags); + + clk_disable(spba_clk); + return 0; +} + +EXPORT_SYMBOL(spba_take_ownership); +EXPORT_SYMBOL(spba_rel_ownership); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("SPBA"); +MODULE_LICENSE("GPL"); diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/system.c linux-2.6.30-rc4-karo/arch/arm/plat-mxc/system.c --- linux-2.6.30-rc4/arch/arm/plat-mxc/system.c 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/system.c 2009-06-08 12:48:23.000000000 +0200 @@ -21,6 +21,7 @@ */ #include +#include #include #include #include @@ -38,18 +39,15 @@ #define WDOG_WCR_ENABLE (1 << 2) #endif +static struct clk *mxc_wdt_clk; + /* * Reset the system. It is called by machine_restart(). */ void arch_reset(char mode, const char *cmd) { - if (!cpu_is_mx1()) { - struct clk *clk; - - clk = clk_get_sys("imx-wdt.0", NULL); - if (!IS_ERR(clk)) - clk_enable(clk); - } + if (mxc_wdt_clk) + clk_enable(mxc_wdt_clk); /* Assert SRS signal */ __raw_writew(WDOG_WCR_ENABLE, WDOG_WCR_REG); @@ -65,3 +63,20 @@ void arch_reset(char mode, const char *c /* we'll take a jump through zero as a poor second */ cpu_reset(0); } + +static int mxc_wdt_init(void) +{ + if (cpu_is_mx1()) + return 0; + + mxc_wdt_clk = clk_get_sys("imx-wdt.0", NULL); + if (IS_ERR(mxc_wdt_clk)) { + int ret = PTR_ERR(mxc_wdt_clk); + + printk(KERN_ERR "%s: Failed to get imx-wdt.0 clk: %d\n", __FUNCTION__, ret); + mxc_wdt_clk = NULL; + return ret; + } + return 0; +} +arch_initcall(mxc_wdt_init); diff -urNp linux-2.6.30-rc4/arch/arm/plat-mxc/time.c linux-2.6.30-rc4-karo/arch/arm/plat-mxc/time.c --- linux-2.6.30-rc4/arch/arm/plat-mxc/time.c 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/plat-mxc/time.c 2009-06-02 18:02:02.000000000 +0200 @@ -66,7 +66,7 @@ static inline void gpt_irq_disable(void) { unsigned int tmp; - if (cpu_is_mx3()) + if (cpu_is_mx3() || cpu_is_mx25()) __raw_writel(0, timer_base + MX3_IR); else { tmp = __raw_readl(timer_base + MXC_TCTL); @@ -76,7 +76,7 @@ static inline void gpt_irq_disable(void) static inline void gpt_irq_enable(void) { - if (cpu_is_mx3()) + if (cpu_is_mx3() || cpu_is_mx25()) __raw_writel(1<<0, timer_base + MX3_IR); else { __raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN, @@ -88,9 +88,9 @@ static void gpt_irq_acknowledge(void) { if (cpu_is_mx1()) __raw_writel(0, timer_base + MX1_2_TSTAT); - if (cpu_is_mx2()) + if (cpu_is_mx2() && !cpu_is_mx25()) __raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP, timer_base + MX1_2_TSTAT); - if (cpu_is_mx3()) + if (cpu_is_mx3() || cpu_is_mx25()) __raw_writel(MX3_TSTAT_OF1, timer_base + MX3_TSTAT); } @@ -117,7 +117,7 @@ static int __init mxc_clocksource_init(s { unsigned int c = clk_get_rate(timer_clk); - if (cpu_is_mx3()) + if (cpu_is_mx3() || cpu_is_mx25()) clocksource_mxc.read = mx3_get_cycles; clocksource_mxc.mult = clocksource_hz2mult(c, @@ -180,7 +180,7 @@ static void mxc_set_mode(enum clock_even if (mode != clockevent_mode) { /* Set event time into far-far future */ - if (cpu_is_mx3()) + if (cpu_is_mx3() || cpu_is_mx25()) __raw_writel(__raw_readl(timer_base + MX3_TCN) - 3, timer_base + MX3_TCMP); else @@ -233,7 +233,7 @@ static irqreturn_t mxc_timer_interrupt(i struct clock_event_device *evt = &clockevent_mxc; uint32_t tstat; - if (cpu_is_mx3()) + if (cpu_is_mx3() || cpu_is_mx25()) tstat = __raw_readl(timer_base + MX3_TSTAT); else tstat = __raw_readl(timer_base + MX1_2_TSTAT); @@ -264,7 +264,7 @@ static int __init mxc_clockevent_init(st { unsigned int c = clk_get_rate(timer_clk); - if (cpu_is_mx3()) + if (cpu_is_mx3() || cpu_is_mx25()) clockevent_mxc.set_next_event = mx3_set_next_event; clockevent_mxc.mult = div_sc(c, NSEC_PER_SEC, @@ -287,6 +287,7 @@ void __init mxc_timer_init(struct clk *t int irq; clk_enable(timer_clk); +printk(KERN_DEBUG "%s: \n", __FUNCTION__); if (cpu_is_mx1()) { #ifdef CONFIG_ARCH_MX1 @@ -306,6 +307,7 @@ void __init mxc_timer_init(struct clk *t } else BUG(); +printk(KERN_DEBUG "%s: timer_base=%p IRQ=%d\n", __FUNCTION__, timer_base, irq); /* * Initialise to a known state (all timers off, and timing reset) */ @@ -313,7 +315,7 @@ void __init mxc_timer_init(struct clk *t __raw_writel(0, timer_base + MXC_TCTL); __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */ - if (cpu_is_mx3()) + if (cpu_is_mx3() || cpu_is_mx25()) tctl_val = MX3_TCTL_CLK_IPG | MX3_TCTL_FRR | MX3_TCTL_WAITEN | MXC_TCTL_TEN; else tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; diff -urNp linux-2.6.30-rc4/arch/arm/tools/mach-types linux-2.6.30-rc4-karo/arch/arm/tools/mach-types --- linux-2.6.30-rc4/arch/arm/tools/mach-types 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/arch/arm/tools/mach-types 2009-06-02 18:02:54.000000000 +0200 @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Mon Mar 23 20:09:01 2009 +# Last update: Mon Apr 20 10:31:38 2009 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -1721,7 +1721,7 @@ sapphire MACH_SAPPHIRE SAPPHIRE 1729 csb637xo MACH_CSB637XO CSB637XO 1730 evisiong MACH_EVISIONG EVISIONG 1731 stmp37xx MACH_STMP37XX STMP37XX 1732 -stmp378x MACH_STMP38XX STMP38XX 1733 +stmp378x MACH_STMP378X STMP378X 1733 tnt MACH_TNT TNT 1734 tbxt MACH_TBXT TBXT 1735 playmate MACH_PLAYMATE PLAYMATE 1736 @@ -2132,3 +2132,41 @@ apollo MACH_APOLLO APOLLO 2141 at91cap9stk MACH_AT91CAP9STK AT91CAP9STK 2142 spc300 MACH_SPC300 SPC300 2143 eko MACH_EKO EKO 2144 +ccw9m2443 MACH_CCW9M2443 CCW9M2443 2145 +ccw9m2443js MACH_CCW9M2443JS CCW9M2443JS 2146 +m2m_router_device MACH_M2M_ROUTER_DEVICE M2M_ROUTER_DEVICE 2147 +str9104nas MACH_STAR9104NAS STAR9104NAS 2148 +pca100 MACH_PCA100 PCA100 2149 +z3_dm365_mod_01 MACH_Z3_DM365_MOD_01 Z3_DM365_MOD_01 2150 +hipox MACH_HIPOX HIPOX 2151 +omap3_piteds MACH_OMAP3_PITEDS OMAP3_PITEDS 2152 +bm150r MACH_BM150R BM150R 2153 +tbone MACH_TBONE TBONE 2154 +merlin MACH_MERLIN MERLIN 2155 +falcon MACH_FALCON FALCON 2156 +davinci_da850_evm MACH_DAVINCI_DA850_EVM DAVINCI_DA850_EVM 2157 +s5p6440 MACH_S5P6440 S5P6440 2158 +at91sam9g10ek MACH_AT91SAM9G10EK AT91SAM9G10EK 2159 +omap_4430sdp MACH_OMAP_4430SDP OMAP_4430SDP 2160 +lpc313x MACH_LPC313X LPC313X 2161 +magx_zn5 MACH_MAGX_ZN5 MAGX_ZN5 2162 +magx_em30 MACH_MAGX_EM30 MAGX_EM30 2163 +magx_ve66 MACH_MAGX_VE66 MAGX_VE66 2164 +meesc MACH_MEESC MEESC 2165 +otc570 MACH_OTC570 OTC570 2166 +bcu2412 MACH_BCU2412 BCU2412 2167 +beacon MACH_BEACON BEACON 2168 +actia_tgw MACH_ACTIA_TGW ACTIA_TGW 2169 +e4430 MACH_E4430 E4430 2170 +ql300 MACH_QL300 QL300 2171 +btmavb101 MACH_BTMAVB101 BTMAVB101 2172 +btmawb101 MACH_BTMAWB101 BTMAWB101 2173 +sq201 MACH_SQ201 SQ201 2174 +quatro45xx MACH_QUATRO45XX QUATRO45XX 2175 +openpad MACH_OPENPAD OPENPAD 2176 +tx25 MACH_TX25 TX25 2177 +omap3_torpedo MACH_OMAP3_TORPEDO OMAP3_TORPEDO 2178 +htcraphael_k MACH_HTCRAPHAEL_K HTCRAPHAEL_K 2179 +pxa255 MACH_PXA255 PXA255 2180 +lal43 MACH_LAL43 LAL43 2181 +htcraphael_cdma500 MACH_HTCRAPHAEL_CDMA500 HTCRAPHAEL_CDMA500 2182 diff -urNp linux-2.6.30-rc4/drivers/leds/leds-gpio.c linux-2.6.30-rc4-karo/drivers/leds/leds-gpio.c --- linux-2.6.30-rc4/drivers/leds/leds-gpio.c 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/drivers/leds/leds-gpio.c 2009-06-02 18:36:36.000000000 +0200 @@ -82,7 +82,7 @@ static int __devinit create_gpio_led(con if (!gpio_is_valid(template->gpio)) { printk(KERN_INFO "Skipping unavilable LED gpio %d (%s)\n", template->gpio, template->name); - return 0; + return -EINVAL; } ret = gpio_request(template->gpio, template->name); diff -urNp linux-2.6.30-rc4/drivers/mtd/nand/Kconfig linux-2.6.30-rc4-karo/drivers/mtd/nand/Kconfig --- linux-2.6.30-rc4/drivers/mtd/nand/Kconfig 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/drivers/mtd/nand/Kconfig 2009-06-02 18:42:05.000000000 +0200 @@ -420,6 +420,27 @@ config MTD_NAND_MXC This enables the driver for the NAND flash controller on the MXC processors. +config MTD_NAND_MXC_FLASH_BBT + bool "Support a flash based bad block table" + depends on MTD_NAND_MXC + +config ARCH_MXC_HAS_NFC_V1 + bool + +config ARCH_MXC_HAS_NFC_V1_1 + select ARCH_MXC_HAS_NFC_V1 + bool + +config ARCH_MXC_HAS_NFC_V2 + bool + +config ARCH_MXC_HAS_NFC_V2_1 + bool + select ARCH_MXC_HAS_NFC_V2 + +config ARCH_MXC_HAS_NFC_V3 + bool + config MTD_NAND_SH_FLCTL tristate "Support for NAND on Renesas SuperH FLCTL" depends on MTD_NAND && SUPERH && CPU_SUBTYPE_SH7723 diff -urNp linux-2.6.30-rc4/drivers/mtd/nand/mxc_nand.c linux-2.6.30-rc4-karo/drivers/mtd/nand/mxc_nand.c --- linux-2.6.30-rc4/drivers/mtd/nand/mxc_nand.c 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/drivers/mtd/nand/mxc_nand.c 2009-06-08 12:51:07.000000000 +0200 @@ -34,23 +34,52 @@ #include #include +#ifdef CONFIG_MTD_DEBUG +static int debug = 0; +module_param(debug, int, S_IRUGO | S_IWUSR); + +#define dbg_lvl(n) ((n) < debug) +#define DBG(lvl, fmt...) do { if (dbg_lvl(lvl)) printk(KERN_DEBUG fmt); } while (0) +#undef DEBUG +#define DEBUG(l, fmt...) DBG(l, fmt) +#else +static int debug; +module_param(debug, int, 0); + +#define dbg_lvl(n) 0 +#define DBG(lvl, fmt...) do { } while (0) +#endif + + #define DRIVER_NAME "mxc_nand" /* Addresses for NFC registers */ -#define NFC_BUF_SIZE 0xE00 -#define NFC_BUF_ADDR 0xE04 -#define NFC_FLASH_ADDR 0xE06 -#define NFC_FLASH_CMD 0xE08 -#define NFC_CONFIG 0xE0A -#define NFC_ECC_STATUS_RESULT 0xE0C -#define NFC_RSLTMAIN_AREA 0xE0E -#define NFC_RSLTSPARE_AREA 0xE10 -#define NFC_WRPROT 0xE12 -#define NFC_UNLOCKSTART_BLKADDR 0xE14 -#define NFC_UNLOCKEND_BLKADDR 0xE16 -#define NFC_NF_WRPRST 0xE18 -#define NFC_CONFIG1 0xE1A -#define NFC_CONFIG2 0xE1C +#define NFC_BUF_SIZE 0x000 +#define NFC_BUF_ADDR 0x004 +#define NFC_FLASH_ADDR 0x006 +#define NFC_FLASH_CMD 0x008 +#define NFC_CONFIG 0x00A +#define NFC_ECC_STATUS_RESULT 0x00C +#define NFC_RSLTMAIN_AREA 0x00E +#define NFC_RSLTSPARE_AREA 0x010 +#define NFC_WRPROT 0x012 +#ifndef CONFIG_ARCH_MXC_HAS_NFC_V1_1 +#define NFC_UNLOCKSTART_BLKADDR 0x014 +#define NFC_UNLOCKEND_BLKADDR 0x016 +#endif +#define NFC_NF_WRPRST 0x018 +#define NFC_CONFIG1 0x01A +#define NFC_CONFIG2 0x01C +#ifdef CONFIG_ARCH_MXC_HAS_NFC_V1_1 +#define NFC_UNLOCKSTART_BLKADDR 0x020 +#define NFC_UNLOCKEND_BLKADDR 0x022 +#define NFC_UNLOCKSTART_BLKADDR1 0x024 +#define NFC_UNLOCKEND_BLKADDR1 0x026 +#define NFC_UNLOCKSTART_BLKADDR2 0x028 +#define NFC_UNLOCKEND_BLKADDR2 0x02a +#define NFC_UNLOCKSTART_BLKADDR3 0x02c +#define NFC_UNLOCKEND_BLKADDR3 0x02e +#endif /* Addresses for NFC RAM BUFFER Main area 0 */ #define MAIN_AREA0 0x000 @@ -59,10 +88,27 @@ #define MAIN_AREA3 0x600 /* Addresses for NFC SPARE BUFFER Spare area 0 */ +#ifndef CONFIG_ARCH_MXC_HAS_NFC_V1_1 +#define SPARE_AREA_SIZE 16 #define SPARE_AREA0 0x800 #define SPARE_AREA1 0x810 #define SPARE_AREA2 0x820 #define SPARE_AREA3 0x830 +#else +#define SPARE_AREA_SIZE 64 +#define MAIN_AREA4 0x800 +#define MAIN_AREA5 0xa00 +#define MAIN_AREA6 0xc00 +#define MAIN_AREA7 0xe00 +#define SPARE_AREA0 0x1000 +#define SPARE_AREA1 0x1040 +#define SPARE_AREA2 0x1080 +#define SPARE_AREA3 0x10c0 +#define SPARE_AREA4 0x1100 +#define SPARE_AREA5 0x1140 +#define SPARE_AREA6 0x1180 +#define SPARE_AREA7 0x11c0 +#endif /* Set INT to 0, FCMD to 1, rest to 0 in NFC_CONFIG2 Register * for Command operation */ @@ -107,6 +153,7 @@ struct mxc_nand_host { struct device *dev; void __iomem *regs; + void __iomem *nfc_buf; int spare_only; int status_request; int pagesize_2k; @@ -120,40 +167,149 @@ struct mxc_nand_host { /* Define delays in microsec for NAND device operations */ #define TROP_US_DELAY 2000 -/* Macros to get byte and bit positions of ECC */ -#define COLPOS(x) ((x) >> 3) -#define BITPOS(x) ((x) & 0xf) - -/* Define single bit Error positions in Main & Spare area */ -#define MAIN_SINGLEBIT_ERROR 0x4 -#define SPARE_SINGLEBIT_ERROR 0x1 +#ifndef CONFIG_ARCH_MXC_HAS_NFC_V1_1 /* OOB placement block for use with hardware ecc generation */ +static struct nand_ecclayout nand_hw_eccoob2k_8 = { + .eccbytes = 5, + .eccpos = {6, 7, 8, 9, 10}, + .oobfree = {{0, 5}, {11, 11}, {27, 11}, {43, 5}} +}; + static struct nand_ecclayout nand_hw_eccoob_8 = { .eccbytes = 5, .eccpos = {6, 7, 8, 9, 10}, - .oobfree = {{0, 5}, {11, 5}, } + .oobfree = {{0, 5}, {11, 5}} +}; + +static struct nand_ecclayout nand_hw_eccoob2k_16 = { + .eccbytes = 5, + .eccpos = {6, 7, 8, 9, 10}, + .oobfree = {{0, 6}, {12, 10}, {28, 10}, {44, 4}} }; static struct nand_ecclayout nand_hw_eccoob_16 = { .eccbytes = 5, .eccpos = {6, 7, 8, 9, 10}, - .oobfree = {{0, 6}, {12, 4}, } + .oobfree = {{0, 6}, {12, 4}} +}; + +#ifdef CONFIG_MTD_NAND_MXC_FLASH_BBT +static u8 bbt_pattern[] = {'B', 'b', 't', '0' }; +static u8 mirror_pattern[] = {'1', 't', 'b', 'B' }; + +static struct nand_bbt_descr bbt_main_descr = { + .options = (NAND_BBT_LASTBLOCK | NAND_BBT_WRITE | + NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP), + .offs = 12, + .len = 4, + .veroffs = 11, + .maxblocks = 4, + .pattern = bbt_pattern, }; +static struct nand_bbt_descr bbt_mirror_descr = { + .options = (NAND_BBT_LASTBLOCK | NAND_BBT_WRITE | + NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP), + .offs = 12, + .len = 4, + .veroffs = 11, + .maxblocks = 4, + .pattern = mirror_pattern, +}; +#endif +#else +/* + * OOB placement block for use with hardware ecc generation + */ +static struct nand_ecclayout nand_hw_eccoob2k_8 = { + .eccbytes = 9, + .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15}, + .oobfree = {{2, 5}, {16, 7}, {32, 7}, {48, 7}}, +}; + +static struct nand_ecclayout nand_hw_eccoob_8 = { + .eccbytes = 9, + .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15}, + .oobfree = {{0, 4}}, +}; + +static struct nand_ecclayout nand_hw_eccoob2k_16 = { + .eccbytes = 9, + .eccpos = {6, 7, 8, 9, 10, 11, 12, 13, 14}, + .oobfree = {{2, 4}, {17, 6}, {33, 6}, {47, 6}}, +}; + +static struct nand_ecclayout nand_hw_eccoob_16 = { + .eccbytes = 9, + .eccpos = {6, 7, 8, 9, 10, 11, 12, 13, 14}, + .oobfree = {{0, 3}} +}; + +#ifdef CONFIG_MTD_NAND_MXC_FLASH_BBT +/* Generic flash bbt decriptors +*/ +static u8 bbt_pattern[] = { 'B', 'b', 't', '0' }; +static u8 mirror_pattern[] = { '1', 't', 'b', 'B' }; + +static struct nand_bbt_descr bbt_main_descr = { + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | + NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, + .offs = 0, + .len = 4, + .veroffs = 4, + .maxblocks = 4, + .pattern = bbt_pattern +}; + +static struct nand_bbt_descr bbt_mirror_descr = { + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | + NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, + .offs = 0, + .len = 4, + .veroffs = 4, + .maxblocks = 4, + .pattern = mirror_pattern +}; +#endif +#endif + #ifdef CONFIG_MTD_PARTITIONS static const char *part_probes[] = { "RedBoot", "cmdlinepart", NULL }; #endif +#ifdef CONFIG_MTD_DEBUG +#define nfc_read_reg(b, r) __nfc_read_reg(b, r, #r, __FUNCTION__) +static inline u16 __nfc_read_reg(void __iomem *base, unsigned int reg, + const char *name, const char *fn) +{ + u16 val = readw(base + reg); + DBG(3, "%s: Read %04x from %s[%02x]\n", fn, val, name, reg); + return val; +} + +#define nfc_write_reg(v, b, r) __nfc_write_reg(v, b, r, #r, __FUNCTION__) +static inline void __nfc_write_reg(u16 val, void __iomem *base, unsigned int reg, + const char *name, const char *fn) +{ + DBG(3, "%s: Writing %04x to %s[%02x]\n", fn, val, name, reg); + writew(val, base + reg); +} +#else +#define nfc_read_reg(b, r) readw(b + r) +#define nfc_write_reg(v, b, r) writew(v, b + r) +#endif + static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) { struct mxc_nand_host *host = dev_id; - uint16_t tmp; - tmp = readw(host->regs + NFC_CONFIG1); + DEBUG(MTD_DEBUG_LEVEL3, "%s(%d)\n", __FUNCTION__, irq); + + tmp = nfc_read_reg(host->regs, NFC_CONFIG1); tmp |= NFC_INT_MSK; /* Disable interrupt */ - writew(tmp, host->regs + NFC_CONFIG1); + nfc_write_reg(tmp, host->regs, NFC_CONFIG1); wake_up(&host->irq_waitq); @@ -166,35 +322,29 @@ static irqreturn_t mxc_nfc_irq(int irq, static void wait_op_done(struct mxc_nand_host *host, int max_retries, uint16_t param, int useirq) { - uint32_t tmp; - if (useirq) { - if ((readw(host->regs + NFC_CONFIG2) & NFC_INT) == 0) { - - tmp = readw(host->regs + NFC_CONFIG1); - tmp &= ~NFC_INT_MSK; /* Enable interrupt */ - writew(tmp, host->regs + NFC_CONFIG1); - - wait_event(host->irq_waitq, - readw(host->regs + NFC_CONFIG2) & NFC_INT); - - tmp = readw(host->regs + NFC_CONFIG2); - tmp &= ~NFC_INT; - writew(tmp, host->regs + NFC_CONFIG2); + if (!(nfc_read_reg(host->regs, NFC_CONFIG2) & NFC_INT)) { + uint32_t cfg1; + const unsigned long timeout = max_retries; + + cfg1 = nfc_read_reg(host->regs, NFC_CONFIG1); + cfg1 &= ~NFC_INT_MSK; /* Enable interrupt */ + nfc_write_reg(cfg1, host->regs, NFC_CONFIG1); + + max_retries = wait_event_timeout(host->irq_waitq, + nfc_read_reg(host->regs, NFC_CONFIG2) & + NFC_INT, timeout); } } else { - while (max_retries-- > 0) { - if (readw(host->regs + NFC_CONFIG2) & NFC_INT) { - tmp = readw(host->regs + NFC_CONFIG2); - tmp &= ~NFC_INT; - writew(tmp, host->regs + NFC_CONFIG2); - break; - } + while (!(nfc_read_reg(host->regs, NFC_CONFIG2) & NFC_INT) && + max_retries-- > 0) { udelay(1); } - if (max_retries <= 0) - DEBUG(MTD_DEBUG_LEVEL0, "%s(%d): INT not set\n", - __func__, param); + } + WARN_ON(nfc_read_reg(host->regs, NFC_CONFIG2) & ~NFC_INT); + nfc_write_reg(0, host->regs, NFC_CONFIG2); + if (WARN_ON(max_retries <= 0)) { + printk(KERN_ERR "%s(%d): INT not set\n", __func__, param); } } @@ -204,8 +354,9 @@ static void send_cmd(struct mxc_nand_hos { DEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x, %d)\n", cmd, useirq); - writew(cmd, host->regs + NFC_FLASH_CMD); - writew(NFC_CMD, host->regs + NFC_CONFIG2); + nfc_write_reg(cmd, host->regs, NFC_FLASH_CMD); + WARN_ON(nfc_read_reg(host->regs, NFC_CONFIG2)); + nfc_write_reg(NFC_CMD, host->regs, NFC_CONFIG2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, cmd, useirq); @@ -218,8 +369,9 @@ static void send_addr(struct mxc_nand_ho { DEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x %d)\n", addr, islast); - writew(addr, host->regs + NFC_FLASH_ADDR); - writew(NFC_ADDR, host->regs + NFC_CONFIG2); + nfc_write_reg(addr, host->regs, NFC_FLASH_ADDR); + WARN_ON(nfc_read_reg(host->regs, NFC_CONFIG2)); + nfc_write_reg(NFC_ADDR, host->regs, NFC_CONFIG2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, addr, islast); @@ -230,22 +382,28 @@ static void send_addr(struct mxc_nand_ho static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id, int spare_only) { + int i; DEBUG(MTD_DEBUG_LEVEL3, "send_prog_page (%d)\n", spare_only); + for (i = 0; i < 4; i++) { + void *src = host->nfc_buf + SPARE_AREA0 + i * 16; + void *dst = host->nfc_buf + SPARE_AREA0 + i * 64; + memcpy(dst, src, 16); + } /* NANDFC buffer 0 is used for page read/write */ - writew(buf_id, host->regs + NFC_BUF_ADDR); + nfc_write_reg(buf_id, host->regs, NFC_BUF_ADDR); /* Configure spare or page+spare access */ if (!host->pagesize_2k) { - uint16_t config1 = readw(host->regs + NFC_CONFIG1); + uint16_t config1 = nfc_read_reg(host->regs, NFC_CONFIG1); if (spare_only) config1 |= NFC_SP_EN; else - config1 &= ~(NFC_SP_EN); - writew(config1, host->regs + NFC_CONFIG1); + config1 &= ~NFC_SP_EN; + nfc_write_reg(config1, host->regs, NFC_CONFIG1); } - - writew(NFC_INPUT, host->regs + NFC_CONFIG2); + WARN_ON(nfc_read_reg(host->regs, NFC_CONFIG2)); + nfc_write_reg(NFC_INPUT, host->regs, NFC_CONFIG2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, spare_only, true); @@ -256,25 +414,33 @@ static void send_prog_page(struct mxc_na static void send_read_page(struct mxc_nand_host *host, uint8_t buf_id, int spare_only) { + int i; + DEBUG(MTD_DEBUG_LEVEL3, "send_read_page (%d)\n", spare_only); /* NANDFC buffer 0 is used for page read/write */ - writew(buf_id, host->regs + NFC_BUF_ADDR); + nfc_write_reg(buf_id, host->regs, NFC_BUF_ADDR); /* Configure spare or page+spare access */ if (!host->pagesize_2k) { - uint32_t config1 = readw(host->regs + NFC_CONFIG1); + uint32_t config1 = nfc_read_reg(host->regs, NFC_CONFIG1); if (spare_only) config1 |= NFC_SP_EN; else config1 &= ~NFC_SP_EN; - writew(config1, host->regs + NFC_CONFIG1); + nfc_write_reg(config1, host->regs, NFC_CONFIG1); } - writew(NFC_OUTPUT, host->regs + NFC_CONFIG2); + WARN_ON(nfc_read_reg(host->regs, NFC_CONFIG2)); + nfc_write_reg(NFC_OUTPUT, host->regs, NFC_CONFIG2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, spare_only, true); + for (i = 0; i < 4; i++) { + void *src = host->nfc_buf + SPARE_AREA0 + i * 64; + void *dst = host->nfc_buf + SPARE_AREA0 + i * 16; + memcpy(dst, src, 16); + } } /* Request the NANDFC to perform a read of the NAND device ID. */ @@ -284,20 +450,23 @@ static void send_read_id(struct mxc_nand uint16_t tmp; /* NANDFC buffer 0 is used for device ID output */ - writew(0x0, host->regs + NFC_BUF_ADDR); + nfc_write_reg(0x0, host->regs, NFC_BUF_ADDR); - /* Read ID into main buffer */ - tmp = readw(host->regs + NFC_CONFIG1); + tmp = nfc_read_reg(host->regs, NFC_CONFIG1); tmp &= ~NFC_SP_EN; - writew(tmp, host->regs + NFC_CONFIG1); + nfc_write_reg(tmp, host->regs, NFC_CONFIG1); - writew(NFC_ID, host->regs + NFC_CONFIG2); + WARN_ON(nfc_read_reg(host->regs, NFC_CONFIG2)); + /* Read ID into main buffer */ + nfc_write_reg(NFC_ID, host->regs, NFC_CONFIG2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, 0, true); if (this->options & NAND_BUSWIDTH_16) { - void __iomem *main_buf = host->regs + MAIN_AREA0; + /* FIXME: This cannot work, because the NFC buffer + * cannot be accessed with byte accesses! */ + void __iomem *main_buf = host->nfc_buf + MAIN_AREA0; /* compress the ID info */ writeb(readb(main_buf + 2), main_buf + 1); writeb(readb(main_buf + 4), main_buf + 2); @@ -311,32 +480,35 @@ static void send_read_id(struct mxc_nand * NAND device status and returns the current status. */ static uint16_t get_dev_status(struct mxc_nand_host *host) { - void __iomem *main_buf = host->regs + MAIN_AREA1; + void __iomem *main_buf = host->nfc_buf + MAIN_AREA1; uint32_t store; uint16_t ret, tmp; /* Issue status request to NAND device */ - /* store the main area1 first word, later do recovery */ + /* store the main area first word, later do recovery */ store = readl(main_buf); /* NANDFC buffer 1 is used for device status to prevent * corruption of read/write buffer on status requests. */ - writew(1, host->regs + NFC_BUF_ADDR); + nfc_write_reg(1, host->regs, NFC_BUF_ADDR); /* Read status into main buffer */ - tmp = readw(host->regs + NFC_CONFIG1); + tmp = nfc_read_reg(host->regs, NFC_CONFIG1); tmp &= ~NFC_SP_EN; - writew(tmp, host->regs + NFC_CONFIG1); + nfc_write_reg(tmp, host->regs, NFC_CONFIG1); - writew(NFC_STATUS, host->regs + NFC_CONFIG2); + WARN_ON(nfc_read_reg(host->regs, NFC_CONFIG2)); + nfc_write_reg(NFC_STATUS, host->regs, NFC_CONFIG2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, 0, true); /* Status is placed in first word of main buffer */ - /* get status, then recovery area 1 data */ + /* get status, then recover area 1 data */ ret = readw(main_buf); writel(store, main_buf); + DBG(0, "%s: status=%02x\n", __FUNCTION__, ret); + return ret; } @@ -369,7 +541,7 @@ static int mxc_nand_correct_data(struct * additional correction. 2-Bit errors cannot be corrected by * HW ECC, so we need to return failure */ - uint16_t ecc_status = readw(host->regs + NFC_ECC_STATUS_RESULT); + uint16_t ecc_status = nfc_read_reg(host->regs, NFC_ECC_STATUS_RESULT); if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) { DEBUG(MTD_DEBUG_LEVEL0, @@ -392,8 +564,10 @@ static u_char mxc_nand_read_byte(struct struct mxc_nand_host *host = nand_chip->priv; uint8_t ret = 0; uint16_t col, rd_word; - uint16_t __iomem *main_buf = host->regs + MAIN_AREA0; - uint16_t __iomem *spare_buf = host->regs + SPARE_AREA0; + uint16_t __iomem *main_buf = host->nfc_buf + MAIN_AREA0; + uint16_t __iomem *spare_buf = host->nfc_buf + SPARE_AREA0; + + WARN_ON(host->spare_only && host->col_addr >= 16); /* Check for status request */ if (host->status_request) @@ -431,14 +605,16 @@ static uint16_t mxc_nand_read_word(struc "mxc_nand_read_word(col = %d)\n", host->col_addr); col = host->col_addr; + /* Adjust saved column address */ if (col < mtd->writesize && host->spare_only) col += mtd->writesize; + WARN_ON(col >= mtd->writesize + 16); if (col < mtd->writesize) - p = (host->regs + MAIN_AREA0) + (col >> 1); + p = (host->nfc_buf + MAIN_AREA0) + (col >> 1); else - p = (host->regs + SPARE_AREA0) + ((col - mtd->writesize) >> 1); + p = (host->nfc_buf + SPARE_AREA0) + ((col - mtd->writesize) >> 1); if (col & 1) { rd_word = readw(p); @@ -474,10 +650,13 @@ static void mxc_nand_write_buf(struct mt /* Adjust saved column address */ if (col < mtd->writesize && host->spare_only) col += mtd->writesize; - +#if 0 n = mtd->writesize + mtd->oobsize - col; n = min(len, n); - +#else + BUG_ON(len > mtd->writesize + mtd->oobsize - col); + n = len; +#endif DEBUG(MTD_DEBUG_LEVEL3, "%s:%d: col = %d, n = %d\n", __func__, __LINE__, col, n); @@ -485,10 +664,10 @@ static void mxc_nand_write_buf(struct mt void __iomem *p; if (col < mtd->writesize) - p = host->regs + MAIN_AREA0 + (col & ~3); + p = host->nfc_buf + MAIN_AREA0 + (col & ~3); else - p = host->regs + SPARE_AREA0 - - mtd->writesize + (col & ~3); + p = host->nfc_buf + SPARE_AREA0 + + (col & ~3) - mtd->writesize; DEBUG(MTD_DEBUG_LEVEL3, "%s:%d: p = %p\n", __func__, __LINE__, p); @@ -542,6 +721,7 @@ static void mxc_nand_write_buf(struct mt DEBUG(MTD_DEBUG_LEVEL3, "%s:%d: n = %d, m = %d, i = %d, col = %d\n", __func__, __LINE__, n, m, i, col); + BUG_ON(m == 0); memcpy(p, &buf[i], m); col += m; @@ -571,18 +751,28 @@ static void mxc_nand_read_buf(struct mtd /* Adjust saved column address */ if (col < mtd->writesize && host->spare_only) col += mtd->writesize; - +#if 0 n = mtd->writesize + mtd->oobsize - col; n = min(len, n); - +#else + /* If more data is requested to be read than is available in + * the flash buffer this is clearly a BUG! */ + BUG_ON(len > mtd->writesize + mtd->oobsize - col); + n = len; +#endif while (n) { void __iomem *p; if (col < mtd->writesize) - p = host->regs + MAIN_AREA0 + (col & ~3); + p = host->nfc_buf + MAIN_AREA0 + (col & ~3); else - p = host->regs + SPARE_AREA0 - - mtd->writesize + (col & ~3); + p = host->nfc_buf + SPARE_AREA0 + + (col & ~3) - mtd->writesize; + + if (dbg_lvl(3)) { + print_hex_dump(KERN_DEBUG, "spare: ", DUMP_PREFIX_ADDRESS, + 16, 2, p, 64, 0); + } if (((col | (int)&buf[i]) & 3) || n < 16) { uint32_t data; @@ -621,15 +811,20 @@ static void mxc_nand_read_buf(struct mtd m += mtd->oobsize; m = min(n, m) & ~3; + DBG(1, "Copying %u byte from offset %03x[%p]\n", + m + (col & 3), col, p); + BUG_ON(m == 0); memcpy(&buf[i], p, m); col += m; i += m; n -= m; } } + if (dbg_lvl(1)) { + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len); + } /* Update saved column address */ host->col_addr = col; - } /* Used by the upper layer to verify the data in NAND Flash @@ -637,7 +832,22 @@ static void mxc_nand_read_buf(struct mtd static int mxc_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) { - return -EFAULT; + struct nand_chip *nand_chip = mtd->priv; + struct mxc_nand_host *host = nand_chip->priv; + int i; + u16 *wp = host->nfc_buf + MAIN_AREA0; + + for (i = 0; i < len >> 1; i++) { + u16 w = *wp++; + u8 c1 = *buf++; + u8 c2 = *buf++; + if ((w & 0xff) != c1 || (w >> 8) != c2) { + DBG(0, "%s: verify error @ %03x: read: %02x %02x expected: %02x %02x\n", + __FUNCTION__, i, w & 0xff, w >> 8, c1, c2); + return -EFAULT; + } + } + return 0; } /* This function is used by upper layer for select and @@ -655,13 +865,15 @@ static void mxc_nand_select_chip(struct } if (chip == -1) { - writew(readw(host->regs + NFC_CONFIG1) & ~NFC_CE, - host->regs + NFC_CONFIG1); + nfc_write_reg(host->regs, + nfc_read_reg(host->regs, NFC_CONFIG1) & ~NFC_CE, + NFC_CONFIG1); return; } - writew(readw(host->regs + NFC_CONFIG1) | NFC_CE, - host->regs + NFC_CONFIG1); + nfc_write_reg(host->regs, + nfc_read_reg(host->regs, NFC_CONFIG1) | NFC_CE, + NFC_CONFIG1); #endif switch (chip) { @@ -679,9 +891,6 @@ static void mxc_nand_select_chip(struct host->clk_act = 1; } break; - - default: - break; } } @@ -692,7 +901,7 @@ static void mxc_nand_command(struct mtd_ { struct nand_chip *nand_chip = mtd->priv; struct mxc_nand_host *host = nand_chip->priv; - int useirq = true; + int useirq = false; DEBUG(MTD_DEBUG_LEVEL3, "mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n", @@ -712,13 +921,11 @@ static void mxc_nand_command(struct mtd_ case NAND_CMD_READ0: host->col_addr = column; host->spare_only = false; - useirq = false; break; case NAND_CMD_READOOB: host->col_addr = column; host->spare_only = true; - useirq = false; if (host->pagesize_2k) command = NAND_CMD_READ0; /* only READ0 is valid */ break; @@ -751,23 +958,25 @@ static void mxc_nand_command(struct mtd_ if (!host->pagesize_2k) send_cmd(host, NAND_CMD_READ0, false); } - useirq = false; break; case NAND_CMD_PAGEPROG: send_prog_page(host, 0, host->spare_only); - +#ifndef CONFIG_ARCH_MXC_HAS_NFC_V1_1 if (host->pagesize_2k) { /* data in 4 areas datas */ send_prog_page(host, 1, host->spare_only); send_prog_page(host, 2, host->spare_only); send_prog_page(host, 3, host->spare_only); } - +#endif + useirq = true; break; case NAND_CMD_ERASE1: - useirq = false; + break; + case NAND_CMD_ERASE2: + useirq = true; break; } @@ -791,23 +1000,13 @@ static void mxc_nand_command(struct mtd_ /* Write out page address, if necessary */ if (page_addr != -1) { - /* paddr_0 - p_addr_7 */ - send_addr(host, (page_addr & 0xff), false); + u32 page_mask = nand_chip->pagemask; - if (host->pagesize_2k) { - send_addr(host, (page_addr >> 8) & 0xFF, false); - if (mtd->size >= 0x40000000) - send_addr(host, (page_addr >> 16) & 0xff, true); - } else { - /* One more address cycle for higher density devices */ - if (mtd->size >= 0x4000000) { - /* paddr_8 - paddr_15 */ - send_addr(host, (page_addr >> 8) & 0xff, false); - send_addr(host, (page_addr >> 16) & 0xff, true); - } else - /* paddr_8 - paddr_15 */ - send_addr(host, (page_addr >> 8) & 0xff, true); - } + do { + send_addr(host, (page_addr & 0xff), false); + page_mask >>= 8; + page_addr >>= 8; + } while (page_mask != 0); } /* Command post-processing step */ @@ -823,14 +1022,17 @@ static void mxc_nand_command(struct mtd_ send_cmd(host, NAND_CMD_READSTART, true); /* read for each AREA */ send_read_page(host, 0, host->spare_only); +#ifndef CONFIG_ARCH_MXC_HAS_NFC_V1_1 send_read_page(host, 1, host->spare_only); send_read_page(host, 2, host->spare_only); send_read_page(host, 3, host->spare_only); +#endif } else send_read_page(host, 0, host->spare_only); break; case NAND_CMD_READID: + host->col_addr = 0; send_read_id(host); break; @@ -851,9 +1053,12 @@ static int __init mxcnd_probe(struct pla struct mtd_info *mtd; struct mxc_nand_platform_data *pdata = pdev->dev.platform_data; struct mxc_nand_host *host; - struct resource *res; + struct resource *res1, *res2; uint16_t tmp; - int err = 0, nr_parts = 0; + int err, nr_parts; + + DBG(0, "%s: pdata=%p hw_ecc=%d width=%d\n", __FUNCTION__, + pdata, pdata->hw_ecc, pdata->width); /* Allocate memory for MTD device structure and private data */ host = kzalloc(sizeof(struct mxc_nand_host), GFP_KERNEL); @@ -868,9 +1073,6 @@ static int __init mxcnd_probe(struct pla mtd->owner = THIS_MODULE; mtd->dev.parent = &pdev->dev; - /* 50 us command delay time */ - this->chip_delay = 5; - this->priv = host; this->dev_ready = mxc_nand_dev_ready; this->cmdfunc = mxc_nand_command; @@ -880,29 +1082,54 @@ static int __init mxcnd_probe(struct pla this->write_buf = mxc_nand_write_buf; this->read_buf = mxc_nand_read_buf; this->verify_buf = mxc_nand_verify_buf; +#ifdef CONFIG_MTD_NAND_MXC_FLASH_BBT + this->bbt_td = &bbt_main_descr; + this->bbt_md = &bbt_mirror_descr; + this->options |= NAND_USE_FLASH_BBT; +#endif - host->clk = clk_get(&pdev->dev, "nfc"); - if (IS_ERR(host->clk)) + host->clk = clk_get(&pdev->dev, "nfc_clk"); + if (IS_ERR(host->clk)) { + err = PTR_ERR(host->clk); goto eclk; + } clk_enable(host->clk); host->clk_act = 1; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { + res1 = platform_get_resource(pdev, IORESOURCE_MEM, 0); + res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res1 || !res2) { err = -ENODEV; goto eres; } - host->regs = ioremap(res->start, res->end - res->start + 1); + if (!request_mem_region(res1->start, resource_size(res1), "mxc_nand regs")) { + err = -EBUSY; + goto ereq1; + } + + if (!request_mem_region(res2->start, resource_size(res2), "mxc_nand buffer")) { + err = -EBUSY; + goto ereq2; + } + + host->regs = ioremap(res1->start, resource_size(res1)); if (!host->regs) { - err = -EIO; - goto eres; + err = -ENOMEM; + goto eunmap1; } - tmp = readw(host->regs + NFC_CONFIG1); + host->nfc_buf = ioremap(res2->start, resource_size(res2)); + if (!host->nfc_buf) { + err = -ENOMEM; + goto eunmap2; + } + + tmp = nfc_read_reg(host->regs, NFC_CONFIG1); tmp |= NFC_INT_MSK; - writew(tmp, host->regs + NFC_CONFIG1); + nfc_write_reg(tmp, host->regs, NFC_CONFIG1); + nfc_write_reg(0, host->regs, NFC_CONFIG2); init_waitqueue_head(&host->irq_waitq); @@ -912,57 +1139,84 @@ static int __init mxcnd_probe(struct pla if (err) goto eirq; - if (pdata->hw_ecc) { - this->ecc.calculate = mxc_nand_calculate_ecc; - this->ecc.hwctl = mxc_nand_enable_hwecc; - this->ecc.correct = mxc_nand_correct_data; - this->ecc.mode = NAND_ECC_HW; - this->ecc.size = 512; - this->ecc.bytes = 3; - this->ecc.layout = &nand_hw_eccoob_8; - tmp = readw(host->regs + NFC_CONFIG1); - tmp |= NFC_ECC_EN; - writew(tmp, host->regs + NFC_CONFIG1); - } else { - this->ecc.size = 512; - this->ecc.bytes = 3; - this->ecc.layout = &nand_hw_eccoob_8; - this->ecc.mode = NAND_ECC_SOFT; - tmp = readw(host->regs + NFC_CONFIG1); - tmp &= ~NFC_ECC_EN; - writew(tmp, host->regs + NFC_CONFIG1); - } - /* Reset NAND */ this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); /* preset operation */ /* Unlock the internal RAM Buffer */ - writew(0x2, host->regs + NFC_CONFIG); + nfc_write_reg(0x2, host->regs, NFC_CONFIG); /* Blocks to be unlocked */ - writew(0x0, host->regs + NFC_UNLOCKSTART_BLKADDR); - writew(0x4000, host->regs + NFC_UNLOCKEND_BLKADDR); + nfc_write_reg(0x0, host->regs, NFC_UNLOCKSTART_BLKADDR); + nfc_write_reg(0x4000, host->regs, NFC_UNLOCKEND_BLKADDR); /* Unlock Block Command for given address range */ - writew(0x4, host->regs + NFC_WRPROT); + nfc_write_reg(0x4, host->regs, NFC_WRPROT); /* NAND bus width determines access funtions used by upper layer */ if (pdata->width == 2) { this->options |= NAND_BUSWIDTH_16; - this->ecc.layout = &nand_hw_eccoob_16; } - host->pagesize_2k = 0; - /* Scan to find existence of the device */ - if (nand_scan(mtd, 1)) { + err = nand_scan_ident(mtd, 1); + if (err) { DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND: Unable to find any NAND device.\n"); - err = -ENXIO; + goto escan; + } + /* this is required before completing the scan */ + host->pagesize_2k = (mtd->writesize == 2048); + tmp = nfc_read_reg(host->regs, NFC_CONFIG1); + tmp |= NFC_ONE_CYCLE; + tmp &= ~(3 << 9); /* clear PPB mask */ + DBG(0, "%s: ppb=%d (%02x)\n", __FUNCTION__, + mtd->erasesize / mtd->writesize, + ffs(mtd->erasesize / mtd->writesize) - 6); + + /* set PPB (pages per block */ + tmp |= (ffs(mtd->erasesize / mtd->writesize) - 6) << 9; + nfc_write_reg(tmp, host->regs, NFC_CONFIG1); + if (pdata->width == 2) { + if (host->pagesize_2k) { + this->ecc.layout = &nand_hw_eccoob2k_16; + } else { + this->ecc.layout = &nand_hw_eccoob_16; + } + } else { + if (host->pagesize_2k) { + this->ecc.layout = &nand_hw_eccoob2k_8; + } else { + this->ecc.layout = &nand_hw_eccoob_8; + } + } + if (pdata->hw_ecc) { + this->ecc.calculate = mxc_nand_calculate_ecc; + this->ecc.hwctl = mxc_nand_enable_hwecc; + this->ecc.correct = mxc_nand_correct_data; + this->ecc.mode = NAND_ECC_HW; + this->ecc.size = 512; + this->ecc.bytes = 3; + tmp = nfc_read_reg(host->regs, NFC_CONFIG1); + tmp |= NFC_ECC_EN; + nfc_write_reg(tmp, host->regs, NFC_CONFIG1); + } else { + this->ecc.size = 512; + this->ecc.bytes = 3; + this->ecc.mode = NAND_ECC_SOFT; + tmp = nfc_read_reg(host->regs, NFC_CONFIG1); + tmp &= ~NFC_ECC_EN; + nfc_write_reg(tmp, host->regs, NFC_CONFIG1); + } + + err = nand_scan_tail(mtd); + if (err) { goto escan; } + pr_info("MXC MTD nand Driver IRQ %d bus width: %u bit %s ECC IO: %08lx\n", + host->irq, pdata->width * 8, pdata->hw_ecc ? "HW" : "SW", + (unsigned long)res1->start); /* Register the partitions */ #ifdef CONFIG_MTD_PARTITIONS nr_parts = @@ -981,10 +1235,19 @@ static int __init mxcnd_probe(struct pla return 0; escan: - free_irq(host->irq, NULL); + free_irq(host->irq, host); eirq: + if (res2) + iounmap(host->nfc_buf); +eunmap2: iounmap(host->regs); +eunmap1: + release_mem_region(res2->start, resource_size(res2)); +ereq2: + release_mem_region(res1->start, resource_size(res1)); +ereq1: eres: + clk_disable(host->clk); clk_put(host->clk); eclk: kfree(host); @@ -995,46 +1258,63 @@ eclk: static int __devexit mxcnd_remove(struct platform_device *pdev) { struct mxc_nand_host *host = platform_get_drvdata(pdev); + struct resource *res; + if (host->clk_act) + clk_disable(host->clk); clk_put(host->clk); - platform_set_drvdata(pdev, NULL); - nand_release(&host->mtd); - free_irq(host->irq, NULL); + free_irq(host->irq, host); iounmap(host->regs); kfree(host); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res) { + release_mem_region(res->start, resource_size(res)); + } + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (res) { + release_mem_region(res->start, resource_size(res)); + } return 0; } #ifdef CONFIG_PM static int mxcnd_suspend(struct platform_device *pdev, pm_message_t state) { - struct mtd_info *info = platform_get_drvdata(pdev); + struct mtd_info *mtd = platform_get_drvdata(pdev); + struct nand_chip *nand_chip = mtd->priv; + struct mxc_nand_host *host = nand_chip->priv; int ret = 0; DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND suspend\n"); - if (info) - ret = info->suspend(info); + if (mtd) + ret = mtd->suspend(mtd); - /* Disable the NFC clock */ - clk_disable(nfc_clk); /* FIXME */ + if (host->clk_act) { + /* Disable the NFC clock */ + clk_disable(host->clk); + } return ret; } static int mxcnd_resume(struct platform_device *pdev) { - struct mtd_info *info = platform_get_drvdata(pdev); + struct mtd_info *mtd = platform_get_drvdata(pdev); + struct nand_chip *nand_chip = mtd->priv; + struct mxc_nand_host *host = nand_chip->priv; int ret = 0; DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND resume\n"); - /* Enable the NFC clock */ - clk_enable(nfc_clk); /* FIXME */ - if (info) - info->resume(info); + if (host->clk_act) { + /* Enable the NFC clock */ + clk_enable(host->clk); + } + if (mtd) + mtd->resume(mtd); return ret; } @@ -1047,7 +1327,7 @@ static int mxcnd_resume(struct platform_ static struct platform_driver mxcnd_driver = { .driver = { .name = DRIVER_NAME, - }, + }, .remove = __exit_p(mxcnd_remove), .suspend = mxcnd_suspend, .resume = mxcnd_resume, @@ -1055,13 +1335,14 @@ static struct platform_driver mxcnd_driv static int __init mxc_nd_init(void) { + int ret; + /* Register the device driver structure. */ - pr_info("MXC MTD nand Driver\n"); - if (platform_driver_probe(&mxcnd_driver, mxcnd_probe) != 0) { + ret = platform_driver_probe(&mxcnd_driver, mxcnd_probe); + if (ret != 0) { printk(KERN_ERR "Driver register failed for mxcnd_driver\n"); - return -ENODEV; } - return 0; + return ret; } static void __exit mxc_nd_cleanup(void) diff -urNp linux-2.6.30-rc4/drivers/net/Kconfig linux-2.6.30-rc4-karo/drivers/net/Kconfig --- linux-2.6.30-rc4/drivers/net/Kconfig 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/drivers/net/Kconfig 2009-06-02 18:42:32.000000000 +0200 @@ -1859,7 +1859,7 @@ config 68360_ENET config FEC bool "FEC ethernet controller (of ColdFire CPUs)" - depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27 + depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27 || MACH_TX25 help Say Y here if you want to use the built-in 10/100 Fast ethernet controller on some Motorola ColdFire and Freescale i.MX processors. diff -urNp linux-2.6.30-rc4/drivers/net/fec.c linux-2.6.30-rc4-karo/drivers/net/fec.c --- linux-2.6.30-rc4/drivers/net/fec.c 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/drivers/net/fec.c 2009-06-02 18:43:03.000000000 +0200 @@ -2,6 +2,12 @@ * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx. * Copyright (c) 1997 Dan Malek (dmalek@jlc.net) * + * This version of the driver is specific to the FADS implementation, + * since the board contains control registers external to the processor + * for the control of the LevelOne LXT970 transceiver. The MPC860T manual + * describes connections using the internal parallel port I/O, which + * is basically all of Port D. + * * Right now, I am very wasteful with the buffers. I allocate memory * pages and then divide them into 2K frame buffers. This way I know I * have buffers large enough to hold one frame within one buffer descriptor. @@ -18,77 +24,123 @@ * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be) * Copyright (c) 2004-2006 Macq Electronique SA. */ +/* + * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ #include #include -#include -#include +#include #include #include #include #include -#include -#include +#include #include +#include #include #include #include #include -#include -#include -#include -#include +#include #include -#include +#include +#include -#include +#include +#include -#ifndef CONFIG_ARCH_MXC -#include -#include +#define DRV_NAME "fec" +#define DEBUG + +#ifdef DEBUG +static int debug = 0; +#define dbg_lvl(n) ((n) < debug) +module_param(debug, int, S_IRUGO | S_IWUSR); + +#define DBG(lvl, fmt...) do { if (dbg_lvl(lvl)) printk(KERN_DEBUG fmt); } while (0) +#else +static int debug; +#define dbg_lvl(n) 0 +module_param(debug, int, 0); + +#define DBG(lvl, fmt...) do { } while (0) #endif +#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \ + defined(CONFIG_M5272) || defined(CONFIG_M528x) || \ + defined(CONFIG_M520x) || defined(CONFIG_M532x) +#include +#include #include "fec.h" - -#ifdef CONFIG_ARCH_MXC +#define FEC_ALIGNMENT (0x03) /*FEC needs 4bytes alignment*/ +#elif defined(CONFIG_ARCH_MXC) #include -#define FEC_ALIGNMENT 0xf +#include +#include "fec.h" +#define FEC_ALIGNMENT (0x0F) /*FEC needs 128bits(16bytes) alignment*/ #else -#define FEC_ALIGNMENT 0x3 +#include +#include +#include "commproc.h" +#define FEC_ALIGNMENT (0x03) /*FEC needs 4bytes alignment */ #endif +#define FEC_ADDR_ALIGNMENT(x) ((unsigned char *)(((unsigned long)(x) + (FEC_ALIGNMENT)) & (~FEC_ALIGNMENT))) + +#if 0 /* * Define the fixed address of the FEC hardware. */ +/* USE resources provided by platform_device! */ +static unsigned int fec_hw[] = { #if defined(CONFIG_M5272) -#define HAVE_mii_link_interrupt - -static unsigned char fec_mac_default[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + (MCF_MBAR + 0x840), +#elif defined(CONFIG_M527x) + (MCF_MBAR + 0x1000), + (MCF_MBAR + 0x1800), +#elif defined(CONFIG_M523x) || defined(CONFIG_M528x) + (MCF_MBAR + 0x1000), +#elif defined(CONFIG_M520x) + (MCF_MBAR+0x30000), +#elif defined(CONFIG_M532x) + (MCF_MBAR+0xfc030000), +#elif defined(CONFIG_ARCH_MXC) + (IO_ADDRESS(FEC_BASE_ADDR)), +#else + &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec), +#endif }; +#endif +#if 0 /* * Some hardware gets it MAC address out of local flash memory. * if this is non-zero then assume it is the address to get MAC from. */ +/* implemented using platform_data! */ #if defined(CONFIG_NETtel) #define FEC_FLASHMAC 0xf0006006 #elif defined(CONFIG_GILBARCONAP) || defined(CONFIG_SCALES) #define FEC_FLASHMAC 0xf0006000 +#elif defined (CONFIG_MTD_KeyTechnology) +#define FEC_FLASHMAC 0xffe04000 #elif defined(CONFIG_CANCam) #define FEC_FLASHMAC 0xf0020000 #elif defined (CONFIG_M5272C3) #define FEC_FLASHMAC (0xffe04000 + 4) #elif defined(CONFIG_MOD5272) -#define FEC_FLASHMAC 0xffc0406b +#define FEC_FLASHMAC 0xffc0406b #else #define FEC_FLASHMAC 0 #endif -#endif /* CONFIG_M5272 */ +#endif + +#define platform_func(p, args...) ((p) ? (p)(args) : 0) /* Forward declarations of some structures to support different PHYs */ - +#ifndef CONFIG_PHYLIB typedef struct { uint mii_data; void (*funct)(uint mii_reg, struct net_device *dev); @@ -103,6 +155,7 @@ typedef struct { const phy_cmd_t *ack_int; const phy_cmd_t *shutdown; } phy_info_t; +#endif /* The number of Tx and Rx buffers. These are allocated from the page * pool. The code may assume these are power of two, so it it best @@ -116,12 +169,13 @@ typedef struct { #define RX_RING_SIZE (FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES) #define FEC_ENET_TX_FRSIZE 2048 #define FEC_ENET_TX_FRPPG (PAGE_SIZE / FEC_ENET_TX_FRSIZE) -#define TX_RING_SIZE 16 /* Must be power of two */ -#define TX_RING_MOD_MASK 15 /* for this to work */ +#define TX_RING_SIZE 16 /* Must be power of two */ +#define TX_RING_MOD_MASK (TX_RING_SIZE - 1) /* for this to work */ #if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE) #error "FEC: descriptor ring size constants too large" #endif +#define CBD_BUF_SIZE ((RX_RING_SIZE + TX_RING_SIZE) * sizeof(cbd_t)) /* Interrupt events/masks. */ @@ -136,6 +190,17 @@ typedef struct { #define FEC_ENET_MII ((uint)0x00800000) /* MII interrupt */ #define FEC_ENET_EBERR ((uint)0x00400000) /* SDMA bus error */ +/* MXC arch interrupt bits */ +#define FEC_ENET_LC ((uint)0x00200000) /* Late collision */ +#define FEC_ENET_RL ((uint)0x00100000) /* Collision retry limit exceeded */ +#define FEC_ENET_UN ((uint)0x00080000) /* TX Fifo underrun */ + +#ifndef CONFIG_ARCH_MXC +#define FEC_ENET_MASK ((uint)0xffc00000) +#else +#define FEC_ENET_MASK ((uint)0xfff80000) +#endif + /* The FEC stores dest/src/type, data, and checksum for receive packets. */ #define PKT_MAXBUF_SIZE 1518 @@ -150,7 +215,7 @@ typedef struct { */ #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC) -#define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16) +#define OPT_FRAME_SIZE (RCR_MAX_FL_set(PKT_MAXBUF_SIZE)) #else #define OPT_FRAME_SIZE 0 #endif @@ -165,31 +230,45 @@ typedef struct { */ struct fec_enet_private { /* Hardware registers of the FEC device */ - volatile fec_t *hwp; - - struct net_device *netdev; - - struct clk *clk; + void __iomem *reg_base; + void __iomem *mib_base; + struct resource *res_mem1; + struct resource *res_mem2; + int etn_irq; + int mii_irq; +#ifndef CONFIG_PHYLIB + struct timer_list *phy_timer; +#else + struct mii_bus *mii; + int mii_complete; +#endif + u32 msg_enable; /* The saved address of a sent-in-place packet/buffer, for skfree(). */ - unsigned char *tx_bounce[TX_RING_SIZE]; + void *tx_bounce[TX_RING_SIZE]; struct sk_buff* tx_skbuff[TX_RING_SIZE]; + struct sk_buff* rx_skbuff[RX_RING_SIZE]; ushort skb_cur; ushort skb_dirty; /* CPM dual port RAM relative addresses. */ - dma_addr_t bd_dma; + struct device *dma_dev; /* pointer to (platform_)device for dma_sync*() functions */ + void *cbd_mem_base; /* save the virtual base address of rx&tx buffer descriptor */ + dma_addr_t cbd_phys_base; /* physical address of buffer descriptor memory for access by FEC HW */ + cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */ cbd_t *tx_bd_base; - cbd_t *cur_rx, *cur_tx; /* The next free ring entry */ - cbd_t *dirty_tx; /* The ring entries to be free()ed. */ + cbd_t *cur_rx, *cur_tx; /* The next free ring entry */ + cbd_t *dirty_tx; /* The ring entries to be free()ed. */ + struct net_device_stats stats; uint tx_full; - /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */ - spinlock_t hw_lock; - /* hold while accessing the mii_list_t() elements */ - spinlock_t mii_lock; + spinlock_t lock; +#ifdef CONFIG_PHYLIB + struct phy_device *phy; + uint phy_speed; +#else uint phy_id; uint phy_id_done; uint phy_status; @@ -199,28 +278,41 @@ struct fec_enet_private { uint sequence_done; uint mii_phy_task_queued; - +#endif uint phy_addr; - int index; - int opened; - int link; - int old_link; - int full_duplex; + unsigned int opened:1; + unsigned int phy_int_enabled:1; + unsigned int linkstatus:1; +#ifndef CONFIG_PHYLIB + unsigned int old_linkstatus:1; +#endif + unsigned int full_duplex:1; + + struct clk *clk; }; -static int fec_enet_open(struct net_device *dev); -static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev); -static void fec_enet_mii(struct net_device *dev); -static irqreturn_t fec_enet_interrupt(int irq, void * dev_id); +#ifdef CONFIG_PHYLIB +static int fec_connect_phy(struct net_device *dev, struct fec_enet_private *fep); +#else +static irqreturn_t mii_link_interrupt(int irq, void *dev_id); +#endif +static void fec_restart(struct net_device *dev, int duplex); static void fec_enet_tx(struct net_device *dev); static void fec_enet_rx(struct net_device *dev); -static int fec_enet_close(struct net_device *dev); -static void set_multicast_list(struct net_device *dev); -static void fec_restart(struct net_device *dev, int duplex); +static void fec_enet_mii(struct net_device *dev); static void fec_stop(struct net_device *dev); -static void fec_set_mac_address(struct net_device *dev); +static void _fec_set_mac_address(struct net_device *dev); +/* + * fec_copy_threshold controls the copy when receiving ethernet frame. + * If ethernet header is aligned on a 4byte boundary, the ip header and + * higher level header will not be aligned. + * The reason is, that an ethernet header is 14bytes long. + * And the max size of tcp & ip header is 128bytes. Normally it is 40bytes. + * So I set the default value between 128 to 256. + */ +static int fec_copy_threshold = 192; /* MII processing. We keep this as simple as possible. Requests are * placed on the list (if there is room). When the request is finished @@ -232,14 +324,16 @@ typedef struct mii_list { struct mii_list *mii_next; } mii_list_t; +#ifndef CONFIG_PHYLIB #define NMII 20 static mii_list_t mii_cmds[NMII]; static mii_list_t *mii_free; static mii_list_t *mii_head; static mii_list_t *mii_tail; -static int mii_queue(struct net_device *dev, int request, - void (*func)(uint, struct net_device *)); +static int mii_queue(struct net_device *dev, int request, + void (*func)(uint, struct net_device *)); +#endif /* Make MII read/write commands for the FEC. */ @@ -284,87 +378,233 @@ static int mii_queue(struct net_device * #define PHY_STAT_100HDX 0x4000 /* 100 Mbit half duplex selected */ #define PHY_STAT_100FDX 0x8000 /* 100 Mbit full duplex selected */ +#ifndef DEBUG +static inline unsigned long fec_reg_read(struct fec_enet_private *fep, unsigned int reg) +{ + return readl(fep->reg_base + reg); +} + +static inline void fec_reg_write(struct fec_enet_private *fep, unsigned int reg, unsigned long val) +{ + writel(val, fep->reg_base + reg); +} +#else +#define fec_reg_read(fep, reg) __fec_reg_read(fep, reg, __FUNCTION__, #reg) +#define fec_reg_write(fep, reg, val) __fec_reg_write(fep, reg, val, __FUNCTION__, #reg) + +static inline unsigned long __fec_reg_read(struct fec_enet_private *fep, unsigned int reg, + const char *func, const char *reg_name) +{ + unsigned long val = readl(fep->reg_base + reg); + DBG(3, "%s: Read %08lx from %s(%03x)\n", func, val, reg_name, reg); + return val; +} + +static inline void __fec_reg_write(struct fec_enet_private *fep, unsigned int reg, + unsigned long val, const char *func, const char *reg_name) +{ + DBG(3, "%s: Writing %08lx to %s(%03x)\n", func, val, reg_name, reg); + writel(val, fep->reg_base + reg); +} +#endif + +static inline void fec_enet_cbd_get(struct fec_enet_private *fep) +{ + DBG(2, "%s: Requesting cbd area: %08lx\n", __FUNCTION__, + (unsigned long)fep->cbd_phys_base); + dma_sync_single_for_cpu(fep->dma_dev, fep->cbd_phys_base, + CBD_BUF_SIZE, DMA_BIDIRECTIONAL); +} + +static inline void fec_enet_cbd_put(struct fec_enet_private *fep) +{ + DBG(2, "%s: Flushing changes to cbd area\n", __FUNCTION__); + dma_sync_single_for_device(fep->dma_dev, fep->cbd_phys_base, + CBD_BUF_SIZE, DMA_BIDIRECTIONAL); +} + +static inline void fec_enet_rxbuf_get(struct fec_enet_private *fep, cbd_t *bdp, ushort len) +{ + DBG(2, "%s: Requesting RX buffer %08lx(%u)\n", __FUNCTION__, + (unsigned long)bdp->cbd_bufaddr, len); + dma_sync_single_for_cpu(fep->dma_dev, bdp->cbd_bufaddr, + len, DMA_FROM_DEVICE); +} + +static inline void fec_enet_rxbuf_put(struct fec_enet_private *fep, cbd_t *bdp, ushort len) +{ + DBG(2, "%s: Releasing RX buffer %08lx(%u)\n", __FUNCTION__, (ulong)bdp->cbd_bufaddr, len); + dma_sync_single_for_device(fep->dma_dev, bdp->cbd_bufaddr, len, DMA_FROM_DEVICE); +} + +static inline void fec_enet_rxbuf_map(struct fec_enet_private *fep, cbd_t *bdp, + void *buf, ushort len) +{ + BUG_ON(!dma_mapping_error(fep->dma_dev, bdp->cbd_bufaddr)); + bdp->cbd_bufaddr = dma_map_single(fep->dma_dev, buf, + len, DMA_FROM_DEVICE); + DBG(2, "%s: RX buffer %p(%u) mapped to %08lx\n", __FUNCTION__, + buf, len, (unsigned long)bdp->cbd_bufaddr); +} + +static inline void fec_enet_rxbuf_unmap(struct fec_enet_private *fep, cbd_t *bdp, ushort len) +{ + DBG(2, "%s: Unmapping RX buffer %08lx(%u)\n", __FUNCTION__, + (unsigned long)bdp->cbd_bufaddr, len); + BUG_ON(dma_mapping_error(fep->dma_dev, bdp->cbd_bufaddr)); + dma_unmap_single(fep->dma_dev, bdp->cbd_bufaddr, + len, DMA_FROM_DEVICE); + bdp->cbd_bufaddr = ~0; +} + +static inline void fec_enet_txbuf_map(struct fec_enet_private *fep, cbd_t *bdp, + void *buf, ushort len) +{ + BUG_ON(!dma_mapping_error(fep->dma_dev, bdp->cbd_bufaddr)); + bdp->cbd_bufaddr = dma_map_single(fep->dma_dev, buf, + len, DMA_TO_DEVICE); + DBG(2, "%s: TX buffer %p(%u) mapped to %08lx\n", __FUNCTION__, + buf, len, (unsigned long)bdp->cbd_bufaddr); +} + +static inline void fec_enet_txbuf_unmap(struct fec_enet_private *fep, cbd_t *bdp, ushort len) +{ + DBG(2, "%s: Unmapping TX buffer %08lx(%u)\n", __FUNCTION__, + (unsigned long)bdp->cbd_bufaddr, len); + BUG_ON(dma_mapping_error(fep->dma_dev, bdp->cbd_bufaddr)); + dma_unmap_single(fep->dma_dev, bdp->cbd_bufaddr, + len, DMA_TO_DEVICE); + bdp->cbd_bufaddr = ~0; +} + +static inline void fec_enet_txbuf_get(struct fec_enet_private *fep, cbd_t *bdp, ushort len) +{ + DBG(2, "%s: Requesting TX buffer %08lx(%u)\n", __FUNCTION__, + (unsigned long)bdp->cbd_bufaddr, len); + dma_sync_single_for_cpu(fep->dma_dev, bdp->cbd_bufaddr, + len, DMA_TO_DEVICE); +} + +static inline void fec_enet_txbuf_put(struct fec_enet_private *fep, cbd_t *bdp, ushort len) +{ + DBG(2, "%s: Releasing TX buffer %08lx(%u)\n", __FUNCTION__, + (unsigned long)bdp->cbd_bufaddr, len); + dma_sync_single_for_device(fep->dma_dev, bdp->cbd_bufaddr, + len, DMA_TO_DEVICE); +} + +static void dump_packet(const char *prefix, const unsigned char *data, int len) +{ + if (dbg_lvl(3)) { + print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, data, len); + } +} + +static void dump_tx_buffers(struct fec_enet_private *fep) +{ + cbd_t *bdp = fep->tx_bd_base; + int i; + + printk(KERN_DEBUG "tx buffers: %u buffers\n", TX_RING_SIZE); + for (i = 0; i < TX_RING_SIZE; i++, bdp++) { + printk(KERN_DEBUG " %p: %04x %04x %08x\n", + bdp, + bdp->cbd_sc, + bdp->cbd_datlen, + bdp->cbd_bufaddr); + print_hex_dump_bytes("tx buffers:", DUMP_PREFIX_ADDRESS, bdp, sizeof(cbd_t)); + } +} + +static void dump_rx_buffers(struct fec_enet_private *fep) +{ + cbd_t *bdp = fep->rx_bd_base; + int i; + + printk(KERN_DEBUG "rx buffers: %lu buffers\n", RX_RING_SIZE); + for (i = 0; i < RX_RING_SIZE; i++, bdp++) { + printk(KERN_DEBUG " %p: %04x %04x %08x\n", + bdp, + bdp->cbd_sc, + bdp->cbd_datlen, + bdp->cbd_bufaddr); + print_hex_dump_bytes("rx buffers:", DUMP_PREFIX_ADDRESS, bdp, sizeof(cbd_t)); + } +} static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct fec_enet_private *fep; - volatile fec_t *fecp; - volatile cbd_t *bdp; - unsigned short status; + struct fec_enet_private *fep = netdev_priv(dev); + cbd_t *bdp; + unsigned short status; unsigned long flags; - fep = netdev_priv(dev); - fecp = (volatile fec_t*)dev->base_addr; - - if (!fep->link) { + if (!fep->linkstatus) { + DBG(0, "%s: Cannot send packet; link is down\n", __FUNCTION__); /* Link is down or autonegotiation is in progress. */ return 1; } - spin_lock_irqsave(&fep->hw_lock, flags); + spin_lock_irqsave(&fep->lock, flags); + + //WARN_ON(fec_reg_read(fep, FEC_TDAR) & TDAR_BUSY); + fec_enet_cbd_get(fep); + /* Fill in a Tx ring entry */ bdp = fep->cur_tx; status = bdp->cbd_sc; -#ifndef final_version +#ifdef DEBUG if (status & BD_ENET_TX_READY) { /* Ooops. All transmit buffers are full. Bail out. * This should not happen, since dev->tbusy should be set. */ printk("%s: tx queue full!.\n", dev->name); - spin_unlock_irqrestore(&fep->hw_lock, flags); + fec_enet_cbd_put(fep); + spin_unlock_irqrestore(&fep->lock, flags); return 1; } #endif - /* Clear all of the status flags. */ status &= ~BD_ENET_TX_STATS; /* Set buffer length and buffer pointer. */ - bdp->cbd_bufaddr = __pa(skb->data); bdp->cbd_datlen = skb->len; + dump_packet("sending packet:", skb->data, skb->len); /* * On some FEC implementations data must be aligned on * 4-byte boundaries. Use bounce buffers to copy data * and get it aligned. Ugh. */ - if (bdp->cbd_bufaddr & FEC_ALIGNMENT) { + if (unlikely((bdp->cbd_bufaddr) & FEC_ALIGNMENT)) { unsigned int index; index = bdp - fep->tx_bd_base; - memcpy(fep->tx_bounce[index], (void *)skb->data, skb->len); - bdp->cbd_bufaddr = __pa(fep->tx_bounce[index]); + memcpy(fep->tx_bounce[index], skb->data, skb->len); + fec_enet_txbuf_map(fep, bdp, fep->tx_bounce[index], skb->len); + } else { + fec_enet_txbuf_map(fep, bdp, skb->data, skb->len); } /* Save skb pointer. */ fep->tx_skbuff[fep->skb_cur] = skb; - dev->stats.tx_bytes += skb->len; - fep->skb_cur = (fep->skb_cur+1) & TX_RING_MOD_MASK; - - /* Push the data cache so the CPM does not get stale memory - * data. - */ - dma_sync_single(NULL, bdp->cbd_bufaddr, - bdp->cbd_datlen, DMA_TO_DEVICE); + fep->stats.tx_bytes += skb->len; + fep->skb_cur = (fep->skb_cur + 1) & TX_RING_MOD_MASK; /* Send it on its way. Tell FEC it's ready, interrupt when done, * it's the last BD of the frame, and to put the CRC on the end. */ - status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | BD_ENET_TX_LAST | BD_ENET_TX_TC); bdp->cbd_sc = status; dev->trans_start = jiffies; - /* Trigger transmission start */ - fecp->fec_x_des_active = 0; - /* If this was the last BD in the ring, start at the beginning again. */ if (status & BD_ENET_TX_WRAP) { @@ -375,12 +615,22 @@ fec_enet_start_xmit(struct sk_buff *skb, if (bdp == fep->dirty_tx) { fep->tx_full = 1; + DBG(0, "TX ring full, stopping netif queue\n"); netif_stop_queue(dev); } - fep->cur_tx = (cbd_t *)bdp; + fep->cur_tx = bdp; + fec_enet_cbd_put(fep); +#if 0 + if (dbg_lvl(3)) { + dump_tx_buffers(fep); + dump_rx_buffers(fep); + } +#endif + /* Trigger transmission start */ + fec_reg_write(fep, FEC_TDAR, DONT_CARE); - spin_unlock_irqrestore(&fep->hw_lock, flags); + spin_unlock_irqrestore(&fep->lock, flags); return 0; } @@ -390,101 +640,126 @@ fec_timeout(struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); - printk("%s: transmit timed out.\n", dev->name); - dev->stats.tx_errors++; -#ifndef final_version + printk(KERN_WARNING "%s: transmit timed out.\n", dev->name); + fep->stats.tx_errors++; +#ifdef DEBUG { - int i; - cbd_t *bdp; + int i; + cbd_t *bdp; - printk("Ring data dump: cur_tx %lx%s, dirty_tx %lx cur_rx: %lx\n", - (unsigned long)fep->cur_tx, fep->tx_full ? " (full)" : "", - (unsigned long)fep->dirty_tx, - (unsigned long)fep->cur_rx); + fec_enet_cbd_get(fep); - bdp = fep->tx_bd_base; - printk(" tx: %u buffers\n", TX_RING_SIZE); - for (i = 0 ; i < TX_RING_SIZE; i++) { - printk(" %08x: %04x %04x %08x\n", - (uint) bdp, - bdp->cbd_sc, - bdp->cbd_datlen, - (int) bdp->cbd_bufaddr); - bdp++; - } + printk(KERN_DEBUG "%s: Ring data dump: cur_tx %p%s, dirty_tx %p cur_rx: %p\n", + __FUNCTION__, + fep->cur_tx, fep->tx_full ? " (full)" : "", + fep->dirty_tx, + fep->cur_rx); - bdp = fep->rx_bd_base; - printk(" rx: %lu buffers\n", (unsigned long) RX_RING_SIZE); - for (i = 0 ; i < RX_RING_SIZE; i++) { - printk(" %08x: %04x %04x %08x\n", - (uint) bdp, - bdp->cbd_sc, - bdp->cbd_datlen, - (int) bdp->cbd_bufaddr); - bdp++; - } + bdp = fep->tx_bd_base; + printk(" tx: %u buffers\n", TX_RING_SIZE); + for (i = 0; i < TX_RING_SIZE; i++) { + printk(" %p: %04x %04x %08x\n", + bdp, + bdp->cbd_sc, + bdp->cbd_datlen, + bdp->cbd_bufaddr); + bdp++; + } + + bdp = fep->rx_bd_base; + printk(" rx: %lu buffers\n", RX_RING_SIZE); + for (i = 0; i < RX_RING_SIZE; i++) { + printk(" %p: %04x %04x %08x\n", + bdp, + bdp->cbd_sc, + bdp->cbd_datlen, + bdp->cbd_bufaddr); + bdp++; + } + fec_enet_cbd_put(fep); } #endif fec_restart(dev, fep->full_duplex); - netif_wake_queue(dev); + DBG(0, "%s: Scheduling netif queue\n", __FUNCTION__); + //netif_schedule(dev); } /* The interrupt handler. * This is called from the MPC core interrupt. */ static irqreturn_t -fec_enet_interrupt(int irq, void * dev_id) +fec_enet_interrupt(int irq, void *dev_id) { - struct net_device *dev = dev_id; - volatile fec_t *fecp; - uint int_events; - irqreturn_t ret = IRQ_NONE; - - fecp = (volatile fec_t*)dev->base_addr; + struct net_device *dev = dev_id; + struct fec_enet_private *fep = netdev_priv(dev); + uint int_events; + int handled = 0; + unsigned int eimr = fec_reg_read(fep, FEC_EIMR); + DBG(2, "%s: %08lx:%08lx\n", __FUNCTION__, + fec_reg_read(fep, FEC_EIR), fec_reg_read(fep, FEC_EIMR)); /* Get the interrupt events that caused us to be here. */ - do { - int_events = fecp->fec_ievent; - fecp->fec_ievent = int_events; + while ((int_events = fec_reg_read(fep, FEC_EIR) & FEC_ENET_MASK) != 0) { + if (int_events & ~eimr) { + printk(KERN_WARNING "%s: masked interrupt condition: %08x\n", + __FUNCTION__, int_events & ~eimr); + } + + fec_reg_write(fep, FEC_EIR, int_events); /* Handle receive event in its own function. */ - if (int_events & FEC_ENET_RXF) { - ret = IRQ_HANDLED; + if (int_events & (FEC_ENET_RXF | FEC_ENET_RXB)) { + DBG(2, "%s: Handling RX Interrupt\n", __FUNCTION__); + handled = 1; fec_enet_rx(dev); } + if (int_events & FEC_ENET_UN) { + printk(KERN_WARNING "TX fifo underrun"); + } /* Transmit OK, or non-fatal error. Update the buffer descriptors. FEC handles all errors, we just discover them as part of the transmit process. */ - if (int_events & FEC_ENET_TXF) { - ret = IRQ_HANDLED; + if (int_events & (FEC_ENET_TXF | FEC_ENET_TXB)) { + DBG(2, "%s: Handling TX Interrupt\n", __FUNCTION__); + handled = 1; fec_enet_tx(dev); } - if (int_events & FEC_ENET_MII) { - ret = IRQ_HANDLED; + if (int_events & (FEC_ENET_MII | FEC_ENET_HBERR)) { + DBG(2, "%s: Handling MII Interrupt\n", __FUNCTION__); + handled = 1; fec_enet_mii(dev); } - - } while (int_events); - - return ret; + } + return IRQ_RETVAL(handled); } +static void fec_free_skb(struct fec_enet_private *fep, cbd_t *bdp, struct sk_buff **pskb) +{ + struct sk_buff *skb = *pskb; + if (!dma_mapping_error(fep->dma_dev, bdp->cbd_bufaddr)) { + fec_enet_txbuf_unmap(fep, bdp, skb->len); + } + dev_kfree_skb_any(skb); + *pskb = NULL; +} static void fec_enet_tx(struct net_device *dev) { - struct fec_enet_private *fep; - volatile cbd_t *bdp; + struct fec_enet_private *fep = netdev_priv(dev); + cbd_t *bdp; unsigned short status; - struct sk_buff *skb; + struct sk_buff *skb; - fep = netdev_priv(dev); - spin_lock_irq(&fep->hw_lock); + spin_lock(&fep->lock); + + //WARN_ON(fec_reg_read(fep, FEC_TDAR) & TDAR_BUSY); + fec_enet_cbd_get(fep); bdp = fep->dirty_tx; while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) { @@ -495,22 +770,22 @@ fec_enet_tx(struct net_device *dev) if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) { - dev->stats.tx_errors++; + fep->stats.tx_errors++; if (status & BD_ENET_TX_HB) /* No heartbeat */ - dev->stats.tx_heartbeat_errors++; + fep->stats.tx_heartbeat_errors++; if (status & BD_ENET_TX_LC) /* Late collision */ - dev->stats.tx_window_errors++; + fep->stats.tx_window_errors++; if (status & BD_ENET_TX_RL) /* Retrans limit */ - dev->stats.tx_aborted_errors++; + fep->stats.tx_aborted_errors++; if (status & BD_ENET_TX_UN) /* Underrun */ - dev->stats.tx_fifo_errors++; + fep->stats.tx_fifo_errors++; if (status & BD_ENET_TX_CSL) /* Carrier lost */ - dev->stats.tx_carrier_errors++; + fep->stats.tx_carrier_errors++; } else { - dev->stats.tx_packets++; + fep->stats.tx_packets++; } -#ifndef final_version +#ifdef DEBUG if (status & BD_ENET_TX_READY) printk("HEY! Enet xmit interrupt and TX_READY.\n"); #endif @@ -518,12 +793,13 @@ fec_enet_tx(struct net_device *dev) * but we eventually sent the packet OK. */ if (status & BD_ENET_TX_DEF) - dev->stats.collisions++; + fep->stats.collisions++; + dump_packet("sent packet:", fep->tx_skbuff[fep->skb_dirty]->data, + fep->tx_skbuff[fep->skb_dirty]->len); /* Free the sk buffer associated with this last transmit. */ - dev_kfree_skb_any(skb); - fep->tx_skbuff[fep->skb_dirty] = NULL; + fec_free_skb(fep, bdp, &fep->tx_skbuff[fep->skb_dirty]); fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK; /* Update pointer to next buffer descriptor to be transmitted. @@ -538,12 +814,15 @@ fec_enet_tx(struct net_device *dev) */ if (fep->tx_full) { fep->tx_full = 0; - if (netif_queue_stopped(dev)) + if (netif_queue_stopped(dev)) { + DBG(0, "%s: Waking up netif queue\n", __FUNCTION__); netif_wake_queue(dev); + } } } - fep->dirty_tx = (cbd_t *)bdp; - spin_unlock_irq(&fep->hw_lock); + fec_enet_cbd_put(fep); + fep->dirty_tx = bdp; + spin_unlock(&fep->lock); } @@ -555,22 +834,22 @@ fec_enet_tx(struct net_device *dev) static void fec_enet_rx(struct net_device *dev) { - struct fec_enet_private *fep; - volatile fec_t *fecp; - volatile cbd_t *bdp; + struct fec_enet_private *fep = netdev_priv(dev); + cbd_t *bdp; unsigned short status; - struct sk_buff *skb; - ushort pkt_len; - __u8 *data; + struct sk_buff *skb; + ushort pkt_len; + int rx_index; #ifdef CONFIG_M532x + /* This is probably nonsense + Proper use of dma-mapping functions should make this obsolete + */ flush_cache_all(); #endif - - fep = netdev_priv(dev); - fecp = (volatile fec_t*)dev->base_addr; - - spin_lock_irq(&fep->hw_lock); + /* reserve the dual port memory area for our use */ + //WARN_ON(fec_reg_read(fep, FEC_RDAR) & RDAR_BUSY); + fec_enet_cbd_get(fep); /* First, grab all of the stats for the incoming packet. * These get messed up if we get called due to a busy condition. @@ -578,32 +857,34 @@ fec_enet_rx(struct net_device *dev) bdp = fep->cur_rx; while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { - -#ifndef final_version + rx_index = bdp - fep->rx_bd_base; +#ifdef DEBUG /* Since we have allocated space to hold a complete frame, * the last indicator should be set. */ - if ((status & BD_ENET_RX_LAST) == 0) - printk("FEC ENET: rcv is not +last\n"); + WARN_ON(!(status & BD_ENET_RX_LAST)); #endif - if (!fep->opened) + if (WARN_ON(!fep->opened)) { + DBG(0, "%s: Driver not opened; ignoring packet\n", __FUNCTION__); +#if 0 goto rx_processing_done; - +#endif + } /* Check for errors. */ if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) { - dev->stats.rx_errors++; + fep->stats.rx_errors++; if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { /* Frame too long or too short. */ - dev->stats.rx_length_errors++; + fep->stats.rx_length_errors++; } if (status & BD_ENET_RX_NO) /* Frame alignment */ - dev->stats.rx_frame_errors++; + fep->stats.rx_frame_errors++; if (status & BD_ENET_RX_CR) /* CRC Error */ - dev->stats.rx_crc_errors++; + fep->stats.rx_crc_errors++; if (status & BD_ENET_RX_OV) /* FIFO overrun */ - dev->stats.rx_fifo_errors++; + fep->stats.rx_fifo_errors++; } /* Report late collisions as a frame error. @@ -611,39 +892,91 @@ while (!((status = bdp->cbd_sc) & BD_ENE * have in the buffer. So, just drop this frame on the floor. */ if (status & BD_ENET_RX_CL) { - dev->stats.rx_errors++; - dev->stats.rx_frame_errors++; + fep->stats.rx_errors++; + fep->stats.rx_frame_errors++; + DBG(0, "%s: Collision detected; dropping packet\n", __FUNCTION__); + if (bdp->cbd_datlen > PKT_MAXBUF_SIZE) { + printk(KERN_ERR "invalid packet size %u; max %u\n", bdp->cbd_datlen, + PKT_MAXBUF_SIZE); + } else { + fec_enet_rxbuf_get(fep, bdp, bdp->cbd_datlen); + dump_packet("received packet:", + fep->rx_skbuff[rx_index]->data, bdp->cbd_datlen); + fec_enet_rxbuf_put(fep, bdp, bdp->cbd_datlen); + } goto rx_processing_done; } - +#if 1 + if (!fep->opened) { + DBG(0, "%s: Driver not opened; ignoring packet\n", __FUNCTION__); + if (bdp->cbd_datlen > PKT_MAXBUF_SIZE) { + printk(KERN_ERR "invalid packet size %u; max %u\n", bdp->cbd_datlen, + PKT_MAXBUF_SIZE); + } else { + fec_enet_rxbuf_get(fep, bdp, bdp->cbd_datlen); + dump_packet("received packet:", + fep->rx_skbuff[rx_index]->data, bdp->cbd_datlen); + fec_enet_rxbuf_put(fep, bdp, bdp->cbd_datlen); + } + goto rx_processing_done; + } +#endif /* Process the incoming frame. */ - dev->stats.rx_packets++; + fep->stats.rx_packets++; pkt_len = bdp->cbd_datlen; - dev->stats.rx_bytes += pkt_len; - data = (__u8*)__va(bdp->cbd_bufaddr); - - dma_sync_single(NULL, (unsigned long)__pa(data), - pkt_len - 4, DMA_FROM_DEVICE); + fep->stats.rx_bytes += pkt_len; /* This does 16 byte alignment, exactly what we need. * The packet length includes FCS, but we don't want to * include that when passing upstream as it messes up * bridging applications. */ - skb = dev_alloc_skb(pkt_len-4); + if ((pkt_len - 4) < fec_copy_threshold) { + skb = dev_alloc_skb(pkt_len); + } else { + skb = dev_alloc_skb(FEC_ENET_RX_FRSIZE); + } if (skb == NULL) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); - dev->stats.rx_dropped++; + fep->stats.rx_dropped++; } else { - skb_put(skb,pkt_len-4); /* Make room */ - skb_copy_to_linear_data(skb, data, pkt_len-4); - skb->protocol=eth_type_trans(skb,dev); + if ((pkt_len - 4) < fec_copy_threshold) { + /* skip 2 bytes, so IP header is on a 4 bytes boundary */ + skb_reserve(skb, 2); + skb_put(skb, pkt_len - 4); /* Make room */ + fec_enet_rxbuf_get(fep, bdp, pkt_len - 4); + skb_copy_to_linear_data(skb, + fep->rx_skbuff[rx_index]->data, + pkt_len - 4); + fec_enet_rxbuf_put(fep, bdp, pkt_len - 4); + } else { + struct sk_buff *pskb = fep->rx_skbuff[rx_index]; + + /* unmap the skb we are going to hand down to the network layer */ + fec_enet_rxbuf_unmap(fep, bdp, FEC_ENET_RX_FRSIZE); + + /* init the newly allocated skb */ + fep->rx_skbuff[rx_index] = skb; + skb->data = FEC_ADDR_ALIGNMENT(skb->data); + /* map the newly allocated skb's data buffer for DMA */ + fec_enet_rxbuf_map(fep, bdp, skb->data, FEC_ENET_RX_FRSIZE); + + skb_put(pskb, pkt_len - 4); /* Make room */ + skb = pskb; + } + skb->dev = dev; + skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); } rx_processing_done: - +#if 0 + if (dbg_lvl(3)) { + dump_rx_buffers(fep); + dump_tx_buffers(fep); + } +#endif /* Clear the status flags for this buffer. */ status &= ~BD_ENET_RX_STATS; @@ -653,6 +986,9 @@ while (!((status = bdp->cbd_sc) & BD_ENE status |= BD_ENET_RX_EMPTY; bdp->cbd_sc = status; + /* release the dual port memory area for use by the FEC hardware */ + fec_enet_cbd_put(fep); + /* Update BD pointer to next entry. */ if (status & BD_ENET_RX_WRAP) @@ -665,10 +1001,10 @@ while (!((status = bdp->cbd_sc) & BD_ENE * incoming frames. On a heavily loaded network, we should be * able to keep up at the expense of system resources. */ - fecp->fec_r_des_active = 0; + fec_reg_write(fep, FEC_RDAR, DONT_CARE); #endif } /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */ - fep->cur_rx = (cbd_t *)bdp; + fep->cur_rx = bdp; #if 0 /* Doing this here will allow us to process all frames in the @@ -678,27 +1014,28 @@ while (!((status = bdp->cbd_sc) & BD_ENE * our way back to the interrupt return only to come right back * here. */ - fecp->fec_r_des_active = 0; + fec_reg_write(fep, FEC_RDAR, DONT_CARE); #endif - - spin_unlock_irq(&fep->hw_lock); } - +#ifdef CONFIG_PHYLIB /* called from interrupt context */ +static void fec_enet_mii(struct net_device *dev) +{ + struct fec_enet_private *fep = netdev_priv(dev); + fep->mii_complete = 1; +} +#else static void fec_enet_mii(struct net_device *dev) { - struct fec_enet_private *fep; - volatile fec_t *ep; + struct fec_enet_private *fep = netdev_priv(dev); mii_list_t *mip; uint mii_reg; - fep = netdev_priv(dev); - spin_lock_irq(&fep->mii_lock); + mii_reg = fec_reg_read(fep, FEC_MMFR); - ep = fep->hwp; - mii_reg = ep->fec_mii_data; + spin_lock(&fep->lock); if ((mip = mii_head) == NULL) { printk("MII and no head!\n"); @@ -713,27 +1050,27 @@ fec_enet_mii(struct net_device *dev) mii_free = mip; if ((mip = mii_head) != NULL) - ep->fec_mii_data = mip->mii_regval; + fec_reg_write(fep, FEC_MMFR, mip->mii_regval); unlock: - spin_unlock_irq(&fep->mii_lock); + spin_unlock(&fep->lock); } static int mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_device *)) { - struct fec_enet_private *fep; + struct fec_enet_private *fep = netdev_priv(dev); unsigned long flags; mii_list_t *mip; int retval; + retval = 0; + + spin_lock_irqsave(&fep->lock,flags); + /* Add PHY address to register command. */ - fep = netdev_priv(dev); - spin_lock_irqsave(&fep->mii_lock, flags); - regval |= fep->phy_addr << 23; - retval = 0; if ((mip = mii_free) != NULL) { mii_free = mip->mii_next; @@ -745,32 +1082,32 @@ mii_queue(struct net_device *dev, int re mii_tail = mip; } else { mii_head = mii_tail = mip; - fep->hwp->fec_mii_data = regval; + fec_reg_write(fep, FEC_MMFR, regval); } } else { retval = 1; } - spin_unlock_irqrestore(&fep->mii_lock, flags); - return retval; + spin_unlock_irqrestore(&fep->lock,flags); + + return(retval); } static void mii_do_cmd(struct net_device *dev, const phy_cmd_t *c) { - if(!c) - return; + int k; - for (; c->mii_data != mk_mii_end; c++) - mii_queue(dev, c->mii_data, c->funct); + for (k = 0; c != NULL && c[k].mii_data != mk_mii_end; k++) { + mii_queue(dev, c[k].mii_data, c[k].funct); + } } static void mii_parse_sr(uint mii_reg, struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); - volatile uint *s = &(fep->phy_status); uint status; - status = *s & ~(PHY_STAT_LINK | PHY_STAT_FAULT | PHY_STAT_ANC); + status = fep->phy_status & ~(PHY_STAT_LINK | PHY_STAT_FAULT | PHY_STAT_ANC); if (mii_reg & 0x0004) status |= PHY_STAT_LINK; @@ -778,31 +1115,30 @@ static void mii_parse_sr(uint mii_reg, s status |= PHY_STAT_FAULT; if (mii_reg & 0x0020) status |= PHY_STAT_ANC; - *s = status; + + fep->phy_status = status; } static void mii_parse_cr(uint mii_reg, struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); - volatile uint *s = &(fep->phy_status); uint status; - status = *s & ~(PHY_CONF_ANE | PHY_CONF_LOOP); + status = fep->phy_status & ~(PHY_CONF_ANE | PHY_CONF_LOOP); if (mii_reg & 0x1000) status |= PHY_CONF_ANE; if (mii_reg & 0x4000) status |= PHY_CONF_LOOP; - *s = status; + fep->phy_status = status; } static void mii_parse_anar(uint mii_reg, struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); - volatile uint *s = &(fep->phy_status); uint status; - status = *s & ~(PHY_CONF_SPMASK); + status = fep->phy_status & ~(PHY_CONF_SPMASK); if (mii_reg & 0x0020) status |= PHY_CONF_10HDX; @@ -812,7 +1148,7 @@ static void mii_parse_anar(uint mii_reg, status |= PHY_CONF_100HDX; if (mii_reg & 0x00100) status |= PHY_CONF_100FDX; - *s = status; + fep->phy_status = status; } /* ------------------------------------------------------------------------- */ @@ -827,10 +1163,9 @@ static void mii_parse_anar(uint mii_reg, static void mii_parse_lxt970_csr(uint mii_reg, struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); - volatile uint *s = &(fep->phy_status); uint status; - status = *s & ~(PHY_STAT_SPMASK); + status = fep->phy_status & ~(PHY_STAT_SPMASK); if (mii_reg & 0x0800) { if (mii_reg & 0x1000) status |= PHY_STAT_100FDX; @@ -842,7 +1177,7 @@ static void mii_parse_lxt970_csr(uint mi else status |= PHY_STAT_10HDX; } - *s = status; + fep->phy_status = status; } static phy_cmd_t const phy_cmd_lxt970_config[] = { @@ -898,16 +1233,15 @@ static phy_info_t const phy_info_lxt970 static void mii_parse_lxt971_sr2(uint mii_reg, struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); - volatile uint *s = &(fep->phy_status); uint status; - status = *s & ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC); + status = fep->phy_status & ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC); if (mii_reg & 0x0400) { - fep->link = 1; + fep->linkstatus = 1; status |= PHY_STAT_LINK; } else { - fep->link = 0; + fep->linkstatus = 0; } if (mii_reg & 0x0080) status |= PHY_STAT_ANC; @@ -925,7 +1259,7 @@ static void mii_parse_lxt971_sr2(uint mi if (mii_reg & 0x0008) status |= PHY_STAT_FAULT; - *s = status; + fep->phy_status = status; } static phy_cmd_t const phy_cmd_lxt971_config[] = { @@ -982,10 +1316,9 @@ static phy_info_t const phy_info_lxt971 static void mii_parse_qs6612_pcr(uint mii_reg, struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); - volatile uint *s = &(fep->phy_status); uint status; - status = *s & ~(PHY_STAT_SPMASK); + status = fep->phy_status & ~(PHY_STAT_SPMASK); switch((mii_reg >> 2) & 7) { case 1: status |= PHY_STAT_10HDX; break; @@ -994,7 +1327,7 @@ static void mii_parse_qs6612_pcr(uint mi case 6: status |= PHY_STAT_100FDX; break; } - *s = status; + fep->phy_status = status; } static phy_cmd_t const phy_cmd_qs6612_config[] = { @@ -1052,10 +1385,9 @@ static phy_info_t const phy_info_qs6612 static void mii_parse_am79c874_dr(uint mii_reg, struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); - volatile uint *s = &(fep->phy_status); uint status; - status = *s & ~(PHY_STAT_SPMASK | PHY_STAT_ANC); + status = fep->phy_status & ~(PHY_STAT_SPMASK | PHY_STAT_ANC); if (mii_reg & 0x0080) status |= PHY_STAT_ANC; @@ -1064,7 +1396,7 @@ static void mii_parse_am79c874_dr(uint m else status |= ((mii_reg & 0x0800) ? PHY_STAT_10FDX : PHY_STAT_10HDX); - *s = status; + fep->phy_status = status; } static phy_cmd_t const phy_cmd_am79c874_config[] = { @@ -1107,7 +1439,7 @@ static phy_info_t const phy_info_am79c87 /* register definitions for the 8721 */ #define MII_KS8721BL_RXERCR 21 -#define MII_KS8721BL_ICSR 27 +#define MII_KS8721BL_ICSR 22 #define MII_KS8721BL_PHYCR 31 static phy_cmd_t const phy_cmd_ks8721bl_config[] = { @@ -1149,32 +1481,31 @@ static phy_info_t const phy_info_ks8721b static void mii_parse_dp8384x_sr2(uint mii_reg, struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); - volatile uint *s = &(fep->phy_status); - *s &= ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC); + fep->phy_status &= ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC); /* Link up */ if (mii_reg & 0x0001) { - fep->link = 1; - *s |= PHY_STAT_LINK; + fep->linkstatus = 1; + fep->phy_status |= PHY_STAT_LINK; } else - fep->link = 0; + fep->linkstatus = 0; /* Status of link */ if (mii_reg & 0x0010) /* Autonegotioation complete */ - *s |= PHY_STAT_ANC; + fep->phy_status |= PHY_STAT_ANC; if (mii_reg & 0x0002) { /* 10MBps? */ if (mii_reg & 0x0004) /* Full Duplex? */ - *s |= PHY_STAT_10FDX; + fep->phy_status |= PHY_STAT_10FDX; else - *s |= PHY_STAT_10HDX; + fep->phy_status |= PHY_STAT_10HDX; } else { /* 100 Mbps? */ if (mii_reg & 0x0004) /* Full Duplex? */ - *s |= PHY_STAT_100FDX; + fep->phy_status |= PHY_STAT_100FDX; else - *s |= PHY_STAT_100HDX; + fep->phy_status |= PHY_STAT_100HDX; } if (mii_reg & 0x0008) - *s |= PHY_STAT_FAULT; + fep->phy_status |= PHY_STAT_FAULT; } static phy_info_t phy_info_dp83848= { @@ -1211,92 +1542,362 @@ static phy_info_t const * const phy_info &phy_info_dp83848, NULL }; - -/* ------------------------------------------------------------------------- */ -#ifdef HAVE_mii_link_interrupt -static irqreturn_t -mii_link_interrupt(int irq, void * dev_id); +#endif /* - * This is specific to the MII interrupt setup of the M5272EVB. + * do some initializtion based architecture of this chip +MOVED to platform_data hooks! */ -static void __inline__ fec_request_mii_intr(struct net_device *dev) -{ - if (request_irq(66, mii_link_interrupt, IRQF_DISABLED, "fec(MII)", dev) != 0) - printk("FEC: Could not allocate fec(MII) IRQ(66)!\n"); -} -static void __inline__ fec_disable_phy_intr(void) -{ - volatile unsigned long *icrp; - icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); - *icrp = 0x08000000; -} +#define PHY_POLL_LINK_ON (1 * HZ) +#define PHY_POLL_LINK_OFF (HZ / 5) -static void __inline__ fec_phy_ack_intr(void) +static int fec_mii_read(struct mii_bus *bus, int phy_id, int regnum); + +#ifdef CONFIG_PHYLIB +static void fec_link_change(struct net_device *dev) { - volatile unsigned long *icrp; - /* Acknowledge the interrupt */ - icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); - *icrp = 0x0d000000; -} -#endif + struct fec_enet_private *fep = netdev_priv(dev); + struct phy_device *phydev = fep->phy; -#ifdef CONFIG_M5272 -static void __inline__ fec_get_mac(struct net_device *dev) + if (phydev->link != fep->linkstatus || + phydev->duplex != fep->full_duplex) { + DBG(0, "%s: link status changed from %d to %d %s -> %s duplex\n", __FUNCTION__, + fep->linkstatus, phydev->link, fep->full_duplex ? "full" : "half", + phydev->duplex ? "full" : "half"); + if (phydev->link) { + fec_restart(dev, phydev->duplex); + } else { + fec_stop(dev); + } + if (fep->linkstatus != phydev->link && netif_msg_link(fep)) { + phy_print_status(phydev); + } + fep->linkstatus = phydev->link; +#if 0 + int i; + for (i = 0; i < 32; i++) { + DBG(0, "%s: PHY reg[%02x]=%04x\n", __FUNCTION__, i, + fec_mii_read(fep->mii, fep->phy_addr, i)); + } +#endif + } +} +#else +static void fec_link_change(struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); - volatile fec_t *fecp; - unsigned char *iap, tmpaddr[ETH_ALEN]; - fecp = fep->hwp; + DBG(0, "%s: link status changed from %d to %d\n", __FUNCTION__, + fep->old_linkstatus, fep->linkstatus); + if (fep->linkstatus) { + int duplex; - if (FEC_FLASHMAC) { - /* - * Get MAC address from FLASH. - * If it is all 1's or 0's, use the default. - */ - iap = (unsigned char *)FEC_FLASHMAC; - if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) && - (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0)) - iap = fec_mac_default; - if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) && - (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff)) - iap = fec_mac_default; + duplex = 0; + if (fep->phy_status & (PHY_STAT_100FDX | PHY_STAT_10FDX)) { + duplex = 1; + } + fec_restart(dev, duplex); + if (fep->phy_timer) { + mod_timer(fep->phy_timer, jiffies + PHY_POLL_LINK_ON); + } } else { - *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low; - *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16); - iap = &tmpaddr[0]; + fec_stop(dev); + if (fep->phy_timer) { + mod_timer(fep->phy_timer, jiffies + PHY_POLL_LINK_OFF); + } } - memcpy(dev->dev_addr, iap, ETH_ALEN); - - /* Adjust MAC if using default MAC address */ - if (iap == fec_mac_default) - dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index; + fep->old_linkstatus = fep->linkstatus; } -#endif -/* ------------------------------------------------------------------------- */ - -static void mii_display_status(struct net_device *dev) +static void fec_phy_timer(unsigned long data) { + struct net_device *dev = (struct net_device *)data; struct fec_enet_private *fep = netdev_priv(dev); - volatile uint *s = &(fep->phy_status); + int link_poll_interval = fep->linkstatus ? PHY_POLL_LINK_ON : PHY_POLL_LINK_OFF; - if (!fep->link && !fep->old_link) { - /* Link is still down - don't print anything */ + if (fep->old_linkstatus != fep->linkstatus) { + fec_link_change(dev); + } + mod_timer(fep->phy_timer, link_poll_interval); +} +#endif + +/* + * Code specific to Freescale i.MXC + */ +static int fec_request_intrs(struct platform_device *pdev, struct net_device *dev) +{ + int ret; + struct fec_enet_private *fep = netdev_priv(dev); + + fep->etn_irq = platform_get_irq(pdev, 0); + fep->mii_irq = platform_get_irq(pdev, 1); + + /* Setup interrupt handlers. */ + ret = request_irq(fep->etn_irq, fec_enet_interrupt, 0, "fec", dev); + if (ret != 0) { + printk(KERN_ERR "FEC: Could not allocate FEC IRQ(%d)!\n", fep->etn_irq); + return ret; + } +#ifndef CONFIG_PHYLIB + if (fep->mii_irq >= 0) { + /* TODO: disable now due to CPLD issue */ + ret = request_irq(fep->mii_irq, mii_link_interrupt, 0, "fec(MII)", dev); + if (ret != 0) { + printk(KERN_ERR "FEC: Could not allocate FEC(MII) IRQ(%d)!\n", + fep->mii_irq); + free_irq(fep->etn_irq, dev); + return ret; + } + /* + * board specific workaround should be done in board specific code + * This is unsafe anyway. An interrupt might have been asserted + * already. Use IRQ_NOAUTOEN with request_irq() to have irq initially disabled. + */ + fep->phy_int_enabled = 1; + } else { + fep->phy_timer = kzalloc(sizeof(struct timer_list), GFP_KERNEL); + if (fep->phy_timer == NULL) { + free_irq(fep->etn_irq, dev); + return -ENOMEM; + } + init_timer(fep->phy_timer); + fep->phy_timer->function = fec_phy_timer; + fep->phy_timer->data = (unsigned long)dev; + fec_link_change(dev); + } +#endif + + return 0; +} + +static void fec_release_intrs(struct net_device *dev) +{ + struct fec_enet_private *fep = netdev_priv(dev); + + free_irq(fep->etn_irq, dev); +#ifndef CONFIG_PHYLIB + if (fep->mii_irq >= 0) { + free_irq(fep->mii_irq, dev); + } +#endif +} + +#ifdef CONFIG_MACH_MX25 +/* + * i.MX25 allows RMII mode to be configured via a gasket + */ +#define FEC_MIIGSK_CFGR 0x300 +#define FEC_MIIGSK_ENR 0x308 + +#define FEC_MIIGSK_CFGR_FRCONT (1 << 6) +#define FEC_MIIGSK_CFGR_LBMODE (1 << 4) +#define FEC_MIIGSK_CFGR_EMODE (1 << 3) +#define FEC_MIIGSK_CFGR_IF_MODE_MASK (3 << 0) +#define FEC_MIIGSK_CFGR_IF_MODE_MII (0 << 0) +#define FEC_MIIGSK_CFGR_IF_MODE_RMII (1 << 0) + +#define FEC_MIIGSK_ENR_READY (1 << 2) +#define FEC_MIIGSK_ENR_EN (1 << 1) + +#ifndef DEBUG +static inline unsigned long fec_reg_read16(struct fec_enet_private *fep, unsigned int reg) +{ + return readw(fep->reg_base + reg); +} + +static inline void fec_reg_write(struct fec_enet_private *fep, unsigned int reg, unsigned long val) +{ + writew(val, fep->reg_base + reg); +} +#else +#define fec_reg_read16(fep, reg) __fec_reg_read16(fep, reg, __FUNCTION__, #reg) +#define fec_reg_write16(fep, reg, val) __fec_reg_write16(fep, reg, val, __FUNCTION__, #reg) + +static inline u16 __fec_reg_read16(struct fec_enet_private *fep, unsigned int reg, + const char *func, const char *reg_name) +{ + u16 val = readw(fep->reg_base + reg); + DBG(0, "%s: Read %04x from %s(%03x)\n", func, val, reg_name, reg); + return val; +} + +static inline void __fec_reg_write16(struct fec_enet_private *fep, unsigned int reg, + u16 val, const char *func, const char *reg_name) +{ + DBG(0, "%s: Writing %04x to %s(%03x)\n", func, val, reg_name, reg); + writew(val, fep->reg_base + reg); +} +#endif + +static void fec_localhw_setup(struct net_device *dev) +{ + struct fec_enet_private *fep = netdev_priv(dev); + int loops; + const int max_loops = 10000; + + /* + * Set up the MII gasket for RMII mode + */ + dev_dbg(&dev->dev, "enable RMII gasket\n"); + + /* disable the gasket and wait */ + fec_reg_write16(fep, FEC_MIIGSK_ENR, 0); + DBG(0, "%s: Waiting for RMII gasket idle\n", __FUNCTION__); + while (fec_reg_read16(fep, FEC_MIIGSK_ENR) & FEC_MIIGSK_ENR_READY) + udelay(1); + DBG(0, "%s: RMII gasket idle\n", __FUNCTION__); + + /* configure the gasket for RMII, 50 MHz, no loopback, no echo */ + fec_reg_write16(fep, FEC_MIIGSK_CFGR, FEC_MIIGSK_CFGR_IF_MODE_RMII); + + /* re-enable the gasket */ + fec_reg_write16(fep, FEC_MIIGSK_ENR, FEC_MIIGSK_ENR_EN); + fec_reg_read16(fep, FEC_MIIGSK_CFGR); + fec_reg_read16(fep, FEC_MIIGSK_ENR); + +#if 1 + DBG(0, "%s: Waiting for RMII gasket ready\n", __FUNCTION__); + for (loops = 0; loops < max_loops; loops++) { + if (readw(fep->reg_base + FEC_MIIGSK_ENR) & FEC_MIIGSK_ENR_READY) + break; + udelay(1); + } + if (fec_reg_read16(fep, FEC_MIIGSK_ENR) & FEC_MIIGSK_ENR_READY) { + DBG(0, "%s: RMII gasket ready after %u loops\n", __FUNCTION__, loops); + } else { + DBG(0, "%s: RMII gasket NOT ready after %u loops\n", __FUNCTION__, loops); + } +#endif +} +#else +static inline void fec_localhw_setup(struct net_device *dev) +{ +} +#endif + +static int fec_set_mii(struct net_device *dev, struct fec_enet_private *fep) +{ + unsigned long rate; + struct clk *clk; + + DBG(0, "%s: \n", __FUNCTION__); + + fec_reg_write(fep, FEC_RCR, OPT_FRAME_SIZE | RCR_MII_MODE); + fec_reg_write(fep, FEC_TCR, 0x00); + + /* + * Set MII speed to 2.5 MHz + */ + clk = clk_get(fep->dma_dev, NULL); + if (!IS_ERR(clk)) { + rate = clk_get_rate(clk); + clk_put(clk); + } else { + printk(KERN_ERR "Failed to get fec clock: %ld\n", PTR_ERR(clk)); + return PTR_ERR(clk); + } + fep->phy_speed = ((((rate + 4999999) / 2500000) / 2) & 0x3F) << 1; + fec_reg_write(fep, FEC_MSCR, fep->phy_speed); + DBG(0, "%s: clkdiv set to %u for MII clock %u at base clock %lu\n", + __FUNCTION__, fep->phy_speed >> 1, 2500000, rate); + DBG(0, "%s: actual MII clock is: %lu\n", __FUNCTION__, rate / (fep->phy_speed)); + + return 0; +} + +static const unsigned char default_mac[ETH_ALEN] = { + 0x00, 0x04, 0x9f, 0x00, 0x74, 0x4a, +}; + +#define FEC_IIM_BASE IO_ADDRESS(IIM_BASE_ADDR) +static void fec_get_mac(struct net_device *dev) +{ +#if 1 + // keep bootloader assigned MAC address + struct fec_enet_private *fep = netdev_priv(dev); + unsigned long eth_addr = fec_reg_read(fep, FEC_PALR); + dev->dev_addr[0] = eth_addr >> 24; + dev->dev_addr[1] = eth_addr >> 16; + dev->dev_addr[2] = eth_addr >> 8; + dev->dev_addr[3] = eth_addr >> 0; + eth_addr = fec_reg_read(fep, FEC_PAUR); + dev->dev_addr[5] = eth_addr >> 16; + dev->dev_addr[4] = eth_addr >> 24; +#else + int i; + unsigned long fec_mac_base = FEC_IIM_BASE + MXC_IIMKEY0; + + if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) { + fec_mac_base = FEC_IIM_BASE + MXC_IIMMAC; + } + + DBG(0, "%s: Reading MAC address from %08lx\n", __FUNCTION__, fec_mac_base); + for (i = 0; i < ETH_ALEN; i++) { + dev->dev_addr[ETH_ALEN - 1 - i] = __raw_readb(fec_mac_base + i * 4); + } + //memcpy(dev->dev_addr, default_mac, ETH_ALEN); +#endif +} + +#ifdef CONFIG_PHYLIB +static inline void fec_enable_phy_intr(struct fec_enet_private *fep) +{ +} +static inline void fec_disable_phy_intr(struct fec_enet_private *fep) +{ +} +static inline void fec_phy_ack_intr(struct fec_enet_private *fep) +{ +} +#else +static inline void fec_enable_phy_intr(struct fec_enet_private *fep) +{ + if (!fep->phy_int_enabled) { + fep->phy_int_enabled = 1; + enable_irq(fep->mii_irq); + } +} + +static inline void fec_disable_phy_intr(struct fec_enet_private *fep) +{ + if (fep->phy_int_enabled) { + disable_irq(fep->mii_irq); + fep->phy_int_enabled = 0; + } +} + +static inline void fec_phy_ack_intr(struct fec_enet_private *fep) +{ + if (fep->phy_int_enabled) { + disable_irq(fep->mii_irq); + fep->phy_int_enabled = 0; + } +} +#endif + +/* ------------------------------------------------------------------------- */ + +#ifndef CONFIG_PHYLIB +static void mii_display_status(struct net_device *dev) +{ + struct fec_enet_private *fep = netdev_priv(dev); + + if (!fep->linkstatus && !fep->old_linkstatus) { + /* Link is still down - don't print anything */ return; } printk("%s: status: ", dev->name); - if (!fep->link) { + if (!fep->linkstatus) { printk("link down"); } else { printk("link up"); - switch(*s & PHY_STAT_SPMASK) { + switch(fep->phy_status & PHY_STAT_SPMASK) { case PHY_STAT_100FDX: printk(", 100MBit Full Duplex"); break; case PHY_STAT_100HDX: printk(", 100MBit Half Duplex"); break; case PHY_STAT_10FDX: printk(", 10MBit Full Duplex"); break; @@ -1305,20 +1906,19 @@ static void mii_display_status(struct ne printk(", Unknown speed/duplex"); } - if (*s & PHY_STAT_ANC) + if (fep->phy_status & PHY_STAT_ANC) printk(", auto-negotiation complete"); } - if (*s & PHY_STAT_FAULT) + if (fep->phy_status & PHY_STAT_FAULT) printk(", remote fault"); printk(".\n"); } -static void mii_display_config(struct work_struct *work) +static void mii_display_config(struct work_struct *w) { - struct fec_enet_private *fep = container_of(work, struct fec_enet_private, phy_task); - struct net_device *dev = fep->netdev; + struct fec_enet_private *fep = container_of(w, struct fec_enet_private, phy_task); uint status = fep->phy_status; /* @@ -1326,7 +1926,7 @@ static void mii_display_config(struct wo ** the workqueue. It is thus safe to allow to reuse it. */ fep->mii_phy_task_queued = 0; - printk("%s: config: auto-negotiation ", dev->name); + //printk("%s: config: auto-negotiation ", dev->name); if (status & PHY_CONF_ANE) printk("on"); @@ -1351,11 +1951,21 @@ static void mii_display_config(struct wo fep->sequence_done = 1; } +#endif -static void mii_relink(struct work_struct *work) +#ifndef CONFIG_PHYLIB +static inline void *priv_netdev(struct fec_enet_private *fep) { - struct fec_enet_private *fep = container_of(work, struct fec_enet_private, phy_task); - struct net_device *dev = fep->netdev; + /* ugly hack, stolen from include linux/netdevice.h */ + return (char *)fep - ((sizeof(struct net_device) + + NETDEV_ALIGN_CONST) + & ~NETDEV_ALIGN_CONST); +} + +static void mii_relink(struct work_struct *w) +{ + struct fec_enet_private *fep = container_of(w, struct fec_enet_private, phy_task); + struct net_device *dev = priv_netdev(fep); int duplex; /* @@ -1363,23 +1973,19 @@ static void mii_relink(struct work_struc ** the workqueue. It is thus safe to allow to reuse it. */ fep->mii_phy_task_queued = 0; - fep->link = (fep->phy_status & PHY_STAT_LINK) ? 1 : 0; + fep->linkstatus = (fep->phy_status & PHY_STAT_LINK) ? 1 : 0; mii_display_status(dev); - fep->old_link = fep->link; + fep->old_linkstatus = fep->linkstatus; - if (fep->link) { + if (fep->linkstatus) { duplex = 0; - if (fep->phy_status - & (PHY_STAT_100FDX | PHY_STAT_10FDX)) + if (fep->phy_status & (PHY_STAT_100FDX | PHY_STAT_10FDX)) { duplex = 1; + } fec_restart(dev, duplex); - } else + } else { fec_stop(dev); - -#if 0 - enable_irq(fep->mii_irq); -#endif - + } } /* mii_queue_relink is called in interrupt context from mii_link_interrupt */ @@ -1429,15 +2035,14 @@ phy_cmd_t const phy_cmd_config[] = { static void mii_discover_phy3(uint mii_reg, struct net_device *dev) { - struct fec_enet_private *fep; + struct fec_enet_private *fep = netdev_priv(dev); int i; - fep = netdev_priv(dev); fep->phy_id |= (mii_reg & 0xffff); printk("fec: PHY @ 0x%x, ID 0x%08x", fep->phy_addr, fep->phy_id); - for(i = 0; phy_info[i]; i++) { - if(phy_info[i]->id == (fep->phy_id >> 4)) + for (i = 0; phy_info[i]; i++) { + if (phy_info[i]->id == (fep->phy_id >> 4)) break; } @@ -1456,13 +2061,9 @@ mii_discover_phy3(uint mii_reg, struct n static void mii_discover_phy(uint mii_reg, struct net_device *dev) { - struct fec_enet_private *fep; - volatile fec_t *fecp; + struct fec_enet_private *fep = netdev_priv(dev); uint phytype; - fep = netdev_priv(dev); - fecp = fep->hwp; - if (fep->phy_addr < 32) { if ((phytype = (mii_reg & 0xffff)) != 0xffff && phytype != 0) { @@ -1470,39 +2071,40 @@ mii_discover_phy(uint mii_reg, struct ne */ fep->phy_id = phytype << 16; mii_queue(dev, mk_mii_read(MII_REG_PHYIR2), - mii_discover_phy3); + mii_discover_phy3); } else { fep->phy_addr++; mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), - mii_discover_phy); + mii_discover_phy); } } else { printk("FEC: No PHY device found.\n"); /* Disable external MII interface */ - fecp->fec_mii_speed = fep->phy_speed = 0; -#ifdef HAVE_mii_link_interrupt - fec_disable_phy_intr(); -#endif + fec_disable_phy_intr(fep); + fec_reg_write(fep, FEC_MSCR, 0); } } +#endif -/* This interrupt occurs when the PHY detects a link change. -*/ -#ifdef HAVE_mii_link_interrupt +#ifndef CONFIG_PHYLIB static irqreturn_t -mii_link_interrupt(int irq, void * dev_id) +mii_link_interrupt(int irq, void *dev_id) { - struct net_device *dev = dev_id; + struct net_device *dev = dev_id; struct fec_enet_private *fep = netdev_priv(dev); - fec_phy_ack_intr(); + DBG(0, "%s: \n", __FUNCTION__); -#if 0 - disable_irq(fep->mii_irq); /* disable now, enable later */ -#endif + fec_phy_ack_intr(fep); - mii_do_cmd(dev, fep->phy->ack_int); - mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */ + /* + * Some board will trigger phy interrupt before phy enable. + * And at that moment , fep->phy is not initialized. + */ + if (fep->phy) { + mii_do_cmd(dev, fep->phy->ack_int); + mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */ + } return IRQ_HANDLED; } @@ -1511,16 +2113,31 @@ mii_link_interrupt(int irq, void * dev_i static int fec_enet_open(struct net_device *dev) { + int ret = 0; struct fec_enet_private *fep = netdev_priv(dev); /* I should reset the ring buffers here, but I don't yet know * a simple way to do that. */ - fec_set_mac_address(dev); + DBG(0, "%s: \n", __FUNCTION__); + _fec_set_mac_address(dev); - fep->sequence_done = 0; - fep->link = 0; +#ifdef CONFIG_PHYLIB + fec_restart(dev, 0); + ret = fec_connect_phy(dev, fep); + if (ret != 0) { + DBG(0, "%s: Failed to connect to PHY: %d\n", __FUNCTION__, ret); + return ret; + } + phy_start(fep->phy); + + fep->linkstatus = fep->phy->link; + //fec_restart(dev, 0); + DBG(0, "%s: Link status is: %d\n", __FUNCTION__, fep->linkstatus); +#else + fep->linkstatus = 0; + fep->sequence_done = 0; if (fep->phy) { mii_do_cmd(dev, fep->phy->ack_int); mii_do_cmd(dev, fep->phy->config); @@ -1542,16 +2159,20 @@ fec_enet_open(struct net_device *dev) * based on this device does not implement a PHY interrupt, * so we are never notified of link change. */ - fep->link = 1; + fep->linkstatus = 1; } else { - fep->link = 1; /* lets just try it and see */ + fep->linkstatus = 1; /* lets just try it and see */ /* no phy, go full duplex, it's most likely a hub chip */ fec_restart(dev, 1); } - - netif_start_queue(dev); + fep->old_linkstatus = fep->linkstatus; +#endif fep->opened = 1; - return 0; /* Success */ +#if 1 + /* enable receiver */ + fec_reg_write(fep, FEC_RDAR, DONT_CARE); +#endif + return ret; } static int @@ -1559,15 +2180,46 @@ fec_enet_close(struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); - /* Don't know what to do yet. - */ + DBG(0, "%s: \n", __FUNCTION__); + fep->opened = 0; - netif_stop_queue(dev); - fec_stop(dev); + if (fep->linkstatus) { + fec_stop(dev); + } +#ifdef CONFIG_PHYLIB + if (fep->phy) { + DBG(0, "%s: Stopping PHY %p\n", __FUNCTION__, fep->phy); + phy_stop(fep->phy); + DBG(0, "%s: Disconnecting PHY %p\n", __FUNCTION__, fep->phy); + phy_disconnect(fep->phy); + fep->phy = NULL; + } +#endif +#if 1 + /* Whack a reset. We should wait for this. + */ + fec_reg_write(fep, FEC_ECR, FEC_ECR_RESET); + udelay(10); + + /* Mask and clear outstanding MII command interrupts. + */ + fec_reg_write(fep, FEC_EIMR, 0); + fec_reg_write(fep, FEC_EIR, FEC_ENET_MII); + fec_disable_phy_intr(fep); + /* Switch off MII */ + fec_reg_write(fep, FEC_MSCR, 0); +#endif return 0; } +static struct net_device_stats *fec_enet_get_stats(struct net_device *dev) +{ + struct fec_enet_private *fep = netdev_priv(dev); + + return &fep->stats; +} + /* Set or clear the multicast filter for this adaptor. * Skeleton taken from sunlance driver. * The CPM Ethernet implementation allows Multicast as well as individual @@ -1583,37 +2235,32 @@ fec_enet_close(struct net_device *dev) static void set_multicast_list(struct net_device *dev) { - struct fec_enet_private *fep; - volatile fec_t *ep; + struct fec_enet_private *fep = netdev_priv(dev); struct dev_mc_list *dmi; unsigned int i, j, bit, data, crc; unsigned char hash; - fep = netdev_priv(dev); - ep = fep->hwp; - - if (dev->flags&IFF_PROMISC) { - ep->fec_r_cntrl |= 0x0008; + if (dev->flags & IFF_PROMISC) { + fec_reg_write(fep, FEC_RCR, fec_reg_read(fep, FEC_RCR) | RCR_PROM); } else { - ep->fec_r_cntrl &= ~0x0008; + fec_reg_write(fep, FEC_RCR, fec_reg_read(fep, FEC_RCR) & ~RCR_PROM); if (dev->flags & IFF_ALLMULTI) { /* Catch all multicast addresses, so set the * filter to all 1's. */ - ep->fec_grp_hash_table_high = 0xffffffff; - ep->fec_grp_hash_table_low = 0xffffffff; + fec_reg_write(fep, FEC_IAUR, ~0); + fec_reg_write(fep, FEC_IALR, ~0); } else { /* Clear filter and add the addresses in hash register. */ - ep->fec_grp_hash_table_high = 0; - ep->fec_grp_hash_table_low = 0; + fec_reg_write(fep, FEC_IAUR, 0); + fec_reg_write(fep, FEC_IALR, 0); dmi = dev->mc_list; - for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) - { + for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) { /* Only support group multicast for now. */ if (!(dmi->dmi_addr[0] & 1)) @@ -1621,13 +2268,11 @@ static void set_multicast_list(struct ne /* calculate crc32 value of mac address */ - crc = 0xffffffff; + crc = ~0; - for (i = 0; i < dmi->dmi_addrlen; i++) - { + for (i = 0; i < dmi->dmi_addrlen; i++) { data = dmi->dmi_addr[i]; - for (bit = 0; bit < 8; bit++, data >>= 1) - { + for (bit = 0; bit < 8; bit++, data >>= 1) { crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CRC32_POLY : 0); } @@ -1639,9 +2284,13 @@ static void set_multicast_list(struct ne hash = (crc >> (32 - HASH_BITS)) & 0x3f; if (hash > 31) - ep->fec_grp_hash_table_high |= 1 << (hash - 32); + fec_reg_write(fep, FEC_IAUR, + fec_reg_read(fep, FEC_IAUR) | + (1 << (hash - 32))); else - ep->fec_grp_hash_table_low |= 1 << hash; + fec_reg_write(fep, FEC_IALR, + fec_reg_read(fep, FEC_IALR) | + (1 << hash)); } } } @@ -1650,106 +2299,272 @@ static void set_multicast_list(struct ne /* Set a MAC change in hardware. */ static void -fec_set_mac_address(struct net_device *dev) +_fec_set_mac_address(struct net_device *dev) { - volatile fec_t *fecp; - - fecp = ((struct fec_enet_private *)netdev_priv(dev))->hwp; + struct fec_enet_private *fep = netdev_priv(dev); /* Set station address. */ - fecp->fec_addr_low = dev->dev_addr[3] | (dev->dev_addr[2] << 8) | - (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24); - fecp->fec_addr_high = (dev->dev_addr[5] << 16) | - (dev->dev_addr[4] << 24); + fec_reg_write(fep, FEC_PALR, dev->dev_addr[3] | (dev->dev_addr[2] << 8) | + (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24)); + fec_reg_write(fep, FEC_PAUR, (dev->dev_addr[5] << 16) | + (dev->dev_addr[4] << 24)); +} + +static int +fec_set_mac_address(struct net_device *dev, void *_addr) +{ + struct sockaddr *addr = _addr; + + if (!is_valid_ether_addr((const char *)&addr->sa_data)) { + printk(KERN_WARNING "Bad ethernet address: %02x:%02x:%02x:%02x:%02x:%02x\n", + addr->sa_data[0], addr->sa_data[1], addr->sa_data[2], addr->sa_data[3], + addr->sa_data[4], addr->sa_data[5]); + return -EINVAL; + } + printk(KERN_DEBUG "Setting MAC address to %02x:%02x:%02x:%02x:%02x:%02x\n", + addr->sa_data[0], addr->sa_data[1], addr->sa_data[2], addr->sa_data[3], + addr->sa_data[4], addr->sa_data[5]); + + memcpy(&dev->dev_addr, &addr->sa_data, ETH_ALEN); + _fec_set_mac_address(dev); + + return 0; } - /* - * XXX: We need to clean up on failure exits here. - * - * index is only used in legacy code - */ -int __init fec_enet_init(struct net_device *dev, int index) +static void fec_enet_free_buffers(struct fec_enet_private *fep) +{ + cbd_t *bdp = fep->rx_bd_base; + int i; + + DBG(0, "%s: Freeing TX bounce buffers %p\n", __FUNCTION__, fep->tx_bounce[0]); + kfree(fep->tx_bounce[0]); + memset(fep->tx_bounce, 0, TX_RING_SIZE * sizeof(void*)); + for (i = 0; i < RX_RING_SIZE; i++, bdp++) { + if (fep->rx_skbuff[i] != NULL) { + DBG(0, "%s: Freeing RX skb %p\n", __FUNCTION__, fep->rx_skbuff[i]); + fec_enet_rxbuf_unmap(fep, bdp, FEC_ENET_RX_FRSIZE); + kfree_skb(fep->rx_skbuff[i]); + fep->rx_skbuff[i] = NULL; + } + } +} + +#ifdef CONFIG_PHYLIB +/* called by the generic PHY layer in interrupt context */ +static int phy_regs[32] = { [0 ... ARRAY_SIZE(phy_regs) - 1] = -1}; +static int fec_mii_read(struct mii_bus *bus, int phy_id, int regnum) { + int ret; + struct net_device *dev = bus->priv; struct fec_enet_private *fep = netdev_priv(dev); - unsigned long mem_addr; - volatile cbd_t *bdp; - cbd_t *cbd_base; - volatile fec_t *fecp; - int i, j; + unsigned long regval = mk_mii_read(regnum) | phy_id << 23; + unsigned long flags; + int loops = 0; - /* Allocate memory for buffer descriptors. - */ - mem_addr = (unsigned long)dma_alloc_coherent(NULL, PAGE_SIZE, - &fep->bd_dma, GFP_KERNEL); - if (mem_addr == 0) { - printk("FEC: allocate descriptor memory failed?\n"); + DBG(1, "%s: \n", __FUNCTION__); +#if 0 + DBG(0, "%s: ECR: %08lx\n", __FUNCTION__, fec_reg_read(fep, FEC_ECR)); + DBG(0, "%s: EIR: %08lx\n", __FUNCTION__, fec_reg_read(fep, FEC_EIR)); + DBG(0, "%s: EIMR: %08lx\n", __FUNCTION__, fec_reg_read(fep, FEC_EIMR)); + DBG(0, "%s: RCR: %08lx\n", __FUNCTION__, fec_reg_read(fep, FEC_RCR)); + DBG(0, "%s: TCR: %08lx\n", __FUNCTION__, fec_reg_read(fep, FEC_TCR)); +#endif + spin_lock_irqsave(&fep->lock, flags); + fep->mii_complete = 0; + fec_reg_write(fep, FEC_MMFR, regval); + spin_unlock_irqrestore(&fep->lock, flags); + + while (!fep->mii_complete) { + if (loops++ == 1000) { + DBG(1, "%s: Waiting for MII completion\n", __FUNCTION__); + } + cpu_relax(); + } + if (loops >= 1000) { + DBG(1, "%s: MII transaction completed\n", __FUNCTION__); + } + ret = fec_reg_read(fep, FEC_MMFR); + if (ret < 0) { + DBG(0, "%s: Failed to read PHY[%02x] reg %02x: %d\n", __FUNCTION__, + phy_id, regnum, ret); + return ret; + } + ret &= 0xffff; + if (phy_regs[regnum] != ret) { + DBG(1, "%s: Read %04x from PHY[%02x] reg %02x\n", __FUNCTION__, + ret, phy_id, regnum); + phy_regs[regnum] = ret; + } + return ret; +} + +static int fec_mii_write(struct mii_bus *bus, int phy_id, int regnum, u16 val) +{ + struct net_device *dev = bus->priv; + struct fec_enet_private *fep = netdev_priv(dev); + unsigned long regval = mk_mii_write(regnum, val) | phy_id << 23; + unsigned long flags; + + DBG(0, "%s: \n", __FUNCTION__); + + spin_lock_irqsave(&fep->lock, flags); + fep->mii_complete = 0; + fec_reg_write(fep, FEC_MMFR, regval); + spin_unlock_irqrestore(&fep->lock, flags); + + while (!fep->mii_complete) { + cpu_relax(); + } + DBG(1, "%s: Wrote %04x to PHY[%02x] reg %02x\n", __FUNCTION__, val, phy_id, regnum); + return 0; +} + +static int fec_mii_reset(struct mii_bus *bus) +{ + DBG(0, "%s: \n", __FUNCTION__); + memset(phy_regs, -1, sizeof(phy_regs)); + return 0; +} + +static int fec_init_phy(struct net_device *dev, struct fec_enet_private *fep) +{ + int ret; + int i; + struct mii_bus *mii; + + mii = mdiobus_alloc(); + if (mii == NULL) { return -ENOMEM; } + mii->name = "fec mii"; + mii->read = fec_mii_read; + mii->write = fec_mii_write; + mii->reset = fec_mii_reset; + mii->priv = dev; + snprintf(mii->id, MII_BUS_ID_SIZE, "%x", 0); + mii->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); + for (i = 0; i < PHY_MAX_ADDR; i++) { + mii->irq[i] = fep->mii_irq >= 0 ? fep->mii_irq : PHY_POLL; + } + + ret = mdiobus_register(mii); + if (ret != 0) { + DBG(0, "%s: Failed to register MII bus: %d\n", __FUNCTION__, ret); + kfree(mii->irq); + mdiobus_free(mii); + return ret; + } + fep->phy_addr = -1; + DBG(0, "%s: MII bus registered\n", __FUNCTION__); + for (i = 0; i < PHY_MAX_ADDR; i++) { + if (mii->phy_map[i] != NULL) { + fep->phy_addr = i; + break; + } + } + if (fep->phy_addr == -1) { + DBG(0, "%s: No PHY found\n", __FUNCTION__); + return -ENODEV; + } + DBG(0, "%s: Using PHY at addr %02x\n", __FUNCTION__, fep->phy_addr); + fep->mii = mii; - spin_lock_init(&fep->hw_lock); - spin_lock_init(&fep->mii_lock); + return 0; +} - /* Create an Ethernet device instance. - */ - fecp = (volatile fec_t *)dev->base_addr; +static int fec_connect_phy(struct net_device *dev, struct fec_enet_private *fep) +{ + struct mii_bus *mii = fep->mii; - fep->index = index; - fep->hwp = fecp; - fep->netdev = dev; + DBG(0, "%s: Connecting PHY at addr %02x\n", __FUNCTION__, + fep->phy_addr); - /* Whack a reset. We should wait for this. - */ - fecp->fec_ecntrl = 1; - udelay(10); + fep->phy = phy_connect(dev, dev_name(&mii->phy_map[fep->phy_addr]->dev), + fec_link_change, 0, mii->phy_map[fep->phy_addr]->interface); + if (IS_ERR(fep->phy)) { + int ret = PTR_ERR(fep->phy); + printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); + fep->phy = NULL; + return ret; + } + DBG(0, "%s: Registered PHY %s[%02x] IRQ %d with %s\n", __FUNCTION__, + dev_name(&fep->phy->dev), fep->phy_addr, fep->phy->irq, dev->name); - /* Set the Ethernet address */ -#ifdef CONFIG_M5272 - fec_get_mac(dev); + return 0; +} #else - { - unsigned long l; - l = fecp->fec_addr_low; - dev->dev_addr[0] = (unsigned char)((l & 0xFF000000) >> 24); - dev->dev_addr[1] = (unsigned char)((l & 0x00FF0000) >> 16); - dev->dev_addr[2] = (unsigned char)((l & 0x0000FF00) >> 8); - dev->dev_addr[3] = (unsigned char)((l & 0x000000FF) >> 0); - l = fecp->fec_addr_high; - dev->dev_addr[4] = (unsigned char)((l & 0xFF000000) >> 24); - dev->dev_addr[5] = (unsigned char)((l & 0x00FF0000) >> 16); - } +static int fec_init_phy(struct net_device *dev, struct fec_enet_private *fep) +{ + /* Queue up command to detect the PHY and initialize the + * remainder of the interface. + */ + fep->phy_id_done = 0; + fep->phy_addr = 0; + mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy); + + return 0; +} #endif - cbd_base = (cbd_t *)mem_addr; +/* Initialize the FEC Ethernet on 860T (or ColdFire 5272). + */ + /* + * XXX: We need to clean up on failure exits here. + */ - /* Set receive and transmit descriptor base. +int __devinit fec_enet_init(struct platform_device *pdev, struct net_device *dev) +{ + int ret; + struct fec_enet_private *fep = netdev_priv(dev); + cbd_t *bdp; + struct sk_buff *pskb; + int i; + void *mem; + + spin_lock_init(&fep->lock); + + /* Whack a reset. We should wait for this. */ - fep->rx_bd_base = cbd_base; - fep->tx_bd_base = cbd_base + RX_RING_SIZE; + fec_reg_write(fep, FEC_ECR, FEC_ECR_RESET); + udelay(10); + + /* Set the Ethernet address. If using multiple Enets on the 8xx, + * this needs some work to get unique addresses. + * + * This is our default MAC address unless the user changes + * it via eth_mac_addr (our dev->set_mac_addr handler). + */ + fec_get_mac(dev); fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; fep->cur_rx = fep->rx_bd_base; fep->skb_cur = fep->skb_dirty = 0; - /* Initialize the receive buffer descriptors. + /* allocate memory for TX bounce buffers */ + mem = kzalloc(TX_RING_SIZE * FEC_ENET_TX_FRSIZE, GFP_KERNEL); + if (mem == NULL) { + return -ENOMEM; + } + + fec_enet_cbd_get(fep); + + /* Initialize the transmit buffer descriptors. */ - bdp = fep->rx_bd_base; - for (i=0; itx_bd_base; - /* Allocate a page. - */ - mem_addr = __get_free_page(GFP_KERNEL); - /* XXX: missing check for allocation failure */ + DBG(0, "%s: Allocated %d byte of TX buffer memory @ %p\n", __FUNCTION__, + TX_RING_SIZE * FEC_ENET_TX_FRSIZE, mem); + for (i = 0; i < TX_RING_SIZE; i++) { + fep->tx_bounce[i] = mem; + DBG(0, "%s: TX bounce buffer[%d]=%p\n", __FUNCTION__, i, fep->tx_bounce[i]); + mem = (void *)((unsigned long)(mem + FEC_ENET_TX_FRSIZE)); /* Initialize the BD for every fragment in the page. */ - for (j=0; jcbd_sc = BD_ENET_RX_EMPTY; - bdp->cbd_bufaddr = __pa(mem_addr); - mem_addr += FEC_ENET_RX_FRSIZE; - bdp++; - } + bdp->cbd_bufaddr = ~0; + bdp++; } /* Set the last buffer to wrap. @@ -1757,87 +2572,88 @@ int __init fec_enet_init(struct net_devi bdp--; bdp->cbd_sc |= BD_SC_WRAP; - /* ...and the same for transmmit. + /* ...and the same for receive. */ - bdp = fep->tx_bd_base; - for (i=0, j=FEC_ENET_TX_FRPPG; i= FEC_ENET_TX_FRPPG) { - mem_addr = __get_free_page(GFP_KERNEL); - j = 1; - } else { - mem_addr += FEC_ENET_TX_FRSIZE; - j++; + bdp = fep->rx_bd_base; + for (i = 0; i < RX_RING_SIZE; i++, bdp++) { + pskb = __dev_alloc_skb(FEC_ENET_RX_FRSIZE, GFP_KERNEL); + if (pskb == NULL) { + DBG(0, "%s: Failed to allocate RX skb; cleaning up\n", __FUNCTION__); + ret = -ENOMEM; + goto cleanup; } - fep->tx_bounce[i] = (unsigned char *) mem_addr; - - /* Initialize the BD for every fragment in the page. - */ - bdp->cbd_sc = 0; - bdp->cbd_bufaddr = 0; - bdp++; + DBG(0, "%s: RX skb allocated @ %p\n", __FUNCTION__, pskb); + fep->rx_skbuff[i] = pskb; + pskb->data = FEC_ADDR_ALIGNMENT(pskb->data); + bdp->cbd_sc = BD_ENET_RX_EMPTY; + bdp->cbd_bufaddr = ~0; + fec_enet_rxbuf_map(fep, bdp, pskb->data, FEC_ENET_RX_FRSIZE); } - /* Set the last buffer to wrap. */ bdp--; bdp->cbd_sc |= BD_SC_WRAP; + fec_enet_cbd_put(fep); /* Set receive and transmit descriptor base. */ - fecp->fec_r_des_start = fep->bd_dma; - fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t) - * RX_RING_SIZE; - -#ifdef HAVE_mii_link_interrupt - fec_request_mii_intr(dev); -#endif - - fecp->fec_grp_hash_table_high = 0; - fecp->fec_grp_hash_table_low = 0; - fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; - fecp->fec_ecntrl = 2; - fecp->fec_r_des_active = 0; -#ifndef CONFIG_M5272 - fecp->fec_hash_table_high = 0; - fecp->fec_hash_table_low = 0; -#endif + fec_reg_write(fep, FEC_ERDSR, fep->cbd_phys_base); + fec_reg_write(fep, FEC_ETDSR, fep->cbd_phys_base + RX_RING_SIZE * sizeof(cbd_t)); + /* Install our interrupt handlers. This varies depending on + * the architecture. + */ + ret = fec_request_intrs(pdev, dev); + if (ret != 0) { + goto cleanup; + } + /* Clear and enable interrupts */ + fec_reg_write(fep, FEC_EIR, fec_reg_read(fep, FEC_EIR)); + fec_reg_write(fep, FEC_EIMR, FEC_ENET_TXF | FEC_ENET_TXB | + FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); + + fec_reg_write(fep, FEC_IAUR, 0); + fec_reg_write(fep, FEC_IALR, 0); + fec_reg_write(fep, FEC_EMRBR, PKT_MAXBLR_SIZE); + fec_reg_write(fep, FEC_ECR, FEC_ECR_ETHER_EN); + fec_localhw_setup(dev); +#if 0 + /* do this in enet_open()! */ + fec_reg_write(fep, FEC_RDAR, DONT_CARE); +#endif /* The FEC Ethernet specific entries in the device structure. */ dev->open = fec_enet_open; dev->hard_start_xmit = fec_enet_start_xmit; dev->tx_timeout = fec_timeout; dev->watchdog_timeo = TX_TIMEOUT; dev->stop = fec_enet_close; + dev->get_stats = fec_enet_get_stats; dev->set_multicast_list = set_multicast_list; + dev->set_mac_address = fec_set_mac_address; - for (i=0; ifec_r_cntrl = OPT_FRAME_SIZE | 0x04; - fecp->fec_x_cntrl = 0x00; - - /* - * Set MII speed to 2.5 MHz - */ - fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999) - / 2500000) / 2) & 0x3F) << 1; - fecp->fec_mii_speed = fep->phy_speed; - fec_restart(dev, 0); - - /* Clear and enable interrupts */ - fecp->fec_ievent = 0xffc00000; - fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII); - - /* Queue up command to detect the PHY and initialize the - * remainder of the interface. - */ - fep->phy_id_done = 0; - fep->phy_addr = 0; - mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy); + ret = fec_set_mii(dev, fep); + if (ret) { + DBG(0, "%s: Failed to initialize MII interface: %d\n", __FUNCTION__, ret); + goto cleanup; + } + ret = fec_init_phy(dev, fep); + if (ret) { + DBG(0, "%s: Failed to initialize PHY: %d\n", __FUNCTION__, ret); + goto cleanup; + } return 0; + cleanup: + fec_enet_free_buffers(fep); + fec_enet_cbd_put(fep); + return ret; } /* This function is called to start or restart the FEC during a link @@ -1847,60 +2663,67 @@ int __init fec_enet_init(struct net_devi static void fec_restart(struct net_device *dev, int duplex) { - struct fec_enet_private *fep; - volatile cbd_t *bdp; - volatile fec_t *fecp; + struct fec_enet_private *fep = netdev_priv(dev); + cbd_t *bdp; int i; + u32 rcr = OPT_FRAME_SIZE | RCR_MII_MODE; /* MII enable */ + u32 tcr = TCR_HBC; - fep = netdev_priv(dev); - fecp = fep->hwp; - + DBG(0, "%s: Restarting FEC in %s-duplex mode\n", __FUNCTION__, + duplex ? "full" : "half"); /* Whack a reset. We should wait for this. - */ - fecp->fec_ecntrl = 1; + */ + fec_reg_write(fep, FEC_ECR, FEC_ECR_RESET); udelay(10); + /* Enable interrupts we wish to service. + */ + fec_reg_write(fep, FEC_EIMR, FEC_ENET_TXF | FEC_ENET_TXB | + FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); + /* Clear any outstanding interrupt. - */ - fecp->fec_ievent = 0xffc00000; + * + */ + fec_reg_write(fep, FEC_EIR, FEC_ENET_MASK); + + fec_enable_phy_intr(fep); /* Set station address. - */ - fec_set_mac_address(dev); + */ + _fec_set_mac_address(dev); /* Reset all multicast. - */ - fecp->fec_grp_hash_table_high = 0; - fecp->fec_grp_hash_table_low = 0; + */ + fec_reg_write(fep, FEC_IAUR, 0); + fec_reg_write(fep, FEC_IALR, 0); /* Set maximum receive buffer size. - */ - fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; + */ + fec_reg_write(fep, FEC_EMRBR, PKT_MAXBLR_SIZE); /* Set receive and transmit descriptor base. - */ - fecp->fec_r_des_start = fep->bd_dma; - fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t) - * RX_RING_SIZE; + */ + fec_reg_write(fep, FEC_ERDSR, fep->cbd_phys_base); + fec_reg_write(fep, FEC_ETDSR, fep->cbd_phys_base + RX_RING_SIZE * sizeof(cbd_t)); fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; fep->cur_rx = fep->rx_bd_base; /* Reset SKB transmit buffers. - */ + */ fep->skb_cur = fep->skb_dirty = 0; - for (i=0; i<=TX_RING_MOD_MASK; i++) { + bdp = fep->tx_bd_base; + for (i = 0; i <= TX_RING_MOD_MASK; i++) { if (fep->tx_skbuff[i] != NULL) { - dev_kfree_skb_any(fep->tx_skbuff[i]); - fep->tx_skbuff[i] = NULL; + fec_free_skb(fep, bdp, &fep->tx_skbuff[i]); + bdp++; } } /* Initialize the receive buffer descriptors. - */ + */ bdp = fep->rx_bd_base; - for (i=0; icbd_sc = BD_ENET_RX_EMPTY; @@ -1908,246 +2731,366 @@ fec_restart(struct net_device *dev, int } /* Set the last buffer to wrap. - */ + */ bdp--; bdp->cbd_sc |= BD_SC_WRAP; /* ...and the same for transmmit. - */ + */ bdp = fep->tx_bd_base; - for (i=0; icbd_sc = 0; - bdp->cbd_bufaddr = 0; + bdp->cbd_bufaddr = ~0; bdp++; } /* Set the last buffer to wrap. - */ + */ bdp--; bdp->cbd_sc |= BD_SC_WRAP; /* Enable MII mode. - */ + */ if (duplex) { - fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;/* MII enable */ - fecp->fec_x_cntrl = 0x04; /* FD enable */ + tcr |= TCR_FDEN; /* FD enable */ } else { - /* MII enable|No Rcv on Xmit */ - fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x06; - fecp->fec_x_cntrl = 0x00; + rcr |= RCR_DRT; /* No Rcv on Xmit */ } + fec_reg_write(fep, FEC_RCR, rcr); + fec_reg_write(fep, FEC_TCR, tcr); fep->full_duplex = duplex; /* Set MII speed. - */ - fecp->fec_mii_speed = fep->phy_speed; + */ + fec_reg_write(fep, FEC_MSCR, fep->phy_speed); /* And last, enable the transmit and receive processing. - */ - fecp->fec_ecntrl = 2; - fecp->fec_r_des_active = 0; + */ + fec_reg_write(fep, FEC_ECR, FEC_ECR_ETHER_EN); + fec_localhw_setup(dev); + fec_reg_write(fep, FEC_RDAR, DONT_CARE); - /* Enable interrupts we wish to service. - */ - fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII); + DBG(0, "%s: Starting netif queue\n", __FUNCTION__); + netif_start_queue(dev); } static void fec_stop(struct net_device *dev) { - volatile fec_t *fecp; - struct fec_enet_private *fep; + struct fec_enet_private *fep = netdev_priv(dev); - fep = netdev_priv(dev); - fecp = fep->hwp; + DBG(0, "%s: Stopping netif queue\n", __FUNCTION__); + netif_stop_queue(dev); /* - ** We cannot expect a graceful transmit stop without link !!! - */ - if (fep->link) - { - fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */ + * We cannot expect a graceful transmit stop without link! + */ + if (fep->linkstatus) { + fec_reg_write(fep, FEC_TCR, 0x01); /* Graceful transmit stop */ udelay(10); - if (!(fecp->fec_ievent & FEC_ENET_GRA)) - printk("fec_stop : Graceful transmit stop did not complete !\n"); - } - + if (!(fec_reg_read(fep, FEC_EIR) & FEC_ENET_GRA)) + dev_warn(&dev->dev, "Graceful transmit stop did not complete!\n"); + } +#if 0 /* Whack a reset. We should wait for this. - */ - fecp->fec_ecntrl = 1; + */ + fec_reg_write(fep, FEC_ECR, FEC_ECR_RESET); udelay(10); - - /* Clear outstanding MII command interrupts. - */ - fecp->fec_ievent = FEC_ENET_MII; - - fecp->fec_imask = FEC_ENET_MII; - fecp->fec_mii_speed = fep->phy_speed; + /* Mask and clear outstanding MII command interrupts. + */ + fec_reg_write(fep, FEC_EIMR, 0); + fec_reg_write(fep, FEC_EIR, FEC_ENET_MII); + fec_enable_phy_intr(fep); + fec_reg_write(fep, FEC_MSCR, fep->phy_speed); +#endif } -static int __devinit -fec_probe(struct platform_device *pdev) +static int __devinit fec_enet_probe(struct platform_device *pdev) { + int ret; struct fec_enet_private *fep; - struct net_device *ndev; - int i, irq, ret = 0; - struct resource *r; - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!r) - return -ENXIO; + struct net_device *dev; + struct fec_enet_platform_data *pdata = pdev->dev.platform_data; + struct resource *res_mem1; + struct resource *res_mem2; + + res_mem1 = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res_mem1 == NULL) { + return -ENODEV; + } - r = request_mem_region(r->start, resource_size(r), pdev->name); - if (!r) + res_mem1 = request_mem_region(res_mem1->start, + resource_size(res_mem1), + DRV_NAME); + if (res_mem1 == NULL) { return -EBUSY; + } + res_mem2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (res_mem2 != NULL) { + res_mem2 = request_mem_region(res_mem2->start, + resource_size(res_mem2), + DRV_NAME); + if (res_mem2 == NULL) { + ret = -EBUSY; + goto release1; + } + } - /* Init network device */ - ndev = alloc_etherdev(sizeof(struct fec_enet_private)); - if (!ndev) - return -ENOMEM; - - SET_NETDEV_DEV(ndev, &pdev->dev); - - /* setup board info structure */ - fep = netdev_priv(ndev); - memset(fep, 0, sizeof(*fep)); + dev = alloc_etherdev(sizeof(struct fec_enet_private)); + if (dev == NULL) { + ret = -ENOMEM; + goto release2; + } + platform_set_drvdata(pdev, dev); + fep = netdev_priv(dev); + fep->res_mem1 = res_mem1; + fep->res_mem2 = res_mem2; + fep->dma_dev = &pdev->dev; + + fep->reg_base = ioremap(res_mem1->start, resource_size(res_mem1)); + if (fep->reg_base == NULL) { + printk("FEC: Mapping FEC registers failed\n"); + ret = -ENOMEM; + goto free_netdev; + } + DBG(0, "%s: FEC registers @ %08lx mapped to %p\n", __FUNCTION__, + (unsigned long)res_mem1->start, fep->reg_base); - ndev->base_addr = (unsigned long)ioremap(r->start, resource_size(r)); + fep->mib_base = ioremap(res_mem2->start, resource_size(res_mem2)); + if (fep->mib_base == NULL) { + printk("FEC: Mapping FEC registers failed\n"); + ret = -ENOMEM; + goto unmap1; + } + DBG(0, "%s: FEC registers @ %08lx mapped to %p\n", __FUNCTION__, + (unsigned long)res_mem2->start, fep->mib_base); - if (!ndev->base_addr) { + /* Allocate memory for buffer descriptors. */ + fep->cbd_mem_base = dma_alloc_coherent(&pdev->dev, CBD_BUF_SIZE, + &fep->cbd_phys_base, + GFP_KERNEL); + if (fep->cbd_mem_base == NULL) { + printk("FEC: allocate descriptor memory failed\n"); ret = -ENOMEM; - goto failed_ioremap; + goto unmap2; } + DBG(0, "%s: Allocated %lu [(%u + %lu) * %d] byte for CBD buffer @ %p[%08lx]\n", + __FUNCTION__, CBD_BUF_SIZE, TX_RING_SIZE, RX_RING_SIZE, + sizeof(cbd_t), fep->cbd_mem_base, + (unsigned long)fep->cbd_phys_base); - platform_set_drvdata(pdev, ndev); + /* Set receive and transmit descriptor base. + */ + fep->rx_bd_base = fep->cbd_mem_base; + fep->tx_bd_base = fep->rx_bd_base + RX_RING_SIZE; - /* This device has up to three irqs on some platforms */ - for (i = 0; i < 3; i++) { - irq = platform_get_irq(pdev, i); - if (i && irq < 0) - break; - ret = request_irq(irq, fec_enet_interrupt, IRQF_DISABLED, pdev->name, ndev); - if (ret) { - while (i >= 0) { - irq = platform_get_irq(pdev, i); - free_irq(irq, ndev); - i--; - } - goto failed_irq; - } + printk("FEC ENET Driver\n"); + ret = platform_func(pdata->arch_init, pdev); + if (ret != 0) { + dev_err(&pdev->dev, "platform init failed: %d\n", ret); + goto free_dma; } - fep->clk = clk_get(&pdev->dev, "fec_clk"); - if (IS_ERR(fep->clk)) { - ret = PTR_ERR(fep->clk); - goto failed_clk; + ret = fec_enet_init(pdev, dev); + if (ret != 0) { + goto fec_disable; } - clk_enable(fep->clk); - ret = fec_enet_init(ndev, 0); - if (ret) - goto failed_init; + /* Enable most messages by default */ + fep->msg_enable = (NETIF_MSG_IFUP << 1) - 1; + ret = register_netdev(dev); + if (ret != 0) { + /* XXX: missing cleanup here */ + goto free_buffers; + } - ret = register_netdev(ndev); - if (ret) - goto failed_register; + printk(KERN_INFO "%s: ethernet %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, + dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], + dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); return 0; -failed_register: -failed_init: - clk_disable(fep->clk); - clk_put(fep->clk); -failed_clk: - for (i = 0; i < 3; i++) { - irq = platform_get_irq(pdev, i); - if (irq > 0) - free_irq(irq, ndev); - } -failed_irq: - iounmap((void __iomem *)ndev->base_addr); -failed_ioremap: - free_netdev(ndev); + free_buffers: + fec_enet_free_buffers(fep); + + fec_disable: + platform_func(pdata->arch_exit, pdev); + + free_dma: + dma_free_coherent(&pdev->dev, CBD_BUF_SIZE, fep->cbd_mem_base, fep->cbd_phys_base); + + unmap2: + if (fep->mib_base) + iounmap(fep->mib_base); + + unmap1: + iounmap(fep->reg_base); + + free_netdev: + free_netdev(dev); + + release2: + if (res_mem2 != NULL) { + release_resource(res_mem2); + } + + release1: + release_resource(res_mem1); return ret; } -static int __devexit -fec_drv_remove(struct platform_device *pdev) +static int __devexit fec_enet_remove(struct platform_device *pdev) { - struct net_device *ndev = platform_get_drvdata(pdev); - struct fec_enet_private *fep = netdev_priv(ndev); + struct net_device *dev = platform_get_drvdata(pdev); + struct fec_enet_private *fep = netdev_priv(dev); + + unregister_netdev(dev); + free_netdev(dev); + +#ifdef CONFIG_PHYLIB + if (fep->mii != NULL) { + kfree(fep->mii->irq); + mdiobus_unregister(fep->mii); + } + mdiobus_free(fep->mii); +#endif + fec_release_intrs(dev); + + DBG(0, "%s: Unmapping FEC registers %p\n", __FUNCTION__, fep->reg_base); + iounmap(fep->reg_base); + if (fep->mib_base) + iounmap(fep->mib_base); + + fec_enet_free_buffers(fep); - platform_set_drvdata(pdev, NULL); + DBG(0, "%s: Freeing CBD buffer area %p[%08lx]\n", __FUNCTION__, + fep->cbd_mem_base, (unsigned long)fep->cbd_phys_base); + dma_free_coherent(&pdev->dev, CBD_BUF_SIZE, fep->cbd_mem_base, fep->cbd_phys_base); - fec_stop(ndev); - clk_disable(fep->clk); - clk_put(fep->clk); - iounmap((void __iomem *)ndev->base_addr); - unregister_netdev(ndev); - free_netdev(ndev); + release_resource(fep->res_mem1); + if (fep->res_mem2 != NULL) { + release_resource(fep->res_mem2); + } return 0; } -static int -fec_suspend(struct platform_device *dev, pm_message_t state) +static void fec_enet_shutdown(struct platform_device *pdev) { - struct net_device *ndev = platform_get_drvdata(dev); - struct fec_enet_private *fep; + struct fec_enet_platform_data *pdata = pdev->dev.platform_data; + + DBG(0, "%s: Shutting down FEC Hardware\n", __FUNCTION__); + platform_func(pdata->arch_exit, pdev); +} + +#ifdef CONFIG_PM +static int fec_enet_suspend(struct platform_device *pdev, pm_message_t state) +{ + int ret; + struct fec_enet_platform_data *pdata = pdev->dev.platform_data; + struct net_device *ndev = platform_get_drvdata(pdev); + struct fec_enet_private *fep = netdev_priv(ndev); - if (ndev) { - fep = netdev_priv(ndev); - if (netif_running(ndev)) { - netif_device_detach(ndev); - fec_stop(ndev); + if (netif_running(ndev)) { + DBG(0, "%s: Detaching netif\n", __FUNCTION__); + netif_device_detach(ndev); +#ifdef CONFIG_PHYLIB + DBG(0, "%s: Disconnecting PHY %p\n", __FUNCTION__, fep->phy); + phy_disconnect(fep->phy); + fep->phy = NULL; +#endif + } +#ifndef CONFIG_PHYLIB + if (fep->phy_timer) { + ret = del_timer_sync(fep->phy_timer); + if (ret != 0) { + DBG(0, "%s: Failed to delete PHY timer: %d\n", __FUNCTION__, ret); + return ret; } } - return 0; +#endif + DBG(0, "%s: Shutting down FEC Hardware %d\n", __FUNCTION__, + netif_running(ndev)); + ret = platform_func(pdata->suspend, pdev); + if (ret != 0 && netif_running(ndev)) { + DBG(0, "%s: Failed to suspend: %d\n", __FUNCTION__, ret); + /* Undo suspend */ +#ifdef CONFIG_PHYLIB + DBG(0, "%s: Reconnecting PHY\n", __FUNCTION__); + if (fec_connect_phy(ndev, fep) != 0) { + DBG(0, "%s: Failed to connect to PHY\n", __FUNCTION__); + return ret; + } + phy_start(fep->phy); +#endif + fec_link_change(ndev); + netif_device_attach(ndev); + } + return ret; } -static int -fec_resume(struct platform_device *dev) +static int fec_enet_resume(struct platform_device *pdev) { - struct net_device *ndev = platform_get_drvdata(dev); + int ret; + struct fec_enet_platform_data *pdata = pdev->dev.platform_data; + struct net_device *ndev = platform_get_drvdata(pdev); - if (ndev) { - if (netif_running(ndev)) { - fec_enet_init(ndev, 0); - netif_device_attach(ndev); + DBG(0, "%s: Powering up FEC Hardware %d\n", __FUNCTION__, + netif_running(ndev)); + ret = platform_func(pdata->resume, pdev); + if (ret != 0) { + DBG(0, "%s: Failed to resume: %d\n", __FUNCTION__, ret); + return ret; + } + if (netif_running(ndev)) { +#ifdef CONFIG_PHYLIB + struct fec_enet_private *fep = netdev_priv(ndev); + + DBG(0, "%s: Reconnecting PHY\n", __FUNCTION__); + ret = fec_connect_phy(ndev, fep); + if (ret != 0) { + DBG(0, "%s: Failed to connect to PHY: %d\n", __FUNCTION__, ret); + return ret; } + phy_start(fep->phy); +#endif + fec_link_change(ndev); + netif_device_attach(ndev); } return 0; } +#else +#define fec_enet_suspend NULL +#define fec_enet_resume NULL +#endif -static struct platform_driver fec_driver = { - .driver = { - .name = "fec", - .owner = THIS_MODULE, +static struct platform_driver fec_enet_driver = { + .driver = { + .name = DRV_NAME, }, - .probe = fec_probe, - .remove = __devexit_p(fec_drv_remove), - .suspend = fec_suspend, - .resume = fec_resume, + .probe = fec_enet_probe, + .remove = __devexit_p(fec_enet_remove), + .shutdown = fec_enet_shutdown, + .suspend = fec_enet_suspend, + .resume = fec_enet_resume, }; -static int __init -fec_enet_module_init(void) +static int __init fec_enet_module_init(void) { - printk(KERN_INFO "FEC Ethernet Driver\n"); + int ret; + + ret = platform_driver_register(&fec_enet_driver); - return platform_driver_register(&fec_driver); + return ret; } +module_init(fec_enet_module_init); -static void __exit -fec_enet_cleanup(void) +static void __exit fec_enet_module_cleanup(void) { - platform_driver_unregister(&fec_driver); + platform_driver_unregister(&fec_enet_driver); } - -module_exit(fec_enet_cleanup); -module_init(fec_enet_module_init); +module_exit(fec_enet_module_cleanup); MODULE_LICENSE("GPL"); diff -urNp linux-2.6.30-rc4/drivers/net/fec.h linux-2.6.30-rc4-karo/drivers/net/fec.h --- linux-2.6.30-rc4/drivers/net/fec.h 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/drivers/net/fec.h 2009-06-02 18:43:03.000000000 +0200 @@ -13,6 +13,15 @@ #define FEC_H /****************************************************************************/ +/* + * dummy value to write into RDAR,TDAR. FEC hardware will scan the TX/RX + * descriptors in memory upon any write access to those registers. + * The actual value written to those registers does not matter. +*/ +#define DONT_CARE 0 +#define RDAR_BUSY (1 << 24) +#define TDAR_BUSY (1 << 24) + #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC) /* @@ -20,6 +29,36 @@ * registers in the same peripheral device on different models * of the ColdFire! */ +// relying on structure alignment for hardware register is just evil +#ifndef GARBAGE +#define FEC_EIR 0x004 +#define FEC_EIMR 0x008 +#define FEC_RDAR 0x010 +#define FEC_TDAR 0x014 +#define FEC_ECR 0x024 +#define FEC_MMFR 0x040 +#define FEC_MSCR 0x044 +#define FEC_MIBC 0x064 +#define FEC_RCR 0x084 +#define FEC_TCR 0x0c4 +#define FEC_PALR 0x0e4 +#define FEC_PAUR 0x0e8 +#define FEC_OPD 0x0ec +#define FEC_IAUR 0x118 +#define FEC_IALR 0x11c +#define FEC_GAUR 0x120 +#define FEC_GALR 0x124 +#define FEC_TFWR 0x144 +#define FEC_FRBR 0x14c +#define FEC_FRSR 0x150 +#define FEC_ERDSR 0x180 +#define FEC_ETDSR 0x184 +#define FEC_EMRBR 0x188 + +#define FEC_ECR_RESET (1 << 0) +#define FEC_ECR_ETHER_EN (1 << 1) +#else + typedef struct fec { unsigned long fec_reserved0; unsigned long fec_ievent; /* Interrupt event reg */ @@ -57,6 +96,7 @@ typedef struct fec { unsigned long fec_x_des_start; /* Transmit descriptor ring */ unsigned long fec_r_buff_size; /* Maximum receive buff size */ } fec_t; +#endif #else @@ -88,8 +128,8 @@ typedef struct fec { unsigned long fec_reserved7[158]; unsigned long fec_addr_low; /* Low 32bits MAC address */ unsigned long fec_addr_high; /* High 16bits MAC address */ - unsigned long fec_grp_hash_table_high;/* High 32bits hash table */ - unsigned long fec_grp_hash_table_low; /* Low 32bits hash table */ + unsigned long fec_hash_table_high; /* High 32bits hash table */ + unsigned long fec_hash_table_low; /* Low 32bits hash table */ unsigned long fec_r_des_start; /* Receive descriptor ring */ unsigned long fec_x_des_start; /* Transmit descriptor ring */ unsigned long fec_r_buff_size; /* Maximum receive buff size */ @@ -103,17 +143,20 @@ typedef struct fec { /* * Define the buffer descriptor structure. */ -#ifdef CONFIG_ARCH_MXC +/* Please see "Receive Buffer Descriptor Field Definitions" in Specification. + * It's LE. + */ +#if defined(CONFIG_ARCH_MXC) typedef struct bufdesc { - unsigned short cbd_datlen; /* Data length */ - unsigned short cbd_sc; /* Control and status info */ - unsigned long cbd_bufaddr; /* Buffer address */ + unsigned short cbd_datlen; /* Data length */ + unsigned short cbd_sc; /* Control and status info */ + dma_addr_t cbd_bufaddr; /* Buffer address as seen by FEC Hardware */ } cbd_t; #else typedef struct bufdesc { unsigned short cbd_sc; /* Control and status info */ unsigned short cbd_datlen; /* Data length */ - unsigned long cbd_bufaddr; /* Buffer address */ + dma_addr_t cbd_bufaddr; /* Buffer address */ } cbd_t; #endif @@ -121,7 +164,7 @@ typedef struct bufdesc { * The following definitions courtesy of commproc.h, which where * Copyright (c) 1997 Dan Malek (dmalek@jlc.net). */ -#define BD_SC_EMPTY ((ushort)0x8000) /* Recieve is empty */ +#define BD_SC_EMPTY ((ushort)0x8000) /* Receive is empty */ #define BD_SC_READY ((ushort)0x8000) /* Transmit is ready */ #define BD_SC_WRAP ((ushort)0x2000) /* Last buffer descriptor */ #define BD_SC_INTRPT ((ushort)0x1000) /* Interrupt on change */ @@ -168,5 +211,22 @@ typedef struct bufdesc { #define BD_ENET_TX_STATS ((ushort)0x03ff) /* All status bits */ +#define RCR_LOOP (1 << 0) +#define RCR_DRT (1 << 1) +#define RCR_MII_MODE (1 << 2) +#define RCR_PROM (1 << 3) +#define RCR_BC_REJ (1 << 4) +#define RCR_FCE (1 << 5) +#define RCR_MAX_FL_SHIFT 16 +#define RCR_MAX_FL_MASK (0x7ff << (RCR_MAX_FL_SHIFT)) +#define RCR_MAX_FL_set(n) (((n) << (RCR_MAX_FL_SHIFT)) & (RCR_MAX_FL_MASK)) +#define RCR_MAX_FL_get(n) (((n) & (RCR_MAX_FL_MASK)) >> (RCR_MAX_FL_SHIFT)) + +#define TCR_GTS (1 << 0) +#define TCR_HBC (1 << 1) +#define TCR_FDEN (1 << 2) +#define TCR_TFCPAUSE (1 << 3) +#define TCR_RFCPAUSE (1 << 4) + /****************************************************************************/ #endif /* FEC_H */ diff -urNp linux-2.6.30-rc4/drivers/video/imxfb.c linux-2.6.30-rc4-karo/drivers/video/imxfb.c --- linux-2.6.30-rc4/drivers/video/imxfb.c 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/drivers/video/imxfb.c 2009-06-02 18:58:52.000000000 +0200 @@ -570,7 +570,7 @@ static int imxfb_resume(struct platform_ #define imxfb_resume NULL #endif -static int __init imxfb_init_fbinfo(struct platform_device *pdev) +static int __devinit imxfb_init_fbinfo(struct platform_device *pdev) { struct imx_fb_platform_data *pdata = pdev->dev.platform_data; struct fb_info *info = dev_get_drvdata(&pdev->dev); @@ -636,7 +636,7 @@ static int __init imxfb_init_fbinfo(stru return 0; } -static int __init imxfb_probe(struct platform_device *pdev) +static int __devinit imxfb_probe(struct platform_device *pdev) { struct imxfb_info *fbi; struct fb_info *info; @@ -754,7 +754,7 @@ failed_map: failed_getclock: iounmap(fbi->regs); failed_ioremap: - release_mem_region(res->start, res->end - res->start); + release_mem_region(res->start, resource_size(res)); failed_req: kfree(info->pseudo_palette); failed_init: @@ -763,7 +763,7 @@ failed_init: return ret; } -static int __devexit imxfb_remove(struct platform_device *pdev) +static int imxfb_remove(struct platform_device *pdev) { struct imx_fb_platform_data *pdata; struct fb_info *info = platform_get_drvdata(pdev); @@ -785,7 +785,7 @@ static int __devexit imxfb_remove(struct framebuffer_release(info); iounmap(fbi->regs); - release_mem_region(res->start, res->end - res->start + 1); + release_mem_region(res->start, resource_size(res)); clk_disable(fbi->clk); clk_put(fbi->clk); @@ -794,7 +794,7 @@ static int __devexit imxfb_remove(struct return 0; } -void imxfb_shutdown(struct platform_device * dev) +void imxfb_shutdown(struct platform_device *dev) { struct fb_info *info = platform_get_drvdata(dev); struct imxfb_info *fbi = info->par; @@ -804,7 +804,8 @@ void imxfb_shutdown(struct platform_dev static struct platform_driver imxfb_driver = { .suspend = imxfb_suspend, .resume = imxfb_resume, - .remove = __devexit_p(imxfb_remove), +// .remove = __devexit_p(imxfb_remove), + .remove = imxfb_remove, .shutdown = imxfb_shutdown, .driver = { .name = DRIVER_NAME, diff -urNp linux-2.6.30-rc4/include/linux/fec_enet.h linux-2.6.30-rc4-karo/include/linux/fec_enet.h --- linux-2.6.30-rc4/include/linux/fec_enet.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.30-rc4-karo/include/linux/fec_enet.h 2009-03-16 12:49:03.000000000 +0100 @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2007 Lothar Wassmann + * + * platform_data definitions for fec_enet device + * + * 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 + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + */ + +struct fec_enet_platform_data { + /* callback for platform specific initialization */ + int (*arch_init)(struct platform_device *dev); + void (*arch_exit)(struct platform_device *dev); + int (*suspend)(struct platform_device *dev); + int (*resume)(struct platform_device *dev); +}; diff -urNp linux-2.6.30-rc4/kernel/printk.c linux-2.6.30-rc4-karo/kernel/printk.c --- linux-2.6.30-rc4/kernel/printk.c 2009-05-13 09:46:19.000000000 +0200 +++ linux-2.6.30-rc4-karo/kernel/printk.c 2009-06-02 19:21:25.000000000 +0200 @@ -637,9 +637,12 @@ static int acquire_console_semaphore_for static const char recursion_bug_msg [] = KERN_CRIT "BUG: recent printk recursion!\n"; static int recursion_bug; -static int new_text_line = 1; + static int new_text_line = 1; static char printk_buf[1024]; +#ifdef CONFIG_DEBUG_LL +extern void asmlinkage printascii(const char *); +#endif asmlinkage int vprintk(const char *fmt, va_list args) { int printed_len = 0; @@ -687,6 +690,9 @@ asmlinkage int vprintk(const char *fmt, sizeof(printk_buf) - printed_len, fmt, args); +#ifdef CONFIG_DEBUG_LL + printascii(printk_buf); +#endif /* * Copy the output into log_buf. If the caller didn't provide * appropriate log level tags, we insert them here